This commit is contained in:
lxsang 2020-01-30 14:04:07 +01:00
parent cbe7c80a8a
commit ed6ece1bc6
4 changed files with 129 additions and 44 deletions

View File

@ -1419,8 +1419,18 @@ void destroy_request(void *data)
dput(rq->request, "REQUEST_HEADER", NULL);
dput(rq->request, "REQUEST_DATA", NULL);
dput(rq->request, "COOKIE", NULL);
#ifdef USE_OPENSSL
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if(rq->client->flags & CLIENT_FL_H2_STREAM)
{
// close the stream
antd_h2_stream_t* stream = (antd_h2_stream_t*)rq->client->stream;
antd_h2_close_stream(stream);
stream->state = H2_STR_FINALIZED;
}
else
{
antd_h2_conn_t* conn = H2_CONN(data);
if(conn)
{
@ -1428,6 +1438,7 @@ void destroy_request(void *data)
antd_h2_close_conn(conn);
dput(rq->request, "H2_CONNECTION", NULL);
}
}
#endif
#endif
freedict(rq->request);

View File

@ -192,7 +192,7 @@ antd_h2_stream_t* antd_h2_init_stream(int id, int wsz)
stream->state = H2_STR_IDLE;
stream->stdin = ALLOC_QUEUE_ROOT();
stream->stdout = ALLOC_QUEUE_ROOT();
//stream->flags = 0;
stream->flags = 0;
stream->dependency = 0;
stream->weight = 255;
return stream;
@ -226,8 +226,33 @@ static void* antd_h2_stream_handle(void* data)
{
antd_request_t* rq = (antd_request_t*) data;
antd_h2_stream_t* stream = (antd_h2_stream_t*) rq->client->stream;
// transition state here
// TODO: next day
antd_task_t* task = NULL;
if(stream->state == H2_STREAM_CLOSED)
{
return antd_empty_task(data, rq->client->last_io);
}
// print header info
antd_h2_frame_t* frame = antd_h2_streamio_get(stream->stdin);
if(!frame)
{
task = antd_create_task(antd_h2_stream_handle,data,NULL,rq->client->last_io);
task->priority++;
return task;
}
// print stream status
printf("End stream: %d\n", stream->flags & H2_END_STREAM_FLG);
printf("Priority %d\n", stream->flags & H2_PRIORITY_FLG );
printf("Exclusive %d\n", stream->flags & H2_EXCLUSIVE_FLG );
printf("dependencies %d\n", stream->dependency);
printf("weight %d\n", stream->weight);
printf("frame end stream %d\n", frame->header.flags & H2_END_STREAM_FLG);
printf("frame end header %d\n", frame->header.flags & H2_END_HEADERS_FLG);
printf("frame padded %d\n", frame->header.flags & H2_PADDED_FLG);
printf("frame priority %d\n", frame->header.flags & H2_PRIORITY_FLG);
return NULL;
}
@ -263,28 +288,59 @@ static int process_header_frame(antd_request_t* rq, antd_h2_frame_header_t* fram
antd_h2_add_stream(conn->streams,stream);
is_new_stream = 1;
}
if( stream->state == H2_STR_IDLE || stream->state == H2_STR_REV_LOC || stream->state == H2_STR_OPEN || stream->state == H2_STR_HALF_CLOSED_REM )
// switch state here
switch (stream->state)
{
case H2_STR_IDLE:
stream->state = H2_STR_OPEN;
break;
case H2_STR_REV_REM:
stream->state = H2_STR_HALF_CLOSED_LOC;
break;
default:
free(data);
return H2_PROTOCOL_ERROR;
}
antd_h2_frame_t* frame = (antd_h2_frame_t*) malloc(sizeof(antd_h2_frame_t));
frame->header = *frame_h;
frame->pageload = data;
stream->flags = (frame_h->flags & H2_END_STREAM_FLG) | (frame_h->flags & H2_PRIORITY_FLG);
if(frame_h->flags & H2_PRIORITY_FLG)
{
uint8_t* ptr = data;
if(frame_h->flags & H2_PADDED_FLG)
ptr += 1;
// set stream weight + dependencies
memcpy(&stream->dependency, ptr, 4);
printf("%u\n", stream->dependency);
stream->dependency = ntohl(stream->dependency) & 0x7FFFFFFF;
printf("%d\n", *ptr);
if(*(ptr) & 0x80)
{
stream->flags |= H2_EXCLUSIVE_FLG;
}
else
{
stream->flags &= ~H2_EXCLUSIVE_FLG;
}
stream->weight = *(data + 4);
// set flag
}
h2_stream_io_put(stream,frame);
if(is_new_stream)
{
// TODO create new request
// just dump the scheduler when we have a connection
antd_schedule_task( antd_create_task(antd_h2_stream_handle, antd_h2_request_init(rq, stream) , NULL, time(NULL)));
}
return H2_NO_ERROR;
}
else
{
free(data);
return H2_PROTOCOL_ERROR;
}
}
antd_h2_frame_t* h2_streamio_get(struct queue_root* io)
antd_h2_frame_t* antd_h2_streamio_get(struct queue_root* io)
{
struct queue_head* head = queue_get(io);
if(!head) return NULL;
@ -300,11 +356,11 @@ void h2_stream_io_put(antd_h2_stream_t* stream, antd_h2_frame_t* frame)
head->data = (void*)frame;
if(frame->header.identifier % 2 == 0)
{
queue_put(head, stream->stdin);
queue_put(head, stream->stdout);
}
else
{
queue_put(head, stream->stdout);
queue_put(head, stream->stdin);
}
}

