mirror of
https://github.com/lxsang/ant-http
synced 2024-11-17 17:08:20 +01:00
cont.
This commit is contained in:
parent
353323f93a
commit
a86a2d150e
5
httpd.c
5
httpd.c
@ -140,11 +140,6 @@ void configure_context(SSL_CTX *ctx)
|
||||
|
||||
#endif
|
||||
|
||||
void schedule_task(antd_task_t* task)
|
||||
{
|
||||
antd_add_task(&scheduler, task);
|
||||
}
|
||||
|
||||
|
||||
void stop_serve(int dummy) {
|
||||
UNUSED(dummy);
|
||||
|
119
lib/h2.c
119
lib/h2.c
@ -1,9 +1,57 @@
|
||||
#include "h2.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
static int antd_h2_read_frame_header(antd_client_t* cl, antd_h2_frame_header_t* frame)
|
||||
{
|
||||
frame->length = 0;
|
||||
frame->type = 0;
|
||||
frame->flags = 0;
|
||||
frame->identifier= 0;
|
||||
uint8_t header[9];
|
||||
if( antd_recv(cl,& header,sizeof(header)) != sizeof(header)) return 0;
|
||||
// network byte order is big endian
|
||||
// read frame length
|
||||
frame->length = (*header << 16) + (*(header + 1)<< 8) + *(header+2);
|
||||
// frame type
|
||||
frame->type = *(header + 3);
|
||||
// frame flags
|
||||
frame->flags = *(header + 4);
|
||||
// frame identifier
|
||||
frame->identifier = ((*(header + 5) & 0x7F) << 24) + (*(header + 6)<< 16) + (*(header + 7)<< 8) + *(header + 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int process_frame(void* source, antd_h2_frame_header_t* frame_h)
|
||||
{
|
||||
// verify frame
|
||||
printf("Frame type: %d\n", frame_h->type & 0xff);
|
||||
printf("Frame flag: %d\n",frame_h->flags);
|
||||
printf("frame identifier: %d\n", frame_h->identifier);
|
||||
uint8_t* frame_data = (uint8_t*)malloc(frame_h->length);
|
||||
if(!frame_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
antd_request_t* rq = (antd_request_t*) source;
|
||||
if(antd_recv(rq->client,frame_data,frame_h->length) != frame_h->length)
|
||||
{
|
||||
// TODO error
|
||||
// go away
|
||||
ERROR("Cannot read all frame data");
|
||||
free(frame_data);
|
||||
return H2_NO_ERROR;
|
||||
}
|
||||
|
||||
free(frame_data);
|
||||
return H2_NO_ERROR;
|
||||
}
|
||||
|
||||
void* antd_h2_preface_ck(void* data)
|
||||
{
|
||||
char buf[25];
|
||||
antd_h2_frame_header_t frame_h;
|
||||
antd_request_t* rq = (antd_request_t*) data;
|
||||
int count = antd_recv(rq->client,buf,24);
|
||||
if(count != 24)
|
||||
@ -11,7 +59,7 @@ void* antd_h2_preface_ck(void* data)
|
||||
// TODO servers MUST treat an invalid connection preface as a
|
||||
// connection error (Section 5.4.1) of type PROTOCOL_ERROR
|
||||
ERROR("Unable to read preface for client %d: [%s]",rq->client->sock,buf);
|
||||
return antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io);
|
||||
return antd_empty_task((void *)rq,rq->client->last_io);
|
||||
}
|
||||
buf[24] = '\0';
|
||||
if(strcmp(buf, H2_CONN_PREFACE) != 0)
|
||||
@ -19,8 +67,19 @@ void* antd_h2_preface_ck(void* data)
|
||||
ERROR("Connection preface is not correct for client %d: [%s]",rq->client->sock,buf);
|
||||
// TODO servers MUST treat an invalid connection preface as a
|
||||
// connection error (Section 5.4.1) of type PROTOCOL_ERROR
|
||||
return antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io);
|
||||
return antd_empty_task((void *)rq, rq->client->last_io);
|
||||
}
|
||||
// read the setting frame
|
||||
if(!antd_h2_read_frame_header(rq->client, &frame_h) || frame_h.type != H2_FRM_SETTINGS)
|
||||
{
|
||||
// TODO: frame error
|
||||
//
|
||||
// send go away with PROTOCOL_ERROR
|
||||
printf("error reading setting frame\n");
|
||||
ERROR("Unable to read setting frame from client %d",rq->client->sock);
|
||||
return antd_empty_task((void *)rq, rq->client->last_io);
|
||||
}
|
||||
process_frame(rq, &frame_h);
|
||||
return antd_create_task(antd_h2_handle, (void *)rq, NULL, rq->client->last_io);
|
||||
}
|
||||
|
||||
@ -30,15 +89,11 @@ void* antd_h2_handle(void* data)
|
||||
antd_task_t* task;
|
||||
if(rq->client->flags & CLIENT_FL_READABLE)
|
||||
{
|
||||
task = antd_create_task(antd_h2_read,(void *)rq, NULL, rq->client->last_io);
|
||||
task->priority++;
|
||||
schedule_task(task);
|
||||
antd_h2_read(data);
|
||||
}
|
||||
if(rq->client->flags & CLIENT_FL_WRITABLE)
|
||||
{
|
||||
task = antd_create_task(antd_h2_write,(void *)rq, NULL, rq->client->last_io);
|
||||
task->priority++;
|
||||
schedule_task(task);
|
||||
antd_h2_write(data);
|
||||
}
|
||||
|
||||
task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io);
|
||||
@ -46,56 +101,26 @@ void* antd_h2_handle(void* data)
|
||||
return task;
|
||||
}
|
||||
|
||||
static int antd_h2_read_frame(antd_client_t* cl, antd_h2_frame_t* frame)
|
||||
{
|
||||
uint8_t tmp;
|
||||
frame->length = 0;
|
||||
frame->type = 0;
|
||||
frame->flags = 0;
|
||||
frame->identifier= 0;
|
||||
if( antd_recv(cl,& frame->length,24) != 24) return 0;
|
||||
printf("length is %d\n", frame->length);
|
||||
// TODO:
|
||||
// Values greater than 2^14 (16,384) MUST NOT be
|
||||
// sent unless the receiver has set a larger value for
|
||||
// SETTINGS_MAX_FRAME_SIZE.
|
||||
if( antd_recv(cl,& frame->type,8) != 8) return 0;
|
||||
printf("type is %d\n", frame->type);
|
||||
if( antd_recv(cl,& frame->flags,8) != 8) return 0;
|
||||
if( antd_recv(cl,& tmp,1) != 1) return 0;
|
||||
// identifier
|
||||
if( antd_recv(cl,& frame->identifier,31) != 31) return 0;
|
||||
frame->data = (uint8_t*) malloc(frame->length);
|
||||
if(!frame->data) return 0;
|
||||
if( antd_recv(cl,frame->data, frame->length) != frame->length)
|
||||
{
|
||||
free(frame->data);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* antd_h2_read(void* data)
|
||||
{
|
||||
antd_h2_frame_t frame;
|
||||
antd_h2_frame_header_t frame_h;
|
||||
antd_request_t* rq = (antd_request_t*) data;
|
||||
antd_task_t* task;
|
||||
if(!antd_h2_read_frame(rq->client, &frame))
|
||||
if(!antd_h2_read_frame_header(rq->client, &frame_h))
|
||||
{
|
||||
// TODO: frame error
|
||||
printf("error reading frame\n");
|
||||
// send goaway frame
|
||||
ERROR("Unable to read frame from client %d",rq->client->sock);
|
||||
task = antd_create_task(NULL, (void *)rq, NULL, time(NULL));
|
||||
task->priority++;
|
||||
return task;
|
||||
return antd_empty_task(data, rq->client->last_io);
|
||||
}
|
||||
// verify frame
|
||||
printf("Frame type: %d\n", frame.type & 0xff);
|
||||
return antd_create_task(NULL, data, NULL, time(NULL));
|
||||
process_frame(data, &frame_h);
|
||||
return antd_empty_task(data, rq->client->last_io);
|
||||
}
|
||||
void* antd_h2_write(void* data)
|
||||
{
|
||||
antd_request_t* rq = (antd_request_t*) data;
|
||||
printf("write task\n");
|
||||
return antd_create_task(NULL, data, NULL, time(NULL));
|
||||
return antd_empty_task(data, rq->client->last_io);
|
||||
}
|
82
lib/h2.h
82
lib/h2.h
@ -16,6 +16,81 @@
|
||||
#define H2_FRM_WINDOW_UPDATE 0x8
|
||||
#define H2_FRM_CONTINUATION 0x9
|
||||
|
||||
// ERROR code
|
||||
/*
|
||||
The associated condition is not a result of an
|
||||
error. For example, a GOAWAY might include this code to indicate
|
||||
graceful shutdown of a connection.
|
||||
*/
|
||||
#define H2_NO_ERROR 0x0
|
||||
/*
|
||||
The endpoint detected an unspecific protocol
|
||||
error. This error is for use when a more specific error code is
|
||||
not available.
|
||||
*/
|
||||
#define H2_PROTOCOL_ERROR 0x1
|
||||
/*
|
||||
The endpoint encountered an unexpected
|
||||
internal error.
|
||||
*/
|
||||
#define H2_INTERNAL_ERROR 0x2
|
||||
/*
|
||||
The endpoint detected that its peer
|
||||
violated the flow-control protocol.
|
||||
*/
|
||||
#define H2_FLOW_CONTROL_ERROR 0x3
|
||||
/*
|
||||
The endpoint sent a SETTINGS frame but did
|
||||
not receive a response in a timely manner. See Section 6.5.3
|
||||
("Settings Synchronization").
|
||||
*/
|
||||
#define H2_SETTINGS_TIMEOUT 0x4
|
||||
/*
|
||||
The endpoint received a frame after a stream
|
||||
was half-closed.
|
||||
*/
|
||||
#define H2_STREAM_CLOSED 0x5
|
||||
/*
|
||||
The endpoint received a frame with an invalid size.
|
||||
*/
|
||||
#define H2_FRAME_SIZE_ERROR 0x6
|
||||
/*
|
||||
The endpoint refused the stream prior to
|
||||
performing any application processing (see Section 8.1.4 for
|
||||
details).
|
||||
*/
|
||||
#define H2_REFUSED_STREAM 0x7
|
||||
/*
|
||||
Used by the endpoint to indicate that the stream is no
|
||||
longer needed.
|
||||
*/
|
||||
#define H2_CANCEL 0x8
|
||||
/*
|
||||
The endpoint is unable to maintain the
|
||||
header compression context for the connection.
|
||||
*/
|
||||
#define H2_COMPRESSION_ERROR 0x9
|
||||
/*
|
||||
The connection established in response to a CONNECT request (Section 8.3) was reset or abnormally closed.
|
||||
*/
|
||||
#define H2_CONNECT_ERROR 0xa
|
||||
/*
|
||||
The endpoint detected that its peer is
|
||||
exhibiting a behavior that might be generating excessive load.
|
||||
*/
|
||||
#define H2_ENHANCE_YOUR_CALM 0xb
|
||||
/*
|
||||
The underlying transport has properties
|
||||
that do not meet minimum security requirements (see Section 9.2).
|
||||
*/
|
||||
#define H2_INADEQUATE_SECURITY 0xc
|
||||
/*
|
||||
The endpoint requires that HTTP/1.1 be used
|
||||
instead of HTTP/2.
|
||||
*/
|
||||
#define H2_HTTP_1_1_REQUIRED 0xd
|
||||
|
||||
|
||||
/**
|
||||
* Struct that holds a
|
||||
* h2 connection
|
||||
@ -33,7 +108,7 @@ typedef struct {
|
||||
} antd_h2_stream_t;
|
||||
|
||||
/**
|
||||
* a H2 frame
|
||||
* a H2 frame header
|
||||
*/
|
||||
typedef struct {
|
||||
// 24 bits length
|
||||
@ -44,8 +119,9 @@ typedef struct {
|
||||
uint8_t flags;
|
||||
// 31 bits identifier
|
||||
unsigned int identifier;
|
||||
uint8_t* data;
|
||||
} antd_h2_frame_t;
|
||||
} antd_h2_frame_header_t;
|
||||
|
||||
|
||||
|
||||
void* antd_h2_read(void* rq);
|
||||
void* antd_h2_write(void* rq);
|
||||
|
@ -83,11 +83,6 @@ int compressable(char* ctype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void schedule_task(antd_task_t* task)
|
||||
{
|
||||
UNUSED(task);
|
||||
}
|
||||
|
||||
void htdocs(antd_request_t* rq, char* dest)
|
||||
{
|
||||
dictionary_t xheader = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER");
|
||||
|
@ -122,7 +122,6 @@ void __attribute__((weak)) dbdir(char* dest);
|
||||
void __attribute__((weak)) tmpdir(char* dest);
|
||||
void __attribute__((weak)) plugindir(char* dest);
|
||||
int __attribute__((weak)) compressable(char* ctype);
|
||||
void __attribute__((weak)) schedule_task(antd_task_t* task);
|
||||
|
||||
void set_nonblock(int socket);
|
||||
//void set_block(int socket);
|
||||
|
@ -379,3 +379,10 @@ void antd_scheduler_wait(antd_scheduler_t* scheduler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
antd_task_t* antd_empty_task(void* data,time_t t)
|
||||
{
|
||||
antd_task_t* task = antd_create_task(NULL,data,NULL,t);
|
||||
task->priority++;
|
||||
return task;
|
||||
}
|
@ -115,6 +115,8 @@ void antd_scheduler_destroy(antd_scheduler_t *);
|
||||
*/
|
||||
antd_task_t *antd_create_task(void *(*handle)(void *), void *data, void *(*callback)(void *), time_t);
|
||||
|
||||
antd_task_t* antd_empty_task(void* data, time_t);
|
||||
|
||||
/*
|
||||
add a task
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user