summaryrefslogtreecommitdiff
path: root/plugin/protocol/http2/src/http2_stream.cpp
diff options
context:
space:
mode:
authorfengweihao <[email protected]>2019-04-30 16:41:01 +0800
committerzhengchao <[email protected]>2019-05-24 18:45:46 +0800
commit6ac97cce6b5f561e4418fbb591c8a487507a7984 (patch)
tree5b18b948a076b8c86f528b923b6087240e4eca07 /plugin/protocol/http2/src/http2_stream.cpp
parent77d2e3fb53821d9b797db08fec795605322612f6 (diff)
1.修改nghttp2库中关于ping包处理流程
2.修改调试log信息等级为debug 3.增加http2关于缓存代码控制宏变量 4.测试存在的几个bug修复
Diffstat (limited to 'plugin/protocol/http2/src/http2_stream.cpp')
-rw-r--r--plugin/protocol/http2/src/http2_stream.cpp510
1 files changed, 321 insertions, 189 deletions
diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp
index db603c7..583dd31 100644
--- a/plugin/protocol/http2/src/http2_stream.cpp
+++ b/plugin/protocol/http2/src/http2_stream.cpp
@@ -67,7 +67,7 @@ static const struct value_string headers_vals[] =
{TFE_HTTP_TRAILER, "Trailer"},
{TFE_HTTP_TRANSFER_ENCODING, "transfer-encoding"},
{TFE_HTTP_VIA, "via"},
- {TFE_HTTP_PRAGMA, "Pragma"},
+ {TFE_HTTP_PRAGMA, "pragma"},
{TFE_HTTP_CONNECTION, "connection"},
{TFE_HTTP_CONT_ENCODING, "content-encoding"},
{TFE_HTTP_CONT_LANGUAGE, "content-language"},
@@ -283,23 +283,17 @@ void half_set_callback(struct http2_half_private * half_private,
static const char *
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;
const struct http2_half_private *half_private = nghttp2_to_half_private(half);
if (unlikely(half_private == NULL))
- goto finish;
+ return NULL;
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;
- }
}
-
- if (header == NULL) goto finish;
- value = (const char *)header->nv.value;
-finish:
- return value;
+ return header != NULL ? (const char *)header->nv.value : NULL;
}
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)
continue;
if (header->field.field_id == name->field_id){
- free(header->nv.value);
- header->nv.value = (uint8_t*)tfe_strdup(value);
- header->nv.valuelen = strlen(value);
- header->field.field_name = (const char *)header->nv.name;
- is_exist = 1;
+ if (value){
+ free(header->nv.value);
+ header->nv.value = (uint8_t*)tfe_strdup(value);
+ header->nv.valuelen = strlen(value);
+ header->field.field_name = (const char *)header->nv.name;
+ is_exist = 1;
+ }else{
+ headers_del(headers, header);
+ }
break;
}
}
if (is_exist == 0){
+ if (value == NULL){
+ goto finish;
+ }
header = ALLOC(struct header_data, 1);
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;
resp->message_state = MANAGE_STAGE_READING;
+ resp->by_stream = by_stream;
}
body->evbuf_body = evbuffer_new();
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 xret = -1;
+ enum tfe_stream_action stream_action = ACTION_DROP_DATA;
struct http2_half_private * resp = nghttp2_to_half_private(half);
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){
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{
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;
}
int h2_half_ops_body_end(struct tfe_http_half * half)
{
+ int xret = -1;
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->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;
}
@@ -540,18 +585,22 @@ void h2_ops_drop(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);
-
- stream_data->spd_set = 1;
+ stream_data->cache.spd_set = 1;
+#endif
}
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);
+ if (stream_data->cache.spd_valid){
- if (stream_data->spd_valid){
- stream_data->rse_set = 1;
+ tfe_stream_resume(stream_data->tf_stream);
+ stream_data->cache.rse_set = 1;
}
+#endif
}
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*
-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);
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.padlen = 0;
+ half_private->stream_id = stream_id;
+ half_private->session = session;
+
half_private->body_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,
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->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 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;
- struct h2_stream_data_t *stream_data = nghttp2_to_stream_data(session);
- if (stream_data->resp)
- resp->body.gzip = stream_data->resp->body.gzip;
+ if (stream->resp)
+ resp->body.gzip = stream->resp->body.gzip;
return &resp->half_public;
}
@@ -646,6 +699,10 @@ upstream_read_callback(nghttp2_session *session, int32_t stream_id,
int datalen = 0;
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);
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;
}
+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
server_frame_submit_data(struct tfe_session_info_t *session_info,
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.read_callback = upstream_read_callback;
- //printf("body->flags = %d\n", body->flags);
-
rv = nghttp2_submit_data(session, body->flags,
h2_stream->stream_id, &data_prd);
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("submit data %d action = %d\n", h2_stream != NULL ? h2_stream->stream_id : NULL, 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));
}
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);
session_info->stream_action = stream_action;
return 0;
@@ -804,7 +894,7 @@ nghttp2_submit_frame_rst_stream(struct tfe_session_info_t *session_info,const ng
}
finish:
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);
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_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){
- 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;
}
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:
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);
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;
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,
ping->opaque_data);
if (rv != 0){
@@ -875,7 +967,7 @@ nghttp2_submit_frame_ping(struct tfe_session_info_t *session_info,const nghttp2_
}
finish:
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);
return 0;
}
@@ -919,10 +1011,6 @@ void delete_http2_stream_data(struct h2_stream_data_t *h2_stream,
const struct tfe_stream *tf_stream,
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->resp, body_flag);
@@ -984,7 +1072,7 @@ nghttp2_submit_frame_goaway(struct tfe_session_info_t *session_info,const nghttp
}
finish:
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);
session_info->goaway = 1;
@@ -1018,13 +1106,13 @@ nghttp2_submit_frame_window_update(struct tfe_session_info_t *session_info,const
}
finish:
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);
return 0;
}
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)
{
int xret = -1;
@@ -1038,6 +1126,10 @@ nghttp2_end_submit_header2(struct tfe_session_info_t *session_info,
if (headers.nvlen <= 0){
goto finish;
}
+ if ((headers.flag & NGHTTP2_FLAG_END_STREAM) != 1 ){
+ goto finish;
+ }
+
stream_id = nghttp2_submit_headers(session_info->as_server, headers.flag,
h2_stream->stream_id, NULL, nghttp2_nv_packet(&headers, hdrs),
headers.nvlen, h2_stream);
@@ -1060,7 +1152,7 @@ finish:
}
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)
{
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;
if (resp->body_state == MANAGE_STAGE_INIT){
- nghttp2_end_submit_header2(session_info, h2_stream);
- //return 1;
+ nghttp2_submit_end_header(session_info, h2_stream);
}
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_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);
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 h2_stream_data_t *h2_stream = NULL;
- if (dir == CONN_DIR_DOWNSTREAM)
+ if (dir == CONN_DIR_DOWNSTREAM){
goto finish;
+ }
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,
@@ -1126,7 +1218,7 @@ nghttp2_submit_frame_data(struct tfe_session_info_t *session_info,const nghttp2_
resp = h2_stream->resp;
resp->body.padlen = frame->data.padlen;
if (resp->body_state != MANAGE_STAGE_COMPLETE){
- submit_end_data(session_info, h2_stream);
+ nghttp2_submit_end_data(session_info, h2_stream);
}
}
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->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);
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;
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);
return 0;
}
-static void
+#ifdef TFE_CACHE
+static int
suspend_start(struct h2_stream_data_t *h2_stream,
struct http2_half_private *half, const struct tfe_stream *stream)
{
- if (h2_stream->spd_valid != 1){
- return;
+ if (h2_stream->cache.spd_valid != 1){
+ return 0;
}
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->spd_valid = 0;
- h2_stream->spd_set_cnt--;
- h2_stream->spd_cnt++;
+ h2_stream->cache.spd_event = (enum tfe_http_event)0;
+ h2_stream->cache.spd_valid = 0;
+ h2_stream->cache.spd_set_cnt--;
+ h2_stream->cache.spd_cnt++;
/* 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);
- return;
+ return 1;
}
+#endif
static void
fill_resp_spec_from_handle(struct http2_half_private *half_private)
@@ -1302,54 +1396,44 @@ fill_resp_spec_from_handle(struct http2_half_private *half_private)
continue;
}
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);
continue;
}
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);
continue;
}
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);
continue;
}
}
- resp_spec->content_length = 0;
-
return;
}
-static enum tfe_stream_action
-nghttp2_server_frame_submit_header(struct tfe_session_info_t *session_info,
- struct h2_stream_data_t *h2_stream)
+static void
+tfe_make_nv(struct http2_headers *headers,
+ const char *name,const char *value, int flag)
{
- int32_t stream_id = 0;
- nghttp2_nv hdrs[128] = {0};
- struct http2_headers *headers = NULL;
- struct http2_half_private *resp = NULL;
- enum tfe_stream_action stream_action = ACTION_DROP_DATA;
+ /*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);
- if (h2_stream->pangu_resp != NULL){
- stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
- goto finish;
- }
- resp = h2_stream->resp;
- if (resp == NULL){
- return ACTION_FORWARD_DATA;
- }
- headers = &resp->headers;
- if (headers->nvlen <= 0){
- return ACTION_FORWARD_DATA;
- }
- stream_id = nghttp2_submit_headers(session_info->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);
-finish:
- return stream_action;
}
int
@@ -1379,15 +1463,104 @@ nghttp2_headers_write_log(struct h2_stream_data_t *h2_stream, const char * str_s
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", str_stream_info, dir, hmsg, h2_stream->tfe_session.session_id,
- method, url, resp_code, cont_type, cont_encoding);
+ 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
+nghttp2_server_frame_submit_header(struct tfe_session_info_t *session_info,
+ struct h2_stream_data_t *h2_stream)
+{
+ int32_t stream_id = 0;
+ nghttp2_nv hdrs[128] = {0};
+ struct http2_headers *headers = NULL;
+ struct http2_half_private *resp = NULL;
+ enum tfe_stream_action stream_action = ACTION_DROP_DATA;
+
+ if (h2_stream->pangu_resp != NULL){
+ stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
+ goto finish;
+ }
+ resp = h2_stream->resp;
+ if (resp == NULL){
+ return ACTION_FORWARD_DATA;
+ }
+ headers = &resp->headers;
+ if (headers->nvlen <= 0){
+ return ACTION_FORWARD_DATA;
+ }
+ stream_id = nghttp2_submit_headers(session_info->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));
+ }
+#ifdef tfe_cache
+ if (headers->flag &NGHTTP2_FLAG_END_STREAM)
+#endif
+ delete_nv_packet_data(headers);
+finish:
+ return stream_action;
+}
+
static int
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;
}
resp = h2_stream->resp;
- suspend_start(h2_stream, resp, session_info->tf_stream);
fill_resp_spec_from_handle(h2_stream->resp);
resp->event_cb(resp, EV_HTTP_RESP_HDR, NULL, 0, resp->event_cb_user);
- if (h2_stream->spd_set){
- h2_stream->spd_event = EV_HTTP_RESP_HDR;
-
- h2_stream->spd_valid = 1;
- h2_stream->spd_set = 0;
- h2_stream->spd_set_cnt++;
- h2_stream->spd_cnt++;
+ if (h2_stream->cache.spd_set){
+ h2_stream->cache.spd_event = EV_HTTP_RESP_HDR;
+ h2_stream->cache.spd_valid = 1;
+ h2_stream->cache.spd_set = 0;
+ h2_stream->cache.spd_set_cnt++;
+ h2_stream->cache.spd_cnt++;
tfe_stream_suspend(session_info->tf_stream, CONN_DIR_UPSTREAM);
+
+ session_info->stream_id = stream_id;
stream_action = ACTION_DEFER_DATA;
goto finish;
}
@@ -1451,11 +1624,13 @@ fill_req_spec_from_handle(struct http2_half_private *half_private)
continue;
}
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);
urllen += head->nv.valuelen;
continue;
}
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);
urllen += head->nv.valuelen;
continue;
@@ -1471,42 +1646,22 @@ fill_req_spec_from_handle(struct http2_half_private *half_private)
return;
}
+#ifdef TFE_CACHE
static int
suspend_stop(struct h2_stream_data_t *h2_stream,
const struct tfe_stream *tf_stream, enum tfe_conn_dir dir)
{
int xret = -1;
- if (h2_stream->spd_set){
- h2_stream->spd_valid = 1;
- h2_stream->spd_set = 0;
+ if (h2_stream->cache.spd_set){
+ h2_stream->cache.spd_valid = 1;
+ h2_stream->cache.spd_set = 0;
tfe_stream_suspend(tf_stream, dir);
xret = 0;
}
return xret;
}
-
-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);
-
-}
+#endif
static enum tfe_stream_action
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
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;
if (h2_stream->resp)
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);
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_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;
if (req == NULL){
stream_action = ACTION_FORWARD_DATA;
@@ -1596,7 +1747,8 @@ nghttp2_client_frame_submit_header(struct tfe_session_info_t *session_info,
goto finish;
}
/*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);
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;
}
req = h2_stream->req;
- suspend_start(h2_stream, req, session_info->tf_stream);
fill_req_spec_from_handle(h2_stream->req);
req->event_cb(req, EV_HTTP_REQ_HDR, NULL, 0, req->event_cb_user);
- if (h2_stream->spd_set){
- h2_stream->spd_event = EV_HTTP_REQ_HDR;
-
- h2_stream->spd_valid = 1;
- h2_stream->spd_set = 0;
- h2_stream->spd_set_cnt++;
- h2_stream->spd_cnt++;
+ if (h2_stream->cache.spd_set){
+ h2_stream->cache.spd_event = EV_HTTP_REQ_HDR;
+ h2_stream->cache.spd_valid = 1;
+ h2_stream->cache.spd_set = 0;
+ h2_stream->cache.spd_set_cnt++;
+ h2_stream->cache.spd_cnt++;
tfe_stream_suspend(session_info->tf_stream, CONN_DIR_DOWNSTREAM);
+ session_info->stream_id = stream_id;
stream_action = ACTION_DEFER_DATA;
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);
if (stream_action == ACTION_DROP_DATA){
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 (dir == CONN_DIR_UPSTREAM){
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);
}
if (dir == CONN_DIR_DOWNSTREAM){
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);
}
}
@@ -1724,6 +1875,7 @@ nghttp2_fill_up_header(nghttp2_session *session, const nghttp2_frame *frame, con
frame->headers.cat != NGHTTP2_HCAT_REQUEST){
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);
if (!h2_stream){
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;
if (error_code == 0 && resp->body_state != MANAGE_STAGE_COMPLETE){
- if (resp->body_state == MANAGE_STAGE_INIT)
- nghttp2_end_submit_header2(session_info, h2_stream);
+ if (resp->body_state == MANAGE_STAGE_INIT &&
+ session_info->stream_action != ACTION_DEFER_DATA)
+ nghttp2_submit_end_header(session_info, h2_stream);
goto end;
}
finish:
@@ -1950,7 +2103,6 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
}else{
resp->body.flags = flags;
}
- //goto finish;
}
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_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);
if (stream_action == ACTION_USER_DATA)
stream_action = ACTION_DROP_DATA;
@@ -2017,7 +2169,7 @@ create_upstream_data(nghttp2_session *session, int32_t stream_id,
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);
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);
if (!h2_stream)
return frame->hd.length;
-
resp = h2_stream->resp;
+ if (!resp)
+ return frame->hd.length;
+
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);
if (h2_stream != NULL){
+ nghttp2_session_set_stream_user_data(session, stream_id, h2_stream);
goto finish;
}
@@ -2171,8 +2326,10 @@ create_serv_stream_data(nghttp2_session *session, int32_t stream_id,
assert(h2_stream);
memset(h2_stream, 0, sizeof(struct h2_stream_data_t));
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);
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;
}
req = h2_stream->req;
+ req->body.flags = flags;
evbuffer_add(req->body.evbuf_body, input, input_len);
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,
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;
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)
goto forward;
-
readlen = nghttp2_session_mem_recv(session_info->as_client, data, len);
if (readlen < 0){
TFE_LOG_ERROR(logger()->handle, "Failed to process server requests. Link message %s",
tfe_stream->str_stream_info);
delete_client_session_data(session_info);
- goto err;
+ goto forward;
}
stream_action = session_info->stream_action;
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){
nghttp2_disect_goaway(session_info);
session_info->goaway = 0;
@@ -2375,18 +2522,14 @@ forward:
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len));
return ACTION_FORWARD_DATA;
}
-err:
- tfe_stream_detach(tfe_stream);
-
- tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_DROP_BYTES, &len, sizeof(len));
- return ACTION_DROP_DATA;
+ return stream_action;
}
enum tfe_stream_action
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)
{
- int readlen = 0, xret = -1;
+ int readlen = 0;
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
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){
TFE_LOG_ERROR(logger()->handle, "Failed to process client requests. Link message %s",
tfe_stream->str_stream_info);
- delete_server_session_data(session_info);
- goto err;
+ delete_server_session_data(session_info);
+ goto forward;
}
stream_action = session_info->stream_action;
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){
nghttp2_disect_goaway(session_info);
session_info->goaway = 0;
@@ -2425,10 +2560,7 @@ forward:
tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_FOWARD_BYTES, &len, sizeof(len));
return ACTION_FORWARD_DATA;
}
-err:
- tfe_stream_detach(tfe_stream);
- tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_DROP_BYTES, &len, sizeof(len));
- return ACTION_DROP_DATA;
+ return stream_action;
}
void