summaryrefslogtreecommitdiffstats
path: root/src/h2load.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/h2load.cc')
-rw-r--r--src/h2load.cc158
1 files changed, 85 insertions, 73 deletions
diff --git a/src/h2load.cc b/src/h2load.cc
index 4f9f00e..43931f9 100644
--- a/src/h2load.cc
+++ b/src/h2load.cc
@@ -47,6 +47,7 @@
#include <thread>
#include <future>
#include <random>
+#include <string_view>
#include <openssl/err.h>
@@ -826,6 +827,7 @@ void Client::process_request_failure() {
<< std::endl;
}
+#ifndef NGHTTP2_OPENSSL_IS_BORINGSSL
namespace {
void print_server_tmp_key(SSL *ssl) {
EVP_PKEY *key;
@@ -847,7 +849,7 @@ void print_server_tmp_key(SSL *ssl) {
std::cout << "DH " << EVP_PKEY_bits(key) << " bits" << std::endl;
break;
case EVP_PKEY_EC: {
-#if OPENSSL_3_0_0_API
+# if OPENSSL_3_0_0_API
std::array<char, 64> curve_name;
const char *cname;
if (!EVP_PKEY_get_utf8_string_param(key, "group", curve_name.data(),
@@ -856,7 +858,7 @@ void print_server_tmp_key(SSL *ssl) {
} else {
cname = curve_name.data();
}
-#else // !OPENSSL_3_0_0_API
+# else // !OPENSSL_3_0_0_API
auto ec = EVP_PKEY_get1_EC_KEY(key);
auto ec_del = defer(EC_KEY_free, ec);
auto nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
@@ -864,7 +866,7 @@ void print_server_tmp_key(SSL *ssl) {
if (!cname) {
cname = OBJ_nid2sn(nid);
}
-#endif // !OPENSSL_3_0_0_API
+# endif // !OPENSSL_3_0_0_API
std::cout << "ECDH " << cname << " " << EVP_PKEY_bits(key) << " bits"
<< std::endl;
@@ -877,6 +879,7 @@ void print_server_tmp_key(SSL *ssl) {
}
}
} // namespace
+#endif // !NGHTTP2_OPENSSL_IS_BORINGSSL
void Client::report_tls_info() {
if (worker->id == 0 && !worker->tls_info_report_done) {
@@ -884,7 +887,9 @@ void Client::report_tls_info() {
auto cipher = SSL_get_current_cipher(ssl);
std::cout << "TLS Protocol: " << tls::get_tls_protocol(ssl) << "\n"
<< "Cipher: " << SSL_CIPHER_get_name(cipher) << std::endl;
+#ifndef NGHTTP2_OPENSSL_IS_BORINGSSL
print_server_tmp_key(ssl);
+#endif // !NGHTTP2_OPENSSL_IS_BORINGSSL
}
}
@@ -927,7 +932,7 @@ void Client::on_header(int32_t stream_id, const uint8_t *name, size_t namelen,
}
if (stream.status_success == -1 && namelen == 7 &&
- util::streq_l(":status", name, namelen)) {
+ ":status"_sr == StringRef{name, namelen}) {
int status = 0;
for (size_t i = 0; i < valuelen; ++i) {
if ('0' <= value[i] && value[i] <= '9') {
@@ -1101,20 +1106,19 @@ int Client::connection_made() {
if (config.is_quic()) {
#ifdef ENABLE_HTTP3
assert(session);
- if (!util::streq(StringRef{&NGHTTP3_ALPN_H3[1]}, proto) &&
- !util::streq_l("h3-29", proto)) {
+ if ("h3"_sr != proto && "h3-29"_sr != proto) {
return -1;
}
#endif // ENABLE_HTTP3
} else if (util::check_h2_is_selected(proto)) {
session = std::make_unique<Http2Session>(this);
- } else if (util::streq(NGHTTP2_H1_1, proto)) {
+ } else if (NGHTTP2_H1_1 == proto) {
session = std::make_unique<Http1Session>(this);
}
// Just assign next_proto to selected_proto anyway to show the
// negotiation result.
- selected_proto = proto.str();
+ selected_proto = proto;
} else if (config.is_quic()) {
std::cerr << "QUIC requires ALPN negotiation" << std::endl;
return -1;
@@ -1123,11 +1127,11 @@ int Client::connection_made() {
<< std::endl;
for (const auto &proto : config.alpn_list) {
- if (util::streq(NGHTTP2_H1_1_ALPN, StringRef{proto})) {
+ if (NGHTTP2_H1_1_ALPN == proto) {
std::cout << "Server does not support ALPN. Falling back to HTTP/1.1."
<< std::endl;
session = std::make_unique<Http1Session>(this);
- selected_proto = NGHTTP2_H1_1.str();
+ selected_proto = NGHTTP2_H1_1;
break;
}
}
@@ -1155,7 +1159,7 @@ int Client::connection_made() {
break;
case Config::PROTO_HTTP1_1:
session = std::make_unique<Http1Session>(this);
- selected_proto = NGHTTP2_H1_1.str();
+ selected_proto = NGHTTP2_H1_1;
break;
default:
// unreachable
@@ -1861,7 +1865,7 @@ std::string get_reqline(const char *uri, const http_parser_url &u) {
std::string reqline;
if (util::has_uri_field(u, UF_PATH)) {
- reqline = util::get_uri_field(uri, u, UF_PATH).str();
+ reqline = util::get_uri_field(uri, u, UF_PATH);
} else {
reqline = "/";
}
@@ -1876,20 +1880,20 @@ std::string get_reqline(const char *uri, const http_parser_url &u) {
} // namespace
namespace {
-constexpr char UNIX_PATH_PREFIX[] = "unix:";
+constexpr auto UNIX_PATH_PREFIX = "unix:"_sr;
} // namespace
namespace {
bool parse_base_uri(const StringRef &base_uri) {
http_parser_url u{};
- if (http_parser_parse_url(base_uri.c_str(), base_uri.size(), 0, &u) != 0 ||
+ if (http_parser_parse_url(base_uri.data(), base_uri.size(), 0, &u) != 0 ||
!util::has_uri_field(u, UF_SCHEMA) || !util::has_uri_field(u, UF_HOST)) {
return false;
}
- config.scheme = util::get_uri_field(base_uri.c_str(), u, UF_SCHEMA).str();
- config.host = util::get_uri_field(base_uri.c_str(), u, UF_HOST).str();
- config.default_port = util::get_default_port(base_uri.c_str(), u);
+ config.scheme = util::get_uri_field(base_uri.data(), u, UF_SCHEMA);
+ config.host = util::get_uri_field(base_uri.data(), u, UF_HOST);
+ config.default_port = util::get_default_port(base_uri.data(), u);
if (util::has_uri_field(u, UF_PORT)) {
config.port = u.port;
} else {
@@ -2033,7 +2037,7 @@ namespace {
int parse_header_table_size(uint32_t &dst, const char *opt,
const char *optarg) {
auto n = util::parse_uint_with_unit(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "--" << opt << ": Bad option value: " << optarg << std::endl;
return -1;
}
@@ -2044,7 +2048,7 @@ int parse_header_table_size(uint32_t &dst, const char *opt,
return -1;
}
- dst = n;
+ dst = *n;
return 0;
}
@@ -2086,7 +2090,7 @@ benchmarking tool for HTTP/2 server)"
} // namespace
namespace {
-constexpr char DEFAULT_ALPN_LIST[] = "h2,h2-16,h2-14,http/1.1";
+constexpr auto DEFAULT_ALPN_LIST = "h2,h2-16,h2-14,http/1.1"_sr;
} // namespace
namespace {
@@ -2373,21 +2377,21 @@ int main(int argc, char **argv) {
switch (c) {
case 'n': {
auto n = util::parse_uint(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "-n: bad option value: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
- config.nreqs = n;
+ config.nreqs = *n;
nreqs_set_manually = true;
break;
}
case 'c': {
auto n = util::parse_uint(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "-c: bad option value: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
- config.nclients = n;
+ config.nclients = *n;
break;
}
case 'd':
@@ -2399,55 +2403,55 @@ int main(int argc, char **argv) {
<< "no threads created." << std::endl;
#else
auto n = util::parse_uint(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "-t: bad option value: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
- config.nthreads = n;
+ config.nthreads = *n;
#endif // NOTHREADS
break;
}
case 'm': {
auto n = util::parse_uint(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "-m: bad option value: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
- config.max_concurrent_streams = n;
+ config.max_concurrent_streams = *n;
break;
}
case 'w':
case 'W': {
auto n = util::parse_uint(optarg);
- if (n == -1 || n > 30) {
+ if (!n || n > 30) {
std::cerr << "-" << static_cast<char>(c)
<< ": specify the integer in the range [0, 30], inclusive"
<< std::endl;
exit(EXIT_FAILURE);
}
if (c == 'w') {
- config.window_bits = n;
+ config.window_bits = *n;
} else {
- config.connection_window_bits = n;
+ config.connection_window_bits = *n;
}
break;
}
case 'f': {
auto n = util::parse_uint_with_unit(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "--max-frame-size: bad option value: " << optarg
<< std::endl;
exit(EXIT_FAILURE);
}
- if (static_cast<uint64_t>(n) < 16_k) {
+ if (static_cast<uint64_t>(*n) < 16_k) {
std::cerr << "--max-frame-size: minimum 16384" << std::endl;
exit(EXIT_FAILURE);
}
- if (static_cast<uint64_t>(n) > 16_m - 1) {
+ if (static_cast<uint64_t>(*n) > 16_m - 1) {
std::cerr << "--max-frame-size: maximum 16777215" << std::endl;
exit(EXIT_FAILURE);
}
- config.max_frame_size = n;
+ config.max_frame_size = *n;
break;
}
case 'H': {
@@ -2481,8 +2485,7 @@ int main(int argc, char **argv) {
break;
case 'p': {
auto proto = StringRef{optarg};
- if (util::strieq(StringRef::from_lit(NGHTTP2_CLEARTEXT_PROTO_VERSION_ID),
- proto)) {
+ if (util::strieq(NGHTTP2_CLEARTEXT_PROTO_VERSION_ID ""_sr, proto)) {
config.no_tls_proto = Config::PROTO_HTTP2;
} else if (util::strieq(NGHTTP2_H1_1, proto)) {
config.no_tls_proto = Config::PROTO_HTTP1_1;
@@ -2494,7 +2497,7 @@ int main(int argc, char **argv) {
}
case 'r': {
auto n = util::parse_uint(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "-r: bad option value: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
@@ -2503,36 +2506,40 @@ int main(int argc, char **argv) {
<< "must be positive." << std::endl;
exit(EXIT_FAILURE);
}
- config.rate = n;
+ config.rate = *n;
break;
}
- case 'T':
- config.conn_active_timeout = util::parse_duration_with_unit(optarg);
- if (!std::isfinite(config.conn_active_timeout)) {
+ case 'T': {
+ auto d = util::parse_duration_with_unit(optarg);
+ if (!d) {
std::cerr << "-T: bad value for the conn_active_timeout wait time: "
<< optarg << std::endl;
exit(EXIT_FAILURE);
}
+ config.conn_active_timeout = *d;
break;
- case 'N':
- config.conn_inactivity_timeout = util::parse_duration_with_unit(optarg);
- if (!std::isfinite(config.conn_inactivity_timeout)) {
+ }
+ case 'N': {
+ auto d = util::parse_duration_with_unit(optarg);
+ if (!d) {
std::cerr << "-N: bad value for the conn_inactivity_timeout wait time: "
<< optarg << std::endl;
exit(EXIT_FAILURE);
}
+ config.conn_inactivity_timeout = *d;
break;
+ }
case 'B': {
auto arg = StringRef{optarg};
config.base_uri = "";
config.base_uri_unix = false;
- if (util::istarts_with_l(arg, UNIX_PATH_PREFIX)) {
+ if (util::istarts_with(arg, UNIX_PATH_PREFIX)) {
// UNIX domain socket path
sockaddr_un un;
- auto path = StringRef{std::begin(arg) + str_size(UNIX_PATH_PREFIX),
- std::end(arg)};
+ auto path =
+ StringRef{std::begin(arg) + UNIX_PATH_PREFIX.size(), std::end(arg)};
if (path.size() == 0 || path.size() + 1 > sizeof(un.sun_path)) {
std::cerr << "--base-uri: invalid UNIX domain socket path: " << arg
@@ -2555,16 +2562,18 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
- config.base_uri = arg.str();
+ config.base_uri = arg;
break;
}
- case 'D':
- config.duration = util::parse_duration_with_unit(optarg);
- if (!std::isfinite(config.duration)) {
+ case 'D': {
+ auto d = util::parse_duration_with_unit(optarg);
+ if (!d) {
std::cerr << "-D: value error " << optarg << std::endl;
exit(EXIT_FAILURE);
}
+ config.duration = *d;
break;
+ }
case 'v':
config.verbose = true;
break;
@@ -2589,18 +2598,19 @@ int main(int argc, char **argv) {
config.ifile = optarg;
config.timing_script = true;
break;
- case 5:
+ case 5: {
// rate-period
- config.rate_period = util::parse_duration_with_unit(optarg);
- if (!std::isfinite(config.rate_period)) {
+ auto d = util::parse_duration_with_unit(optarg);
+ if (!d) {
std::cerr << "--rate-period: value error " << optarg << std::endl;
exit(EXIT_FAILURE);
}
+ config.rate_period = *d;
break;
+ }
case 6:
// --h1
- config.alpn_list =
- util::parse_config_str_list(StringRef::from_lit("http/1.1"));
+ config.alpn_list = util::parse_config_str_list("http/1.1"_sr);
config.no_tls_proto = Config::PROTO_HTTP1_1;
break;
case 7:
@@ -2617,14 +2627,16 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
break;
- case 9:
+ case 9: {
// --warm-up-time
- config.warm_up_time = util::parse_duration_with_unit(optarg);
- if (!std::isfinite(config.warm_up_time)) {
+ auto d = util::parse_duration_with_unit(optarg);
+ if (!d) {
std::cerr << "--warm-up-time: value error " << optarg << std::endl;
exit(EXIT_FAILURE);
}
+ config.warm_up_time = *d;
break;
+ }
case 10:
// --log-file
logfile = optarg;
@@ -2634,11 +2646,12 @@ int main(int argc, char **argv) {
auto p = util::split_hostport(StringRef{optarg});
int64_t port = 0;
if (p.first.empty() ||
- (!p.second.empty() && (port = util::parse_uint(p.second)) == -1)) {
+ (!p.second.empty() &&
+ (port = util::parse_uint(p.second).value_or(-1)) == -1)) {
std::cerr << "--connect-to: Invalid value " << optarg << std::endl;
exit(EXIT_FAILURE);
}
- config.connect_to_host = p.first.str();
+ config.connect_to_host = p.first;
config.connect_to_port = port;
break;
}
@@ -2672,17 +2685,17 @@ int main(int argc, char **argv) {
case 17: {
// --max-udp-payload-size
auto n = util::parse_uint_with_unit(optarg);
- if (n == -1) {
+ if (!n) {
std::cerr << "--max-udp-payload-size: bad option value: " << optarg
<< std::endl;
exit(EXIT_FAILURE);
}
- if (static_cast<uint64_t>(n) > 64_k) {
+ if (static_cast<uint64_t>(*n) > 64_k) {
std::cerr << "--max-udp-payload-size: must not exceed 65536"
<< std::endl;
exit(EXIT_FAILURE);
}
- config.max_udp_payload_size = n;
+ config.max_udp_payload_size = *n;
break;
}
case 18:
@@ -2723,8 +2736,7 @@ int main(int argc, char **argv) {
}
if (config.alpn_list.empty()) {
- config.alpn_list =
- util::parse_config_str_list(StringRef::from_lit(DEFAULT_ALPN_LIST));
+ config.alpn_list = util::parse_config_str_list(DEFAULT_ALPN_LIST);
}
// serialize the APLN tokens
@@ -2991,8 +3003,8 @@ int main(int argc, char **argv) {
shared_nva.emplace_back("user-agent", user_agent);
// list header fields that can be overridden.
- auto override_hdrs = make_array<std::string>(":authority", "host", ":method",
- ":scheme", "user-agent");
+ auto override_hdrs = std::to_array<std::string_view>(
+ {":authority", "host", ":method", ":scheme", "user-agent"});
for (auto &kv : config.custom_headers) {
if (std::find(std::begin(override_hdrs), std::end(override_hdrs),
@@ -3059,15 +3071,15 @@ int main(int argc, char **argv) {
// 2 for :path, and possible content-length
nva.reserve(2 + shared_nva.size());
- nva.push_back(http2::make_nv_ls(":path", req));
+ nva.push_back(http2::make_field_v(":path"_sr, req));
for (auto &nv : shared_nva) {
- nva.push_back(http2::make_nv(nv.name, nv.value, false));
+ nva.push_back(http2::make_field_nv(nv.name, nv.value));
}
if (!content_length_str.empty()) {
- nva.push_back(http2::make_nv(StringRef::from_lit("content-length"),
- StringRef{content_length_str}));
+ nva.push_back(
+ http2::make_field_nv("content-length"_sr, content_length_str));
}
config.nva.push_back(std::move(nva));