View File

@ -117,6 +117,15 @@ field value other than 0 MUST be treated as a connection error
#define H2_SETTINGS_MAX_HEADER_LIST_SIZE 0x6
/*header flag*/
#define H2_END_STREAM_FLG 0x1
#define H2_END_HEADERS_FLG 0x4
#define H2_PADDED_FLG 0x8
#define H2_PRIORITY_FLG 0x20
#define H2_EXCLUSIVE_FLG 0x40
// stream state
typedef enum {
H2_STR_IDLE,
@ -125,7 +134,8 @@ typedef enum {
H2_STR_REV_REM,
H2_STR_HALF_CLOSED_LOC,
H2_STR_HALF_CLOSED_REM,
H2_STR_CLOSED
H2_STR_CLOSED,
H2_STR_FINALIZED
} antd_h2_stream_state_t;
typedef struct{
@ -162,8 +172,8 @@ typedef struct {
struct queue_root* stdout;
int win_sz;
antd_h2_stream_state_t state;
//uint8_t flags;
int dependency;
uint8_t flags;
uint32_t dependency;
uint8_t weight;
int id;
} antd_h2_stream_t;
@ -200,7 +210,7 @@ void antd_h2_del_stream(antd_h2_stream_list_t*, int);
void antd_h2_close_all_streams(antd_h2_stream_list_t*);
void antd_h2_update_streams_win_sz(antd_h2_stream_list_t streams, int offset);
void h2_stream_io_put(antd_h2_stream_t*, antd_h2_frame_t*);
antd_h2_frame_t* h2_streamio_get(struct queue_root*);
antd_h2_frame_t* antd_h2_streamio_get(struct queue_root*);
antd_request_t* antd_h2_request_init(antd_request_t*, antd_h2_stream_t*);

View File

@ -1,4 +1,5 @@
#include "handle.h"
#define HTML_TPL "<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><h2>%s</h2></BODY></HTML>"
static const char* S_100 = "Continue";
@ -661,6 +662,10 @@ int antd_close(void* src)
}
#endif
#ifdef USE_OPENSSL
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if(!(source->flags & CLIENT_FL_H2_STREAM))
{
#endif
if(source->stream){
//printf("SSL:Shutdown ssl\n");
//SSL_shutdown((SSL*) source->ssl);
@ -676,6 +681,9 @@ int antd_close(void* src)
source->stream = NULL;
//LOG("Freeing SSL\n");
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
}
#endif
#endif
//printf("Close sock %d\n", source->sock);
int ret = close(source->id);