ant-http/lib/h2.c
2020-01-15 18:27:28 +01:00

101 lines
3.2 KiB
C

#include "h2.h"
#include "scheduler.h"
void* antd_h2_preface_ck(void* data)
{
char buf[25];
antd_request_t* rq = (antd_request_t*) data;
int count = antd_recv(rq->client,buf,24);
if(count != 24)
{
// 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);
}
buf[24] = '\0';
if(strcmp(buf, H2_CONN_PREFACE) != 0)
{
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_create_task(antd_h2_handle, (void *)rq, NULL, rq->client->last_io);
}
void* antd_h2_handle(void* data)
{
antd_request_t* rq = (antd_request_t*) 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);
}
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);
}
task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io);
task->priority++;
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_request_t* rq = (antd_request_t*) data;
antd_task_t* task;
if(!antd_h2_read_frame(rq->client, &frame))
{
// TODO: frame error
printf("error reading frame\n");
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;
}
// verify frame
printf("Frame type: %d\n", frame.type & 0xff);
return antd_create_task(NULL, data, NULL, time(NULL));
}
void* antd_h2_write(void* data)
{
printf("write task\n");
return antd_create_task(NULL, data, NULL, time(NULL));
}