1.修改nghttp2库中关于ping包处理流程

2.修改调试log信息等级为debug
3.增加http2关于缓存代码控制宏变量
4.测试存在的几个bug修复
This commit is contained in:
fengweihao
2019-04-30 16:41:01 +08:00
committed by zhengchao
parent 77d2e3fb53
commit 6ac97cce6b
5 changed files with 374 additions and 211 deletions

View File

@@ -57,12 +57,17 @@ struct http2_half_private
/* UNDERLAY BUFFER */ /* UNDERLAY BUFFER */
int method_or_status; int method_or_status;
int by_stream;
char * url_storage; char * url_storage;
struct data_t body; struct data_t body;
struct http2_headers headers; struct http2_headers headers;
struct http2_headers promised; struct http2_headers promised;
/*Read Cache**/
int32_t stream_id;
nghttp2_session *session;
enum nghttp2_manage_stage body_state; enum nghttp2_manage_stage body_state;
enum nghttp2_manage_stage message_state; enum nghttp2_manage_stage message_state;
@@ -75,21 +80,26 @@ struct http2_half_private
void (* event_cb_user_deleter)(void *); void (* event_cb_user_deleter)(void *);
}; };
struct h2_stream_data_t{ struct cache_trapper_t{
struct tfe_http_session tfe_session;
TAILQ_ENTRY(h2_stream_data_t) next;
int32_t stream_id;
int spd_set; int spd_set;
int spd_valid; int spd_valid;
int rse_set; int rse_set;
int set_cnt; //int set_cnt;
int flag_end; //int flag_end;
int spd_set_cnt; int spd_set_cnt;
int spd_cnt; int spd_cnt;
tfe_http_event spd_event; tfe_http_event spd_event;
};
struct h2_stream_data_t{
struct tfe_http_session tfe_session;
TAILQ_ENTRY(h2_stream_data_t) next;
const struct tfe_stream *tf_stream;
int32_t stream_id;
nghttp2_session *session;
struct cache_trapper_t cache;
struct http_frame_session_ctx *frame_ctx; struct http_frame_session_ctx *frame_ctx;
struct http2_half_private *req, *pangu_req; struct http2_half_private *req, *pangu_req;
struct http2_half_private *resp, *pangu_resp; struct http2_half_private *resp, *pangu_resp;
@@ -101,6 +111,8 @@ struct tfe_session_info_t
int goaway; int goaway;
int32_t stream_id;
enum tfe_stream_action stream_action; enum tfe_stream_action stream_action;
unsigned int thread_id; unsigned int thread_id;
@@ -136,6 +148,7 @@ struct stream_tap_info_t
#define TFE_NGHTTP2_RESPONSE 0x00004000 #define TFE_NGHTTP2_RESPONSE 0x00004000
#define ACTION_USER_DATA 3 #define ACTION_USER_DATA 3
#define NGHTTP2_NO_USER_ERROR 0x0e
static inline const struct http2_half_private * static inline const struct http2_half_private *
nghttp2_to_half_private(const struct tfe_http_half * half_public) nghttp2_to_half_private(const struct tfe_http_half * half_public)

View File

@@ -120,6 +120,30 @@ http2_stream_open(const struct tfe_stream *stream, unsigned int thread_id,
return 0; return 0;
} }
/*setting frame: 00 00 12 04 00 00 00 00 00 00 03 00 00 00 80 00 04 7f ff ff ff 00 05 00 ff ff ff 00 00 04 08 00
00 00 00 00 7f ff 00 00 ***/
static int
search_up_stream_data(const unsigned char * data, size_t len)
{
uint8_t indetifier = 0;
if (get_u_int8_t(data, 3) != 0x4)
return 0;
indetifier = get_u_int8_t(data, 10);
if (indetifier < NGHTTP2_SETTINGS_HEADER_TABLE_SIZE ||
indetifier > NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)
return 0;
indetifier = get_u_int8_t(data, 16);
if (indetifier < NGHTTP2_SETTINGS_HEADER_TABLE_SIZE ||
indetifier > NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)
return 0;
return 1;
}
static enum tfe_stream_action static enum tfe_stream_action
http2_stream_data(const struct tfe_stream * stream, unsigned int thread_id, http2_stream_data(const struct tfe_stream * stream, unsigned int thread_id,
enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme) enum tfe_conn_dir dir, const unsigned char * data, size_t len, void ** pme)
@@ -134,13 +158,7 @@ http2_stream_data(const struct tfe_stream * stream, unsigned int thread_id,
tfe_stream_action_set_opt(stream, ACTION_OPT_DEFER_BYTES, (void *) &defer_bytes, sizeof(defer_bytes)); tfe_stream_action_set_opt(stream, ACTION_OPT_DEFER_BYTES, (void *) &defer_bytes, sizeof(defer_bytes));
return ACTION_DEFER_DATA; return ACTION_DEFER_DATA;
} }
/*setting frame: 00 00 12 04 00 00 00 00 00 00 03 00 00 00 80 00 04 7f ff ff ff 00 05 00 ff ff ff 00 00 04 08 00 if (search_up_stream_data(data, len)){
00 00 00 00 7f ff 00 00 ***/
if (get_u_int8_t(data, 3) == 0x4
&& ((get_u_int8_t(data, 9) == 0x00 && get_u_int8_t(data, 10) == 0x03)
|| (get_u_int8_t(data, 15) == 0x00 && get_u_int8_t(data, 16) == 0x04)
|| (get_u_int8_t(data, 21) == 0x00 && get_u_int8_t(data, 22) == 0x05))){
}else{ }else{
goto finish; goto finish;
} }

View File

