From 3e1aad60b7216585a5cdcc3cccb74542f4bd4482 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 12 Aug 2013 22:33:51 +0900 Subject: [PATCH] nghttp: Remove --no-tls option and detect TLS requirement using URI scheme --- src/nghttp.cc | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/nghttp.cc b/src/nghttp.cc index aaa596ed..d559509d 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -79,7 +79,6 @@ struct Config { bool verbose; bool get_assets; bool stat; - bool no_tls; bool no_connection_flow_control; bool no_stream_flow_control; bool upgrade; @@ -99,7 +98,6 @@ struct Config { verbose(false), get_assets(false), stat(false), - no_tls(false), no_connection_flow_control(false), no_stream_flow_control(false), upgrade(false), @@ -400,6 +398,7 @@ struct HttpClient { std::set path_cache; // The number of completed requests, including failed ones. size_t complete; + std::string scheme; std::string hostport; SessionStat stat; // Used for parse the HTTP upgrade response from server @@ -436,6 +435,11 @@ struct HttpClient { delete htp; } + bool need_upgrade() const + { + return config.upgrade && scheme == "http"; + } + int initiate_connection(const std::string& host, uint16_t port) { int rv; @@ -475,7 +479,7 @@ struct HttpClient { return -1; } bufferevent_enable(bev, EV_READ); - if(config.upgrade) { + if(need_upgrade()) { htp = new http_parser(); http_parser_init(htp, HTTP_RESPONSE); htp->data = this; @@ -610,14 +614,14 @@ struct HttpClient { int on_connect() { int rv; - if(!config.upgrade) { + if(!need_upgrade()) { record_handshake_time(); } rv = nghttp2_session_client_new(&session, callbacks, this); if(rv != 0) { return -1; } - if(config.upgrade) { + if(need_upgrade()) { // Adjust stream user-data depending on the existence of upload // data Request *stream_user_data = nullptr; @@ -641,7 +645,7 @@ struct HttpClient { // If upgrade succeeds, the SETTINGS value sent with // HTTP2-Settings header field has already been submitted to // session object. - if(!config.upgrade) { + if(!need_upgrade()) { nghttp2_settings_entry iv[16]; auto niv = populate_settings(iv); rv = nghttp2_submit_settings(session, iv, niv); @@ -658,7 +662,7 @@ struct HttpClient { } // Adjust first request depending on the existence of the upload // data - for(auto i = std::begin(reqvec)+(config.upgrade && !reqvec[0]->data_prd); + for(auto i = std::begin(reqvec)+(need_upgrade() && !reqvec[0]->data_prd); i != std::end(reqvec); ++i) { submit_request(this, config.headers, (*i).get()); } @@ -744,6 +748,7 @@ struct HttpClient { if(reqvec.empty()) { return; } + scheme = get_uri_field(reqvec[0]->uri.c_str(), reqvec[0]->u, UF_SCHEMA); std::stringstream ss; if(reqvec[0]->is_ipv6_literal_addr()) { ss << "["; @@ -1187,7 +1192,7 @@ void eventcb(bufferevent *bev, short events, void *ptr) std::cerr << "Setting option TCP_NODELAY failed: errno=" << errno << std::endl; } - if(config.upgrade) { + if(client->need_upgrade()) { rv = client->on_upgrade_connect(); } else { // TODO Check NPN result and fail fast? @@ -1239,7 +1244,8 @@ ssize_t client_recv_callback(nghttp2_session *session, } } // namespace -int communicate(const std::string& host, uint16_t port, +int communicate(const std::string& scheme, const std::string& host, + uint16_t port, std::vector> requests, @@ -1248,7 +1254,7 @@ int communicate(const std::string& host, uint16_t port, int result = 0; auto evbase = event_base_new(); SSL_CTX *ssl_ctx = nullptr; - if(!config.no_tls) { + if(scheme == "https") { ssl_ctx = SSL_CTX_new(SSLv23_client_method()); if(!ssl_ctx) { std::cerr << "Failed to create SSL_CTX: " @@ -1355,6 +1361,7 @@ int run(char **uris, int n) callbacks.on_unknown_frame_recv_callback = on_unknown_frame_recv_callback; } callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback; + std::string prev_scheme; std::string prev_host; uint16_t prev_port = 0; int failures = 0; @@ -1385,15 +1392,17 @@ int run(char **uris, int n) has_uri_field(u, UF_SCHEMA)) { uint16_t port = has_uri_field(u, UF_PORT) ? u.port : get_default_port(uri.c_str(), u); - if(!fieldeq(uri.c_str(), u, UF_HOST, prev_host.c_str()) || + if(!fieldeq(uri.c_str(), u, UF_SCHEMA, prev_scheme.c_str()) || + !fieldeq(uri.c_str(), u, UF_HOST, prev_host.c_str()) || u.port != prev_port) { if(!requests.empty()) { - if (communicate(prev_host, prev_port, std::move(requests), - &callbacks) != 0) { + if (communicate(prev_scheme, prev_host, prev_port, + std::move(requests), &callbacks) != 0) { ++failures; } requests.clear(); } + prev_scheme = get_uri_field(uri.c_str(), u, UF_SCHEMA); prev_host = get_uri_field(uri.c_str(), u, UF_HOST); prev_port = port; } @@ -1402,7 +1411,7 @@ int run(char **uris, int n) } } if(!requests.empty()) { - if (communicate(prev_host, prev_port, std::move(requests), + if (communicate(prev_scheme, prev_host, prev_port, std::move(requests), &callbacks) != 0) { ++failures; } @@ -1413,7 +1422,7 @@ int run(char **uris, int n) void print_usage(std::ostream& out) { out << "Usage: nghttp [-FOafnsuv] [-t ] [-w ] [--cert=]\n" - << " [--key=] [--no-tls] [-d ] [-m ] [-p ]\n" + << " [--key=] [-d ] [-m ] [-p ]\n" << " ..." << std::endl; } @@ -1444,7 +1453,6 @@ void print_help(std::ostream& out) << " The file must be in PEM format.\n" << " --key= Use the client private key file. The file\n" << " must be in PEM format.\n" - << " --no-tls Disable SSL/TLS.\n" << " -d, --data= Post FILE to server. If - is given, data\n" << " will be read from stdin.\n" << " -m, --multiply= Request each URI times. By default, same\n" @@ -1455,7 +1463,8 @@ void print_help(std::ostream& out) << " -f, --no-stream-flow-control\n" << " Disables stream level flow control.\n" << " -u, --upgrade Perform HTTP Upgrade for HTTP/2.0. This\n" - << " option is ignored if --no-tls is not given.\n" + << " option is ignored if the request URI has\n" + << " https scheme.\n" << " If -d is used, the HTTP upgrade request is\n" << " performed with OPTIONS method.\n" << " -p, --pri=\n" @@ -1480,7 +1489,6 @@ int main(int argc, char **argv) {"key", required_argument, &flag, 2 }, {"help", no_argument, 0, 'h' }, {"header", required_argument, 0, 'H' }, - {"no-tls", no_argument, &flag, 3 }, {"data", required_argument, 0, 'd' }, {"multiply", required_argument, 0, 'm' }, {"no-connection-flow-control", no_argument, 0, 'F'}, @@ -1597,10 +1605,6 @@ int main(int argc, char **argv) // key option config.keyfile = optarg; break; - case 3: - // no-tls option - config.no_tls = true; - break; } break; default: @@ -1610,12 +1614,6 @@ int main(int argc, char **argv) set_color_output(isatty(fileno(stdout))); - if(!config.no_tls && config.upgrade) { - std::cerr << "Warning: -u is ignored because --no-tls is not given." - << std::endl; - config.upgrade = false; - } - struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); act.sa_handler = SIG_IGN;