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) {}
|
||||
|
||||
Config::~Config() {
|
||||
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':
|
||||
if (!parse_base_uri(optarg)) {
|
||||
std::cerr << "invalid base URI: " << optarg << std::endl;
|
||||
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 << "--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) {
|
||||
|
|
Loading…
Reference in New Issue