From 9f9c0cbcd1805458963101be9a4483fd2afd074f Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 28 Jul 2013 19:28:41 +0900 Subject: [PATCH] nghttpd: Add -F and -f option to disable connection/stream level flow control --- src/HttpServer.cc | 30 ++++++++++++++++++++++++++---- src/HttpServer.h | 2 ++ src/nghttpd.cc | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 1dcaaa18..28135267 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -72,6 +72,8 @@ Config::Config() data_ptr(nullptr), verify_client(false), no_tls(false), + no_connection_flow_control(false), + no_stream_flow_control(false), output_upper_thres(1024*1024) {} @@ -346,13 +348,28 @@ int Http2Handler::on_connect() if(r != 0) { return r; } - nghttp2_settings_entry entry; - entry.settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; - entry.value = NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS; - r = nghttp2_submit_settings(session_, &entry, 1); + nghttp2_settings_entry entry[2]; + size_t niv = 1; + entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; + entry[0].value = NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS; + if(sessions_->get_config()->no_connection_flow_control && + sessions_->get_config()->no_stream_flow_control) { + entry[niv].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; + entry[niv].value = 1; + ++niv; + } + r = nghttp2_submit_settings(session_, entry, niv); if(r != 0) { return r; } + if(sessions_->get_config()->no_connection_flow_control && + !sessions_->get_config()->no_stream_flow_control) { + r = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_END_FLOW_CONTROL, + 0, 0); + if(r != 0) { + return r; + } + } return on_write(); } @@ -698,6 +715,11 @@ void hd_on_frame_recv_callback auto req = util::make_unique(stream_id); append_nv(req.get(), frame->headers.nva, frame->headers.nvlen); hd->add_stream(stream_id, std::move(req)); + if(!hd->get_config()->no_connection_flow_control && + hd->get_config()->no_stream_flow_control) { + nghttp2_submit_window_update(session, NGHTTP2_FLAG_END_FLOW_CONTROL, + stream_id, 0); + } break; } case NGHTTP2_HCAT_HEADERS: diff --git a/src/HttpServer.h b/src/HttpServer.h index 216ab971..a27974e2 100644 --- a/src/HttpServer.h +++ b/src/HttpServer.h @@ -57,6 +57,8 @@ struct Config { void *data_ptr; bool verify_client; bool no_tls; + bool no_connection_flow_control; + bool no_stream_flow_control; size_t output_upper_thres; Config(); }; diff --git a/src/nghttpd.cc b/src/nghttpd.cc index 1e5420f2..28ab2c12 100644 --- a/src/nghttpd.cc +++ b/src/nghttpd.cc @@ -45,7 +45,7 @@ namespace nghttp2 { namespace { void print_usage(std::ostream& out) { - out << "Usage: nghttpd [-DVhv] [-d ] [--no-tls] [ ]" + out << "Usage: nghttpd [-FDVfhv] [-d ] [--no-tls] [ ]" << std::endl; } } // namespace @@ -73,6 +73,10 @@ void print_help(std::ostream& out) << " -v, --verbose Print debug information such as reception/\n" << " transmission of frames and name/value pairs.\n" << " --no-tls Disable SSL/TLS.\n" + << " -F, --no-connection-flow-control\n" + << " Disables connection level flow control.\n" + << " -f, --no-stream-flow-control\n" + << " Disables stream level flow control.\n" << " -h, --help Print this help.\n" << std::endl; } @@ -90,14 +94,19 @@ int main(int argc, char **argv) {"verbose", no_argument, 0, 'v' }, {"verify-client", no_argument, 0, 'V' }, {"no-tls", no_argument, &flag, 1 }, + {"no-connection-flow-control", no_argument, 0, 'F'}, + {"no-stream-flow-control", no_argument, 0, 'f'}, {0, 0, 0, 0 } }; int option_index = 0; - int c = getopt_long(argc, argv, "DVd:hv", long_options, &option_index); + int c = getopt_long(argc, argv, "FDVd:fhv", long_options, &option_index); if(c == -1) { break; } switch(c) { + case 'F': + config.no_connection_flow_control = true; + break; case 'D': config.daemon = true; break; @@ -107,6 +116,9 @@ int main(int argc, char **argv) case 'd': config.htdocs = optarg; break; + case 'f': + config.no_stream_flow_control = true; + break; case 'h': print_help(std::cout); exit(EXIT_SUCCESS);