nghttpx: Make Downstream state enum class
This commit is contained in:
parent
0735ec55f3
commit
1b42110d4f
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue