nghttpx: Support spdy/3.1, require spdylay >= 1.2.0
This commit is contained in:
parent
45c3c5b80f
commit
58beaa371d
|
@ -210,7 +210,7 @@ fi
|
|||
AM_CONDITIONAL([HAVE_LIBXML2], [ test "x${have_libxml2}" = "xyes" ])
|
||||
|
||||
# spdylay (for src/nghttpx)
|
||||
PKG_CHECK_MODULES([LIBSPDYLAY], [libspdylay >= 1.0.0],
|
||||
PKG_CHECK_MODULES([LIBSPDYLAY], [libspdylay >= 1.2.0],
|
||||
[have_spdylay=yes], [have_spdylay=no])
|
||||
if test "x${have_spdylay}" = "xyes"; then
|
||||
AC_DEFINE([HAVE_SPDYLAY], [1], [Define to 1 if you have `spdylay` library.])
|
||||
|
|
|
@ -324,7 +324,7 @@ bool conf_exists(const char *path)
|
|||
namespace {
|
||||
const char *DEFAULT_NPN_LIST = NGHTTP2_PROTO_VERSION_ID ","
|
||||
#ifdef HAVE_SPDYLAY
|
||||
"spdy/3,spdy/2,"
|
||||
"spdy/3.1,spdy/3,spdy/2,"
|
||||
#endif // HAVE_SPDYLAY
|
||||
"http/1.1";
|
||||
} // namespace
|
||||
|
|
|
@ -61,8 +61,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
|
|||
response_connection_close_(false),
|
||||
response_header_key_prev_(false),
|
||||
response_body_buf_(nullptr),
|
||||
response_rst_stream_error_code_(NGHTTP2_NO_ERROR),
|
||||
recv_window_size_(0)
|
||||
response_rst_stream_error_code_(NGHTTP2_NO_ERROR)
|
||||
{}
|
||||
|
||||
Downstream::~Downstream()
|
||||
|
@ -531,21 +530,6 @@ void Downstream::set_priority(int pri)
|
|||
priority_ = pri;
|
||||
}
|
||||
|
||||
int32_t Downstream::get_recv_window_size() const
|
||||
{
|
||||
return recv_window_size_;
|
||||
}
|
||||
|
||||
void Downstream::inc_recv_window_size(int32_t amount)
|
||||
{
|
||||
recv_window_size_ += amount;
|
||||
}
|
||||
|
||||
void Downstream::set_recv_window_size(int32_t new_size)
|
||||
{
|
||||
recv_window_size_ = new_size;
|
||||
}
|
||||
|
||||
void Downstream::check_upgrade_fulfilled()
|
||||
{
|
||||
if(request_method_ == "CONNECT") {
|
||||
|
|
|
@ -67,9 +67,6 @@ public:
|
|||
// Returns true if output buffer is full. If underlying dconn_ is
|
||||
// NULL, this function always returns false.
|
||||
bool get_output_buffer_full();
|
||||
int32_t get_recv_window_size() const;
|
||||
void inc_recv_window_size(int32_t amount);
|
||||
void set_recv_window_size(int32_t new_size);
|
||||
// Returns true if upgrade (HTTP Upgrade or CONNECT) is succeeded.
|
||||
void check_upgrade_fulfilled();
|
||||
// Checks request headers whether the request is upgrade request or
|
||||
|
@ -217,7 +214,6 @@ private:
|
|||
evbuffer *response_body_buf_;
|
||||
// RST_STREAM error_code from downstream HTTP2 connection
|
||||
nghttp2_error_code response_rst_stream_error_code_;
|
||||
int32_t recv_window_size_;
|
||||
};
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
|
@ -254,14 +254,32 @@ void on_data_chunk_recv_callback(spdylay_session *session,
|
|||
return;
|
||||
}
|
||||
if(upstream->get_flow_control()) {
|
||||
downstream->inc_recv_window_size(len);
|
||||
if(downstream->get_recv_window_size() >
|
||||
std::max(65536, upstream->get_initial_window_size())) {
|
||||
// If connection-level window control is not enabled (e.g,
|
||||
// spdy/3), spdylay_session_get_recv_data_length() is always
|
||||
// returns 0.
|
||||
if(spdylay_session_get_recv_data_length(session) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
spdylay_session_get_local_window_size(session))) {
|
||||
if(LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Flow control error: recv_window_size="
|
||||
<< downstream->get_recv_window_size()
|
||||
<< ", initial_window_size="
|
||||
<< upstream->get_initial_window_size();
|
||||
ULOG(INFO, upstream)
|
||||
<< "Flow control error on connection: "
|
||||
<< "recv_window_size="
|
||||
<< spdylay_session_get_recv_data_length(session)
|
||||
<< ", initial_window_size="
|
||||
<< spdylay_session_get_local_window_size(session);
|
||||
}
|
||||
spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
return;
|
||||
}
|
||||
if(spdylay_session_get_stream_recv_data_length(session, stream_id) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
spdylay_session_get_stream_local_window_size(session))) {
|
||||
if(LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream)
|
||||
<< "Flow control error: recv_window_size="
|
||||
<< spdylay_session_get_stream_recv_data_length(session, stream_id)
|
||||
<< ", initial_window_size="
|
||||
<< spdylay_session_get_stream_local_window_size(session);
|
||||
}
|
||||
upstream->rst_stream(downstream, SPDYLAY_FLOW_CONTROL_ERROR);
|
||||
return;
|
||||
|
@ -679,12 +697,13 @@ int SpdyUpstream::rst_stream(Downstream *downstream, int status_code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int SpdyUpstream::window_update(Downstream *downstream)
|
||||
int SpdyUpstream::window_update(Downstream *downstream, int32_t delta)
|
||||
{
|
||||
int rv;
|
||||
rv = spdylay_submit_window_update(session_, downstream->get_stream_id(),
|
||||
downstream->get_recv_window_size());
|
||||
downstream->set_recv_window_size(0);
|
||||
rv = spdylay_submit_window_update(session_,
|
||||
downstream ?
|
||||
downstream->get_stream_id() : 0,
|
||||
delta);
|
||||
if(rv < SPDYLAY_ERR_FATAL) {
|
||||
ULOG(FATAL, this) << "spdylay_submit_window_update() failed: "
|
||||
<< spdylay_strerror(rv);
|
||||
|
@ -921,11 +940,40 @@ int32_t SpdyUpstream::get_initial_window_size() const
|
|||
void SpdyUpstream::pause_read(IOCtrlReason reason)
|
||||
{}
|
||||
|
||||
namespace {
|
||||
int32_t determine_window_update_transmission(spdylay_session *session,
|
||||
int32_t stream_id)
|
||||
{
|
||||
int32_t recv_length, window_size;
|
||||
if(stream_id == 0) {
|
||||
recv_length = spdylay_session_get_recv_data_length(session);
|
||||
window_size = spdylay_session_get_local_window_size(session);
|
||||
} else {
|
||||
recv_length = spdylay_session_get_stream_recv_data_length
|
||||
(session, stream_id);
|
||||
window_size = spdylay_session_get_stream_local_window_size(session);
|
||||
}
|
||||
if(recv_length != -1 && window_size != -1) {
|
||||
if(recv_length >= window_size / 2) {
|
||||
return recv_length;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int SpdyUpstream::resume_read(IOCtrlReason reason, Downstream *downstream)
|
||||
{
|
||||
if(get_flow_control()) {
|
||||
if(downstream->get_recv_window_size() >= get_initial_window_size()/2) {
|
||||
window_update(downstream);
|
||||
int32_t delta;
|
||||
delta = determine_window_update_transmission(session_, 0);
|
||||
if(delta != -1) {
|
||||
window_update(0, delta);
|
||||
}
|
||||
delta = determine_window_update_transmission
|
||||
(session_, downstream->get_stream_id());
|
||||
if(delta != -1) {
|
||||
window_update(downstream, delta);
|
||||
}
|
||||
}
|
||||
return send();
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
spdylay_session* get_http2_session();
|
||||
|
||||
int rst_stream(Downstream *downstream, int status_code);
|
||||
int window_update(Downstream *downstream);
|
||||
int window_update(Downstream *downstream, int32_t delta);
|
||||
int error_reply(Downstream *downstream, unsigned int status_code);
|
||||
|
||||
virtual void pause_read(IOCtrlReason reason);
|
||||
|
|
Loading…
Reference in New Issue