diff options
| author | lijia <[email protected]> | 2024-06-18 16:45:35 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2024-06-20 18:51:47 +0800 |
| commit | 05e8c9db6912dc95de9691e9b90e549a4c3beffe (patch) | |
| tree | ed5d4b3392bdd577986d26ac8d5c6da21f9c2b2a /src/http_decoder_half.cpp | |
| parent | 7d6170a23027aff0ebf2e7832dc11e4bbdce57ea (diff) | |
feat: TSG-20446, support http tunnel with CONNECT method.
Diffstat (limited to 'src/http_decoder_half.cpp')
| -rw-r--r-- | src/http_decoder_half.cpp | 139 |
1 files changed, 77 insertions, 62 deletions
diff --git a/src/http_decoder_half.cpp b/src/http_decoder_half.cpp index 441ff2c..6074307 100644 --- a/src/http_decoder_half.cpp +++ b/src/http_decoder_half.cpp @@ -21,7 +21,7 @@ struct http_decoder_half_data size_t decompress_body_len; int joint_url_complete; - struct hstring joint_url; // http://<host>[:<port>]/<path>?<searchpart> + hstring joint_url; // http://<host>[:<port>]/<path>?<searchpart> long long transaction_index; }; @@ -42,7 +42,7 @@ struct http_decoder_half long long trans_counter; long long err_counter; - long long transaction_seq; + long long transaction_seq; //accumulated const char *data; int data_len; @@ -77,9 +77,9 @@ http_decoder_half_data_decompress(struct http_decoder_half_data *data) return; } - struct hstring raw_body = {0}; + hstring raw_body = {0}; http_decoder_table_get_body(data->table, &raw_body); - if (raw_body.str == NULL || raw_body.str_len == 0) + if (raw_body.iov_base == NULL || raw_body.iov_len == 0) { return; } @@ -90,8 +90,8 @@ http_decoder_half_data_decompress(struct http_decoder_half_data *data) } assert(data->decompress); - if (http_content_decompress_write(data->decompress, raw_body.str, - raw_body.str_len, + if (http_content_decompress_write(data->decompress, (char *)raw_body.iov_base, + raw_body.iov_len, &data->ref_decompress_body, &data->decompress_body_len) == -1) { @@ -226,12 +226,12 @@ static int on_uri(llhttp_t *http, const char *at, size_t length) return 0; } -static void http_decoder_cached_portion_url(struct http_decoder_half *half, const struct hstring *uri_result) +static void http_decoder_cached_portion_url(struct http_decoder_half *half, const hstring *uri_result) { struct http_decoder_half_data *ref_data = half->ref_data; int uri_skip_len = 0; - if ((uri_result->str_len) > 7 && (strncasecmp("http://", uri_result->str, 7) == 0)) // absolute URI + if ((uri_result->iov_len) > 7 && (strncasecmp("http://", (char *)uri_result->iov_base, 7) == 0)) // absolute URI { uri_skip_len = strlen("http://"); ref_data->joint_url_complete = 1; @@ -241,9 +241,9 @@ static void http_decoder_cached_portion_url(struct http_decoder_half *half, cons ref_data->joint_url_complete = 0; } - ref_data->joint_url.str_len = uri_result->str_len - uri_skip_len; - ref_data->joint_url.str = MEMPOOL_CALLOC(half->http_ev_ctx->ref_mempool, char, ref_data->joint_url.str_len); - memcpy(ref_data->joint_url.str, uri_result->str + uri_skip_len, ref_data->joint_url.str_len); + ref_data->joint_url.iov_len = uri_result->iov_len - uri_skip_len; + ref_data->joint_url.iov_base = MEMPOOL_CALLOC(half->http_ev_ctx->ref_mempool, char, ref_data->joint_url.iov_len); + memcpy(ref_data->joint_url.iov_base, (char *)uri_result->iov_base + uri_skip_len, ref_data->joint_url.iov_len); } /* Information-only callbacks, return value is ignored */ @@ -261,9 +261,9 @@ static int on_uri_complete(llhttp_t *http) http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_URI); - struct hstring uri_result = {}; + hstring uri_result = {}; http_decoder_table_get_uri(half->ref_data->table, &uri_result); - assert(uri_result.str); + assert(uri_result.iov_base); http_decoder_cached_portion_url(half, &uri_result); return 0; @@ -408,17 +408,17 @@ static int on_header_value_complete(llhttp_t *http) if (half->ref_data->content_encoding == HTTP_CONTENT_ENCODING_NONE) { struct http_header http_hdr = {0}; - struct hstring key = {.str = (char *)"Content-Encoding", .str_len = 16}; + hstring key = {.iov_base = (char *)"Content-Encoding", .iov_len = 16}; if (http_decoder_table_get_header(half->ref_data->table, &key, &http_hdr) == 0) { char encoding_str[MAX_ENCODING_STR_LEN + 1] = {0}; - size_t str_len = http_hdr.val.str_len; - if (str_len > MAX_ENCODING_STR_LEN) + size_t iov_len = http_hdr.val.iov_len; + if (iov_len > MAX_ENCODING_STR_LEN) { - str_len = MAX_ENCODING_STR_LEN; + iov_len = MAX_ENCODING_STR_LEN; } - memcpy(encoding_str, http_hdr.val.str, str_len); + memcpy(encoding_str, http_hdr.val.iov_base, iov_len); half->ref_data->content_encoding = http_content_encoding_str2int(encoding_str); } } @@ -539,8 +539,7 @@ static int on_body(llhttp_t *http, const char *at, size_t length) return 0; } -static void http_decoder_half_init(struct http_decoder_half *half, - http_event_cb *http_ev_cb, enum llhttp_type type) +static void http_decoder_half_init(struct http_decoder_half *half, http_event_cb *http_ev_cb, enum llhttp_type type) { llhttp_settings_init(&half->settings); llhttp_init(&half->parser, type, &half->settings); @@ -579,8 +578,9 @@ static void http_decoder_half_init(struct http_decoder_half *half, half->ref_data = NULL; } -struct http_decoder_half * http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *ev_cb, enum llhttp_type http_type, - int decompress_switch, struct http_decoder_env *httpd_env) +struct http_decoder_half * http_decoder_half_new(struct http_decoder_exdata *hd_ctx, nmx_pool_t *mempool, + http_event_cb *ev_cb, enum llhttp_type http_type, + int decompress_switch, struct http_decoder_env *httpd_env, long long start_seq) { struct http_decoder_half *half = MEMPOOL_CALLOC(mempool, struct http_decoder_half, 1); assert(half); @@ -588,8 +588,9 @@ struct http_decoder_half * http_decoder_half_new(nmx_pool_t *mempool, http_event half->decompress_switch = decompress_switch; half->http_ev_ctx = MEMPOOL_CALLOC(mempool, struct http_event_context, 1); http_decoder_half_init(half, ev_cb, http_type); - + half->http_ev_ctx->ref_httpd_ctx = hd_ctx; half->httpd_env = httpd_env; + half->transaction_seq = start_seq; return half; } @@ -609,7 +610,7 @@ void http_decoder_half_free(nmx_pool_t *mempool, struct http_decoder_half *half) MEMPOOL_FREE(mempool, half); } -void http_decoder_half_reinit(struct http_decoder_half *half, int topic_id, +void http_decoder_half_reinit(struct http_decoder_half *half, struct http_decoder_result_queue *queue, nmx_pool_t *mempool, struct session *sess) { @@ -618,8 +619,6 @@ void http_decoder_half_reinit(struct http_decoder_half *half, int topic_id, { http_decoder_table_reinit(half->ref_data->table); } - - half->http_ev_ctx->topic_id = topic_id; half->http_ev_ctx->ref_mempool = mempool; half->http_ev_ctx->ref_session = sess; half->http_ev_ctx->ref_queue = queue; @@ -810,10 +809,10 @@ void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_d data->decompress = NULL; } - if (data->joint_url.str) + if (data->joint_url.iov_base) { - MEMPOOL_FREE(mempool, data->joint_url.str); - data->joint_url.str = NULL; + MEMPOOL_FREE(mempool, data->joint_url.iov_base); + data->joint_url.iov_base = NULL; data->joint_url_complete = 0; } MEMPOOL_FREE(mempool, data); @@ -846,7 +845,7 @@ int http_decoder_half_data_get_response_line(struct http_decoder_half_data *data } int http_decoder_half_data_get_header(const struct http_decoder_half_data *data, - const struct hstring *key, + const hstring *key, struct http_header *hdr_result) { return http_decoder_table_get_header(data->table, key, hdr_result); @@ -877,7 +876,7 @@ int http_decoder_half_data_has_parsed_header(struct http_decoder_half_data *data } int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *data, - struct hstring *body) + hstring *body) { if (NULL == data || NULL == body) { @@ -887,15 +886,15 @@ int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *dat } int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data, - struct hstring *body) + hstring *body) { if (HTTP_CONTENT_ENCODING_NONE == data->content_encoding) { return http_decoder_table_get_body(data->table, body); } - body->str = data->ref_decompress_body; - body->str_len = data->decompress_body_len; + body->iov_base = data->ref_decompress_body; + body->iov_len = data->decompress_body_len; return 0; } @@ -923,17 +922,17 @@ static void using_session_addr_as_host(struct session *ref_session, char ip_string_buf[INET6_ADDRSTRLEN]; if (SESSION_ADDR_TYPE_IPV4_TCP == ssaddr_type || SESSION_ADDR_TYPE_IPV4_UDP == ssaddr_type) { - host_result->val.str = MEMPOOL_CALLOC(mempool, char, (INET_ADDRSTRLEN + 7) /* "ip:port" max length */); + host_result->val.iov_base = MEMPOOL_CALLOC(mempool, char, (INET_ADDRSTRLEN + 7) /* "ip:port" max length */); inet_ntop(AF_INET, &ssaddr->ipv4.daddr, ip_string_buf, INET_ADDRSTRLEN); - sprintf(host_result->val.str, "%s:%u", ip_string_buf, ntohs(ssaddr->ipv4.dport)); - host_result->val.str_len = strlen(host_result->val.str); + sprintf((char *)host_result->val.iov_base, "%s:%u", ip_string_buf, ntohs(ssaddr->ipv4.dport)); + host_result->val.iov_len = strlen((char *)host_result->val.iov_base); } else if (SESSION_ADDR_TYPE_IPV6_TCP == ssaddr_type || SESSION_ADDR_TYPE_IPV6_UDP == ssaddr_type) { - host_result->val.str = MEMPOOL_CALLOC(mempool, char, (INET6_ADDRSTRLEN + 7) /* "ip:port" max length */); + host_result->val.iov_base = MEMPOOL_CALLOC(mempool, char, (INET6_ADDRSTRLEN + 7) /* "ip:port" max length */); inet_ntop(AF_INET6, &ssaddr->ipv6.daddr, ip_string_buf, INET6_ADDRSTRLEN); - sprintf(host_result->val.str, "%s:%u", ip_string_buf, ntohs(ssaddr->ipv6.dport)); - host_result->val.str_len = strlen(host_result->val.str); + sprintf((char *)host_result->val.iov_base, "%s:%u", ip_string_buf, ntohs(ssaddr->ipv6.dport)); + host_result->val.iov_len = strlen((char *)host_result->val.iov_base); } else { @@ -944,30 +943,43 @@ static void using_session_addr_as_host(struct session *ref_session, void http_decoder_join_url(struct http_decoder_half_data *hfdata, nmx_pool_t *mempool, const struct http_header *host_hdr) { int append_slash_len = 0; - if ('/' != hfdata->joint_url.str[0]) + if ('/' != ((char *)hfdata->joint_url.iov_base)[0]) { append_slash_len = 1; } - int url_cache_str_len = host_hdr->val.str_len + hfdata->joint_url.str_len + append_slash_len; + int url_cache_str_len = host_hdr->val.iov_len + hfdata->joint_url.iov_len + append_slash_len; char *url_cache_str = MEMPOOL_CALLOC(mempool, char, url_cache_str_len); char *ptr = url_cache_str; - memcpy(ptr, host_hdr->val.str, host_hdr->val.str_len); - ptr += host_hdr->val.str_len; + memcpy(ptr, host_hdr->val.iov_base, host_hdr->val.iov_len); + ptr += host_hdr->val.iov_len; if (append_slash_len) { *ptr = '/'; ptr++; } - memcpy(ptr, hfdata->joint_url.str, hfdata->joint_url.str_len); + memcpy(ptr, hfdata->joint_url.iov_base, hfdata->joint_url.iov_len); - MEMPOOL_FREE(mempool, hfdata->joint_url.str); // free the cached uri buffer - hfdata->joint_url.str = url_cache_str; - hfdata->joint_url.str_len = url_cache_str_len; + MEMPOOL_FREE(mempool, hfdata->joint_url.iov_base); // free the cached uri buffer + hfdata->joint_url.iov_base = url_cache_str; + hfdata->joint_url.iov_len = url_cache_str_len; hfdata->joint_url_complete = 1; } +void http_decoder_get_url(struct http_decoder_half_data *hfdata, nmx_pool_t *mempool) +{ + struct http_request_line reqline = {}; + http_decoder_half_data_get_request_line(hfdata, &reqline); + if(unlikely(strncasecmp_safe("CONNECT", (char *)reqline.method.iov_base, 7, reqline.method.iov_len) == 0)) + { + hfdata->joint_url.iov_base = MEMPOOL_CALLOC(mempool, char, reqline.uri.iov_len+1); + memcpy(hfdata->joint_url.iov_base, reqline.uri.iov_base, reqline.uri.iov_len); + hfdata->joint_url.iov_len = reqline.uri.iov_len; + hfdata->joint_url_complete = 1; + } +} + int http_decoder_join_url_finally(struct http_event_context *ev_ctx, struct http_decoder_half_data *hfdata, nmx_pool_t *mempool) @@ -981,14 +993,14 @@ int http_decoder_join_url_finally(struct http_event_context *ev_ctx, using_session_addr_as_host(ev_ctx->ref_session, &addr_as_host, mempool); http_decoder_join_url(hfdata, mempool, &addr_as_host); - MEMPOOL_FREE(mempool, addr_as_host.val.str); // free session addr to host buffer + MEMPOOL_FREE(mempool, addr_as_host.val.iov_base); // free session addr to host buffer return 1; } void http_decoder_get_host_feed_url(struct http_decoder_half *half) { struct http_header host_result = {}; - struct hstring host_key = {(char *)"Host", 4}; + hstring host_key = {(char *)"Host", 4}; const char *host_refer_str = NULL; int host_refer_len = 0; @@ -1007,14 +1019,14 @@ void http_decoder_get_host_feed_url(struct http_decoder_half *half) http_decoder_join_url(half->ref_data, half->http_ev_ctx->ref_mempool, &host_result); } -int http_half_data_get_url(struct http_decoder_half_data *res_data, struct hstring *url) +int http_half_data_get_url(struct http_decoder_half_data *res_data, hstring *url) { if (0 == res_data->joint_url_complete) { return -1; } - url->str = res_data->joint_url.str; - url->str_len = res_data->joint_url.str_len; + url->iov_base = res_data->joint_url.iov_base; + url->iov_len = res_data->joint_url.iov_len; return 0; } @@ -1033,24 +1045,20 @@ int http_half_data_get_total_parsed_header_count(struct http_decoder_half_data * return http_decoder_table_get_total_parsed_header(half_data->table); } -void http_half_pre_context_free(struct session *sess, struct http_decoder_env *httpd_env, - struct http_decoder_exdata *ex_data) +void http_half_pre_context_free(struct session *sess, struct http_decoder_exdata *exdata) { - if (NULL == ex_data) - { - return; - } struct http_message *msg = NULL; struct http_decoder_half_data *req_data; struct http_decoder_half_data *res_data; - struct http_decoder_result_queue *queue = ex_data->queue; + struct http_decoder_result_queue *queue = exdata->queue; + for(int i = 0; i < queue->queue_size; i++){ req_data = queue->array[i].req_data; res_data = queue->array[i].res_data; if ((req_data != NULL) && (NULL == res_data) && (req_data->state < HTTP_EVENT_REQ_END)) { msg = http_message_new(HTTP_TRANSACTION_FREE, queue, i, HTTP_REQUEST); - session_mq_publish_message(sess, httpd_env->httpd_msg_topic_id, msg); + session_mq_publish_message(sess, exdata->pub_topic_id, msg); } } @@ -1059,7 +1067,7 @@ void http_half_pre_context_free(struct session *sess, struct http_decoder_env *h if ((res_data != NULL) && (res_data->state < HTTP_EVENT_RES_END)) { msg = http_message_new(HTTP_TRANSACTION_FREE, queue, i, HTTP_RESPONSE); - session_mq_publish_message(sess, httpd_env->httpd_msg_topic_id, msg); + session_mq_publish_message(sess, exdata->pub_topic_id, msg); } } } @@ -1067,4 +1075,11 @@ void http_half_pre_context_free(struct session *sess, struct http_decoder_env *h void http_half_update_state(struct http_decoder_half_data *hf_data, enum http_event state) { hf_data->state = state; +} + +void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long long *max_req_seq, long long *max_res_seq) +{ + assert(exdata && max_req_seq && max_res_seq); + *max_req_seq = exdata->decoder->c2s_half->transaction_seq; + *max_res_seq = exdata->decoder->s2c_half->transaction_seq; }
\ No newline at end of file |
