Commit 933e0f40 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

h2load: Support UNIX domain socket

parent 3ad9f9e7
......@@ -86,7 +86,11 @@ Config::Config()
port(0), default_port(0), verbose(false), timing_script(false) {}
Config::~Config() {
freeaddrinfo(addrs);
if (base_uri_unix) {
delete addrs;
} else {
freeaddrinfo(addrs);
}
if (data_fd != -1) {
close(data_fd);
......@@ -1301,6 +1305,18 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
namespace {
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;
addrinfo hints{}, *res;
......@@ -1357,6 +1373,10 @@ int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
}
} // namespace
namespace {
constexpr char UNIX_PATH_PREFIX[] = "unix:";
} // namespace
namespace {
bool parse_base_uri(std::string base_uri) {
http_parser_url u{};
......@@ -1636,11 +1656,16 @@ Options:
contained in other URIs, if present, are ignored.
Definition of a base URI overrides all scheme, host or
port values.
-B, --base-uri=<URI>
-B, --base-uri=(<URI>|unix:<PATH>)
Specify URI from which the scheme, host and port will be
used for all requests. The base URI overrides all
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>
Comma delimited list of ALPN protocol identifier sorted
in the order of preference. That means most desirable
......@@ -1819,13 +1844,40 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
break;
case 'B':
case 'B': {
config.base_uri = "";
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);
}
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 << "invalid base URI: " << optarg << std::endl;
std::cerr << "--base-uri: invalid base URI: " << optarg << std::endl;
exit(EXIT_FAILURE);
}
config.base_uri = optarg;
break;
}
case 'v':
config.verbose = true;
break;
......
......@@ -34,6 +34,7 @@
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif // HAVE_NETDB_H
#include <sys/un.h>
#include <vector>
#include <string>
......@@ -100,6 +101,11 @@ struct Config {
bool verbose;
bool timing_script;
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
// preference.
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);
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>
bool ends_with(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2) {
......
......@@ -362,6 +362,9 @@ void test_util_starts_with(void) {
CU_ASSERT(util::starts_with("ofoo", ""));
CU_ASSERT(util::istarts_with("fOOo", "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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment