diff options
| author | Lu <[email protected]> | 2018-07-23 20:22:55 +0800 |
|---|---|---|
| committer | Lu <[email protected]> | 2018-07-23 20:22:55 +0800 |
| commit | 3e75742fccb84f8c3f5054de1a7f0241f837b3a7 (patch) | |
| tree | 73e4cc29ccc4a9df715d84d3e5314ec92275690f /src | |
| parent | f4587a5594be6c23037374c8bec157ac931d8b69 (diff) | |
修正访问ifeng.com、qq.com时报文格式解析错误导致assert()的问题
* ifeng.com没有正确提供Content-Length,导致reserve()传入的数据长度溢出;
* qq.com出现了Header K-V中V为空的现象,原实现不能正确处理,现修正。
Diffstat (limited to 'src')
| -rw-r--r-- | src/http1.cc | 48 | ||||
| -rw-r--r-- | src/pxythrmgr.cc | 6 |
2 files changed, 23 insertions, 31 deletions
diff --git a/src/http1.cc b/src/http1.cc index 35eaad5..cbde86a 100644 --- a/src/http1.cc +++ b/src/http1.cc @@ -97,18 +97,10 @@ public: void ConstructByHttpParserField(const char * data, size_t len) { - /* 收到了一个完成的Header K-V,写入Header字段 */ - if (!str_last_header_field_.empty() && !str_last_value_field_.empty()) - { - Add(str_last_header_field_, str_last_value_field_); - - /* 添加完毕,清除状态 */ - str_last_header_field_.clear(); - str_last_value_field_.clear(); - } + if (!str_last_value_field_.empty()) + ConstructByHttpParserComplete(); - /* 新的K-V对或Continued Field */ - /* Value不应该有值 */ + /* 新的K-V对或Continued Field, Value不应该有值 */ assert(str_last_value_field_.empty()); str_last_header_field_ += std::string(data, data + len); } @@ -117,21 +109,23 @@ public: { /* 处理到Value时,Field不应为空 * Value可能分成片段,多次调用给出,在这里需要将他们拼合 */ - assert(!str_last_header_field_.empty()); str_last_value_field_ += std::string(data, data + len); } void ConstructByHttpParserComplete() { /* 收到了一个完成的Header K-V,写入Header字段 */ - if (!str_last_header_field_.empty() && !str_last_value_field_.empty()) + if (!str_last_header_field_.empty()) { Add(str_last_header_field_, str_last_value_field_); - - /* 添加完毕,清除状态 */ - str_last_header_field_.clear(); - str_last_value_field_.clear(); } + else + { + LOG(WARNING) << "Empty HTTP Header field recieved, drop this header-value."; + } + + str_last_header_field_.clear(); + str_last_value_field_.clear(); /* 完成时,不应该有值没有写入Header记录 */ assert(str_last_header_field_.empty()); @@ -634,7 +628,7 @@ private: void __new_body_content(size_t content_length) { body_contents_.emplace_back(std::make_unique<body_content_t>(), false); - __last_body_content().ptr->reserve(content_length); + if (content_length > 0) __last_body_content().ptr->reserve(content_length); } struct __body_content & __last_body_content() @@ -739,13 +733,14 @@ int Http1ResponseParserCallbacks::CallbackOnBody(http_parser * parser, const cha auto * resp_ptr = __response_this_ptr(parser); resp_ptr->__set_section_state(resp_ptr->kSectionBody, resp_ptr->kStateReading); + auto content_length = parser->flags & F_CONTENTLENGTH ? parser->content_length : 0; + /* 第一次回调Body,分配内存,预留内存空间 */ if (resp_ptr->__is_body_content_empty()) { - resp_ptr->__new_body_content(parser->content_length); + resp_ptr->__new_body_content(content_length); } - /* 追加数据 */ auto & __last_body_content = resp_ptr->__last_body_content().ptr; __last_body_content->insert(__last_body_content->end(), at, at + length); @@ -979,8 +974,8 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_c if (request.ReadOnly() || request.Complete(HttpRequest::kSecionMessage)) { - evbuffer_add_buffer(upstream_evbuf, request.StolenEvbuf().release()); - return 0; + auto __ev_buffer_ptr = request.StolenEvbuf(); + evbuffer_add_buffer(upstream_evbuf, __ev_buffer_ptr.get()); } return 0; @@ -1056,13 +1051,10 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_ } __forward: - if (session->NeedToDrop()) - { - auto __to_drop_evbuf = response.StolenEvBuf(); - } - else + auto __evbuf_ptr = response.StolenEvBuf(); + if (!session->NeedToDrop()) { - evbuffer_add_buffer(upstream_evbuf, response.StolenEvBuf().release()); + evbuffer_add_buffer(upstream_evbuf, __evbuf_ptr.get()); } if (response.SectionState(response.kSectionMessage) == response.kStateComplete || diff --git a/src/pxythrmgr.cc b/src/pxythrmgr.cc index b3357b3..72b287e 100644 --- a/src/pxythrmgr.cc +++ b/src/pxythrmgr.cc @@ -194,7 +194,7 @@ void tfe_thread_manager_attach_by_thread_id( tfe_thread_manager_ctx *ctx, int thread_id, struct event_base **ev_base_out, struct evdns_base **evdns_base_out) { - std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); + //std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); *ev_base_out = ctx->thr_ctx[thread_id]->evbase; *evdns_base_out = ctx->thr_ctx[thread_id]->dnsbase; } @@ -208,7 +208,7 @@ void tfe_thread_manager_attach_by_thread_id( int tfe_thread_manager_attach(tfe_thread_manager_ctx *ctx, struct event_base **evbase, struct evdns_base **dnsbase) { - std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); + //std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); int min_thread_id = 0; size_t min_load = ctx->thr_ctx[min_thread_id]->load; @@ -237,7 +237,7 @@ int tfe_thread_manager_attach(tfe_thread_manager_ctx *ctx, */ void tfe_thread_manager_detach(tfe_thread_manager_ctx *ctx, int thread_id) { - std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); + //std::lock_guard<decltype(ctx->lock)> __lock_guard(ctx->lock); ctx->thr_ctx[thread_id]->load--; } |
