nghttpx: Make Downstream state enum class

This commit is contained in:
Tatsuhiro Tsujikawa 2018-10-17 10:03:32 +09:00
parent 0735ec55f3
commit 1b42110d4f
9 changed files with 166 additions and 150 deletions

View File

@ -133,8 +133,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
downstream_stream_id_(-1), downstream_stream_id_(-1),
response_rst_stream_error_code_(NGHTTP2_NO_ERROR), response_rst_stream_error_code_(NGHTTP2_NO_ERROR),
affinity_cookie_(0), affinity_cookie_(0),
request_state_(INITIAL), request_state_(DownstreamState::INITIAL),
response_state_(INITIAL), response_state_(DownstreamState::INITIAL),
dispatch_state_(DISPATCH_NONE), dispatch_state_(DISPATCH_NONE),
upgraded_(false), upgraded_(false),
chunked_request_(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_; } 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_; } bool Downstream::get_chunked_request() const { return chunked_request_; }
@ -711,9 +713,13 @@ int Downstream::on_read() {
return dconn_->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_; } 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 { bool Downstream::get_http2_upgrade_request() const {
return req_.http2_upgrade_seen && req_.fs.header(http2::HD_HTTP2_SETTINGS) && 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 { StringRef Downstream::get_http2_settings() const {
@ -1055,10 +1061,10 @@ bool Downstream::get_request_header_sent() const {
} }
bool Downstream::request_submission_ready() const { bool Downstream::request_submission_ready() const {
return (request_state_ == Downstream::HEADER_COMPLETE || return (request_state_ == DownstreamState::HEADER_COMPLETE ||
request_state_ == Downstream::MSG_COMPLETE) && request_state_ == DownstreamState::MSG_COMPLETE) &&
(request_pending_ || !request_header_sent_) && (request_pending_ || !request_header_sent_) &&
response_state_ == Downstream::INITIAL; response_state_ == DownstreamState::INITIAL;
} }
int Downstream::get_dispatch_state() const { return dispatch_state_; } 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 // We should check request and response buffer. If request buffer
// is not empty, then we might leave downstream connection in weird // is not empty, then we might leave downstream connection in weird
// state, especially for HTTP/1.1 // state, especially for HTTP/1.1
return dconn_ && response_state_ == Downstream::MSG_COMPLETE && return dconn_ && response_state_ == DownstreamState::MSG_COMPLETE &&
request_state_ == Downstream::MSG_COMPLETE && !upgraded_ && request_state_ == DownstreamState::MSG_COMPLETE && !upgraded_ &&
!resp_.connection_close && request_buf_.rleft() == 0; !resp_.connection_close && request_buf_.rleft() == 0;
} }

View File

@ -276,6 +276,22 @@ struct Response {
bool headers_only; 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 { class Downstream {
public: public:
Downstream(Upstream *upstream, MemchunkPool *mcpool, int32_t stream_id); Downstream(Upstream *upstream, MemchunkPool *mcpool, int32_t stream_id);
@ -349,24 +365,8 @@ public:
void set_request_downstream_host(const StringRef &host); void set_request_downstream_host(const StringRef &host);
bool expect_response_body() const; bool expect_response_body() const;
bool expect_response_trailer() const; bool expect_response_trailer() const;
enum { void set_request_state(DownstreamState state);
INITIAL, DownstreamState get_request_state() const;
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;
DefaultMemchunks *get_request_buf(); DefaultMemchunks *get_request_buf();
void set_request_pending(bool f); void set_request_pending(bool f);
bool get_request_pending() const; bool get_request_pending() const;
@ -391,8 +391,8 @@ public:
bool get_chunked_response() const; bool get_chunked_response() const;
void set_chunked_response(bool f); void set_chunked_response(bool f);
void set_response_state(int state); void set_response_state(DownstreamState state);
int get_response_state() const; DownstreamState get_response_state() const;
DefaultMemchunks *get_response_buf(); DefaultMemchunks *get_response_buf();
bool response_buf_full(); bool response_buf_full();
// Validates that received response body length and content-length // Validates that received response body length and content-length
@ -557,9 +557,9 @@ private:
// An affinity cookie value. // An affinity cookie value.
uint32_t affinity_cookie_; uint32_t affinity_cookie_;
// request state // request state
int request_state_; DownstreamState request_state_;
// response state // response state
int response_state_; DownstreamState response_state_;
// only used by HTTP/2 upstream // only used by HTTP/2 upstream
int dispatch_state_; int dispatch_state_;
// true if the connection is upgraded (HTTP Upgrade or CONNECT), // true if the connection is upgraded (HTTP Upgrade or CONNECT),

View File

@ -62,10 +62,10 @@ Http2DownstreamConnection::~Http2DownstreamConnection() {
downstream_->disable_downstream_wtimer(); downstream_->disable_downstream_wtimer();
uint32_t error_code; uint32_t error_code;
if (downstream_->get_request_state() == Downstream::STREAM_CLOSED && if (downstream_->get_request_state() == DownstreamState::STREAM_CLOSED &&
downstream_->get_upgraded()) { downstream_->get_upgraded()) {
// For upgraded connection, send NO_ERROR. Should we consider // 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; error_code = NGHTTP2_NO_ERROR;
} else { } else {
error_code = NGHTTP2_INTERNAL_ERROR; error_code = NGHTTP2_INTERNAL_ERROR;
@ -143,9 +143,9 @@ int Http2DownstreamConnection::submit_rst_stream(Downstream *downstream,
if (http2session_->get_state() == Http2Session::CONNECTED && if (http2session_->get_state() == Http2Session::CONNECTED &&
downstream->get_downstream_stream_id() != -1) { downstream->get_downstream_stream_id() != -1) {
switch (downstream->get_response_state()) { switch (downstream->get_response_state()) {
case Downstream::MSG_RESET: case DownstreamState::MSG_RESET:
case Downstream::MSG_BAD_HEADER: case DownstreamState::MSG_BAD_HEADER:
case Downstream::MSG_COMPLETE: case DownstreamState::MSG_COMPLETE:
break; break;
default: default:
if (LOG_ENABLED(INFO)) { 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; *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
if (input_empty && 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 // If connection is upgraded, don't set EOF flag, since HTTP/1
// will set MSG_COMPLETE to request state after upgrade response // will set MSG_COMPLETE to request state after upgrade response
// header is seen. // header is seen.
(!req.upgrade_request || (!req.upgrade_request ||
(downstream->get_response_state() == Downstream::HEADER_COMPLETE && (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE &&
!downstream->get_upgraded()))) { !downstream->get_upgraded()))) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF; *data_flags |= NGHTTP2_DATA_FLAG_EOF;

View File

@ -833,34 +833,34 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
auto upstream = downstream->get_upstream(); auto upstream = downstream->get_upstream();
if (downstream->get_downstream_stream_id() % 2 == 0 && 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 // Downstream is canceled in backend before it is submitted in
// frontend session. // frontend session.
// This will avoid to send RST_STREAM to backend // 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); upstream->cancel_premature_downstream(downstream);
} else { } else {
if (downstream->get_upgraded() && if (downstream->get_upgraded() && downstream->get_response_state() ==
downstream->get_response_state() == Downstream::HEADER_COMPLETE) { DownstreamState::HEADER_COMPLETE) {
// For tunneled connection, we have to submit RST_STREAM to // For tunneled connection, we have to submit RST_STREAM to
// upstream *after* whole response body is sent. We just set // upstream *after* whole response body is sent. We just set
// MSG_COMPLETE here. Upstream will take care of that. // MSG_COMPLETE here. Upstream will take care of that.
downstream->get_upstream()->on_downstream_body_complete(downstream); 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) { } else if (error_code == NGHTTP2_NO_ERROR) {
switch (downstream->get_response_state()) { switch (downstream->get_response_state()) {
case Downstream::MSG_COMPLETE: case DownstreamState::MSG_COMPLETE:
case Downstream::MSG_BAD_HEADER: case DownstreamState::MSG_BAD_HEADER:
break; break;
default: default:
downstream->set_response_state(Downstream::MSG_RESET); downstream->set_response_state(DownstreamState::MSG_RESET);
} }
} else if (downstream->get_response_state() != } else if (downstream->get_response_state() !=
Downstream::MSG_BAD_HEADER) { DownstreamState::MSG_BAD_HEADER) {
downstream->set_response_state(Downstream::MSG_RESET); 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() == downstream->get_response_rst_stream_error_code() ==
NGHTTP2_NO_ERROR) { NGHTTP2_NO_ERROR) {
downstream->set_response_rst_stream_error_code(error_code); downstream->set_response_rst_stream_error_code(error_code);
@ -1133,13 +1133,13 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
if (rv != 0) { if (rv != 0) {
http2session->submit_rst_stream(frame->hd.stream_id, http2session->submit_rst_stream(frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR); NGHTTP2_PROTOCOL_ERROR);
downstream->set_response_state(Downstream::MSG_RESET); downstream->set_response_state(DownstreamState::MSG_RESET);
} }
return 0; return 0;
} }
downstream->set_response_state(Downstream::HEADER_COMPLETE); downstream->set_response_state(DownstreamState::HEADER_COMPLETE);
downstream->check_upgrade_fulfilled_http2(); downstream->check_upgrade_fulfilled_http2();
if (downstream->get_upgraded()) { if (downstream->get_upgraded()) {
@ -1150,7 +1150,7 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
delete handler; delete handler;
return -1; return -1;
} }
downstream->set_request_state(Downstream::HEADER_COMPLETE); downstream->set_request_state(DownstreamState::HEADER_COMPLETE);
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
SSLOG(INFO, http2session) SSLOG(INFO, http2session)
<< "HTTP upgrade success. stream_id=" << frame->hd.stream_id; << "HTTP upgrade success. stream_id=" << frame->hd.stream_id;
@ -1193,12 +1193,12 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
if (rv != 0) { if (rv != 0) {
// Handling early return (in other words, response was hijacked by // Handling early return (in other words, response was hijacked by
// mruby scripting). // 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); http2session->submit_rst_stream(frame->hd.stream_id, NGHTTP2_CANCEL);
} else { } else {
http2session->submit_rst_stream(frame->hd.stream_id, http2session->submit_rst_stream(frame->hd.stream_id,
NGHTTP2_INTERNAL_ERROR); 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) { if (rv != 0) {
http2session->submit_rst_stream(frame->hd.stream_id, http2session->submit_rst_stream(frame->hd.stream_id,
NGHTTP2_INTERNAL_ERROR); 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) { } else if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
downstream->disable_downstream_rtimer(); 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); rv = upstream->on_downstream_body_complete(downstream);
if (rv != 0) { 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) { if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
downstream->disable_downstream_rtimer(); downstream->disable_downstream_rtimer();
if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if (downstream->get_response_state() ==
downstream->set_response_state(Downstream::MSG_COMPLETE); DownstreamState::HEADER_COMPLETE) {
downstream->set_response_state(DownstreamState::MSG_COMPLETE);
auto upstream = downstream->get_upstream(); auto upstream = downstream->get_upstream();
rv = upstream->on_downstream_body_complete(downstream); rv = upstream->on_downstream_body_complete(downstream);
if (rv != 0) { if (rv != 0) {
downstream->set_response_state(Downstream::MSG_RESET); downstream->set_response_state(DownstreamState::MSG_RESET);
} }
} }
} else { } else {
@ -1442,7 +1444,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} }
downstream->set_response_state(Downstream::MSG_RESET); downstream->set_response_state(DownstreamState::MSG_RESET);
} }
call_downstream_readcb(http2session, downstream); call_downstream_readcb(http2session, downstream);
@ -1536,8 +1538,8 @@ int on_frame_not_send_callback(nghttp2_session *session,
return 0; return 0;
} }
// To avoid stream hanging around, flag Downstream::MSG_RESET. // To avoid stream hanging around, flag DownstreamState::MSG_RESET.
downstream->set_response_state(Downstream::MSG_RESET); downstream->set_response_state(DownstreamState::MSG_RESET);
call_downstream_readcb(http2session, downstream); call_downstream_readcb(http2session, downstream);
return 0; return 0;
@ -2279,7 +2281,7 @@ int Http2Session::handle_downstream_push_promise_complete(
auto upstream = promised_downstream->get_upstream(); 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); promised_downstream->set_request_header_sent(true);
if (upstream->on_downstream_push_promise_complete(downstream, if (upstream->on_downstream_push_promise_complete(downstream,

View File

@ -77,7 +77,7 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
req.unconsumed_body_length = 0; 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); upstream->remove_downstream(downstream);
// downstream was deleted // downstream was deleted
@ -89,7 +89,7 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
downstream->detach_downstream_connection(); 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. // 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 > if (req.fs.buffer_size() + namebuf.len + valuebuf.len >
httpconf.request_header_field_buffer || httpconf.request_header_field_buffer ||
req.fs.num_fields() >= httpconf.max_request_header_fields) { 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; return 0;
} }
@ -312,7 +312,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
auto &req = downstream->request(); auto &req = downstream->request();
req.tstamp = lgconf->tstamp; req.tstamp = lgconf->tstamp;
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return 0; return 0;
} }
@ -413,7 +413,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
downstream->inspect_http2_request(); downstream->inspect_http2_request();
downstream->set_request_state(Downstream::HEADER_COMPLETE); downstream->set_request_state(DownstreamState::HEADER_COMPLETE);
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
auto upstream = downstream->get_upstream(); auto upstream = downstream->get_upstream();
@ -432,10 +432,10 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
downstream->disable_upstream_rtimer(); 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; return 0;
} }
@ -467,7 +467,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); 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); downstream_queue_.mark_failure(downstream);
return; return;
@ -483,7 +483,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); 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); downstream_queue_.mark_failure(downstream);
@ -504,7 +504,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
return; return;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return; return;
} }
} }
@ -556,12 +556,12 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
downstream->disable_upstream_rtimer(); downstream->disable_upstream_rtimer();
if (downstream->end_upload_data() != 0) { 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); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
} }
} }
downstream->set_request_state(Downstream::MSG_COMPLETE); downstream->set_request_state(DownstreamState::MSG_COMPLETE);
} }
return 0; return 0;
@ -585,12 +585,12 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
downstream->disable_upstream_rtimer(); downstream->disable_upstream_rtimer();
if (downstream->end_upload_data() != 0) { 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); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
} }
} }
downstream->set_request_state(Downstream::MSG_COMPLETE); downstream->set_request_state(DownstreamState::MSG_COMPLETE);
} }
return 0; return 0;
@ -637,7 +637,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
downstream->reset_upstream_rtimer(); downstream->reset_upstream_rtimer();
if (downstream->push_upload_data_chunk(data, len) != 0) { 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); 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->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 // a bit weird but start_downstream() expects that given
// downstream is in pending queue. // downstream is in pending queue.
@ -1241,7 +1241,7 @@ ClientHandler *Http2Upstream::get_client_handler() const { return handler_; }
int Http2Upstream::downstream_read(DownstreamConnection *dconn) { int Http2Upstream::downstream_read(DownstreamConnection *dconn) {
auto downstream = dconn->get_downstream(); 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, // The downstream stream was reset (canceled). In this case,
// RST_STREAM to the upstream and delete downstream connection // RST_STREAM to the upstream and delete downstream connection
// here. Deleting downstream will be taken place at // here. Deleting downstream will be taken place at
@ -1252,7 +1252,8 @@ int Http2Upstream::downstream_read(DownstreamConnection *dconn) {
downstream->pop_downstream_connection(); downstream->pop_downstream_connection();
// dconn was deleted // dconn was deleted
dconn = nullptr; 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) { if (error_reply(downstream, 502) != 0) {
return -1; return -1;
} }
@ -1316,19 +1317,20 @@ int Http2Upstream::downstream_eof(DownstreamConnection *dconn) {
// dconn was deleted // dconn was deleted
dconn = nullptr; dconn = nullptr;
// downstream wil be deleted in on_stream_close_callback. // 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 // Server may indicate the end of the request by EOF
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
ULOG(INFO, this) << "Downstream body was ended by EOF"; 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 // For tunneled connection, MSG_COMPLETE signals
// downstream_data_read_callback to send RST_STREAM after pending // downstream_data_read_callback to send RST_STREAM after pending
// response body is sent. This is needed to ensure that RST_STREAM // response body is sent. This is needed to ensure that RST_STREAM
// is sent after all pending data are sent. // is sent after all pending data are sent.
on_downstream_body_complete(downstream); 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 // If stream was not closed, then we set MSG_COMPLETE and let
// on_stream_close_callback delete downstream. // on_stream_close_callback delete downstream.
if (error_reply(downstream, 502) != 0) { if (error_reply(downstream, 502) != 0) {
@ -1360,7 +1362,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) {
// dconn was deleted // dconn was deleted
dconn = nullptr; 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 // For SSL tunneling, we issue RST_STREAM. For other types of
// stream, we don't have to do anything since response was // stream, we don't have to do anything since response was
// complete. // complete.
@ -1368,7 +1370,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) {
rst_stream(downstream, NGHTTP2_NO_ERROR); rst_stream(downstream, NGHTTP2_NO_ERROR);
} }
} else { } else {
if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) {
if (downstream->get_upgraded()) { if (downstream->get_upgraded()) {
on_downstream_body_complete(downstream); on_downstream_body_complete(downstream);
} else { } else {
@ -1385,7 +1387,7 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) {
return -1; return -1;
} }
} }
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
} }
handler_->signal_write(); handler_->signal_write();
// At this point, downstream may be deleted. // 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; *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
if (body_empty && if (body_empty &&
downstream->get_response_state() == Downstream::MSG_COMPLETE) { downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF; *data_flags |= NGHTTP2_DATA_FLAG_EOF;
@ -1549,7 +1551,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
buf->append(body, bodylen); buf->append(body, bodylen);
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
if (data_prd_ptr) { if (data_prd_ptr) {
downstream->reset_upstream_wtimer(); downstream->reset_upstream_wtimer();
@ -1569,7 +1571,7 @@ int Http2Upstream::error_reply(Downstream *downstream,
resp.http_status = status_code; resp.http_status = status_code;
auto body = downstream->get_response_buf(); auto body = downstream->get_response_buf();
body->append(html); body->append(html);
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
nghttp2_data_provider data_prd; nghttp2_data_provider data_prd;
data_prd.source.ptr = downstream; data_prd.source.ptr = downstream;
@ -1667,7 +1669,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return -1; return -1;
} }
} }
@ -1683,7 +1685,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return -1; return -1;
} }
} }
@ -2045,7 +2047,7 @@ int Http2Upstream::on_downstream_reset(Downstream *downstream, bool no_retry) {
} }
if (!downstream->request_submission_ready()) { 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. // We have got all response body already. Send it off.
downstream->pop_downstream_connection(); downstream->pop_downstream_connection();
return 0; return 0;

View File

@ -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) { if (rv == SHRPX_ERR_TLS_REQUIRED) {
rv = upstream->on_downstream_abort_request_with_https_redirect(downstream); rv = upstream->on_downstream_abort_request_with_https_redirect(downstream);
@ -901,7 +901,7 @@ namespace {
int htp_msg_begincb(http_parser *htp) { int htp_msg_begincb(http_parser *htp) {
auto downstream = static_cast<Downstream *>(htp->data); auto downstream = static_cast<Downstream *>(htp->data);
if (downstream->get_response_state() != Downstream::INITIAL) { if (downstream->get_response_state() != DownstreamState::INITIAL) {
return -1; return -1;
} }
@ -966,7 +966,7 @@ int htp_hdrs_completecb(http_parser *htp) {
return -1; return -1;
} }
} else if (resp.fs.parse_content_length() != 0) { } 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; return -1;
} }
@ -992,7 +992,7 @@ int htp_hdrs_completecb(http_parser *htp) {
} }
resp.connection_close = !http_should_keep_alive(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(); downstream->inspect_http1_response();
if (downstream->get_upgraded()) { if (downstream->get_upgraded()) {
// content-length must be ignored for upgraded connection. // 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) { if (upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0) != 0) {
return -1; return -1;
} }
downstream->set_request_state(Downstream::HEADER_COMPLETE); downstream->set_request_state(DownstreamState::HEADER_COMPLETE);
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "HTTP upgrade success. stream_id=" LOG(INFO) << "HTTP upgrade success. stream_id="
<< downstream->get_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; return -1;
} }
if (downstream->get_response_state() == Downstream::INITIAL) { if (downstream->get_response_state() == DownstreamState::INITIAL) {
if (resp.fs.header_key_prev()) { if (resp.fs.header_key_prev()) {
resp.fs.append_last_header_key(data, len); resp.fs.append_last_header_key(data, len);
} else { } else {
@ -1123,7 +1123,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::INITIAL) { if (downstream->get_response_state() == DownstreamState::INITIAL) {
resp.fs.append_last_header_value(data, len); resp.fs.append_last_header_value(data, len);
} else { } else {
resp.fs.append_last_trailer_value(data, len); resp.fs.append_last_trailer_value(data, len);
@ -1163,7 +1163,7 @@ int htp_msg_completecb(http_parser *htp) {
return 0; return 0;
} }
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
// Block reading another response message from (broken?) // Block reading another response message from (broken?)
// server. This callback is not called if the connection is // server. This callback is not called if the connection is
// tunneled. // tunneled.
@ -1435,7 +1435,7 @@ int HttpDownstreamConnection::process_input(const uint8_t *data,
if (htperr != HPE_OK) { if (htperr != HPE_OK) {
// Handling early return (in other words, response was hijacked by // Handling early return (in other words, response was hijacked by
// mruby scripting). // mruby scripting).
if (downstream_->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream_->get_response_state() == DownstreamState::MSG_COMPLETE) {
return SHRPX_ERR_DCONN_CANCELED; return SHRPX_ERR_DCONN_CANCELED;
} }

View File

@ -111,8 +111,9 @@ int htp_uricb(http_parser *htp, const char *data, size_t len) {
ULOG(INFO, upstream) << "Too large URI size=" ULOG(INFO, upstream) << "Too large URI size="
<< req.fs.buffer_size() + len; << req.fs.buffer_size() + len;
} }
assert(downstream->get_request_state() == Downstream::INITIAL); assert(downstream->get_request_state() == DownstreamState::INITIAL);
downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); downstream->set_request_state(
DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE);
return -1; 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=" ULOG(INFO, upstream) << "Too large header block size="
<< req.fs.buffer_size() + len; << req.fs.buffer_size() + len;
} }
if (downstream->get_request_state() == Downstream::INITIAL) { if (downstream->get_request_state() == DownstreamState::INITIAL) {
downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); downstream->set_request_state(
DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE);
} }
return -1; return -1;
} }
if (downstream->get_request_state() == Downstream::INITIAL) { if (downstream->get_request_state() == DownstreamState::INITIAL) {
if (req.fs.header_key_prev()) { if (req.fs.header_key_prev()) {
req.fs.append_last_header_key(data, len); req.fs.append_last_header_key(data, len);
} else { } 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; << "Too many header field num=" << req.fs.num_fields() + 1;
} }
downstream->set_request_state( downstream->set_request_state(
Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE);
return -1; return -1;
} }
req.fs.alloc_add_header_name(StringRef{data, len}); 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=" ULOG(INFO, upstream) << "Too large header block size="
<< req.fs.buffer_size() + len; << req.fs.buffer_size() + len;
} }
if (downstream->get_request_state() == Downstream::INITIAL) { if (downstream->get_request_state() == DownstreamState::INITIAL) {
downstream->set_request_state(Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); downstream->set_request_state(
DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE);
} }
return -1; return -1;
} }
if (downstream->get_request_state() == Downstream::INITIAL) { if (downstream->get_request_state() == DownstreamState::INITIAL) {
req.fs.append_last_header_value(data, len); req.fs.append_last_header_value(data, len);
} else { } else {
req.fs.append_last_trailer_value(data, len); 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 #ifdef HAVE_MRUBY
auto worker = handler->get_worker(); auto worker = handler->get_worker();
@ -419,7 +422,7 @@ int htp_hdrs_completecb(http_parser *htp) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return 0; return 0;
} }
@ -429,7 +432,7 @@ int htp_hdrs_completecb(http_parser *htp) {
if (rv == SHRPX_ERR_TLS_REQUIRED) { if (rv == SHRPX_ERR_TLS_REQUIRED) {
upstream->redirect_to_https(downstream); upstream->redirect_to_https(downstream);
} }
downstream->set_request_state(Downstream::CONNECT_FAIL); downstream->set_request_state(DownstreamState::CONNECT_FAIL);
return -1; return -1;
} }
@ -438,7 +441,7 @@ int htp_hdrs_completecb(http_parser *htp) {
auto dconn_ptr = dconn.get(); auto dconn_ptr = dconn.get();
#endif // HAVE_MRUBY #endif // HAVE_MRUBY
if (downstream->attach_downstream_connection(std::move(dconn)) != 0) { 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; return -1;
} }
@ -453,7 +456,7 @@ int htp_hdrs_completecb(http_parser *htp) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return 0; return 0;
} }
} }
@ -494,7 +497,7 @@ int htp_bodycb(http_parser *htp, const char *data, size_t len) {
if (rv != 0) { if (rv != 0) {
// Ignore error if response has been completed. We will end up in // Ignore error if response has been completed. We will end up in
// htp_msg_completecb, and request will end gracefully. // 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; return 0;
} }
@ -513,10 +516,10 @@ int htp_msg_completecb(http_parser *htp) {
} }
auto handler = upstream->get_client_handler(); auto handler = upstream->get_client_handler();
auto downstream = upstream->get_downstream(); auto downstream = upstream->get_downstream();
downstream->set_request_state(Downstream::MSG_COMPLETE); downstream->set_request_state(DownstreamState::MSG_COMPLETE);
rv = downstream->end_upload_data(); rv = downstream->end_upload_data();
if (rv != 0) { 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 // Here both response and request were completed. One of the
// reason why end_upload_data() failed is when we sent response // reason why end_upload_data() failed is when we sent response
// in request phase hook. We only delete and proceed to the // in request phase hook. We only delete and proceed to the
@ -596,8 +599,8 @@ int HttpsUpstream::on_read() {
if (downstream) { if (downstream) {
// To avoid reading next pipelined request // To avoid reading next pipelined request
switch (downstream->get_request_state()) { switch (downstream->get_request_state()) {
case Downstream::INITIAL: case DownstreamState::INITIAL:
case Downstream::HEADER_COMPLETE: case DownstreamState::HEADER_COMPLETE:
break; break;
default: default:
return 0; return 0;
@ -625,8 +628,8 @@ int HttpsUpstream::on_read() {
// We may pause parser in htp_msg_completecb when both side are // We may pause parser in htp_msg_completecb when both side are
// completed. Signal write, so that we can run on_write(). // completed. Signal write, so that we can run on_write().
if (downstream && if (downstream &&
downstream->get_request_state() == Downstream::MSG_COMPLETE && downstream->get_request_state() == DownstreamState::MSG_COMPLETE &&
downstream->get_response_state() == Downstream::MSG_COMPLETE) { downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
handler_->signal_write(); handler_->signal_write();
} }
return 0; return 0;
@ -639,7 +642,8 @@ int HttpsUpstream::on_read() {
<< http_errno_description(htperr); << 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_->set_should_close_after_write(true);
handler_->signal_write(); handler_->signal_write();
return 0; return 0;
@ -652,10 +656,10 @@ int HttpsUpstream::on_read() {
} else if (downstream) { } else if (downstream) {
status_code = downstream->response().http_status; status_code = downstream->response().http_status;
if (status_code == 0) { if (status_code == 0) {
if (downstream->get_request_state() == Downstream::CONNECT_FAIL) { if (downstream->get_request_state() == DownstreamState::CONNECT_FAIL) {
status_code = 502; status_code = 502;
} else if (downstream->get_request_state() == } else if (downstream->get_request_state() ==
Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE) { DownstreamState::HTTP1_REQUEST_HEADER_TOO_LARGE) {
status_code = 431; status_code = 431;
} else { } else {
status_code = 400; status_code = 400;
@ -701,7 +705,7 @@ int HttpsUpstream::on_write() {
// We need to postpone detachment until all data are sent so that // We need to postpone detachment until all data are sent so that
// we can notify nghttp2 library all data consumed. // 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()) { if (downstream->can_detach_downstream_connection()) {
// Keep-alive // Keep-alive
downstream->detach_downstream_connection(); downstream->detach_downstream_connection();
@ -711,7 +715,7 @@ int HttpsUpstream::on_write() {
// dconn was deleted // dconn was deleted
} }
// We need this if response ends before request. // 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(); delete_downstream();
if (handler_->get_should_close_after_write()) { if (handler_->get_should_close_after_write()) {
@ -778,11 +782,11 @@ int HttpsUpstream::downstream_read(DownstreamConnection *dconn) {
return downstream_error(dconn, Downstream::EVENT_ERROR); 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; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_BAD_HEADER) { if (downstream->get_response_state() == DownstreamState::MSG_BAD_HEADER) {
error_reply(502); error_reply(502);
downstream->pop_downstream_connection(); downstream->pop_downstream_connection();
goto end; goto end;
@ -820,23 +824,23 @@ int HttpsUpstream::downstream_eof(DownstreamConnection *dconn) {
DCLOG(INFO, dconn) << "EOF"; DCLOG(INFO, dconn) << "EOF";
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
goto end; 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 // Server may indicate the end of the request by EOF
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
DCLOG(INFO, dconn) << "The end of the response body was indicated by " DCLOG(INFO, dconn) << "The end of the response body was indicated by "
<< "EOF"; << "EOF";
} }
on_downstream_body_complete(downstream); on_downstream_body_complete(downstream);
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
downstream->pop_downstream_connection(); downstream->pop_downstream_connection();
goto end; 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 // we did not send any response headers, so we can reply error
// message. // message.
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
@ -865,7 +869,7 @@ int HttpsUpstream::downstream_error(DownstreamConnection *dconn, int events) {
DCLOG(INFO, dconn) << "Timeout"; DCLOG(INFO, dconn) << "Timeout";
} }
} }
if (downstream->get_response_state() != Downstream::INITIAL) { if (downstream->get_response_state() != DownstreamState::INITIAL) {
return -1; return -1;
} }
@ -952,7 +956,7 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
output->append(body, bodylen); output->append(body, bodylen);
downstream->response_sent_body_length += bodylen; downstream->response_sent_body_length += bodylen;
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(DownstreamState::MSG_COMPLETE);
return 0; return 0;
} }
@ -998,7 +1002,7 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
output->append(html); output->append(html);
downstream->response_sent_body_length += html.size(); 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> downstream) { void HttpsUpstream::attach_downstream(std::unique_ptr<Downstream> downstream) {
@ -1064,7 +1068,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return -1; return -1;
} }
} }
@ -1077,7 +1081,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
return -1; return -1;
} }
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
return -1; return -1;
} }
} }
@ -1312,7 +1316,7 @@ int HttpsUpstream::on_downstream_body_complete(Downstream *downstream) {
if (req.connection_close || resp.connection_close || if (req.connection_close || resp.connection_close ||
// To avoid to stall upload body // 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(); auto handler = get_client_handler();
handler->set_should_close_after_write(true); 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()) { if (!downstream_->request_submission_ready()) {
switch (downstream_->get_response_state()) { switch (downstream_->get_response_state()) {
case Downstream::MSG_COMPLETE: case DownstreamState::MSG_COMPLETE:
// We have got all response body already. Send it off. // We have got all response body already. Send it off.
return 0; return 0;
case Downstream::INITIAL: case DownstreamState::INITIAL:
if (on_downstream_abort_request(downstream_.get(), 502) != 0) { if (on_downstream_abort_request(downstream_.get(), 502) != 0) {
return -1; return -1;
} }
return 0; return 0;
default:
break;
} }
// Return error so that caller can delete handler // Return error so that caller can delete handler
return -1; return -1;

View File

@ -82,7 +82,7 @@ int MRubyContext::run_app(Downstream *downstream, int phase) {
if (mrb_->exc) { if (mrb_->exc) {
// If response has been committed, ignore error // 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; rv = -1;
} }

View File

@ -209,7 +209,7 @@ mrb_value response_return(mrb_state *mrb, mrb_value self) {
auto &balloc = downstream->get_block_allocator(); 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"); 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(); auto &resp = downstream->response();
int rv; 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"); mrb_raise(mrb, E_RUNTIME_ERROR, "response has already been committed");
} }