From c280cc7c4d591d1db4b1c68bcf7936dc4a960fc2 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 11 Feb 2014 17:23:22 +0900 Subject: [PATCH] nghttpx: Add --padding option for debugging purpose --- src/shrpx.cc | 11 +++++++++++ src/shrpx_config.cc | 3 +++ src/shrpx_config.h | 2 ++ src/shrpx_http.cc | 11 +++++++++++ src/shrpx_http.h | 6 ++++++ src/shrpx_http2_session.cc | 3 +++ src/shrpx_http2_upstream.cc | 3 +++ 7 files changed, 39 insertions(+) diff --git a/src/shrpx.cc b/src/shrpx.cc index a2daecad..48242dc1 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -437,6 +437,7 @@ void fill_default_config() mod_config()->http2_upstream_dump_response_header = nullptr; mod_config()->http2_no_cookie_crumbling = false; mod_config()->upstream_frame_debug = false; + mod_config()->padding = 0; } } // namespace @@ -675,6 +676,11 @@ void print_help(std::ostream& out) << " --backend-no-tls Disable SSL/TLS on backend connections.\n" << " --http2-no-cookie-crumbling\n" << " Don't crumble cookie header field.\n" + << " --padding=\n" + << " Padding boundary for HTTP/2 frame payload.\n" + << " Specify 0 to disable padding. This option is\n" + << " meant for debugging purpose and not intended\n" + << " to enhance protocol security.\n" << "\n" << " Mode:\n" << " (default mode) Accept HTTP/2.0, SPDY and HTTP/1.1 over\n" @@ -824,6 +830,7 @@ int main(int argc, char **argv) {"frontend-http2-connection-window-bits", required_argument, &flag, 46}, {"backend-http2-connection-window-bits", required_argument, &flag, 47}, {"tls-proto-list", required_argument, &flag, 48}, + {"padding", required_argument, &flag, 49}, {nullptr, 0, nullptr, 0 } }; @@ -1060,6 +1067,10 @@ int main(int argc, char **argv) // --tls-proto-list cmdcfgs.emplace_back(SHRPX_OPT_TLS_PROTO_LIST, optarg); break; + case 49: + // --padding + cmdcfgs.emplace_back(SHRPX_OPT_PADDING, optarg); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index d2f5b504..2514d34c 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -116,6 +116,7 @@ const char SHRPX_OPT_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER[] = "frontend-http2-dump-response-header"; const char SHRPX_OPT_HTTP2_NO_COOKIE_CRUMBLING[] = "http2-no-cookie-crumbling"; const char SHRPX_OPT_FRONTEND_FRAME_DEBUG[] = "frontend-frame-debug"; +const char SHRPX_OPT_PADDING[] = "padding"; namespace { Config *config = nullptr; @@ -483,6 +484,8 @@ int parse_config(const char *opt, const char *optarg) mod_config()->http2_no_cookie_crumbling = util::strieq(optarg, "yes"); } else if(util::strieq(opt, SHRPX_OPT_FRONTEND_FRAME_DEBUG)) { mod_config()->upstream_frame_debug = util::strieq(optarg, "yes"); + } else if(util::strieq(opt, SHRPX_OPT_PADDING)) { + mod_config()->padding = strtoul(optarg, nullptr, 10); } else if(util::strieq(opt, "conf")) { LOG(WARNING) << "conf is ignored"; } else { diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 6ca420e0..04da1801 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -103,6 +103,7 @@ extern const char SHRPX_OPT_FRONTEND_HTTP2_DUMP_REQUEST_HEADER[]; extern const char SHRPX_OPT_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER[]; extern const char SHRPX_OPT_HTTP2_NO_COOKIE_CRUMBLING[]; extern const char SHRPX_OPT_FRONTEND_FRAME_DEBUG[]; +extern const char SHRPX_OPT_PADDING[]; union sockaddr_union { sockaddr sa; @@ -180,6 +181,7 @@ struct Config { size_t npn_list_len; // The number of elements in tls_proto_list size_t tls_proto_list_len; + size_t padding; // downstream protocol; this will be determined by given options. shrpx_proto downstream_proto; int syslog_facility; diff --git a/src/shrpx_http.cc b/src/shrpx_http.cc index d2cc11d0..8f5e9dd5 100644 --- a/src/shrpx_http.cc +++ b/src/shrpx_http.cc @@ -94,6 +94,17 @@ std::string colorizeHeaders(const char *hdrs) return nhdrs; } +ssize_t select_padding_callback +(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payload, + void *user_data) +{ + auto bd = get_config()->padding; + if(frame->hd.length == 0) { + return bd; + } + return std::min(max_payload, (frame->hd.length + bd - 1) / bd * bd); +} + } // namespace http } // namespace shrpx diff --git a/src/shrpx_http.h b/src/shrpx_http.h index feace2a5..bd519b16 100644 --- a/src/shrpx_http.h +++ b/src/shrpx_http.h @@ -29,6 +29,8 @@ #include +#include + namespace shrpx { namespace http { @@ -40,6 +42,10 @@ std::string create_via_header_value(int major, int minor); // Adds ANSI color codes to HTTP headers |hdrs|. std::string colorizeHeaders(const char *hdrs); +ssize_t select_padding_callback +(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payload, + void *user_data); + } // namespace http } // namespace shrpx diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index ccf4b3e3..ebbf97c1 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -1193,6 +1193,9 @@ int Http2Session::on_connect() callbacks.on_unknown_frame_recv_callback = on_unknown_frame_recv_callback; callbacks.on_header_callback = on_header_callback; callbacks.on_begin_headers_callback = on_begin_headers_callback; + if(get_config()->padding) { + callbacks.select_padding_callback = http::select_padding_callback; + } nghttp2_opt_set opt_set; opt_set.no_auto_stream_window_update = 1; diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index d469b7c5..085d5f5d 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -519,6 +519,9 @@ Http2Upstream::Http2Upstream(ClientHandler *handler) callbacks.on_unknown_frame_recv_callback = on_unknown_frame_recv_callback; callbacks.on_header_callback = on_header_callback; callbacks.on_begin_headers_callback = on_begin_headers_callback; + if(get_config()->padding) { + callbacks.select_padding_callback = http::select_padding_callback; + } nghttp2_opt_set opt_set; opt_set.no_auto_stream_window_update = 1;