@@ -67,7 +67,7 @@ static const struct value_string headers_vals[] =
{TFE_HTTP_TRAILER, "Trailer"}, {TFE_HTTP_TRAILER, "Trailer"},
{TFE_HTTP_TRANSFER_ENCODING, "transfer-encoding"}, {TFE_HTTP_TRANSFER_ENCODING, "transfer-encoding"},
{TFE_HTTP_VIA, "via"}, {TFE_HTTP_VIA, "via"},
{TFE_HTTP_PRAGMA, "Pragma"}, {TFE_HTTP_PRAGMA, "pragma"},
{TFE_HTTP_CONNECTION, "connection"}, {TFE_HTTP_CONNECTION, "connection"},
{TFE_HTTP_CONT_ENCODING, "content-encoding"}, {TFE_HTTP_CONT_ENCODING, "content-encoding"},
{TFE_HTTP_CONT_LANGUAGE, "content-language"}, {TFE_HTTP_CONT_LANGUAGE, "content-language"},
@@ -283,23 +283,17 @@ void half_set_callback(struct http2_half_private * half_private,
static const char * static const char *
half_ops_field_read(const struct tfe_http_half * half, const struct http_field_name * field) half_ops_field_read(const struct tfe_http_half * half, const struct http_field_name * field)
{ {
const char *value = NULL;
struct header_data *header = NULL; struct header_data *header = NULL;
const struct http2_half_private *half_private = nghttp2_to_half_private(half); const struct http2_half_private *half_private = nghttp2_to_half_private(half);
if (unlikely(half_private == NULL)) if (unlikely(half_private == NULL))
goto finish; return NULL;
foreach_headers(&half_private->headers, header){ foreach_headers(&half_private->headers, header){
if (header->field.field_id == field->field_id){ if (http_field_name_compare(&header->field, field) != 0) continue;
break; break;
}
} }
return header != NULL ? (const char *)header->nv.value : NULL;
if (header == NULL) goto finish;
value = (const char *)header->nv.value;
finish:
return value;
} }
static int static int
@@ -317,15 +311,22 @@ half_ops_field_write(struct tfe_http_half * half, const struct http_field_name *
if (header->field.field_id == TFE_HTTP_UNKNOWN_FIELD) if (header->field.field_id == TFE_HTTP_UNKNOWN_FIELD)
continue; continue;
if (header->field.field_id == name->field_id){ if (header->field.field_id == name->field_id){
free(header->nv.value); if (value){
header->nv.value = (uint8_t*)tfe_strdup(value); free(header->nv.value);
header->nv.valuelen = strlen(value); header->nv.value = (uint8_t*)tfe_strdup(value);
header->field.field_name = (const char *)header->nv.name; header->nv.valuelen = strlen(value);
is_exist = 1; header->field.field_name = (const char *)header->nv.name;
is_exist = 1;
}else{
headers_del(headers, header);
}
break; break;
} }
} }
if (is_exist == 0){ if (is_exist == 0){
if (value == NULL){
goto finish;
}
header = ALLOC(struct header_data, 1); header = ALLOC(struct header_data, 1);
memset(header, 0, sizeof(struct header_data)); memset(header, 0, sizeof(struct header_data));
@@ -467,15 +468,24 @@ int h2_half_ops_body_begin(struct tfe_http_half * half, int by_stream)
body->gzip = HTTP2_CONTENT_ENCODING_NONE; body->gzip = HTTP2_CONTENT_ENCODING_NONE;
resp->message_state = MANAGE_STAGE_READING; resp->message_state = MANAGE_STAGE_READING;
resp->by_stream = by_stream;
} }
body->evbuf_body = evbuffer_new(); body->evbuf_body = evbuffer_new();
return 0; return 0;
} }
static tfe_stream_action
cache_frame_submit_data(int32_t stream_id, nghttp2_session *session);
static enum tfe_stream_action
cache_frame_submit_header(nghttp2_session *as_server,
int32_t stream_id);
int h2_half_ops_body_data(struct tfe_http_half * half, const unsigned char * data, size_t sz_data) int h2_half_ops_body_data(struct tfe_http_half * half, const unsigned char * data, size_t sz_data)
{ {
int xret = -1; int xret = -1;
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
struct http2_half_private * resp = nghttp2_to_half_private(half); struct http2_half_private * resp = nghttp2_to_half_private(half);
struct data_t *body = &resp->body; struct data_t *body = &resp->body;
@@ -483,21 +493,56 @@ int h2_half_ops_body_data(struct tfe_http_half * half, const unsigned char * dat
if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){ if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){
xret = deflate_write(&body->deflate, (const uint8_t *)data, sz_data, xret = deflate_write(&body->deflate, (const uint8_t *)data, sz_data,
resp->body.evbuf_body, body->gzip, 0); resp->body.evbuf_body, body->gzip, 0);
}else{ }else{
xret = evbuffer_add(resp->body.evbuf_body, data, sz_data); xret = evbuffer_add(resp->body.evbuf_body, data, sz_data);
} }
if (resp->by_stream){
stream_action = cache_frame_submit_header(resp->session, resp->stream_id);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(resp->session);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal downstream send error: %s\n",
nghttp2_strerror(xret));
}
}
stream_action = cache_frame_submit_data(resp->stream_id, resp->session);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(resp->session);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
}
}
}
return xret; return xret;
} }
int h2_half_ops_body_end(struct tfe_http_half * half) int h2_half_ops_body_end(struct tfe_http_half * half)
{ {
int xret = -1;
struct http2_half_private * resp = nghttp2_to_half_private(half); struct http2_half_private * resp = nghttp2_to_half_private(half);
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
resp->body_state = MANAGE_STAGE_COMPLETE; resp->body_state = MANAGE_STAGE_COMPLETE;
resp->message_state = MANAGE_STAGE_COMPLETE; resp->message_state = MANAGE_STAGE_COMPLETE;
if (resp->by_stream){
resp->body.flags |= NGHTTP2_FLAG_END_STREAM;
stream_action = cache_frame_submit_data(resp->stream_id, resp->session);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(resp->session);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
}
}
}
return 0; return 0;
} }
@@ -540,18 +585,22 @@ void h2_ops_drop(struct tfe_http_session * session)
void h2_ops_suspend(struct tfe_http_session * session) void h2_ops_suspend(struct tfe_http_session * session)
{ {
#ifdef TFE_CACHE
struct h2_stream_data_t *stream_data = nghttp2_to_stream_data((struct tfe_http_session *)session); struct h2_stream_data_t *stream_data = nghttp2_to_stream_data((struct tfe_http_session *)session);
stream_data->cache.spd_set = 1;
stream_data->spd_set = 1; #endif
} }
void h2_ops_resume(struct tfe_http_session * session) void h2_ops_resume(struct tfe_http_session * session)
{ {
#ifdef TFE_CACHE
struct h2_stream_data_t *stream_data = nghttp2_to_stream_data((struct tfe_http_session *)session); struct h2_stream_data_t *stream_data = nghttp2_to_stream_data((struct tfe_http_session *)session);
if (stream_data->cache.spd_valid){
if (stream_data->spd_valid){ tfe_stream_resume(stream_data->tf_stream);
stream_data->rse_set = 1; stream_data->cache.rse_set = 1;
} }
#endif
} }
void h2_ops_request_set(struct tfe_http_session * session, struct tfe_http_half * req_user) void h2_ops_request_set(struct tfe_http_session * session, struct tfe_http_half * req_user)
@@ -571,7 +620,8 @@ void h2_ops_response_set(struct tfe_http_session * session, struct tfe_http_half
} }
static struct http2_half_private* static struct http2_half_private*
tfe_half_private_init(enum tfe_http_direction direction) tfe_half_private_init(enum tfe_http_direction direction, int32_t stream_id,
nghttp2_session *session)
{ {
struct http2_half_private *half_private = ALLOC(struct http2_half_private, 1); struct http2_half_private *half_private = ALLOC(struct http2_half_private, 1);
assert(half_private); assert(half_private);
@@ -586,6 +636,9 @@ tfe_half_private_init(enum tfe_http_direction direction)
half_private->body.gzip = HTTP2_CONTENT_ENCODING_NONE; half_private->body.gzip = HTTP2_CONTENT_ENCODING_NONE;
half_private->body.padlen = 0; half_private->body.padlen = 0;
half_private->stream_id = stream_id;
half_private->session = session;
half_private->body_state = MANAGE_STAGE_INIT; half_private->body_state = MANAGE_STAGE_INIT;
half_private->message_state = MANAGE_STAGE_INIT; half_private->message_state = MANAGE_STAGE_INIT;
@@ -595,7 +648,7 @@ tfe_half_private_init(enum tfe_http_direction direction)
struct tfe_http_half * h2_ops_request_create(struct tfe_http_session * session, struct tfe_http_half * h2_ops_request_create(struct tfe_http_session * session,
enum tfe_http_std_method method, const char * uri) enum tfe_http_std_method method, const char * uri)
{ {
struct http2_half_private * req = tfe_half_private_init(TFE_HTTP_REQUEST); struct http2_half_private * req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL);
req->method_or_status = method; req->method_or_status = method;
req->url_storage = tfe_strdup(uri); req->url_storage = tfe_strdup(uri);
@@ -605,13 +658,13 @@ struct tfe_http_half * h2_ops_request_create(struct tfe_http_session * session,
struct tfe_http_half * h2_ops_response_create(struct tfe_http_session * session, int resp_code) struct tfe_http_half * h2_ops_response_create(struct tfe_http_session * session, int resp_code)
{ {
struct http2_half_private * resp = tfe_half_private_init(TFE_HTTP_RESPONSE); struct h2_stream_data_t *stream = nghttp2_to_stream_data(session);
struct http2_half_private * resp = tfe_half_private_init(TFE_HTTP_RESPONSE, stream->stream_id,
stream->session);
resp->method_or_status = resp_code; resp->method_or_status = resp_code;
struct h2_stream_data_t *stream_data = nghttp2_to_stream_data(session); if (stream->resp)
if (stream_data->resp) resp->body.gzip = stream->resp->body.gzip;
resp->body.gzip = stream_data->resp->body.gzip;
return &resp->half_public; return &resp->half_public;
} }
@@ -646,6 +699,10 @@ upstream_read_callback(nghttp2_session *session, int32_t stream_id,
int datalen = 0; int datalen = 0;
struct data_t *body = (struct data_t *)source->ptr; struct data_t *body = (struct data_t *)source->ptr;
if (!body || NULL == body->evbuf_body){
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
return datalen;
}
size_t inputlen = evbuffer_get_length(body->evbuf_body); size_t inputlen = evbuffer_get_length(body->evbuf_body);
unsigned char *input = evbuffer_pullup(body->evbuf_body, -1); unsigned char *input = evbuffer_pullup(body->evbuf_body, -1);
@@ -707,6 +764,42 @@ nghttp2_server_frame_submit_response(struct tfe_session_info_t *session_info,
return ACTION_DROP_DATA; return ACTION_DROP_DATA;
} }
static tfe_stream_action
cache_frame_submit_data(int32_t stream_id, nghttp2_session *session)
{
int rv = -1;
struct http2_headers *headers = NULL;
struct h2_stream_data_t *h2_stream = NULL;
struct http2_half_private *pangu_resp = NULL;
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session, stream_id);
if (!h2_stream){
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Cache id %d, Flow is empty", stream_id);
return stream_action;
}
pangu_resp = h2_stream->pangu_resp;
headers = &pangu_resp->headers;
if (headers->nvlen > 0){
return ACTION_FORWARD_DATA;
}
struct data_t *body = &pangu_resp->body;
nghttp2_data_provider data_prd;
data_prd.source.ptr = (void *)body;
data_prd.read_callback = upstream_read_callback;
rv = nghttp2_submit_data(session, body->flags,
stream_id, &data_prd);
if (rv != 0){
printf("Fatal data error: %s\n", nghttp2_strerror(rv));
}
return stream_action;
}
static enum tfe_stream_action static enum tfe_stream_action
server_frame_submit_data(struct tfe_session_info_t *session_info, server_frame_submit_data(struct tfe_session_info_t *session_info,
struct h2_stream_data_t *h2_stream, struct h2_stream_data_t *h2_stream,
@@ -727,8 +820,6 @@ server_frame_submit_data(struct tfe_session_info_t *session_info,
data_prd.source.ptr = (void *)body; data_prd.source.ptr = (void *)body;
data_prd.read_callback = upstream_read_callback; data_prd.read_callback = upstream_read_callback;
//printf("body->flags = %d\n", body->flags);
rv = nghttp2_submit_data(session, body->flags, rv = nghttp2_submit_data(session, body->flags,
h2_stream->stream_id, &data_prd); h2_stream->stream_id, &data_prd);
if (rv != 0){ if (rv != 0){
@@ -736,7 +827,6 @@ server_frame_submit_data(struct tfe_session_info_t *session_info,
printf("Fatal data error: %s\n", nghttp2_strerror(rv)); printf("Fatal data error: %s\n", nghttp2_strerror(rv));
} }
} }
//printf("submit data %d action = %d\n", h2_stream != NULL ? h2_stream->stream_id : NULL, stream_action);
return stream_action; return stream_action;
} }
@@ -772,7 +862,7 @@ nghttp2_submit_frame_priority(struct tfe_session_info_t *session_info,const nght
dir, nghttp2_strerror(xret)); dir, nghttp2_strerror(xret));
} }
finish: finish:
TFE_LOG_INFO(logger()->handle, "%s, %d, submit priority, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit priority, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
return 0; return 0;
@@ -804,7 +894,7 @@ nghttp2_submit_frame_rst_stream(struct tfe_session_info_t *session_info,const ng
} }
finish: finish:
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
TFE_LOG_INFO(logger()->handle, "%s, %d, submit rst stream, stream_id:%d, action:%d, error_code = %d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit rst stream, stream_id:%d, action:%d, error_code = %d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action, rst_stream->error_code); dir, frame->hd.stream_id, session_info->stream_action, rst_stream->error_code);
return 0; return 0;
} }
@@ -819,9 +909,15 @@ nghttp2_submit_frame_settings(struct tfe_session_info_t *session_info,const nght
nghttp2_settings settings = frame->settings; nghttp2_settings settings = frame->settings;
nghttp2_session *session = (dir == CONN_DIR_UPSTREAM) ? session_info->as_server : session_info->as_client; nghttp2_session *session = (dir == CONN_DIR_UPSTREAM) ? session_info->as_server : session_info->as_client;
nghttp2_session *_session = (dir == CONN_DIR_UPSTREAM) ? session_info->as_client : session_info->as_server;
if(settings.hd.flags == NGHTTP2_FLAG_ACK){ if(settings.hd.flags == NGHTTP2_FLAG_ACK){
stream_action = ACTION_FORWARD_DATA; xret = nghttp2_session_send(_session);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
}
stream_action = ACTION_DROP_DATA;
goto finish; goto finish;
} }
rv = nghttp2_submit_settings(session, settings.hd.flags, rv = nghttp2_submit_settings(session, settings.hd.flags,
@@ -840,7 +936,7 @@ nghttp2_submit_frame_settings(struct tfe_session_info_t *session_info,const nght
} }
finish: finish:
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
TFE_LOG_INFO(logger()->handle, "%s, %d, submit setting, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit setting, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
return 0; return 0;
} }
@@ -853,12 +949,8 @@ nghttp2_submit_frame_ping(struct tfe_session_info_t *session_info,const nghttp2_
enum tfe_stream_action stream_action = ACTION_DROP_DATA; enum tfe_stream_action stream_action = ACTION_DROP_DATA;
const nghttp2_ping *ping = &frame->ping; const nghttp2_ping *ping = &frame->ping;
nghttp2_session *session = (dir == CONN_DIR_UPSTREAM) ? session_info->as_server : session_info->as_client; nghttp2_session *session = (dir == CONN_DIR_UPSTREAM) ? session_info->as_server : session_info->as_client;
//if(ping->hd.flags & NGHTTP2_FLAG_ACK){
// stream_action = ACTION_FORWARD_DATA;
// goto finish;
//}
rv = nghttp2_submit_ping(session, ping->hd.flags, rv = nghttp2_submit_ping(session, ping->hd.flags,
ping->opaque_data); ping->opaque_data);
if (rv != 0){ if (rv != 0){
@@ -875,7 +967,7 @@ nghttp2_submit_frame_ping(struct tfe_session_info_t *session_info,const nghttp2_
} }
finish: finish:
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
TFE_LOG_INFO(logger()->handle, "%s, %d, submit ping, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit ping, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
return 0; return 0;
} }
@@ -919,10 +1011,6 @@ void delete_http2_stream_data(struct h2_stream_data_t *h2_stream,
const struct tfe_stream *tf_stream, const struct tfe_stream *tf_stream,
int body_flag) int body_flag)
{ {
if (tf_stream){
//nghttp2_write_access_log(h2_stream, tf_stream->str_stream_info);
}
delete_stream_half_data(&h2_stream->req, body_flag); delete_stream_half_data(&h2_stream->req, body_flag);
delete_stream_half_data(&h2_stream->resp, body_flag); delete_stream_half_data(&h2_stream->resp, body_flag);
@@ -984,7 +1072,7 @@ nghttp2_submit_frame_goaway(struct tfe_session_info_t *session_info,const nghttp
} }
finish: finish:
snprintf(error, goaway->opaque_data_len, "%s", goaway->opaque_data); snprintf(error, goaway->opaque_data_len, "%s", goaway->opaque_data);
TFE_LOG_INFO(logger()->handle, "%s, %d, submit goaway, stream_id:%d, action:%d, errod_code:%d, data:%s", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit goaway, stream_id:%d, action:%d, errod_code:%d, data:%s", session_info->tf_stream->str_stream_info,
dir, goaway->last_stream_id, session_info->stream_action, goaway->error_code, goaway->opaque_data); dir, goaway->last_stream_id, session_info->stream_action, goaway->error_code, goaway->opaque_data);
session_info->goaway = 1; session_info->goaway = 1;
@@ -1018,13 +1106,13 @@ nghttp2_submit_frame_window_update(struct tfe_session_info_t *session_info,const
} }
finish: finish:
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
TFE_LOG_INFO(logger()->handle, "%s, %d, submit window update, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit window update, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
return 0; return 0;
} }
static int static int
nghttp2_end_submit_header2(struct tfe_session_info_t *session_info, nghttp2_submit_end_header(struct tfe_session_info_t *session_info,
struct h2_stream_data_t *h2_stream) struct h2_stream_data_t *h2_stream)
{ {
int xret = -1; int xret = -1;
@@ -1038,6 +1126,10 @@ nghttp2_end_submit_header2(struct tfe_session_info_t *session_info,
if (headers.nvlen <= 0){ if (headers.nvlen <= 0){
goto finish; goto finish;
} }
if ((headers.flag & NGHTTP2_FLAG_END_STREAM) != 1 ){
goto finish;
}
stream_id = nghttp2_submit_headers(session_info->as_server, headers.flag, stream_id = nghttp2_submit_headers(session_info->as_server, headers.flag,
h2_stream->stream_id, NULL, nghttp2_nv_packet(&headers, hdrs), h2_stream->stream_id, NULL, nghttp2_nv_packet(&headers, hdrs),
headers.nvlen, h2_stream); headers.nvlen, h2_stream);
@@ -1060,7 +1152,7 @@ finish:
} }
static int static int
submit_end_data(struct tfe_session_info_t *session_info, nghttp2_submit_end_data(struct tfe_session_info_t *session_info,
struct h2_stream_data_t *h2_stream) struct h2_stream_data_t *h2_stream)
{ {
int xret = -1; int xret = -1;
@@ -1069,8 +1161,7 @@ submit_end_data(struct tfe_session_info_t *session_info,
struct http2_half_private *resp = h2_stream->resp; struct http2_half_private *resp = h2_stream->resp;
if (resp->body_state == MANAGE_STAGE_INIT){ if (resp->body_state == MANAGE_STAGE_INIT){
nghttp2_end_submit_header2(session_info, h2_stream); nghttp2_submit_end_header(session_info, h2_stream);
//return 1;
} }
if (resp->body_state != MANAGE_STAGE_INIT){ if (resp->body_state != MANAGE_STAGE_INIT){
@@ -1096,7 +1187,7 @@ submit_end_data(struct tfe_session_info_t *session_info,
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
} }
} }
TFE_LOG_INFO(logger()->handle, "%s, 1, End of stream submit, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, 1, End of stream submit, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
h2_stream->stream_id, session_info->stream_action); h2_stream->stream_id, session_info->stream_action);
if (stream_action == ACTION_USER_DATA) if (stream_action == ACTION_USER_DATA)
@@ -1112,8 +1203,9 @@ nghttp2_submit_frame_data(struct tfe_session_info_t *session_info,const nghttp2_
struct http2_half_private *resp = NULL; struct http2_half_private *resp = NULL;
struct h2_stream_data_t *h2_stream = NULL; struct h2_stream_data_t *h2_stream = NULL;
if (dir == CONN_DIR_DOWNSTREAM) if (dir == CONN_DIR_DOWNSTREAM){
goto finish; goto finish;
}
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM){ if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM){
h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session_info->as_client, h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session_info->as_client,
@@ -1126,7 +1218,7 @@ nghttp2_submit_frame_data(struct tfe_session_info_t *session_info,const nghttp2_
resp = h2_stream->resp; resp = h2_stream->resp;
resp->body.padlen = frame->data.padlen; resp->body.padlen = frame->data.padlen;
if (resp->body_state != MANAGE_STAGE_COMPLETE){ if (resp->body_state != MANAGE_STAGE_COMPLETE){
submit_end_data(session_info, h2_stream); nghttp2_submit_end_data(session_info, h2_stream);
} }
} }
finish: finish:
@@ -1161,7 +1253,7 @@ upstream_create_req(struct tfe_session_info_t *session_info, nghttp2_session *as
h2_stream->stream_id = stream_id; h2_stream->stream_id = stream_id;
h2_stream->req = tfe_half_private_init(TFE_HTTP_REQUEST); h2_stream->req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL);
tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_REQUEST); tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_REQUEST);
event = ALLOC(struct user_event_dispatch, 1); event = ALLOC(struct user_event_dispatch, 1);
@@ -1261,34 +1353,36 @@ nghttp2_submit_frame_push_promise(struct tfe_session_info_t *session_info,const
} }
session_info->stream_action = stream_action; session_info->stream_action = stream_action;
finish: finish:
TFE_LOG_INFO(logger()->handle, "%s, %d, submit push promise, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit push promise, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
return 0; return 0;
} }
static void #ifdef TFE_CACHE
static int
suspend_start(struct h2_stream_data_t *h2_stream, suspend_start(struct h2_stream_data_t *h2_stream,
struct http2_half_private *half, const struct tfe_stream *stream) struct http2_half_private *half, const struct tfe_stream *stream)
{ {
if (h2_stream->spd_valid != 1){ if (h2_stream->cache.spd_valid != 1){
return; return 0;
} }
tfe_stream_resume(stream); tfe_stream_resume(stream);
enum tfe_http_event spd_event = h2_stream->spd_event; enum tfe_http_event spd_event = h2_stream->cache.spd_event;
h2_stream->spd_event = (enum tfe_http_event)0; h2_stream->cache.spd_event = (enum tfe_http_event)0;
h2_stream->spd_valid = 0; h2_stream->cache.spd_valid = 0;
h2_stream->spd_set_cnt--; h2_stream->cache.spd_set_cnt--;
h2_stream->spd_cnt++; h2_stream->cache.spd_cnt++;
/* Call user callback, tell user we resume from suspend */ /* Call user callback, tell user we resume from suspend */
h2_stream->rse_set = 0; h2_stream->cache.rse_set = 0;
half->event_cb(half, spd_event, NULL, 0, half->event_cb_user); half->event_cb(half, spd_event, NULL, 0, half->event_cb_user);
return; return 1;
} }
#endif
static void static void
fill_resp_spec_from_handle(struct http2_half_private *half_private) fill_resp_spec_from_handle(struct http2_half_private *half_private)
@@ -1302,23 +1396,135 @@ fill_resp_spec_from_handle(struct http2_half_private *half_private)
continue; continue;
} }
if (!strncmp((char *)(head->nv.name), "content-type", strlen("content-type"))){ if (!strncmp((char *)(head->nv.name), "content-type", strlen("content-type"))){
//resp_spec->content_type = tfe_strdup((const char *)(head->nv.value));
resp_spec->content_type = (const char *)(head->nv.value); resp_spec->content_type = (const char *)(head->nv.value);
continue; continue;
} }
if (!strncmp((char *)(head->nv.name), "content-encoding", strlen("content-encoding"))){ if (!strncmp((char *)(head->nv.name), "content-encoding", strlen("content-encoding"))){
//resp_spec->content_encoding = tfe_strdup((const char *)(head->nv.value));
resp_spec->content_encoding = (const char *)(head->nv.value); resp_spec->content_encoding = (const char *)(head->nv.value);
continue; continue;
} }
if (!strncmp((char *)(head->nv.name), "content-length", strlen("content-length"))){ if (!strncmp((char *)(head->nv.name), "content-length", strlen("content-length"))){
//resp_spec->content_length = tfe_strdup((const char *)(head->nv.value));
resp_spec->content_length = (const char *)(head->nv.value); resp_spec->content_length = (const char *)(head->nv.value);
continue; continue;
} }
} }
resp_spec->content_length = 0;
return; return;
} }
static void
tfe_make_nv(struct http2_headers *headers,
const char *name,const char *value, int flag)
{
/*Add head*/
struct header_data *head = NULL;
head = ALLOC(struct header_data, 1);
head->nv.name = (uint8_t *)tfe_strdup((const char *)name);
head->nv.namelen = strlen(name);
head->nv.value = (uint8_t *)tfe_strdup((const char *)value);;
head->nv.valuelen = strlen(value);
headers->flag = 0x04;
if (flag)
headers_add_head(headers, head);
else
headers_add_tail(headers, head);
}
int
nghttp2_headers_write_log(struct h2_stream_data_t *h2_stream, const char * str_stream_info,
int dir)
{
/* Request */
struct http2_half_private *req = h2_stream->req;
/* Response */
struct http2_half_private *resp = h2_stream->resp;
/* Req-Public */
struct tfe_http_req_spec *req_spec = req ? &(req->half_public.req_spec) : NULL;
/* Resp-Public */
struct tfe_http_resp_spec *resp_spec = resp ? &(resp->half_public.resp_spec) : NULL;
const char * method = req_spec ? val_to_str(req_spec->method, method_vals) : "-";
const char * url = req_spec ? req_spec->url : "-";
char resp_code[TFE_STRING_MAX];
if (resp_spec)
snprintf(resp_code, sizeof(resp_code) - 1, "%d", resp_spec->resp_code);
else
snprintf(resp_code, sizeof(resp_code) - 1, "%s", "-");
const char * cont_type = resp_spec ? resp_spec->content_type != NULL ? resp_spec->content_type : "-" : "-";
const char * cont_encoding =
resp_spec ? resp_spec->content_encoding != NULL ? resp_spec->content_encoding : "-" : "-";
const char *hmsg = (dir == CONN_DIR_UPSTREAM) ? "response" : "request";
const char * panggu_req = h2_stream->pangu_req ? "USER/REQ" : "-";
const char * panggu_resp = h2_stream->pangu_resp ? "USER/RESP" : "-";
/* SUSPEND */
const char * suspend = h2_stream->cache.spd_cnt > 0 ? "SUSPEND" : "-";
char *access_log;
asprintf(&access_log, "%s %d %s stream_id:%d %s %s HTTP2.0 %s %s %s %s %s %s", str_stream_info, dir, hmsg, h2_stream->tfe_session.session_id,
method, url, resp_code, cont_type, cont_encoding, panggu_req, panggu_resp, suspend);
TFE_LOG_INFO(logger()->handle, "%s", access_log);
free(access_log);
return 0;
}
static enum tfe_stream_action
cache_frame_submit_header(nghttp2_session *as_server,
int32_t stream_id)
{
nghttp2_nv hdrs[128] = {0};
struct http2_headers *headers = NULL;
struct http2_half_private *pangu_resp = NULL;
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
struct h2_stream_data_t *h2_stream = NULL;
#define VALUE_LEN 128
char value[VALUE_LEN] = {0};
h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(as_server, stream_id);
if (!h2_stream){
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Cache id %d, Flow is empty", stream_id);
return stream_action;
}
pangu_resp = h2_stream->pangu_resp;
if (pangu_resp == NULL){
return ACTION_FORWARD_DATA;
}
headers = &pangu_resp->headers;
if (headers->nvlen <= 0){
return ACTION_FORWARD_DATA;
}
snprintf(value, VALUE_LEN, "%d", pangu_resp->method_or_status);
tfe_make_nv(&pangu_resp->headers, ":status", (const char *)value, 1);
snprintf(value, VALUE_LEN, "tfe/%s", tfe_version());
tfe_make_nv(&pangu_resp->headers, "X-TG-Construct-By", (const char *)value, 0);
stream_id = nghttp2_submit_headers(as_server, headers->flag,
h2_stream->stream_id, NULL, nghttp2_nv_packet(headers, hdrs),
headers->nvlen, h2_stream);
if (stream_id < 0){
printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id));
}
delete_nv_packet_data(headers);
nghttp2_headers_write_log(h2_stream, h2_stream->tf_stream->str_stream_info, CONN_DIR_UPSTREAM);
return stream_action;
}
static enum tfe_stream_action static enum tfe_stream_action
nghttp2_server_frame_submit_header(struct tfe_session_info_t *session_info, nghttp2_server_frame_submit_header(struct tfe_session_info_t *session_info,
struct h2_stream_data_t *h2_stream) struct h2_stream_data_t *h2_stream)
@@ -1347,47 +1553,14 @@ nghttp2_server_frame_submit_header(struct tfe_session_info_t *session_info,
if (stream_id < 0){ if (stream_id < 0){
printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id)); printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id));
} }
delete_nv_packet_data(headers); #ifdef tfe_cache
if (headers->flag &NGHTTP2_FLAG_END_STREAM)
#endif
delete_nv_packet_data(headers);
finish: finish:
return stream_action; return stream_action;
} }
int
nghttp2_headers_write_log(struct h2_stream_data_t *h2_stream, const char * str_stream_info,
int dir)
{
/* Request */
struct http2_half_private *req = h2_stream->req;
/* Response */
struct http2_half_private *resp = h2_stream->resp;
/* Req-Public */
struct tfe_http_req_spec *req_spec = req ? &(req->half_public.req_spec) : NULL;
/* Resp-Public */
struct tfe_http_resp_spec *resp_spec = resp ? &(resp->half_public.resp_spec) : NULL;
const char * method = req_spec ? val_to_str(req_spec->method, method_vals) : "-";
const char * url = req_spec ? req_spec->url : "-";
char resp_code[TFE_STRING_MAX];
if (resp_spec)
snprintf(resp_code, sizeof(resp_code) - 1, "%d", resp_spec->resp_code);
else
snprintf(resp_code, sizeof(resp_code) - 1, "%s", "-");
const char * cont_type = resp_spec ? resp_spec->content_type != NULL ? resp_spec->content_type : "-" : "-";
const char * cont_encoding =
resp_spec ? resp_spec->content_encoding != NULL ? resp_spec->content_encoding : "-" : "-";
const char *hmsg = (dir == CONN_DIR_UPSTREAM) ? "response" : "request";
char *access_log;
asprintf(&access_log, "%s %d %s stream_id:%d %s %s HTTP2.0 %s %s %s", str_stream_info, dir, hmsg, h2_stream->tfe_session.session_id,
method, url, resp_code, cont_type, cont_encoding);
TFE_LOG_INFO(logger()->handle, "%s", access_log);
free(access_log);
return 0;
}
static int static int
nghttp2_server_submit_header(struct tfe_session_info_t *session_info, int32_t stream_id) nghttp2_server_submit_header(struct tfe_session_info_t *session_info, int32_t stream_id)
{ {
@@ -1406,18 +1579,18 @@ nghttp2_server_submit_header(struct tfe_session_info_t *session_info, int32_t st
goto finish; goto finish;
} }
resp = h2_stream->resp; resp = h2_stream->resp;
suspend_start(h2_stream, resp, session_info->tf_stream);
fill_resp_spec_from_handle(h2_stream->resp); fill_resp_spec_from_handle(h2_stream->resp);
resp->event_cb(resp, EV_HTTP_RESP_HDR, NULL, 0, resp->event_cb_user); resp->event_cb(resp, EV_HTTP_RESP_HDR, NULL, 0, resp->event_cb_user);
if (h2_stream->spd_set){ if (h2_stream->cache.spd_set){
h2_stream->spd_event = EV_HTTP_RESP_HDR; h2_stream->cache.spd_event = EV_HTTP_RESP_HDR;
h2_stream->cache.spd_valid = 1;
h2_stream->spd_valid = 1; h2_stream->cache.spd_set = 0;
h2_stream->spd_set = 0; h2_stream->cache.spd_set_cnt++;
h2_stream->spd_set_cnt++; h2_stream->cache.spd_cnt++;
h2_stream->spd_cnt++;
tfe_stream_suspend(session_info->tf_stream, CONN_DIR_UPSTREAM); tfe_stream_suspend(session_info->tf_stream, CONN_DIR_UPSTREAM);
session_info->stream_id = stream_id;
stream_action = ACTION_DEFER_DATA; stream_action = ACTION_DEFER_DATA;
goto finish; goto finish;
} }
@@ -1451,11 +1624,13 @@ fill_req_spec_from_handle(struct http2_half_private *half_private)
continue; continue;
} }
if (!strncmp((char *)(head->nv.name), ":authority", strlen(":authority"))){ if (!strncmp((char *)(head->nv.name), ":authority", strlen(":authority"))){
//req_spec->host = tfe_strdup((const char *)(head->nv.value));
req_spec->host = (const char *)(head->nv.value); req_spec->host = (const char *)(head->nv.value);
urllen += head->nv.valuelen; urllen += head->nv.valuelen;
continue; continue;
} }
if (!strncmp((char *)(head->nv.name), ":path", strlen(":path"))){ if (!strncmp((char *)(head->nv.name), ":path", strlen(":path"))){
//req_spec->uri = tfe_strdup((const char*)(head->nv.value));
req_spec->uri = (const char*)(head->nv.value); req_spec->uri = (const char*)(head->nv.value);
urllen += head->nv.valuelen; urllen += head->nv.valuelen;
continue; continue;
@@ -1471,42 +1646,22 @@ fill_req_spec_from_handle(struct http2_half_private *half_private)
return; return;
} }
#ifdef TFE_CACHE
static int static int
suspend_stop(struct h2_stream_data_t *h2_stream, suspend_stop(struct h2_stream_data_t *h2_stream,
const struct tfe_stream *tf_stream, enum tfe_conn_dir dir) const struct tfe_stream *tf_stream, enum tfe_conn_dir dir)
{ {
int xret = -1; int xret = -1;
if (h2_stream->spd_set){ if (h2_stream->cache.spd_set){
h2_stream->spd_valid = 1; h2_stream->cache.spd_valid = 1;
h2_stream->spd_set = 0; h2_stream->cache.spd_set = 0;
tfe_stream_suspend(tf_stream, dir); tfe_stream_suspend(tf_stream, dir);
xret = 0; xret = 0;
} }
return xret; return xret;
} }
#endif
static void
tfe_make_nv(struct http2_headers *headers,
const char *name,const char *value, int flag)
{
/*Add head*/
struct header_data *head = NULL;
head = ALLOC(struct header_data, 1);
head->nv.name = (uint8_t *)tfe_strdup((const char *)name);
head->nv.namelen = strlen(name);
head->nv.value = (uint8_t *)tfe_strdup((const char *)value);;
head->nv.valuelen = strlen(value);
headers->flag = 0x04;
if (flag)
headers_add_head(headers, head);
else
headers_add_tail(headers, head);
}
static enum tfe_stream_action static enum tfe_stream_action
tfe_submit_response(struct tfe_session_info_t *session_info, tfe_submit_response(struct tfe_session_info_t *session_info,
@@ -1541,13 +1696,13 @@ tfe_submit_response(struct tfe_session_info_t *session_info,
static void static void
downstream_create_resp(struct h2_stream_data_t *h2_stream, nghttp2_session *as_client, downstream_create_resp(struct h2_stream_data_t *h2_stream, nghttp2_session *as_client,
const struct tfe_stream *tf_stream, unsigned int thread_id) nghttp2_session *as_server, const struct tfe_stream *tf_stream, unsigned int thread_id)
{ {
struct user_event_dispatch *event = NULL; struct user_event_dispatch *event = NULL;
if (h2_stream->resp) if (h2_stream->resp)
goto finish; goto finish;
h2_stream->resp = tfe_half_private_init(TFE_HTTP_RESPONSE); h2_stream->resp = tfe_half_private_init(TFE_HTTP_RESPONSE, h2_stream->stream_id, as_server);
tfe_half_session_init(h2_stream, h2_stream->stream_id, TFE_HTTP_RESPONSE); tfe_half_session_init(h2_stream, h2_stream->stream_id, TFE_HTTP_RESPONSE);
event = ALLOC(struct user_event_dispatch, 1); event = ALLOC(struct user_event_dispatch, 1);
@@ -1576,10 +1731,6 @@ nghttp2_client_frame_submit_header(struct tfe_session_info_t *session_info,
enum tfe_http_std_method method = (enum tfe_http_std_method)NGHTTP2_METHOD_UNKNOWN; enum tfe_http_std_method method = (enum tfe_http_std_method)NGHTTP2_METHOD_UNKNOWN;
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA; enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
if (0 == suspend_stop(h2_stream, session_info->tf_stream, CONN_DIR_DOWNSTREAM)){
stream_action = ACTION_DEFER_DATA;
goto finish;
}
req = h2_stream->pangu_req != NULL ? h2_stream->pangu_req : h2_stream->req; req = h2_stream->pangu_req != NULL ? h2_stream->pangu_req : h2_stream->req;
if (req == NULL){ if (req == NULL){
stream_action = ACTION_FORWARD_DATA; stream_action = ACTION_FORWARD_DATA;
@@ -1596,7 +1747,8 @@ nghttp2_client_frame_submit_header(struct tfe_session_info_t *session_info,
goto finish; goto finish;
} }
/*Create C' half_private_resp**/ /*Create C' half_private_resp**/
downstream_create_resp(h2_stream, session_info->as_client, session_info->tf_stream, session_info->thread_id); downstream_create_resp(h2_stream, session_info->as_client, session_info->as_server,
session_info->tf_stream, session_info->thread_id);
nghttp2_session_set_next_stream_id(session_info->as_client, h2_stream->stream_id); nghttp2_session_set_next_stream_id(session_info->as_client, h2_stream->stream_id);
method = nghttp2_get_method(h2_stream->req); method = nghttp2_get_method(h2_stream->req);
@@ -1642,23 +1794,22 @@ nghttp2_client_submit_header(struct tfe_session_info_t *session_info, int32_t st
goto finish; goto finish;
} }
req = h2_stream->req; req = h2_stream->req;
suspend_start(h2_stream, req, session_info->tf_stream);
fill_req_spec_from_handle(h2_stream->req); fill_req_spec_from_handle(h2_stream->req);
req->event_cb(req, EV_HTTP_REQ_HDR, NULL, 0, req->event_cb_user); req->event_cb(req, EV_HTTP_REQ_HDR, NULL, 0, req->event_cb_user);
if (h2_stream->spd_set){ if (h2_stream->cache.spd_set){
h2_stream->spd_event = EV_HTTP_REQ_HDR; h2_stream->cache.spd_event = EV_HTTP_REQ_HDR;
h2_stream->cache.spd_valid = 1;
h2_stream->spd_valid = 1; h2_stream->cache.spd_set = 0;
h2_stream->spd_set = 0; h2_stream->cache.spd_set_cnt++;
h2_stream->spd_set_cnt++; h2_stream->cache.spd_cnt++;
h2_stream->spd_cnt++;
tfe_stream_suspend(session_info->tf_stream, CONN_DIR_DOWNSTREAM); tfe_stream_suspend(session_info->tf_stream, CONN_DIR_DOWNSTREAM);
session_info->stream_id = stream_id;
stream_action = ACTION_DEFER_DATA; stream_action = ACTION_DEFER_DATA;
goto finish; goto finish;
} }
nghttp2_headers_write_log(h2_stream, session_info->tf_stream->str_stream_info, CONN_DIR_DOWNSTREAM);
nghttp2_headers_write_log(h2_stream, session_info->tf_stream->str_stream_info, CONN_DIR_DOWNSTREAM);
stream_action = nghttp2_client_frame_submit_header(session_info, h2_stream); stream_action = nghttp2_client_frame_submit_header(session_info, h2_stream);
if (stream_action == ACTION_DROP_DATA){ if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(session_info->as_client); xret = nghttp2_session_send(session_info->as_client);
@@ -1685,12 +1836,12 @@ nghttp2_submit_frame_header(struct tfe_session_info_t *session_info,const nghttp
if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS){ if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS){
if (dir == CONN_DIR_UPSTREAM){ if (dir == CONN_DIR_UPSTREAM){
xret = nghttp2_server_submit_header(session_info, frame->hd.stream_id); xret = nghttp2_server_submit_header(session_info, frame->hd.stream_id);
TFE_LOG_INFO(logger()->handle, "%s, %d, submit response header, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit response header, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
} }
if (dir == CONN_DIR_DOWNSTREAM){ if (dir == CONN_DIR_DOWNSTREAM){
xret = nghttp2_client_submit_header(session_info, frame->hd.stream_id); xret = nghttp2_client_submit_header(session_info, frame->hd.stream_id);
TFE_LOG_INFO(logger()->handle, "%s, %d, submit request header, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit request header, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
dir, frame->hd.stream_id, session_info->stream_action); dir, frame->hd.stream_id, session_info->stream_action);
} }
} }
@@ -1724,6 +1875,7 @@ nghttp2_fill_up_header(nghttp2_session *session, const nghttp2_frame *frame, con
frame->headers.cat != NGHTTP2_HCAT_REQUEST){ frame->headers.cat != NGHTTP2_HCAT_REQUEST){
return 0; return 0;
} }
struct h2_stream_data_t *h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); struct h2_stream_data_t *h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if (!h2_stream){ if (!h2_stream){
TFE_LOG_ERROR(logger()->handle, "Header stream id %d, can't find stream information", TFE_LOG_ERROR(logger()->handle, "Header stream id %d, can't find stream information",
@@ -1841,8 +1993,9 @@ nghttp2_on_stream_close(nghttp2_session *session, const nghttp2_frame *frame, co
resp = h2_stream->resp; resp = h2_stream->resp;
if (error_code == 0 && resp->body_state != MANAGE_STAGE_COMPLETE){ if (error_code == 0 && resp->body_state != MANAGE_STAGE_COMPLETE){
if (resp->body_state == MANAGE_STAGE_INIT) if (resp->body_state == MANAGE_STAGE_INIT &&
nghttp2_end_submit_header2(session_info, h2_stream); session_info->stream_action != ACTION_DEFER_DATA)
nghttp2_submit_end_header(session_info, h2_stream);
goto end; goto end;
} }
finish: finish:
@@ -1950,7 +2103,6 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
}else{ }else{
resp->body.flags = flags; resp->body.flags = flags;
} }
//goto finish;
} }
stream_action = server_frame_submit_data(session_info, h2_stream, CONN_DIR_UPSTREAM); stream_action = server_frame_submit_data(session_info, h2_stream, CONN_DIR_UPSTREAM);
@@ -1961,7 +2113,7 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
} }
} }
TFE_LOG_INFO(logger()->handle, "%s, 1, submit data %d, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, TFE_LOG_DEBUG(logger()->handle, "%s, 1, submit data %d, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info,
(int)input_len, stream_id, stream_action); (int)input_len, stream_id, stream_action);
if (stream_action == ACTION_USER_DATA) if (stream_action == ACTION_USER_DATA)
stream_action = ACTION_DROP_DATA; stream_action = ACTION_DROP_DATA;
@@ -2017,7 +2169,7 @@ create_upstream_data(nghttp2_session *session, int32_t stream_id,
goto finish; goto finish;
} }
h2_stream->resp = tfe_half_private_init(TFE_HTTP_RESPONSE); h2_stream->resp = tfe_half_private_init(TFE_HTTP_RESPONSE, stream_id, session_info->as_server);
tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_RESPONSE); tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_RESPONSE);
event = ALLOC(struct user_event_dispatch, 1); event = ALLOC(struct user_event_dispatch, 1);
@@ -2046,8 +2198,10 @@ static ssize_t nghttp2_client_select_padding_callback(nghttp2_session *session,
h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if (!h2_stream) if (!h2_stream)
return frame->hd.length; return frame->hd.length;
resp = h2_stream->resp; resp = h2_stream->resp;
if (!resp)
return frame->hd.length;
return (ssize_t)MIN(max_payloadlen, frame->hd.length + (resp->body.padlen)); return (ssize_t)MIN(max_payloadlen, frame->hd.length + (resp->body.padlen));
} }
@@ -2164,6 +2318,7 @@ create_serv_stream_data(nghttp2_session *session, int32_t stream_id,
h2_stream = TAILQ_LIST_FIND(session_info, stream_id); h2_stream = TAILQ_LIST_FIND(session_info, stream_id);
if (h2_stream != NULL){ if (h2_stream != NULL){
nghttp2_session_set_stream_user_data(session, stream_id, h2_stream);
goto finish; goto finish;
} }
@@ -2171,8 +2326,10 @@ create_serv_stream_data(nghttp2_session *session, int32_t stream_id,
assert(h2_stream); assert(h2_stream);
memset(h2_stream, 0, sizeof(struct h2_stream_data_t)); memset(h2_stream, 0, sizeof(struct h2_stream_data_t));
h2_stream->stream_id = stream_id; h2_stream->stream_id = stream_id;
h2_stream->session = session_info->as_server;
h2_stream->tf_stream = session_info->tf_stream;
h2_stream->req = tfe_half_private_init(TFE_HTTP_REQUEST); h2_stream->req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL);
tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_REQUEST); tfe_half_session_init(h2_stream, stream_id, TFE_HTTP_REQUEST);
event = ALLOC(struct user_event_dispatch, 1); event = ALLOC(struct user_event_dispatch, 1);
@@ -2222,6 +2379,7 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
goto finish; goto finish;
} }
req = h2_stream->req; req = h2_stream->req;
req->body.flags = flags;
evbuffer_add(req->body.evbuf_body, input, input_len); evbuffer_add(req->body.evbuf_body, input, input_len);
if (req->body.gzip != HTTP2_CONTENT_ENCODING_NONE){ if (req->body.gzip != HTTP2_CONTENT_ENCODING_NONE){
@@ -2333,7 +2491,7 @@ enum tfe_stream_action
detect_up_stream_protocol(struct tfe_session_info_t *session_info, const struct tfe_stream *tfe_stream, detect_up_stream_protocol(struct tfe_session_info_t *session_info, const struct tfe_stream *tfe_stream,
unsigned int thread_id, const unsigned char *data, size_t len) unsigned int thread_id, const unsigned char *data, size_t len)
{ {
int readlen = 0, xret = -1; int readlen = 0;
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA; enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
session_info->tf_stream = tfe_stream; session_info->tf_stream = tfe_stream;
@@ -2341,26 +2499,15 @@ detect_up_stream_protocol(struct tfe_session_info_t *session_info, const struct
if (!session_info->as_server) if (!session_info->as_server)
goto forward; goto forward;
readlen = nghttp2_session_mem_recv(session_info->as_client, data, len); readlen = nghttp2_session_mem_recv(session_info->as_client, data, len);
if (readlen < 0){ if (readlen < 0){
TFE_LOG_ERROR(logger()->handle, "Failed to process server requests. Link message %s", TFE_LOG_ERROR(logger()->handle, "Failed to process server requests. Link message %s",
tfe_stream->str_stream_info); tfe_stream->str_stream_info);
delete_client_session_data(session_info); delete_client_session_data(session_info);
goto err; goto forward;
} }
stream_action = session_info->stream_action; stream_action = session_info->stream_action;
session_info->stream_action = ACTION_DROP_DATA; session_info->stream_action = ACTION_DROP_DATA;
//printf("up stream_acion = %d\n", stream_action);
if (stream_action == ACTION_FORWARD_DATA){
xret = nghttp2_session_send(session_info->as_client);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal downstream send error: %s\n",
nghttp2_strerror(xret));
}
stream_action = ACTION_DROP_DATA;
}
if (session_info->goaway){ if (session_info->goaway){
nghttp2_disect_goaway(session_info); nghttp2_disect_goaway(session_info);
session_info->goaway = 0; session_info->goaway = 0;
@@ -2375,18 +2522,14 @@ forward:
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len)); tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len));
return ACTION_FORWARD_DATA; return ACTION_FORWARD_DATA;
} }
err: return stream_action;
tfe_stream_detach(tfe_stream);
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_DROP_BYTES, &len, sizeof(len));
return ACTION_DROP_DATA;
} }
enum tfe_stream_action enum tfe_stream_action
detect_down_stream_protocol(struct tfe_session_info_t *session_info, const struct tfe_stream *tfe_stream, detect_down_stream_protocol(struct tfe_session_info_t *session_info, const struct tfe_stream *tfe_stream,
unsigned int thread_id, const unsigned char *data, size_t len) unsigned int thread_id, const unsigned char *data, size_t len)
{ {
int readlen = 0, xret = -1; int readlen = 0;
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA; enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
session_info->tf_stream = tfe_stream; session_info->tf_stream = tfe_stream;
@@ -2399,19 +2542,11 @@ detect_down_stream_protocol(struct tfe_session_info_t *session_info, const struc
if (readlen < 0){ if (readlen < 0){
TFE_LOG_ERROR(logger()->handle, "Failed to process client requests. Link message %s", TFE_LOG_ERROR(logger()->handle, "Failed to process client requests. Link message %s",
tfe_stream->str_stream_info); tfe_stream->str_stream_info);
delete_server_session_data(session_info); delete_server_session_data(session_info);
goto err; goto forward;
} }
stream_action = session_info->stream_action; stream_action = session_info->stream_action;
session_info->stream_action = ACTION_DROP_DATA; session_info->stream_action = ACTION_DROP_DATA;
if (stream_action == ACTION_FORWARD_DATA){
xret = nghttp2_session_send(session_info->as_server);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret));
}
stream_action = ACTION_DROP_DATA;
}
if (session_info->goaway){ if (session_info->goaway){
nghttp2_disect_goaway(session_info); nghttp2_disect_goaway(session_info);
session_info->goaway = 0; session_info->goaway = 0;
@@ -2425,10 +2560,7 @@ forward:
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len)); tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len));
return ACTION_FORWARD_DATA; return ACTION_FORWARD_DATA;
} }
err: return stream_action;
tfe_stream_detach(tfe_stream);
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_DROP_BYTES, &len, sizeof(len));
return ACTION_DROP_DATA;
} }
void void

View File

@@ -81,7 +81,7 @@ set_property(TARGET http-parser-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${
ExternalProject_Add(nghttp2 ExternalProject_Add(nghttp2
PREFIX nghttp2 PREFIX nghttp2
URL ${CMAKE_CURRENT_SOURCE_DIR}/nghttp2-1.24.0.tar.gz URL ${CMAKE_CURRENT_SOURCE_DIR}/nghttp2-1.24.0.tar.gz
URL_MD5 214f4e02980ea1644ea9e11a60897bed URL_MD5 8b29f5c780f08d8111f953f9fa0fad0c
CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared
BUILD_IN_SOURCE 1) BUILD_IN_SOURCE 1)

Binary file not shown.