nghttpx: Add ability to Http2Upstream to send RST_STREAM after END_STREAM

This commit is contained in:
Tatsuhiro Tsujikawa 2014-07-02 23:56:26 +09:00
parent acb3d4dcfc
commit 93b3a44fb5
3 changed files with 33 additions and 1 deletions

View File

@ -66,7 +66,8 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
request_header_key_prev_(false), request_header_key_prev_(false),
chunked_response_(false), chunked_response_(false),
response_connection_close_(false), response_connection_close_(false),
response_header_key_prev_(false) response_header_key_prev_(false),
rst_stream_after_end_stream_(false)
{} {}
Downstream::~Downstream() Downstream::~Downstream()
@ -779,4 +780,14 @@ void Downstream::set_response_rst_stream_error_code
response_rst_stream_error_code_ = error_code; response_rst_stream_error_code_ = error_code;
} }
bool Downstream::get_rst_stream_after_end_stream() const
{
return rst_stream_after_end_stream_;
}
void Downstream::set_rst_stream_after_end_stream(bool f)
{
rst_stream_after_end_stream_ = f;
}
} // namespace shrpx } // namespace shrpx

View File

@ -218,6 +218,9 @@ public:
// Maximum buffer size for header name/value pairs. // Maximum buffer size for header name/value pairs.
static const size_t MAX_HEADERS_SUM = 32768; static const size_t MAX_HEADERS_SUM = 32768;
bool get_rst_stream_after_end_stream() const;
void set_rst_stream_after_end_stream(bool f);
private: private:
Headers request_headers_; Headers request_headers_;
Headers response_headers_; Headers response_headers_;
@ -275,6 +278,10 @@ private:
bool chunked_response_; bool chunked_response_;
bool response_connection_close_; bool response_connection_close_;
bool response_header_key_prev_; bool response_header_key_prev_;
// If true, RST_STREAM with NGHTTP2_NO_ERROR is issued after
// response is closed with END_STREAM.
bool rst_stream_after_end_stream_;
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -453,6 +453,11 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
return 0; return 0;
} }
if(!downstream->get_downstream_connection()) {
upstream->handle_ign_data_chunk(len);
return 0;
}
if(downstream->push_upload_data_chunk(data, len) != 0) { if(downstream->push_upload_data_chunk(data, len) != 0) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
upstream->handle_ign_data_chunk(len); upstream->handle_ign_data_chunk(len);
@ -994,6 +999,12 @@ ssize_t downstream_data_read_callback(nghttp2_session *session,
downstream->get_response_state() == Downstream::MSG_COMPLETE) { downstream->get_response_state() == Downstream::MSG_COMPLETE) {
if(!downstream->get_upgraded()) { if(!downstream->get_upgraded()) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF; *data_flags |= NGHTTP2_DATA_FLAG_EOF;
if(downstream->get_rst_stream_after_end_stream() &&
downstream->get_request_state() != Downstream::MSG_COMPLETE) {
upstream->rst_stream(downstream, NGHTTP2_NO_ERROR);
}
} else { } else {
// For tunneling, issue RST_STREAM to finish the stream. // For tunneling, issue RST_STREAM to finish the stream.
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {
@ -1054,6 +1065,9 @@ int Http2Upstream::error_reply(Downstream *downstream,
upstream_response(get_client_handler()->get_ipaddr(), upstream_response(get_client_handler()->get_ipaddr(),
status_code, downstream); status_code, downstream);
} }
downstream->set_rst_stream_after_end_stream(true);
return 0; return 0;
} }