h2load: Support UNIX domain socket
This commit is contained in:
parent
3ad9f9e730
commit
933e0f40bb
|
@ -86,7 +86,11 @@ Config::Config()
|
||||||
port(0), default_port(0), verbose(false), timing_script(false) {}
|
port(0), default_port(0), verbose(false), timing_script(false) {}
|
||||||
|
|
||||||
Config::~Config() {
|
Config::~Config() {
|
||||||
|
if (base_uri_unix) {
|
||||||
|
delete addrs;
|
||||||
|
} else {
|
||||||
freeaddrinfo(addrs);
|
freeaddrinfo(addrs);
|
||||||
|
}
|
||||||
|
|
||||||
if (data_fd != -1) {
|
if (data_fd != -1) {
|
||||||
close(data_fd);
|
close(data_fd);
|
||||||
|
@ -1301,6 +1305,18 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void resolve_host() {
|
void resolve_host() {
|
||||||
|
if (config.base_uri_unix) {
|
||||||
|
auto res = make_unique<addrinfo>();
|
||||||
|
res->ai_family = config.unix_addr.sun_family;
|
||||||
|
res->ai_socktype = SOCK_STREAM;
|
||||||
|
res->ai_addrlen = sizeof(config.unix_addr);
|
||||||
|
res->ai_addr =
|
||||||
|
static_cast<struct sockaddr *>(static_cast<void *>(&config.unix_addr));
|
||||||
|
|
||||||
|
config.addrs = res.release();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
addrinfo hints{}, *res;
|
addrinfo hints{}, *res;
|
||||||
|
|
||||||
|
@ -1357,6 +1373,10 @@ int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr char UNIX_PATH_PREFIX[] = "unix:";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool parse_base_uri(std::string base_uri) {
|
bool parse_base_uri(std::string base_uri) {
|
||||||
http_parser_url u{};
|
http_parser_url u{};
|
||||||
|
@ -1636,11 +1656,16 @@ Options:
|
||||||
contained in other URIs, if present, are ignored.
|
contained in other URIs, if present, are ignored.
|
||||||
Definition of a base URI overrides all scheme, host or
|
Definition of a base URI overrides all scheme, host or
|
||||||
port values.
|
port values.
|
||||||
-B, --base-uri=<URI>
|
-B, --base-uri=(<URI>|unix:<PATH>)
|
||||||
Specify URI from which the scheme, host and port will be
|
Specify URI from which the scheme, host and port will be
|
||||||
used for all requests. The base URI overrides all
|
used for all requests. The base URI overrides all
|
||||||
values defined either at the command line or inside
|
values defined either at the command line or inside
|
||||||
input files.
|
input files. If argument starts with "unix:", then the
|
||||||
|
rest of the argument will be treated as UNIX domain
|
||||||
|
socket path. The connection is made through that path
|
||||||
|
instead of TCP. In this case, scheme is inferred from
|
||||||
|
the first URI appeared in the command line or inside
|
||||||
|
input files as usual.
|
||||||
--npn-list=<LIST>
|
--npn-list=<LIST>
|
||||||
Comma delimited list of ALPN protocol identifier sorted
|
Comma delimited list of ALPN protocol identifier sorted
|
||||||
in the order of preference. That means most desirable
|
in the order of preference. That means most desirable
|
||||||
|
@ -1819,13 +1844,40 @@ int main(int argc, char **argv) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B': {
|
||||||
if (!parse_base_uri(optarg)) {
|
config.base_uri = "";
|
||||||
std::cerr << "invalid base URI: " << optarg << std::endl;
|
config.base_uri_unix = false;
|
||||||
|
|
||||||
|
if (util::istarts_with_l(optarg, UNIX_PATH_PREFIX)) {
|
||||||
|
// UNIX domain socket path
|
||||||
|
sockaddr_un un;
|
||||||
|
|
||||||
|
auto path = optarg + str_size(UNIX_PATH_PREFIX);
|
||||||
|
auto pathlen = strlen(optarg) - str_size(UNIX_PATH_PREFIX);
|
||||||
|
|
||||||
|
if (pathlen == 0 || pathlen + 1 > sizeof(un.sun_path)) {
|
||||||
|
std::cerr << "--base-uri: invalid UNIX domain socket path: " << optarg
|
||||||
|
<< std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.base_uri_unix = true;
|
||||||
|
|
||||||
|
auto &unix_addr = config.unix_addr;
|
||||||
|
std::copy_n(path, pathlen + 1, unix_addr.sun_path);
|
||||||
|
unix_addr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_base_uri(optarg)) {
|
||||||
|
std::cerr << "--base-uri: invalid base URI: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
config.base_uri = optarg;
|
config.base_uri = optarg;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'v':
|
case 'v':
|
||||||
config.verbose = true;
|
config.verbose = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif // HAVE_NETDB_H
|
#endif // HAVE_NETDB_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -100,6 +101,11 @@ struct Config {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool timing_script;
|
bool timing_script;
|
||||||
std::string base_uri;
|
std::string base_uri;
|
||||||
|
// true if UNIX domain socket is used. In this case, base_uri is
|
||||||
|
// not used in usual way.
|
||||||
|
bool base_uri_unix;
|
||||||
|
// used when UNIX domain socket is used (base_uri_unix is true).
|
||||||
|
sockaddr_un unix_addr;
|
||||||
// list of supported NPN/ALPN protocol strings in the order of
|
// list of supported NPN/ALPN protocol strings in the order of
|
||||||
// preference.
|
// preference.
|
||||||
std::vector<std::string> npn_list;
|
std::vector<std::string> npn_list;
|
||||||
|
|
|
@ -212,6 +212,11 @@ bool istarts_with(InputIt a, size_t an, const char *b) {
|
||||||
|
|
||||||
bool istarts_with(const char *a, const char *b);
|
bool istarts_with(const char *a, const char *b);
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
bool istarts_with_l(const std::string &a, const char(&b)[N]) {
|
||||||
|
return istarts_with(std::begin(a), std::end(a), b, b + N - 1);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename InputIterator1, typename InputIterator2>
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
bool ends_with(InputIterator1 first1, InputIterator1 last1,
|
bool ends_with(InputIterator1 first1, InputIterator1 last1,
|
||||||
InputIterator2 first2, InputIterator2 last2) {
|
InputIterator2 first2, InputIterator2 last2) {
|
||||||
|
|
|
@ -362,6 +362,9 @@ void test_util_starts_with(void) {
|
||||||
CU_ASSERT(util::starts_with("ofoo", ""));
|
CU_ASSERT(util::starts_with("ofoo", ""));
|
||||||
CU_ASSERT(util::istarts_with("fOOo", "Foo"));
|
CU_ASSERT(util::istarts_with("fOOo", "Foo"));
|
||||||
CU_ASSERT(!util::istarts_with("ofoo", "foo"));
|
CU_ASSERT(!util::istarts_with("ofoo", "foo"));
|
||||||
|
|
||||||
|
CU_ASSERT(util::istarts_with_l("fOOo", "Foo"));
|
||||||
|
CU_ASSERT(!util::istarts_with_l("ofoo", "foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_util_ends_with(void) {
|
void test_util_ends_with(void) {
|
||||||
|
|
Loading…
Reference in New Issue