diff options
Diffstat (limited to 'src/http1.cc')
| -rw-r--r-- | src/http1.cc | 95 |
1 files changed, 69 insertions, 26 deletions
diff --git a/src/http1.cc b/src/http1.cc index 868d367..6a06d15 100644 --- a/src/http1.cc +++ b/src/http1.cc @@ -545,7 +545,9 @@ public: void Body(std::vector<body_content_ptr_t> body) override { + assert(body_contents_.empty()); body_contents_.clear(); + for (auto & body_content_iter : body) { body_contents_.emplace_back(std::move(body_content_iter), true); @@ -557,7 +559,6 @@ private: short resp_version_major_{1}; short resp_version_minor_{1}; - bool parse_complete_{false}; bool forward_{true}; bool readonly_{false}; @@ -831,9 +832,29 @@ void Http1Response::Construct() /* 结尾行 */ evbuffer_add_printf(evbuf_ptr, "\r\n"); - /* TODO: 消息体的构建 */ + for(auto & body_segment : body_contents_) + { + if (body_segment.ptr == nullptr || !body_segment.is_complete) continue; + auto * body_segment_ptr = body_segment.ptr.get(); + + if (body_is_chunk) + { + evbuffer_add_printf(evbuf_ptr, "%lx\r\n", body_segment_ptr->size()); + evbuffer_add(evbuf_ptr, body_segment_ptr->data(), body_segment.ptr->size()); + evbuffer_add_printf(evbuf_ptr, "\r\n"); + } + else + { + evbuffer_add(evbuf_ptr, body_segment.ptr->data(), body_segment.ptr->size()); + } + } + evbuf_content_raw_ = std::move(evbuf_construct); - parse_complete_ = true; + section_state[kSectionHeader] = kStateComplete; + section_state[kSectionBody] = kStateComplete; + section_state[kSectionMessage] = kStateComplete; + + return; } evbuffer_unique_ptr_t Http1Response::StolenEvBuf() @@ -865,14 +886,14 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_c pxy_conn_desc_t * conn_other) { /* Get the last session */ - auto & http_session = last_uncomplete_session(); - auto & request = dynamic_cast<Http1Request &>(http_session.request()); + auto * http_session = last_uncomplete_session(kDirectionRequest); + assert(http_session != nullptr); + auto & request = dynamic_cast<Http1Request &>(http_session->request()); auto * downstream_evbuf = bufferevent_get_input(conn_this->bev); auto * upstream_evbuf = bufferevent_get_output(conn_other->bev); ssize_t forward_len = request.ConstructFromEvBuf(downstream_evbuf); - if (forward_len < 0) { LOG(DEBUG) << "ctx = " << conn_ctx << " " @@ -884,15 +905,17 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_c if (request.Complete(HttpRequest::kSectionHeader)) { - http_session.CallRequestHeaderCallback(); + LOG(DEBUG) << std::addressof(http_session) << "CallRequestHeaderCallback"; + http_session->CallRequestHeaderCallback(); } if (request.Complete(HttpRequest::kSectionBody) && request.Body() != nullptr) { - http_session.CallRequestBodyCallback(); + LOG(DEBUG) << std::addressof(http_session) << "CallRequestBodyCallback"; + http_session->CallRequestBodyCallback(); } - if (http_session.NeedToDrop()) + if (http_session->NeedToDrop()) { drop_last_session(); return 0; @@ -910,14 +933,14 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_c int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_conn_desc_t * conn_this, pxy_conn_desc_t * conn_other) { - auto & http_session = last_uncomplete_session(); - auto & response = dynamic_cast<Http1Response &>(http_session.response()); + auto * http_session = last_uncomplete_session(kDirectionResponse); + assert(http_session != nullptr); + auto & response = dynamic_cast<Http1Response &>(http_session->response()); auto * downstream_evbuf = bufferevent_get_input(conn_this->bev); auto * upstream_evbuf = bufferevent_get_output(conn_other->bev); ssize_t forward_len = response.ConstructFromEvBuf(downstream_evbuf); - if (forward_len < 0) { LOG(DEBUG) << conn_ctx << "ResponseConstructFromEvBuf Failed, connection turns to passthrough"; @@ -931,12 +954,14 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_ if (response.SectionState(response.kSectionHeader) == response.kStateComplete) { - http_session.CallRequestHeaderCallback(); + LOG(DEBUG) << std::addressof(http_session) << "CallResponseHeaderCallback"; + http_session->CallResponseHeaderCallback(); } if (response.SectionState(response.kSectionBody) == response.kStateComplete) { - http_session.CallResponseBodyCallback(); + LOG(DEBUG) << std::addressof(http_session) << "CallResponseBodyCallback"; + http_session->CallResponseBodyCallback(); } /* 如果有任何一部分为Reading,说明该部分数据还为到来,暂时不转发 */ @@ -952,13 +977,13 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_ if (response.SectionState(response.kSectionMessage) == response.kStateComplete) { - drop_last_session(); + drop_first_session(); } return 0; } -HttpSession & Http1Connection::create_new_session() +HttpSession * Http1Connection::create_new_session() { /* Create new session, set a new request */ auto __http_session = std::unique_ptr<HttpSession>(new HttpSession(*this)); @@ -970,22 +995,40 @@ HttpSession & Http1Connection::create_new_session() /* Add to the last record */ http_sessions_.push_back(std::move(__http_session)); - return *http_sessions_.back(); + return http_sessions_.back().get(); } -HttpSession & Http1Connection::last_uncomplete_session() +HttpSession * Http1Connection::last_uncomplete_session(enum direction dir) { - if (http_sessions_.cbegin() == http_sessions_.cend()) - return create_new_session(); + if (dir == kDirectionRequest) + { + if (http_sessions_.empty()) + { + return create_new_session(); + } - /* 最后一个Session已经处理结束了,新建一个Session */ - auto & __session = http_sessions_.back(); + /* 看一下请求侧的状态,如果已经处理完了,说明使用了HttpPipeLine,新建一个Session */ + auto * __session = http_sessions_.back().get(); + if (__session->request().Complete(HttpRequest::kSecionMessage)) + return create_new_session(); - if (__session->request().Complete(HttpRequest::kSecionMessage)) - return create_new_session(); + /* 否则,返回最后一个没有完全处理结束的Session */ + return __session; + } + else if (dir == kDirectionResponse) + { + if (http_sessions_.empty()) + { + LOG(DEBUG) << "session queue is empty, no corresponding session for response."; + return nullptr; + } + + auto * __session = http_sessions_.front().get(); + return __session; + } - /* 否则,返回最后一个没有完全处理结束的Session */ - return *__session; + assert(0); + return nullptr; } void Http1Connection::drop_last_session() |
