diff --git a/src/shrpx_downstream.cc b/src/shrpx_downstream.cc index 0cd0da9c..8c02b340 100644 --- a/src/shrpx_downstream.cc +++ b/src/shrpx_downstream.cc @@ -133,8 +133,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool, downstream_stream_id_(-1), response_rst_stream_error_code_(NGHTTP2_NO_ERROR), affinity_cookie_(0), - request_state_(INITIAL), - response_state_(INITIAL), + request_state_(DownstreamState::INITIAL), + response_state_(DownstreamState::INITIAL), dispatch_state_(DISPATCH_NONE), upgraded_(false), chunked_request_(false), @@ -596,9 +596,11 @@ void Downstream::set_stream_id(int32_t stream_id) { stream_id_ = stream_id; } int32_t Downstream::get_stream_id() const { return stream_id_; } -void Downstream::set_request_state(int state) { request_state_ = state; } +void Downstream::set_request_state(DownstreamState state) { + request_state_ = state; +} -int Downstream::get_request_state() const { return request_state_; } +DownstreamState Downstream::get_request_state() const { return request_state_; } bool Downstream::get_chunked_request() const { return chunked_request_; } @@ -711,9 +713,13 @@ int Downstream::on_read() { return dconn_->on_read(); } -void Downstream::set_response_state(int state) { response_state_ = state; } +void Downstream::set_response_state(DownstreamState state) { + response_state_ = state; +} -int Downstream::get_response_state() const { return response_state_; } +DownstreamState Downstream::get_response_state() const { + return response_state_; +} DefaultMemchunks *Downstream::get_response_buf() { return &response_buf_; } @@ -869,7 +875,7 @@ bool Downstream::get_upgraded() const { return upgraded_; } bool Downstream::get_http2_upgrade_request() const { return req_.http2_upgrade_seen && req_.fs.header(http2::HD_HTTP2_SETTINGS) && - response_state_ == INITIAL; + response_state_ == DownstreamState::INITIAL; } StringRef Downstream::get_http2_settings() const { @@ -1055,10 +1061,10 @@ bool Downstream::get_request_header_sent() const { } bool Downstream::request_submission_ready() const { - return (request_state_ == Downstream::HEADER_COMPLETE || - request_state_ == Downstream::MSG_COMPLETE) && + return (request_state_ == DownstreamState::HEADER_COMPLETE || + request_state_ == DownstreamState::MSG_COMPLETE) && (request_pending_ || !request_header_sent_) && - response_state_ == Downstream::INITIAL; + response_state_ == DownstreamState::INITIAL; } int Downstream::get_dispatch_state() const { return dispatch_state_; } @@ -1082,8 +1088,8 @@ bool Downstream::can_detach_downstream_connection() const { // We should check request and response buffer. If request buffer // is not empty, then we might leave downstream connection in weird // state, especially for HTTP/1.1 - return dconn_ && response_state_ == Downstream::MSG_COMPLETE && - request_state_ == Downstream::MSG_COMPLETE && !upgraded_ && + return dconn_ && response_state_ == DownstreamState::MSG_COMPLETE && + request_state_ == DownstreamState::MSG_COMPLETE && !upgraded_ && !resp_.connection_close && request_buf_.rleft() == 0; } diff --git a/src/shrpx_downstream.h b/src/shrpx_downstream.h index f113fccb..ce137547 100644 --- a/src/shrpx_downstream.h +++ b/src/shrpx_downstream.h @@ -276,6 +276,22 @@ struct Response { bool headers_only; }; +enum class DownstreamState { + INITIAL, + HEADER_COMPLETE, + MSG_COMPLETE, + STREAM_CLOSED, + CONNECT_FAIL, + MSG_RESET, + // header contains invalid header field. We can safely send error + // response (502) to a client. + MSG_BAD_HEADER, + // header fields in HTTP/1 request exceed the configuration limit. + // This state is only transitioned from INITIAL state, and solely + // used to signal 431 status code to the client. + HTTP1_REQUEST_HEADER_TOO_LARGE, +}; + class Downstream { public: Downstream(Upstream *upstream, MemchunkPool *mcpool, int32_t stream_id); @@ -349,24 +365,8 @@ public: void set_request_downstream_host(const StringRef &host); bool expect_response_body() const; bool expect_response_trailer() const; - enum { - INITIAL, - HEADER_COMPLETE, - MSG_COMPLETE, - STREAM_CLOSED, - CONNECT_FAIL, - IDLE, - MSG_RESET, - // header contains invalid header field. We can safely send error - // response (502) to a client. - MSG_BAD_HEADER, - // header fields in HTTP/1 request exceed the configuration limit. - // This state is only transitioned from INITIAL state, and solely - // used to signal 431 status code to the client. - HTTP1_REQUEST_HEADER_TOO_LARGE, - }; - void set_request_state(int state); - int get_request_state() const; + void set_request_state(DownstreamState state); + DownstreamState get_request_state() const; DefaultMemchunks *get_request_buf(); void set_request_pending(bool f); bool get_request_pending() const; @@ -391,8 +391,8 @@ public: bool get_chunked_response() const; void set_chunked_response(bool f); - void set_response_state(int state); - int get_response_state() const; + void set_response_state(DownstreamState state); + DownstreamState get_response_state() const; DefaultMemchunks *get_response_buf(); bool response_buf_full(); // Validates that received response body length and content-length @@ -557,9 +557,9 @@ private: // An affinity cookie value. uint32_t affinity_cookie_; // request state - int request_state_; + DownstreamState request_state_; // response state - int response_state_; + DownstreamState response_state_; // only used by HTTP/2 upstream int dispatch_state_; // true if the connection is upgraded (HTTP Upgrade or CONNECT), diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 8897dd62..66f9274f 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -62,10 +62,10 @@ Http2DownstreamConnection::~Http2DownstreamConnection() { downstream_->disable_downstream_wtimer(); uint32_t error_code; - if (downstream_->get_request_state() == Downstream::STREAM_CLOSED && + if (downstream_->get_request_state() == DownstreamState::STREAM_CLOSED && downstream_->get_upgraded()) { // For upgraded connection, send NO_ERROR. Should we consider - // request states other than Downstream::STREAM_CLOSED ? + // request states other than DownstreamState::STREAM_CLOSED ? error_code = NGHTTP2_NO_ERROR; } else { error_code = NGHTTP2_INTERNAL_ERROR; @@ -143,9 +143,9 @@ int Http2DownstreamConnection::submit_rst_stream(Downstream *downstream, if (http2session_->get_state() == Http2Session::CONNECTED && downstream->get_downstream_stream_id() != -1) { switch (downstream->get_response_state()) { - case Downstream::MSG_RESET: - case Downstream::MSG_BAD_HEADER: - case Downstream::MSG_COMPLETE: + case DownstreamState::MSG_RESET: + case DownstreamState::MSG_BAD_HEADER: + case DownstreamState::MSG_COMPLETE: break; default: if (LOG_ENABLED(INFO)) { @@ -188,12 +188,12 @@ ssize_t http2_data_read_callback(nghttp2_session *session, int32_t stream_id, *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; if (input_empty && - downstream->get_request_state() == Downstream::MSG_COMPLETE && + downstream->get_request_state() == DownstreamState::MSG_COMPLETE && // If connection is upgraded, don't set EOF flag, since HTTP/1 // will set MSG_COMPLETE to request state after upgrade response // header is seen. (!req.upgrade_request || - (downstream->get_response_state() == Downstream::HEADER_COMPLETE && + (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE && !downstream->get_upgraded()))) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 321acb67..e09b594b 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -833,34 +833,34 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, auto upstream = downstream->get_upstream(); if (downstream->get_downstream_stream_id() % 2 == 0 && - downstream->get_request_state() == Downstream::INITIAL) { + downstream->get_request_state() == DownstreamState::INITIAL) { // Downstream is canceled in backend before it is submitted in // frontend session. // This will avoid to send RST_STREAM to backend - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); upstream->cancel_premature_downstream(downstream); } else { - if (downstream->get_upgraded() && - downstream->get_response_state() == Downstream::HEADER_COMPLETE) { + if (downstream->get_upgraded() && downstream->get_response_state() == + DownstreamState::HEADER_COMPLETE) { // For tunneled connection, we have to submit RST_STREAM to // upstream *after* whole response body is sent. We just set // MSG_COMPLETE here. Upstream will take care of that. downstream->get_upstream()->on_downstream_body_complete(downstream); - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); } else if (error_code == NGHTTP2_NO_ERROR) { switch (downstream->get_response_state()) { - case Downstream::MSG_COMPLETE: - case Downstream::MSG_BAD_HEADER: + case DownstreamState::MSG_COMPLETE: + case DownstreamState::MSG_BAD_HEADER: break; default: - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } } else if (downstream->get_response_state() != - Downstream::MSG_BAD_HEADER) { - downstream->set_response_state(Downstream::MSG_RESET); + DownstreamState::MSG_BAD_HEADER) { + downstream->set_response_state(DownstreamState::MSG_RESET); } - if (downstream->get_response_state() == Downstream::MSG_RESET && + if (downstream->get_response_state() == DownstreamState::MSG_RESET && downstream->get_response_rst_stream_error_code() == NGHTTP2_NO_ERROR) { downstream->set_response_rst_stream_error_code(error_code); @@ -1133,13 +1133,13 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream, if (rv != 0) { http2session->submit_rst_stream(frame->hd.stream_id, NGHTTP2_PROTOCOL_ERROR); - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } return 0; } - downstream->set_response_state(Downstream::HEADER_COMPLETE); + downstream->set_response_state(DownstreamState::HEADER_COMPLETE); downstream->check_upgrade_fulfilled_http2(); if (downstream->get_upgraded()) { @@ -1150,7 +1150,7 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream, delete handler; return -1; } - downstream->set_request_state(Downstream::HEADER_COMPLETE); + downstream->set_request_state(DownstreamState::HEADER_COMPLETE); if (LOG_ENABLED(INFO)) { SSLOG(INFO, http2session) << "HTTP upgrade success. stream_id=" << frame->hd.stream_id; @@ -1193,12 +1193,12 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream, if (rv != 0) { // Handling early return (in other words, response was hijacked by // mruby scripting). - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { http2session->submit_rst_stream(frame->hd.stream_id, NGHTTP2_CANCEL); } else { http2session->submit_rst_stream(frame->hd.stream_id, NGHTTP2_INTERNAL_ERROR); - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } } @@ -1225,20 +1225,21 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, if (rv != 0) { http2session->submit_rst_stream(frame->hd.stream_id, NGHTTP2_INTERNAL_ERROR); - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } else if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { downstream->disable_downstream_rtimer(); - if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { + if (downstream->get_response_state() == + DownstreamState::HEADER_COMPLETE) { - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); rv = upstream->on_downstream_body_complete(downstream); if (rv != 0) { - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } } } @@ -1274,15 +1275,16 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { downstream->disable_downstream_rtimer(); - if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { - downstream->set_response_state(Downstream::MSG_COMPLETE); + if (downstream->get_response_state() == + DownstreamState::HEADER_COMPLETE) { + downstream->set_response_state(DownstreamState::MSG_COMPLETE); auto upstream = downstream->get_upstream(); rv = upstream->on_downstream_body_complete(downstream); if (rv != 0) { - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } } } else { @@ -1442,7 +1444,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags, return NGHTTP2_ERR_CALLBACK_FAILURE; } - downstream->set_response_state(Downstream::MSG_RESET); + downstream->set_response_state(DownstreamState::MSG_RESET); } call_downstream_readcb(http2session, downstream); @@ -1536,8 +1538,8 @@ int on_frame_not_send_callback(nghttp2_session *session, return 0; } - // To avoid stream hanging around, flag Downstream::MSG_RESET. - downstream->set_response_state(Downstream::MSG_RESET); + // To avoid stream hanging around, flag DownstreamState::MSG_RESET. + downstream->set_response_state(DownstreamState::MSG_RESET); call_downstream_readcb(http2session, downstream); return 0; @@ -2279,7 +2281,7 @@ int Http2Session::handle_downstream_push_promise_complete( auto upstream = promised_downstream->get_upstream(); - promised_downstream->set_request_state(Downstream::MSG_COMPLETE); + promised_downstream->set_request_state(DownstreamState::MSG_COMPLETE); promised_downstream->set_request_header_sent(true); if (upstream->on_downstream_push_promise_complete(downstream, diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index ac284e63..7762b147 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -77,7 +77,7 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, req.unconsumed_body_length = 0; - if (downstream->get_request_state() == Downstream::CONNECT_FAIL) { + if (downstream->get_request_state() == DownstreamState::CONNECT_FAIL) { upstream->remove_downstream(downstream); // downstream was deleted @@ -89,7 +89,7 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, downstream->detach_downstream_connection(); } - downstream->set_request_state(Downstream::STREAM_CLOSED); + downstream->set_request_state(DownstreamState::STREAM_CLOSED); // At this point, downstream read may be paused. @@ -187,7 +187,7 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame, if (req.fs.buffer_size() + namebuf.len + valuebuf.len > httpconf.request_header_field_buffer || req.fs.num_fields() >= httpconf.max_request_header_fields) { - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } @@ -312,7 +312,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream, auto &req = downstream->request(); req.tstamp = lgconf->tstamp; - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } @@ -413,7 +413,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream, downstream->inspect_http2_request(); - downstream->set_request_state(Downstream::HEADER_COMPLETE); + downstream->set_request_state(DownstreamState::HEADER_COMPLETE); #ifdef HAVE_MRUBY auto upstream = downstream->get_upstream(); @@ -432,10 +432,10 @@ int Http2Upstream::on_request_headers(Downstream *downstream, if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { downstream->disable_upstream_rtimer(); - downstream->set_request_state(Downstream::MSG_COMPLETE); + downstream->set_request_state(DownstreamState::MSG_COMPLETE); } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } @@ -467,7 +467,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) { rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); } - downstream->set_request_state(Downstream::CONNECT_FAIL); + downstream->set_request_state(DownstreamState::CONNECT_FAIL); downstream_queue_.mark_failure(downstream); return; @@ -483,7 +483,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) { rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); } - downstream->set_request_state(Downstream::CONNECT_FAIL); + downstream->set_request_state(DownstreamState::CONNECT_FAIL); downstream_queue_.mark_failure(downstream); @@ -504,7 +504,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) { return; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return; } } @@ -556,12 +556,12 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, downstream->disable_upstream_rtimer(); if (downstream->end_upload_data() != 0) { - if (downstream->get_response_state() != Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) { upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); } } - downstream->set_request_state(Downstream::MSG_COMPLETE); + downstream->set_request_state(DownstreamState::MSG_COMPLETE); } return 0; @@ -585,12 +585,12 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, downstream->disable_upstream_rtimer(); if (downstream->end_upload_data() != 0) { - if (downstream->get_response_state() != Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) { upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); } } - downstream->set_request_state(Downstream::MSG_COMPLETE); + downstream->set_request_state(DownstreamState::MSG_COMPLETE); } return 0; @@ -637,7 +637,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags, downstream->reset_upstream_rtimer(); if (downstream->push_upload_data_chunk(data, len) != 0) { - if (downstream->get_response_state() != Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) { upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); } @@ -757,7 +757,7 @@ int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame, promised_downstream->inspect_http2_request(); - promised_downstream->set_request_state(Downstream::MSG_COMPLETE); + promised_downstream->set_request_state(DownstreamState::MSG_COMPLETE); // a bit weird but start_downstream() expects that given // downstream is in pending queue. @@ -1241,7 +1241,7 @@ ClientHandler *Http2Upstream::get_client_handler() const { return handler_; } int Http2Upstream::downstream_read(DownstreamConnection *dconn) { auto downstream = dconn->get_downstream(); - if (downstream->get_response_state() == Downstream::MSG_RESET) { + if (downstream->get_response_state() == DownstreamState::MSG_RESET) { // The downstream stream was reset (canceled). In this case, // RST_STREAM to the upstream and delete downstream connection // here. Deleting downstream will be taken place at @@ -1252,7 +1252,8 @@ int Http2Upstream::downstream_read(DownstreamConnection *dconn) { downstream->pop_downstream_connection(); // dconn was deleted dconn = nullptr; - } else if (downstream->get_response_state() == Downstream::MSG_BAD_HEADER) { + } else if (downstream->get_response_state() == + DownstreamState::MSG_BAD_HEADER) { if (error_reply(downstream, 502) != 0) { return -1; } @@ -1316,19 +1317,20 @@ int Http2Upstream::downstream_eof(DownstreamConnection *dconn) { // dconn was deleted dconn = nullptr; // downstream wil be deleted in on_stream_close_callback. - if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) { // Server may indicate the end of the request by EOF if (LOG_ENABLED(INFO)) { ULOG(INFO, this) << "Downstream body was ended by EOF"; } - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); // For tunneled connection, MSG_COMPLETE signals // downstream_data_read_callback to send RST_STREAM after pending // response body is sent. This is needed to ensure that RST_STREAM // is sent after all pending data are sent. on_downstream_body_complete(downstream); - } else if (downstream->get_response_state() != Downstream::MSG_COMPLETE) { + } else if (downstream->get_response_state() != + DownstreamState::MSG_COMPLETE) { // If stream was not closed, then we set MSG_COMPLETE and let // on_stream_close_callback delete downstream. if (error_reply(downstream, 502) != 0) { @@ -1360,7 +1362,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) { // dconn was deleted dconn = nullptr; - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { // For SSL tunneling, we issue RST_STREAM. For other types of // stream, we don't have to do anything since response was // complete. @@ -1368,7 +1370,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) { rst_stream(downstream, NGHTTP2_NO_ERROR); } } else { - if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) { if (downstream->get_upgraded()) { on_downstream_body_complete(downstream); } else { @@ -1385,7 +1387,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) { return -1; } } - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); } handler_->signal_write(); // At this point, downstream may be deleted. @@ -1452,7 +1454,7 @@ ssize_t downstream_data_read_callback(nghttp2_session *session, *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; if (body_empty && - downstream->get_response_state() == Downstream::MSG_COMPLETE) { + downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; @@ -1549,7 +1551,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body, buf->append(body, bodylen); - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); if (data_prd_ptr) { downstream->reset_upstream_wtimer(); @@ -1569,7 +1571,7 @@ int Http2Upstream::error_reply(Downstream *downstream, resp.http_status = status_code; auto body = downstream->get_response_buf(); body->append(html); - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); nghttp2_data_provider data_prd; data_prd.source.ptr = downstream; @@ -1667,7 +1669,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return -1; } } @@ -1683,7 +1685,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return -1; } } @@ -2045,7 +2047,7 @@ int Http2Upstream::on_downstream_reset(Downstream *downstream, bool no_retry) { } if (!downstream->request_submission_ready()) { - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { // We have got all response body already. Send it off. downstream->pop_downstream_connection(); return 0; diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index 6b9fe509..6b4c28eb 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -100,7 +100,7 @@ void retry_downstream_connection(Downstream *downstream, } } - downstream->set_request_state(Downstream::CONNECT_FAIL); + downstream->set_request_state(DownstreamState::CONNECT_FAIL); if (rv == SHRPX_ERR_TLS_REQUIRED) { rv = upstream->on_downstream_abort_request_with_https_redirect(downstream); @@ -901,7 +901,7 @@ namespace { int htp_msg_begincb(http_parser *htp) { auto downstream = static_cast(htp->data); - if (downstream->get_response_state() != Downstream::INITIAL) { + if (downstream->get_response_state() != DownstreamState::INITIAL) { return -1; } @@ -966,7 +966,7 @@ int htp_hdrs_completecb(http_parser *htp) { return -1; } } else if (resp.fs.parse_content_length() != 0) { - downstream->set_response_state(Downstream::MSG_BAD_HEADER); + downstream->set_response_state(DownstreamState::MSG_BAD_HEADER); return -1; } @@ -992,7 +992,7 @@ int htp_hdrs_completecb(http_parser *htp) { } resp.connection_close = !http_should_keep_alive(htp); - downstream->set_response_state(Downstream::HEADER_COMPLETE); + downstream->set_response_state(DownstreamState::HEADER_COMPLETE); downstream->inspect_http1_response(); if (downstream->get_upgraded()) { // content-length must be ignored for upgraded connection. @@ -1023,7 +1023,7 @@ int htp_hdrs_completecb(http_parser *htp) { if (upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0) != 0) { return -1; } - downstream->set_request_state(Downstream::HEADER_COMPLETE); + downstream->set_request_state(DownstreamState::HEADER_COMPLETE); if (LOG_ENABLED(INFO)) { LOG(INFO) << "HTTP upgrade success. stream_id=" << downstream->get_stream_id(); @@ -1086,7 +1086,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { return -1; } - if (downstream->get_response_state() == Downstream::INITIAL) { + if (downstream->get_response_state() == DownstreamState::INITIAL) { if (resp.fs.header_key_prev()) { resp.fs.append_last_header_key(data, len); } else { @@ -1123,7 +1123,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) { return -1; } - if (downstream->get_response_state() == Downstream::INITIAL) { + if (downstream->get_response_state() == DownstreamState::INITIAL) { resp.fs.append_last_header_value(data, len); } else { resp.fs.append_last_trailer_value(data, len); @@ -1163,7 +1163,7 @@ int htp_msg_completecb(http_parser *htp) { return 0; } - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); // Block reading another response message from (broken?) // server. This callback is not called if the connection is // tunneled. @@ -1435,7 +1435,7 @@ int HttpDownstreamConnection::process_input(const uint8_t *data, if (htperr != HPE_OK) { // Handling early return (in other words, response was hijacked by // mruby scripting). - if (downstream_->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream_->get_response_state() == DownstreamState::MSG_COMPLETE) { return SHRPX_ERR_DCONN_CANCELED; } diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index d297d38b..35486dde 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -111,8 +111,9 @@ int htp_uricb(http_parser *htp, const char *data, size_t len) { ULOG(INFO, upstream) << "Too large URI size=" << req.fs.buffer_size() + len; } - assert(downstream->get_request_state() == Downstream::INITIAL); - downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); + assert(downstream->get_request_state() == DownstreamState::INITIAL); + downstream->set_request_state( + DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE); return -1; } @@ -141,12 +142,13 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { ULOG(INFO, upstream) << "Too large header block size=" << req.fs.buffer_size() + len; } - if (downstream->get_request_state() == Downstream::INITIAL) { - downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); + if (downstream->get_request_state() == DownstreamState::INITIAL) { + downstream->set_request_state( + DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE); } return -1; } - if (downstream->get_request_state() == Downstream::INITIAL) { + if (downstream->get_request_state() == DownstreamState::INITIAL) { if (req.fs.header_key_prev()) { req.fs.append_last_header_key(data, len); } else { @@ -156,7 +158,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { << "Too many header field num=" << req.fs.num_fields() + 1; } downstream->set_request_state( - Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); + DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE); return -1; } req.fs.alloc_add_header_name(StringRef{data, len}); @@ -192,12 +194,13 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) { ULOG(INFO, upstream) << "Too large header block size=" << req.fs.buffer_size() + len; } - if (downstream->get_request_state() == Downstream::INITIAL) { - downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); + if (downstream->get_request_state() == DownstreamState::INITIAL) { + downstream->set_request_state( + DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE); } return -1; } - if (downstream->get_request_state() == Downstream::INITIAL) { + if (downstream->get_request_state() == DownstreamState::INITIAL) { req.fs.append_last_header_value(data, len); } else { req.fs.append_last_trailer_value(data, len); @@ -397,7 +400,7 @@ int htp_hdrs_completecb(http_parser *htp) { } } - downstream->set_request_state(Downstream::HEADER_COMPLETE); + downstream->set_request_state(DownstreamState::HEADER_COMPLETE); #ifdef HAVE_MRUBY auto worker = handler->get_worker(); @@ -419,7 +422,7 @@ int htp_hdrs_completecb(http_parser *htp) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } @@ -429,7 +432,7 @@ int htp_hdrs_completecb(http_parser *htp) { if (rv == SHRPX_ERR_TLS_REQUIRED) { upstream->redirect_to_https(downstream); } - downstream->set_request_state(Downstream::CONNECT_FAIL); + downstream->set_request_state(DownstreamState::CONNECT_FAIL); return -1; } @@ -438,7 +441,7 @@ int htp_hdrs_completecb(http_parser *htp) { auto dconn_ptr = dconn.get(); #endif // HAVE_MRUBY if (downstream->attach_downstream_connection(std::move(dconn)) != 0) { - downstream->set_request_state(Downstream::CONNECT_FAIL); + downstream->set_request_state(DownstreamState::CONNECT_FAIL); return -1; } @@ -453,7 +456,7 @@ int htp_hdrs_completecb(http_parser *htp) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } } @@ -494,7 +497,7 @@ int htp_bodycb(http_parser *htp, const char *data, size_t len) { if (rv != 0) { // Ignore error if response has been completed. We will end up in // htp_msg_completecb, and request will end gracefully. - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return 0; } @@ -513,10 +516,10 @@ int htp_msg_completecb(http_parser *htp) { } auto handler = upstream->get_client_handler(); auto downstream = upstream->get_downstream(); - downstream->set_request_state(Downstream::MSG_COMPLETE); + downstream->set_request_state(DownstreamState::MSG_COMPLETE); rv = downstream->end_upload_data(); if (rv != 0) { - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { // Here both response and request were completed. One of the // reason why end_upload_data() failed is when we sent response // in request phase hook. We only delete and proceed to the @@ -596,8 +599,8 @@ int HttpsUpstream::on_read() { if (downstream) { // To avoid reading next pipelined request switch (downstream->get_request_state()) { - case Downstream::INITIAL: - case Downstream::HEADER_COMPLETE: + case DownstreamState::INITIAL: + case DownstreamState::HEADER_COMPLETE: break; default: return 0; @@ -625,8 +628,8 @@ int HttpsUpstream::on_read() { // We may pause parser in htp_msg_completecb when both side are // completed. Signal write, so that we can run on_write(). if (downstream && - downstream->get_request_state() == Downstream::MSG_COMPLETE && - downstream->get_response_state() == Downstream::MSG_COMPLETE) { + downstream->get_request_state() == DownstreamState::MSG_COMPLETE && + downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { handler_->signal_write(); } return 0; @@ -639,7 +642,8 @@ int HttpsUpstream::on_read() { << http_errno_description(htperr); } - if (downstream && downstream->get_response_state() != Downstream::INITIAL) { + if (downstream && + downstream->get_response_state() != DownstreamState::INITIAL) { handler_->set_should_close_after_write(true); handler_->signal_write(); return 0; @@ -652,10 +656,10 @@ int HttpsUpstream::on_read() { } else if (downstream) { status_code = downstream->response().http_status; if (status_code == 0) { - if (downstream->get_request_state() == Downstream::CONNECT_FAIL) { + if (downstream->get_request_state() == DownstreamState::CONNECT_FAIL) { status_code = 502; } else if (downstream->get_request_state() == - Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE) { + DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE) { status_code = 431; } else { status_code = 400; @@ -701,7 +705,7 @@ int HttpsUpstream::on_write() { // We need to postpone detachment until all data are sent so that // we can notify nghttp2 library all data consumed. - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { if (downstream->can_detach_downstream_connection()) { // Keep-alive downstream->detach_downstream_connection(); @@ -711,7 +715,7 @@ int HttpsUpstream::on_write() { // dconn was deleted } // We need this if response ends before request. - if (downstream->get_request_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_request_state() == DownstreamState::MSG_COMPLETE) { delete_downstream(); if (handler_->get_should_close_after_write()) { @@ -778,11 +782,11 @@ int HttpsUpstream::downstream_read(DownstreamConnection *dconn) { return downstream_error(dconn, Downstream::EVENT_ERROR); } - if (downstream->get_response_state() == Downstream::MSG_RESET) { + if (downstream->get_response_state() == DownstreamState::MSG_RESET) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_BAD_HEADER) { + if (downstream->get_response_state() == DownstreamState::MSG_BAD_HEADER) { error_reply(502); downstream->pop_downstream_connection(); goto end; @@ -820,23 +824,23 @@ int HttpsUpstream::downstream_eof(DownstreamConnection *dconn) { DCLOG(INFO, dconn) << "EOF"; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { goto end; } - if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) { // Server may indicate the end of the request by EOF if (LOG_ENABLED(INFO)) { DCLOG(INFO, dconn) << "The end of the response body was indicated by " << "EOF"; } on_downstream_body_complete(downstream); - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); downstream->pop_downstream_connection(); goto end; } - if (downstream->get_response_state() == Downstream::INITIAL) { + if (downstream->get_response_state() == DownstreamState::INITIAL) { // we did not send any response headers, so we can reply error // message. if (LOG_ENABLED(INFO)) { @@ -865,7 +869,7 @@ int HttpsUpstream::downstream_error(DownstreamConnection *dconn, int events) { DCLOG(INFO, dconn) << "Timeout"; } } - if (downstream->get_response_state() != Downstream::INITIAL) { + if (downstream->get_response_state() != DownstreamState::INITIAL) { return -1; } @@ -952,7 +956,7 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body, output->append(body, bodylen); downstream->response_sent_body_length += bodylen; - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); return 0; } @@ -998,7 +1002,7 @@ void HttpsUpstream::error_reply(unsigned int status_code) { output->append(html); downstream->response_sent_body_length += html.size(); - downstream->set_response_state(Downstream::MSG_COMPLETE); + downstream->set_response_state(DownstreamState::MSG_COMPLETE); } void HttpsUpstream::attach_downstream(std::unique_ptr downstream) { @@ -1064,7 +1068,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return -1; } } @@ -1077,7 +1081,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) { return -1; } - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { return -1; } } @@ -1312,7 +1316,7 @@ int HttpsUpstream::on_downstream_body_complete(Downstream *downstream) { if (req.connection_close || resp.connection_close || // To avoid to stall upload body - downstream->get_request_state() != Downstream::MSG_COMPLETE) { + downstream->get_request_state() != DownstreamState::MSG_COMPLETE) { auto handler = get_client_handler(); handler->set_should_close_after_write(true); } @@ -1399,14 +1403,16 @@ int HttpsUpstream::on_downstream_reset(Downstream *downstream, bool no_retry) { if (!downstream_->request_submission_ready()) { switch (downstream_->get_response_state()) { - case Downstream::MSG_COMPLETE: + case DownstreamState::MSG_COMPLETE: // We have got all response body already. Send it off. return 0; - case Downstream::INITIAL: + case DownstreamState::INITIAL: if (on_downstream_abort_request(downstream_.get(), 502) != 0) { return -1; } return 0; + default: + break; } // Return error so that caller can delete handler return -1; diff --git a/src/shrpx_mruby.cc b/src/shrpx_mruby.cc index c7fe434a..15466c06 100644 --- a/src/shrpx_mruby.cc +++ b/src/shrpx_mruby.cc @@ -82,7 +82,7 @@ int MRubyContext::run_app(Downstream *downstream, int phase) { if (mrb_->exc) { // If response has been committed, ignore error - if (downstream->get_response_state() != Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) { rv = -1; } diff --git a/src/shrpx_mruby_module_response.cc b/src/shrpx_mruby_module_response.cc index 3b24ea06..0dc8ddb1 100644 --- a/src/shrpx_mruby_module_response.cc +++ b/src/shrpx_mruby_module_response.cc @@ -209,7 +209,7 @@ mrb_value response_return(mrb_state *mrb, mrb_value self) { auto &balloc = downstream->get_block_allocator(); - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { mrb_raise(mrb, E_RUNTIME_ERROR, "response has already been committed"); } @@ -283,7 +283,7 @@ mrb_value response_send_info(mrb_state *mrb, mrb_value self) { auto &resp = downstream->response(); int rv; - if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) { mrb_raise(mrb, E_RUNTIME_ERROR, "response has already been committed"); }