2012-06-04 16:48:31 +02:00
|
|
|
/*
|
2014-03-30 12:09:21 +02:00
|
|
|
* nghttp2 - HTTP/2 C Library
|
2012-06-04 16:48:31 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
#include "shrpx_config.h"
|
|
|
|
|
2015-05-13 15:30:35 +02:00
|
|
|
#ifdef HAVE_PWD_H
|
2012-08-01 17:06:41 +02:00
|
|
|
#include <pwd.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#endif // HAVE_PWD_H
|
|
|
|
#ifdef HAVE_NETDB_H
|
2012-08-01 17:06:41 +02:00
|
|
|
#include <netdb.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#endif // HAVE_NETDB_H
|
|
|
|
#ifdef HAVE_SYSLOG_H
|
2012-08-01 18:20:18 +02:00
|
|
|
#include <syslog.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#endif // HAVE_SYSLOG_H
|
2012-12-03 07:33:04 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#ifdef HAVE_FCNTL_H
|
2015-01-06 16:25:10 +01:00
|
|
|
#include <fcntl.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#endif // HAVE_FCNTL_H
|
|
|
|
#ifdef HAVE_UNISTD_H
|
2012-12-03 07:33:04 +01:00
|
|
|
#include <unistd.h>
|
2015-05-13 15:30:35 +02:00
|
|
|
#endif // HAVE_UNISTD_H
|
2012-08-01 17:06:41 +02:00
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
#include <cerrno>
|
|
|
|
#include <limits>
|
|
|
|
#include <fstream>
|
|
|
|
|
2013-07-12 17:19:03 +02:00
|
|
|
#include <nghttp2/nghttp2.h>
|
2013-02-22 13:54:07 +01:00
|
|
|
|
2013-08-27 19:47:22 +02:00
|
|
|
#include "http-parser/http_parser.h"
|
|
|
|
|
2012-08-01 17:26:24 +02:00
|
|
|
#include "shrpx_log.h"
|
2013-02-06 15:27:05 +01:00
|
|
|
#include "shrpx_ssl.h"
|
2013-02-09 08:42:01 +01:00
|
|
|
#include "shrpx_http.h"
|
2013-08-27 19:47:22 +02:00
|
|
|
#include "http2.h"
|
2012-08-01 17:06:41 +02:00
|
|
|
#include "util.h"
|
2015-02-05 15:21:53 +01:00
|
|
|
#include "template.h"
|
2015-07-09 19:52:11 +02:00
|
|
|
#include "base64.h"
|
2012-08-01 17:06:41 +02:00
|
|
|
|
2012-06-04 16:48:31 +02:00
|
|
|
namespace shrpx {
|
|
|
|
|
|
|
|
namespace {
|
2013-10-02 16:13:25 +02:00
|
|
|
Config *config = nullptr;
|
2012-06-04 16:48:31 +02:00
|
|
|
} // namespace
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
const Config *get_config() { return config; }
|
2012-06-04 16:48:31 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
Config *mod_config() { return config; }
|
2012-06-04 16:48:31 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
void create_config() { config = new Config(); }
|
2012-06-04 16:48:31 +02:00
|
|
|
|
2016-01-19 15:26:04 +01:00
|
|
|
std::string EMPTY_STRING;
|
|
|
|
|
2015-01-07 16:01:09 +01:00
|
|
|
TicketKeys::~TicketKeys() {
|
|
|
|
/* Erase keys from memory */
|
|
|
|
for (auto &key : keys) {
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
DownstreamAddr::DownstreamAddr(const DownstreamAddr &other)
|
2016-01-27 13:14:07 +01:00
|
|
|
: addr(other.addr),
|
|
|
|
host(other.host),
|
|
|
|
hostport(other.hostport),
|
|
|
|
port(other.port),
|
|
|
|
host_unix(other.host_unix) {}
|
2015-07-09 19:52:11 +02:00
|
|
|
|
|
|
|
DownstreamAddr &DownstreamAddr::operator=(const DownstreamAddr &other) {
|
|
|
|
if (this == &other) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr = other.addr;
|
2016-01-16 16:52:41 +01:00
|
|
|
host = other.host;
|
|
|
|
hostport = other.hostport;
|
2015-07-09 19:52:11 +02:00
|
|
|
port = other.port;
|
|
|
|
host_unix = other.host_unix;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2015-09-25 19:38:45 +02:00
|
|
|
DownstreamAddrGroup::DownstreamAddrGroup(const DownstreamAddrGroup &other)
|
|
|
|
: pattern(strcopy(other.pattern)), addrs(other.addrs) {}
|
|
|
|
|
|
|
|
DownstreamAddrGroup &DownstreamAddrGroup::
|
|
|
|
operator=(const DownstreamAddrGroup &other) {
|
|
|
|
if (this == &other) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
pattern = strcopy(other.pattern);
|
|
|
|
addrs = other.addrs;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-08-01 17:06:41 +02:00
|
|
|
namespace {
|
|
|
|
int split_host_port(char *host, size_t hostlen, uint16_t *port_ptr,
|
2015-07-09 19:52:11 +02:00
|
|
|
const char *hostport, size_t hostportlen) {
|
2012-08-01 17:06:41 +02:00
|
|
|
// host and port in |hostport| is separated by single ','.
|
|
|
|
const char *p = strchr(hostport, ',');
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!p) {
|
2012-08-01 17:26:24 +02:00
|
|
|
LOG(ERROR) << "Invalid host, port: " << hostport;
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2014-11-27 15:39:04 +01:00
|
|
|
size_t len = p - hostport;
|
|
|
|
if (hostlen < len + 1) {
|
2012-08-01 17:26:24 +02:00
|
|
|
LOG(ERROR) << "Hostname too long: " << hostport;
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy(host, hostport, len);
|
|
|
|
host[len] = '\0';
|
|
|
|
|
|
|
|
errno = 0;
|
2015-07-09 19:52:11 +02:00
|
|
|
auto portlen = hostportlen - len - 1;
|
|
|
|
auto d = util::parse_uint(reinterpret_cast<const uint8_t *>(p + 1), portlen);
|
|
|
|
if (1 <= d && d <= std::numeric_limits<uint16_t>::max()) {
|
2012-08-01 17:06:41 +02:00
|
|
|
*port_ptr = d;
|
|
|
|
return 0;
|
|
|
|
} else {
|
2015-07-09 19:52:11 +02:00
|
|
|
LOG(ERROR) << "Port is invalid: " << std::string(p + 1, portlen);
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2012-12-07 15:14:20 +01:00
|
|
|
namespace {
|
2014-11-27 15:39:04 +01:00
|
|
|
bool is_secure(const char *filename) {
|
2012-12-03 07:33:04 +01:00
|
|
|
struct stat buf;
|
|
|
|
int rv = stat(filename, &buf);
|
|
|
|
if (rv == 0) {
|
2014-11-27 15:39:04 +01:00
|
|
|
if ((buf.st_mode & S_IRWXU) && !(buf.st_mode & S_IRWXG) &&
|
2012-12-03 07:33:04 +01:00
|
|
|
!(buf.st_mode & S_IRWXO)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2012-12-07 15:14:20 +01:00
|
|
|
} // namespace
|
2012-12-03 07:33:04 +01:00
|
|
|
|
2015-01-07 17:26:30 +01:00
|
|
|
std::unique_ptr<TicketKeys>
|
2015-07-17 18:49:20 +02:00
|
|
|
read_tls_ticket_key_file(const std::vector<std::string> &files,
|
|
|
|
const EVP_CIPHER *cipher, const EVP_MD *hmac) {
|
2015-02-05 15:21:53 +01:00
|
|
|
auto ticket_keys = make_unique<TicketKeys>();
|
2015-01-07 17:26:30 +01:00
|
|
|
auto &keys = ticket_keys->keys;
|
|
|
|
keys.resize(files.size());
|
2015-07-17 18:49:20 +02:00
|
|
|
auto enc_keylen = EVP_CIPHER_key_length(cipher);
|
|
|
|
auto hmac_keylen = EVP_MD_size(hmac);
|
|
|
|
if (cipher == EVP_aes_128_cbc()) {
|
|
|
|
// backward compatibility, as a legacy of using same file format
|
|
|
|
// with nginx and apache.
|
|
|
|
hmac_keylen = 16;
|
|
|
|
}
|
2015-07-26 19:12:07 +02:00
|
|
|
auto expectedlen = keys[0].data.name.size() + enc_keylen + hmac_keylen;
|
2015-07-17 18:49:20 +02:00
|
|
|
char buf[256];
|
|
|
|
assert(sizeof(buf) >= expectedlen);
|
|
|
|
|
2015-01-07 17:26:30 +01:00
|
|
|
size_t i = 0;
|
|
|
|
for (auto &file : files) {
|
2015-07-17 18:49:20 +02:00
|
|
|
struct stat fst {};
|
|
|
|
|
|
|
|
if (stat(file.c_str(), &fst) == -1) {
|
|
|
|
auto error = errno;
|
|
|
|
LOG(ERROR) << "tls-ticket-key-file: could not stat file " << file
|
|
|
|
<< ", errno=" << error;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-07-19 13:50:14 +02:00
|
|
|
if (static_cast<size_t>(fst.st_size) != expectedlen) {
|
2015-07-17 18:49:20 +02:00
|
|
|
LOG(ERROR) << "tls-ticket-key-file: the expected file size is "
|
|
|
|
<< expectedlen << ", the actual file size is " << fst.st_size;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-01-07 17:26:30 +01:00
|
|
|
std::ifstream f(file.c_str());
|
|
|
|
if (!f) {
|
|
|
|
LOG(ERROR) << "tls-ticket-key-file: could not open file " << file;
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-07-17 18:49:20 +02:00
|
|
|
|
|
|
|
f.read(buf, expectedlen);
|
2015-07-19 13:50:14 +02:00
|
|
|
if (static_cast<size_t>(f.gcount()) != expectedlen) {
|
2015-07-17 18:49:20 +02:00
|
|
|
LOG(ERROR) << "tls-ticket-key-file: want to read " << expectedlen
|
|
|
|
<< " bytes but only read " << f.gcount() << " bytes from "
|
|
|
|
<< file;
|
2015-01-07 17:26:30 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto &key = keys[i++];
|
2015-07-17 18:49:20 +02:00
|
|
|
key.cipher = cipher;
|
|
|
|
key.hmac = hmac;
|
|
|
|
key.hmac_keylen = hmac_keylen;
|
|
|
|
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
|
|
|
LOG(INFO) << "enc_keylen=" << enc_keylen
|
|
|
|
<< ", hmac_keylen=" << key.hmac_keylen;
|
|
|
|
}
|
|
|
|
|
2015-01-07 17:26:30 +01:00
|
|
|
auto p = buf;
|
2015-07-26 19:12:07 +02:00
|
|
|
std::copy_n(p, key.data.name.size(), std::begin(key.data.name));
|
|
|
|
p += key.data.name.size();
|
|
|
|
std::copy_n(p, enc_keylen, std::begin(key.data.enc_key));
|
2015-07-17 18:49:20 +02:00
|
|
|
p += enc_keylen;
|
2015-07-26 19:12:07 +02:00
|
|
|
std::copy_n(p, hmac_keylen, std::begin(key.data.hmac_key));
|
2015-01-07 17:26:30 +01:00
|
|
|
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
2015-07-17 18:49:20 +02:00
|
|
|
LOG(INFO) << "session ticket key: " << util::format_hex(key.data.name);
|
2015-01-07 17:26:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ticket_keys;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
FILE *open_file_for_write(const char *filename) {
|
2015-01-22 15:20:16 +01:00
|
|
|
#if defined O_CLOEXEC
|
2015-01-06 16:25:10 +01:00
|
|
|
auto fd = open(filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC,
|
|
|
|
S_IRUSR | S_IWUSR);
|
2015-01-22 15:20:16 +01:00
|
|
|
#else
|
|
|
|
auto fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
|
|
|
|
|
|
|
// We get race condition if execve is called at the same time.
|
|
|
|
if (fd != -1) {
|
2015-03-02 21:14:09 +01:00
|
|
|
util::make_socket_closeonexec(fd);
|
2015-01-22 15:20:16 +01:00
|
|
|
}
|
|
|
|
#endif
|
2015-01-06 16:25:10 +01:00
|
|
|
if (fd == -1) {
|
|
|
|
LOG(ERROR) << "Failed to open " << filename
|
|
|
|
<< " for writing. Cause: " << strerror(errno);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
auto f = fdopen(fd, "wb");
|
2014-11-27 15:39:04 +01:00
|
|
|
if (f == nullptr) {
|
|
|
|
LOG(ERROR) << "Failed to open " << filename
|
|
|
|
<< " for writing. Cause: " << strerror(errno);
|
2014-08-19 17:17:50 +02:00
|
|
|
return nullptr;
|
2013-11-17 15:52:19 +01:00
|
|
|
}
|
2014-08-12 15:22:02 +02:00
|
|
|
|
2013-11-17 15:52:19 +01:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
std::string read_passwd_from_file(const char *filename) {
|
2012-12-03 07:33:04 +01:00
|
|
|
std::string line;
|
|
|
|
|
|
|
|
if (!is_secure(filename)) {
|
|
|
|
LOG(ERROR) << "Private key passwd file " << filename
|
|
|
|
<< " has insecure mode.";
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ifstream in(filename, std::ios::binary);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!in) {
|
2012-12-03 07:33:04 +01:00
|
|
|
LOG(ERROR) << "Could not open key passwd file " << filename;
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::getline(in, line);
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
std::pair<std::string, std::string> parse_header(const char *optarg) {
|
2015-12-25 12:57:24 +01:00
|
|
|
const auto *colon = strchr(optarg, ':');
|
2014-04-26 07:56:08 +02:00
|
|
|
|
2015-12-25 12:57:24 +01:00
|
|
|
if (colon == nullptr || colon == optarg) {
|
2014-04-26 07:56:08 +02:00
|
|
|
return {"", ""};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto value = colon + 1;
|
2014-11-27 15:39:04 +01:00
|
|
|
for (; *value == '\t' || *value == ' '; ++value)
|
|
|
|
;
|
2014-04-26 07:56:08 +02:00
|
|
|
|
2015-11-05 14:48:54 +01:00
|
|
|
auto p = std::make_pair(std::string(optarg, colon),
|
|
|
|
std::string(value, strlen(value)));
|
|
|
|
util::inp_strlower(p.first);
|
|
|
|
|
2015-12-25 12:57:24 +01:00
|
|
|
if (!nghttp2_check_header_name(
|
|
|
|
reinterpret_cast<const uint8_t *>(p.first.c_str()), p.first.size()) ||
|
|
|
|
!nghttp2_check_header_value(
|
|
|
|
reinterpret_cast<const uint8_t *>(p.second.c_str()),
|
|
|
|
p.second.size())) {
|
|
|
|
return {"", ""};
|
|
|
|
}
|
|
|
|
|
2015-11-05 14:48:54 +01:00
|
|
|
return p;
|
2014-04-26 07:56:08 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
template <typename T>
|
|
|
|
int parse_uint(T *dest, const char *opt, const char *optarg) {
|
2014-08-27 16:36:36 +02:00
|
|
|
char *end = nullptr;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
|
|
|
auto val = strtol(optarg, &end, 10);
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!optarg[0] || errno != 0 || *end || val < 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": bad value. Specify an integer >= 0.";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*dest = val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-01-13 13:54:53 +01:00
|
|
|
namespace {
|
|
|
|
template <typename T>
|
|
|
|
int parse_uint_with_unit(T *dest, const char *opt, const char *optarg) {
|
|
|
|
auto n = util::parse_uint_with_unit(optarg);
|
|
|
|
if (n == -1) {
|
|
|
|
LOG(ERROR) << opt << ": bad value: '" << optarg << "'";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*dest = n;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
template <typename T>
|
|
|
|
int parse_int(T *dest, const char *opt, const char *optarg) {
|
2014-08-27 16:36:36 +02:00
|
|
|
char *end = nullptr;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
|
|
|
auto val = strtol(optarg, &end, 10);
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!optarg[0] || errno != 0 || *end) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": bad value. Specify an integer.";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*dest = val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-14 16:36:44 +02:00
|
|
|
namespace {
|
2015-07-14 16:45:50 +02:00
|
|
|
// generated by gennghttpxfun.py
|
2015-07-14 16:36:44 +02:00
|
|
|
LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
|
|
|
|
switch (namelen) {
|
|
|
|
case 3:
|
|
|
|
switch (name[2]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("pi", name, 2)) {
|
|
|
|
return SHRPX_LOGF_PID;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
switch (name[3]) {
|
|
|
|
case 'n':
|
|
|
|
if (util::strieq_l("alp", name, 3)) {
|
|
|
|
return SHRPX_LOGF_ALPN;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
switch (name[5]) {
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("statu", name, 5)) {
|
|
|
|
return SHRPX_LOGF_STATUS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
switch (name[6]) {
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("reques", name, 6)) {
|
|
|
|
return SHRPX_LOGF_REQUEST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
switch (name[9]) {
|
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("time_loca", name, 9)) {
|
|
|
|
return SHRPX_LOGF_TIME_LOCAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("ssl_ciphe", name, 9)) {
|
|
|
|
return SHRPX_LOGF_SSL_CIPHER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
switch (name[10]) {
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("remote_add", name, 10)) {
|
|
|
|
return SHRPX_LOGF_REMOTE_ADDR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("remote_por", name, 10)) {
|
|
|
|
return SHRPX_LOGF_REMOTE_PORT;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("server_por", name, 10)) {
|
|
|
|
return SHRPX_LOGF_SERVER_PORT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
switch (name[11]) {
|
|
|
|
case '1':
|
|
|
|
if (util::strieq_l("time_iso860", name, 11)) {
|
|
|
|
return SHRPX_LOGF_TIME_ISO8601;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("request_tim", name, 11)) {
|
|
|
|
return SHRPX_LOGF_REQUEST_TIME;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("ssl_protoco", name, 11)) {
|
|
|
|
return SHRPX_LOGF_SSL_PROTOCOL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
switch (name[13]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("ssl_session_i", name, 13)) {
|
|
|
|
return SHRPX_LOGF_SSL_SESSION_ID;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
switch (name[14]) {
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("body_bytes_sen", name, 14)) {
|
|
|
|
return SHRPX_LOGF_BODY_BYTES_SENT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
switch (name[17]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("ssl_session_reuse", name, 17)) {
|
|
|
|
return SHRPX_LOGF_SSL_SESSION_REUSED;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return SHRPX_LOGF_NONE;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2014-11-18 16:56:44 +01:00
|
|
|
namespace {
|
2014-11-27 15:39:04 +01:00
|
|
|
bool var_token(char c) {
|
2015-11-27 16:41:39 +01:00
|
|
|
return util::is_alpha(c) || util::is_digit(c) || c == '_';
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
std::vector<LogFragment> parse_log_format(const char *optarg) {
|
2014-11-18 16:56:44 +01:00
|
|
|
auto literal_start = optarg;
|
|
|
|
auto p = optarg;
|
|
|
|
auto eop = p + strlen(optarg);
|
|
|
|
|
|
|
|
auto res = std::vector<LogFragment>();
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
for (; p != eop;) {
|
|
|
|
if (*p != '$') {
|
2014-11-18 16:56:44 +01:00
|
|
|
++p;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto var_start = p;
|
|
|
|
|
|
|
|
++p;
|
|
|
|
|
2015-07-14 15:25:52 +02:00
|
|
|
const char *var_name;
|
|
|
|
size_t var_namelen;
|
|
|
|
if (p != eop && *p == '{') {
|
|
|
|
var_name = ++p;
|
|
|
|
for (; p != eop && var_token(*p); ++p)
|
|
|
|
;
|
|
|
|
|
|
|
|
if (p == eop || *p != '}') {
|
|
|
|
LOG(WARN) << "Missing '}' after " << std::string(var_start, p);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var_namelen = p - var_name;
|
|
|
|
++p;
|
|
|
|
} else {
|
|
|
|
var_name = p;
|
|
|
|
for (; p != eop && var_token(*p); ++p)
|
|
|
|
;
|
2014-11-18 16:56:44 +01:00
|
|
|
|
2015-07-14 15:25:52 +02:00
|
|
|
var_namelen = p - var_name;
|
|
|
|
}
|
2014-11-18 16:56:44 +01:00
|
|
|
|
|
|
|
const char *value = nullptr;
|
|
|
|
|
2015-07-14 16:36:44 +02:00
|
|
|
auto type = log_var_lookup_token(var_name, var_namelen);
|
|
|
|
|
|
|
|
if (type == SHRPX_LOGF_NONE) {
|
2015-11-27 16:31:42 +01:00
|
|
|
if (util::istarts_with(var_name, var_namelen, "http_")) {
|
2015-10-28 15:12:16 +01:00
|
|
|
if (util::streq("host", var_name + str_size("http_"),
|
|
|
|
var_namelen - str_size("http_"))) {
|
|
|
|
// Special handling of host header field. We will use
|
|
|
|
// :authority header field if host header is missing. This
|
|
|
|
// is a typical case in HTTP/2.
|
|
|
|
type = SHRPX_LOGF_AUTHORITY;
|
|
|
|
} else {
|
|
|
|
type = SHRPX_LOGF_HTTP;
|
|
|
|
value = var_name + str_size("http_");
|
|
|
|
}
|
2015-07-14 16:36:44 +02:00
|
|
|
} else {
|
|
|
|
LOG(WARN) << "Unrecognized log format variable: "
|
|
|
|
<< std::string(var_name, var_namelen);
|
|
|
|
continue;
|
|
|
|
}
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (literal_start < var_start) {
|
2016-01-17 07:04:09 +01:00
|
|
|
res.emplace_back(SHRPX_LOGF_LITERAL,
|
|
|
|
ImmutableString(literal_start, var_start));
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
2015-07-14 15:25:52 +02:00
|
|
|
literal_start = p;
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (value == nullptr) {
|
2015-07-14 15:43:02 +02:00
|
|
|
res.emplace_back(type);
|
2015-07-14 15:25:52 +02:00
|
|
|
continue;
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
2016-01-17 07:04:09 +01:00
|
|
|
auto name = std::string(value, var_name + var_namelen);
|
|
|
|
for (auto &c : name) {
|
|
|
|
if (c == '_') {
|
|
|
|
c = '-';
|
2015-07-14 15:25:52 +02:00
|
|
|
}
|
|
|
|
}
|
2016-01-17 07:04:09 +01:00
|
|
|
|
|
|
|
res.emplace_back(type, ImmutableString(name));
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (literal_start != eop) {
|
2016-01-17 07:04:09 +01:00
|
|
|
res.emplace_back(SHRPX_LOGF_LITERAL, ImmutableString(literal_start, eop));
|
2014-11-18 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-08-27 16:36:36 +02:00
|
|
|
namespace {
|
2015-01-27 16:36:44 +01:00
|
|
|
int parse_duration(ev_tstamp *dest, const char *opt, const char *optarg) {
|
2015-01-29 15:28:47 +01:00
|
|
|
auto t = util::parse_duration_with_unit(optarg);
|
2015-01-27 16:36:44 +01:00
|
|
|
if (t == std::numeric_limits<double>::infinity()) {
|
|
|
|
LOG(ERROR) << opt << ": bad value: '" << optarg << "'";
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-01-27 16:36:44 +01:00
|
|
|
*dest = t;
|
2014-08-27 16:36:36 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
namespace {
|
|
|
|
// Parses host-path mapping patterns in |src|, and stores mappings in
|
|
|
|
// config. We will store each host-path pattern found in |src| with
|
|
|
|
// |addr|. |addr| will be copied accordingly. Also we make a group
|
|
|
|
// based on the pattern. The "/" pattern is considered as catch-all.
|
2015-07-11 10:30:38 +02:00
|
|
|
void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
2015-07-09 19:52:11 +02:00
|
|
|
// This returns at least 1 element (it could be empty string). We
|
|
|
|
// will append '/' to all patterns, so it becomes catch-all pattern.
|
2015-09-14 15:33:48 +02:00
|
|
|
auto mapping = util::split_config_str_list(src, ':');
|
2015-07-09 19:52:11 +02:00
|
|
|
assert(!mapping.empty());
|
2016-01-19 08:56:12 +01:00
|
|
|
auto &addr_groups = mod_config()->conn.downstream.addr_groups;
|
|
|
|
|
2015-07-20 14:37:23 +02:00
|
|
|
for (const auto &raw_pattern : mapping) {
|
2015-07-09 19:52:11 +02:00
|
|
|
auto done = false;
|
|
|
|
std::string pattern;
|
2015-07-20 14:37:23 +02:00
|
|
|
auto slash = std::find(raw_pattern.first, raw_pattern.second, '/');
|
|
|
|
if (slash == raw_pattern.second) {
|
2015-07-09 19:52:11 +02:00
|
|
|
// This effectively makes empty pattern to "/".
|
2015-07-20 14:37:23 +02:00
|
|
|
pattern.assign(raw_pattern.first, raw_pattern.second);
|
2015-07-09 19:52:11 +02:00
|
|
|
util::inp_strlower(pattern);
|
2015-11-27 16:03:16 +01:00
|
|
|
pattern += '/';
|
2015-07-09 19:52:11 +02:00
|
|
|
} else {
|
2015-07-20 14:37:23 +02:00
|
|
|
pattern.assign(raw_pattern.first, slash);
|
2015-07-09 19:52:11 +02:00
|
|
|
util::inp_strlower(pattern);
|
2015-07-20 14:37:23 +02:00
|
|
|
pattern += http2::normalize_path(slash, raw_pattern.second);
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
2016-01-19 08:56:12 +01:00
|
|
|
for (auto &g : addr_groups) {
|
2015-09-25 19:38:45 +02:00
|
|
|
if (g.pattern.get() == pattern) {
|
2015-07-09 19:52:11 +02:00
|
|
|
g.addrs.push_back(addr);
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (done) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
DownstreamAddrGroup g(pattern);
|
|
|
|
g.addrs.push_back(addr);
|
2015-09-25 19:38:45 +02:00
|
|
|
|
|
|
|
mod_config()->router.add_route(g.pattern.get(), strlen(g.pattern.get()),
|
2016-01-19 08:56:12 +01:00
|
|
|
addr_groups.size());
|
2015-09-25 19:38:45 +02:00
|
|
|
|
2016-01-19 08:56:12 +01:00
|
|
|
addr_groups.push_back(std::move(g));
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2016-01-15 15:04:58 +01:00
|
|
|
namespace {
|
|
|
|
int parse_forwarded_node_type(const std::string &optarg) {
|
|
|
|
if (util::strieq(optarg, "obfuscated")) {
|
|
|
|
return FORWARDED_NODE_OBFUSCATED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (util::strieq(optarg, "ip")) {
|
|
|
|
return FORWARDED_NODE_IP;
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:18:27 +01:00
|
|
|
if (optarg.size() < 2 || optarg[0] != '_') {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (std::find_if_not(std::begin(optarg), std::end(optarg), [](char c) {
|
|
|
|
return util::is_alpha(c) || util::is_digit(c) || c == '.' || c == '_' ||
|
|
|
|
c == '-';
|
|
|
|
}) != std::end(optarg)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FORWARDED_NODE_OBFUSCATED;
|
2016-01-15 15:04:58 +01:00
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2015-07-14 16:45:50 +02:00
|
|
|
// generated by gennghttpxfun.py
|
2015-07-14 16:21:38 +02:00
|
|
|
enum {
|
2015-09-06 11:39:32 +02:00
|
|
|
SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_ACCESSLOG_FILE,
|
|
|
|
SHRPX_OPTID_ACCESSLOG_FORMAT,
|
|
|
|
SHRPX_OPTID_ACCESSLOG_SYSLOG,
|
2016-01-15 15:04:58 +01:00
|
|
|
SHRPX_OPTID_ADD_FORWARDED,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_ADD_REQUEST_HEADER,
|
|
|
|
SHRPX_OPTID_ADD_RESPONSE_HEADER,
|
|
|
|
SHRPX_OPTID_ADD_X_FORWARDED_FOR,
|
|
|
|
SHRPX_OPTID_ALTSVC,
|
|
|
|
SHRPX_OPTID_BACKEND,
|
|
|
|
SHRPX_OPTID_BACKEND_HTTP_PROXY_URI,
|
|
|
|
SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND,
|
|
|
|
SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST,
|
2016-02-06 11:50:21 +01:00
|
|
|
SHRPX_OPTID_BACKEND_HTTP1_TLS,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS,
|
|
|
|
SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER,
|
|
|
|
SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS,
|
|
|
|
SHRPX_OPTID_BACKEND_IPV4,
|
|
|
|
SHRPX_OPTID_BACKEND_IPV6,
|
|
|
|
SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT,
|
|
|
|
SHRPX_OPTID_BACKEND_NO_TLS,
|
|
|
|
SHRPX_OPTID_BACKEND_READ_TIMEOUT,
|
|
|
|
SHRPX_OPTID_BACKEND_REQUEST_BUFFER,
|
|
|
|
SHRPX_OPTID_BACKEND_RESPONSE_BUFFER,
|
2016-02-06 16:16:14 +01:00
|
|
|
SHRPX_OPTID_BACKEND_TLS_SESSION_CACHE_PER_WORKER,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_BACKEND_TLS_SNI_FIELD,
|
|
|
|
SHRPX_OPTID_BACKEND_WRITE_TIMEOUT,
|
|
|
|
SHRPX_OPTID_BACKLOG,
|
|
|
|
SHRPX_OPTID_CACERT,
|
|
|
|
SHRPX_OPTID_CERTIFICATE_FILE,
|
|
|
|
SHRPX_OPTID_CIPHERS,
|
|
|
|
SHRPX_OPTID_CLIENT,
|
|
|
|
SHRPX_OPTID_CLIENT_CERT_FILE,
|
|
|
|
SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE,
|
|
|
|
SHRPX_OPTID_CLIENT_PROXY,
|
|
|
|
SHRPX_OPTID_CONF,
|
|
|
|
SHRPX_OPTID_DAEMON,
|
|
|
|
SHRPX_OPTID_DH_PARAM_FILE,
|
|
|
|
SHRPX_OPTID_ERRORLOG_FILE,
|
|
|
|
SHRPX_OPTID_ERRORLOG_SYSLOG,
|
2015-10-03 00:32:58 +02:00
|
|
|
SHRPX_OPTID_FASTOPEN,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE,
|
2016-01-15 15:04:58 +01:00
|
|
|
SHRPX_OPTID_FORWARDED_BY,
|
|
|
|
SHRPX_OPTID_FORWARDED_FOR,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_FRONTEND,
|
|
|
|
SHRPX_OPTID_FRONTEND_FRAME_DEBUG,
|
|
|
|
SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS,
|
|
|
|
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER,
|
|
|
|
SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER,
|
|
|
|
SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT,
|
|
|
|
SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS,
|
|
|
|
SHRPX_OPTID_FRONTEND_NO_TLS,
|
|
|
|
SHRPX_OPTID_FRONTEND_READ_TIMEOUT,
|
|
|
|
SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT,
|
|
|
|
SHRPX_OPTID_HEADER_FIELD_BUFFER,
|
2015-07-23 16:54:56 +02:00
|
|
|
SHRPX_OPTID_HOST_REWRITE,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_HTTP2_BRIDGE,
|
|
|
|
SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS,
|
|
|
|
SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING,
|
|
|
|
SHRPX_OPTID_HTTP2_PROXY,
|
|
|
|
SHRPX_OPTID_INCLUDE,
|
|
|
|
SHRPX_OPTID_INSECURE,
|
|
|
|
SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT,
|
|
|
|
SHRPX_OPTID_LOG_LEVEL,
|
|
|
|
SHRPX_OPTID_MAX_HEADER_FIELDS,
|
2016-02-06 09:22:23 +01:00
|
|
|
SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS,
|
2016-02-06 04:25:34 +01:00
|
|
|
SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS,
|
2015-10-05 17:10:42 +02:00
|
|
|
SHRPX_OPTID_MRUBY_FILE,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_NO_HOST_REWRITE,
|
2016-02-06 09:05:14 +01:00
|
|
|
SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_NO_LOCATION_REWRITE,
|
|
|
|
SHRPX_OPTID_NO_OCSP,
|
|
|
|
SHRPX_OPTID_NO_SERVER_PUSH,
|
|
|
|
SHRPX_OPTID_NO_VIA,
|
|
|
|
SHRPX_OPTID_NPN_LIST,
|
|
|
|
SHRPX_OPTID_OCSP_UPDATE_INTERVAL,
|
|
|
|
SHRPX_OPTID_PADDING,
|
|
|
|
SHRPX_OPTID_PID_FILE,
|
|
|
|
SHRPX_OPTID_PRIVATE_KEY_FILE,
|
|
|
|
SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE,
|
|
|
|
SHRPX_OPTID_READ_BURST,
|
|
|
|
SHRPX_OPTID_READ_RATE,
|
2016-02-06 09:22:23 +01:00
|
|
|
SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER,
|
2016-02-06 04:25:34 +01:00
|
|
|
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_RLIMIT_NOFILE,
|
|
|
|
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
|
|
|
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
2016-01-15 15:04:58 +01:00
|
|
|
SHRPX_OPTID_STRIP_INCOMING_FORWARDED,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR,
|
|
|
|
SHRPX_OPTID_SUBCERT,
|
|
|
|
SHRPX_OPTID_SYSLOG_FACILITY,
|
2015-10-21 12:22:46 +02:00
|
|
|
SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT,
|
|
|
|
SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_TLS_PROTO_LIST,
|
2015-07-25 15:22:17 +02:00
|
|
|
SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED,
|
2016-02-12 16:20:38 +01:00
|
|
|
SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE,
|
|
|
|
SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE,
|
2016-02-11 14:56:45 +01:00
|
|
|
SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_TLS,
|
2015-07-28 16:49:37 +02:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_CIPHER,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_FILE,
|
2015-07-27 17:54:44 +02:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED,
|
2016-02-13 10:17:11 +01:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE,
|
2015-07-27 18:02:33 +02:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_INTERVAL,
|
2015-07-27 18:17:29 +02:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL,
|
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY,
|
2016-02-13 10:17:11 +01:00
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE,
|
|
|
|
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS,
|
2015-07-14 16:21:38 +02:00
|
|
|
SHRPX_OPTID_USER,
|
|
|
|
SHRPX_OPTID_VERIFY_CLIENT,
|
|
|
|
SHRPX_OPTID_VERIFY_CLIENT_CACERT,
|
|
|
|
SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS,
|
|
|
|
SHRPX_OPTID_WORKER_READ_BURST,
|
|
|
|
SHRPX_OPTID_WORKER_READ_RATE,
|
|
|
|
SHRPX_OPTID_WORKER_WRITE_BURST,
|
|
|
|
SHRPX_OPTID_WORKER_WRITE_RATE,
|
|
|
|
SHRPX_OPTID_WORKERS,
|
|
|
|
SHRPX_OPTID_WRITE_BURST,
|
|
|
|
SHRPX_OPTID_WRITE_RATE,
|
|
|
|
SHRPX_OPTID_MAXIDX,
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
2015-07-14 16:45:50 +02:00
|
|
|
// generated by gennghttpxfun.py
|
2015-07-14 16:21:38 +02:00
|
|
|
int option_lookup_token(const char *name, size_t namelen) {
|
|
|
|
switch (namelen) {
|
|
|
|
case 4:
|
|
|
|
switch (name[3]) {
|
|
|
|
case 'f':
|
|
|
|
if (util::strieq_l("con", name, 3)) {
|
|
|
|
return SHRPX_OPTID_CONF;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("use", name, 3)) {
|
|
|
|
return SHRPX_OPTID_USER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
switch (name[5]) {
|
|
|
|
case 'a':
|
|
|
|
if (util::strieq_l("no-vi", name, 5)) {
|
|
|
|
return SHRPX_OPTID_NO_VIA;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
if (util::strieq_l("altsv", name, 5)) {
|
|
|
|
return SHRPX_OPTID_ALTSVC;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
if (util::strieq_l("daemo", name, 5)) {
|
|
|
|
return SHRPX_OPTID_DAEMON;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("cacer", name, 5)) {
|
|
|
|
return SHRPX_OPTID_CACERT;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("clien", name, 5)) {
|
|
|
|
return SHRPX_OPTID_CLIENT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
switch (name[6]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("backen", name, 6)) {
|
|
|
|
return SHRPX_OPTID_BACKEND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("includ", name, 6)) {
|
|
|
|
return SHRPX_OPTID_INCLUDE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
if (util::strieq_l("backlo", name, 6)) {
|
|
|
|
return SHRPX_OPTID_BACKLOG;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("paddin", name, 6)) {
|
|
|
|
return SHRPX_OPTID_PADDING;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
if (util::strieq_l("no-ocs", name, 6)) {
|
|
|
|
return SHRPX_OPTID_NO_OCSP;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("cipher", name, 6)) {
|
|
|
|
return SHRPX_OPTID_CIPHERS;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("worker", name, 6)) {
|
|
|
|
return SHRPX_OPTID_WORKERS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("subcer", name, 6)) {
|
|
|
|
return SHRPX_OPTID_SUBCERT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
switch (name[7]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("fronten", name, 7)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("insecur", name, 7)) {
|
|
|
|
return SHRPX_OPTID_INSECURE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("pid-fil", name, 7)) {
|
|
|
|
return SHRPX_OPTID_PID_FILE;
|
|
|
|
}
|
|
|
|
break;
|
2015-10-03 00:32:58 +02:00
|
|
|
case 'n':
|
|
|
|
if (util::strieq_l("fastope", name, 7)) {
|
|
|
|
return SHRPX_OPTID_FASTOPEN;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("npn-lis", name, 7)) {
|
|
|
|
return SHRPX_OPTID_NPN_LIST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
switch (name[8]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("read-rat", name, 8)) {
|
|
|
|
return SHRPX_OPTID_READ_RATE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("log-leve", name, 8)) {
|
|
|
|
return SHRPX_OPTID_LOG_LEVEL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
switch (name[9]) {
|
|
|
|
case 'e':
|
2015-10-05 17:10:42 +02:00
|
|
|
if (util::strieq_l("mruby-fil", name, 9)) {
|
|
|
|
return SHRPX_OPTID_MRUBY_FILE;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
if (util::strieq_l("write-rat", name, 9)) {
|
|
|
|
return SHRPX_OPTID_WRITE_RATE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("read-burs", name, 9)) {
|
|
|
|
return SHRPX_OPTID_READ_BURST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
switch (name[10]) {
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("write-burs", name, 10)) {
|
|
|
|
return SHRPX_OPTID_WRITE_BURST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'y':
|
|
|
|
if (util::strieq_l("http2-prox", name, 10)) {
|
|
|
|
return SHRPX_OPTID_HTTP2_PROXY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
switch (name[11]) {
|
|
|
|
case '4':
|
|
|
|
if (util::strieq_l("backend-ipv", name, 11)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_IPV4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '6':
|
|
|
|
if (util::strieq_l("backend-ipv", name, 11)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_IPV6;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
2015-07-23 16:54:56 +02:00
|
|
|
if (util::strieq_l("host-rewrit", name, 11)) {
|
|
|
|
return SHRPX_OPTID_HOST_REWRITE;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
if (util::strieq_l("http2-bridg", name, 11)) {
|
|
|
|
return SHRPX_OPTID_HTTP2_BRIDGE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'y':
|
|
|
|
if (util::strieq_l("client-prox", name, 11)) {
|
|
|
|
return SHRPX_OPTID_CLIENT_PROXY;
|
|
|
|
}
|
2016-01-15 15:04:58 +01:00
|
|
|
if (util::strieq_l("forwarded-b", name, 11)) {
|
|
|
|
return SHRPX_OPTID_FORWARDED_BY;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
switch (name[12]) {
|
2016-01-15 15:04:58 +01:00
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("add-forwarde", name, 12)) {
|
|
|
|
return SHRPX_OPTID_ADD_FORWARDED;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("dh-param-fil", name, 12)) {
|
|
|
|
return SHRPX_OPTID_DH_PARAM_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("errorlog-fil", name, 12)) {
|
|
|
|
return SHRPX_OPTID_ERRORLOG_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("rlimit-nofil", name, 12)) {
|
|
|
|
return SHRPX_OPTID_RLIMIT_NOFILE;
|
|
|
|
}
|
|
|
|
break;
|
2016-01-15 15:04:58 +01:00
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("forwarded-fo", name, 12)) {
|
|
|
|
return SHRPX_OPTID_FORWARDED_FOR;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("verify-clien", name, 12)) {
|
|
|
|
return SHRPX_OPTID_VERIFY_CLIENT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
switch (name[13]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("accesslog-fil", name, 13)) {
|
|
|
|
return SHRPX_OPTID_ACCESSLOG_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
if (util::strieq_l("no-server-pus", name, 13)) {
|
|
|
|
return SHRPX_OPTID_NO_SERVER_PUSH;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("backend-no-tl", name, 13)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_NO_TLS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("tls-proto-lis", name, 13)) {
|
|
|
|
return SHRPX_OPTID_TLS_PROTO_LIST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
switch (name[14]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("no-host-rewrit", name, 14)) {
|
|
|
|
return SHRPX_OPTID_NO_HOST_REWRITE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
if (util::strieq_l("errorlog-syslo", name, 14)) {
|
|
|
|
return SHRPX_OPTID_ERRORLOG_SYSLOG;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("frontend-no-tl", name, 14)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_NO_TLS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'y':
|
|
|
|
if (util::strieq_l("syslog-facilit", name, 14)) {
|
|
|
|
return SHRPX_OPTID_SYSLOG_FACILITY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
switch (name[15]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("certificate-fil", name, 15)) {
|
|
|
|
return SHRPX_OPTID_CERTIFICATE_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("client-cert-fil", name, 15)) {
|
|
|
|
return SHRPX_OPTID_CLIENT_CERT_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("private-key-fil", name, 15)) {
|
|
|
|
return SHRPX_OPTID_PRIVATE_KEY_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("worker-read-rat", name, 15)) {
|
|
|
|
return SHRPX_OPTID_WORKER_READ_RATE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
if (util::strieq_l("accesslog-syslo", name, 15)) {
|
|
|
|
return SHRPX_OPTID_ACCESSLOG_SYSLOG;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("accesslog-forma", name, 15)) {
|
|
|
|
return SHRPX_OPTID_ACCESSLOG_FORMAT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
switch (name[16]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("worker-write-rat", name, 16)) {
|
|
|
|
return SHRPX_OPTID_WORKER_WRITE_RATE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
2016-02-06 11:50:21 +01:00
|
|
|
if (util::strieq_l("backend-http1-tl", name, 16)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP1_TLS;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
if (util::strieq_l("max-header-field", name, 16)) {
|
|
|
|
return SHRPX_OPTID_MAX_HEADER_FIELDS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("worker-read-burs", name, 16)) {
|
|
|
|
return SHRPX_OPTID_WORKER_READ_BURST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
switch (name[17]) {
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("add-request-heade", name, 17)) {
|
|
|
|
return SHRPX_OPTID_ADD_REQUEST_HEADER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("worker-write-burs", name, 17)) {
|
|
|
|
return SHRPX_OPTID_WORKER_WRITE_BURST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 19:
|
|
|
|
switch (name[18]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("no-location-rewrit", name, 18)) {
|
|
|
|
return SHRPX_OPTID_NO_LOCATION_REWRITE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("tls-ticket-key-fil", name, 18)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("add-response-heade", name, 18)) {
|
|
|
|
return SHRPX_OPTID_ADD_RESPONSE_HEADER;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("add-x-forwarded-fo", name, 18)) {
|
|
|
|
return SHRPX_OPTID_ADD_X_FORWARDED_FOR;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("header-field-buffe", name, 18)) {
|
|
|
|
return SHRPX_OPTID_HEADER_FIELD_BUFFER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("stream-read-timeou", name, 18)) {
|
|
|
|
return SHRPX_OPTID_STREAM_READ_TIMEOUT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 20:
|
|
|
|
switch (name[19]) {
|
|
|
|
case 'g':
|
|
|
|
if (util::strieq_l("frontend-frame-debu", name, 19)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_FRAME_DEBUG;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("ocsp-update-interva", name, 19)) {
|
|
|
|
return SHRPX_OPTID_OCSP_UPDATE_INTERVAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("backend-read-timeou", name, 19)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_READ_TIMEOUT;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("stream-write-timeou", name, 19)) {
|
|
|
|
return SHRPX_OPTID_STREAM_WRITE_TIMEOUT;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("verify-client-cacer", name, 19)) {
|
|
|
|
return SHRPX_OPTID_VERIFY_CLIENT_CACERT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 21:
|
|
|
|
switch (name[20]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("backend-tls-sni-fiel", name, 20)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_TLS_SNI_FIELD;
|
|
|
|
}
|
|
|
|
break;
|
2015-09-06 11:39:32 +02:00
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("accept-proxy-protoco", name, 20)) {
|
|
|
|
return SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-28 16:49:37 +02:00
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("tls-ticket-key-ciphe", name, 20)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_CIPHER;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("backend-write-timeou", name, 20)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_WRITE_TIMEOUT;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("frontend-read-timeou", name, 20)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_READ_TIMEOUT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 22:
|
|
|
|
switch (name[21]) {
|
|
|
|
case 'i':
|
|
|
|
if (util::strieq_l("backend-http-proxy-ur", name, 21)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP_PROXY_URI;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("backend-request-buffe", name, 21)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_REQUEST_BUFFER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("frontend-write-timeou", name, 21)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 23:
|
|
|
|
switch (name[22]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("client-private-key-fil", name, 22)) {
|
|
|
|
return SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE;
|
|
|
|
}
|
|
|
|
if (util::strieq_l("private-key-passwd-fil", name, 22)) {
|
|
|
|
return SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("backend-response-buffe", name, 22)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_RESPONSE_BUFFER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
switch (name[23]) {
|
2015-07-27 17:54:44 +02:00
|
|
|
case 'd':
|
2016-01-15 15:04:58 +01:00
|
|
|
if (util::strieq_l("strip-incoming-forwarde", name, 23)) {
|
|
|
|
return SHRPX_OPTID_STRIP_INCOMING_FORWARDED;
|
|
|
|
}
|
2015-07-27 17:54:44 +02:00
|
|
|
if (util::strieq_l("tls-ticket-key-memcache", name, 23)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("fetch-ocsp-response-fil", name, 23)) {
|
|
|
|
return SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("listener-disable-timeou", name, 23)) {
|
|
|
|
return SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT;
|
|
|
|
}
|
2015-10-21 12:22:46 +02:00
|
|
|
if (util::strieq_l("tls-dyn-rec-idle-timeou", name, 23)) {
|
|
|
|
return SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 25:
|
|
|
|
switch (name[24]) {
|
|
|
|
case 'g':
|
|
|
|
if (util::strieq_l("http2-no-cookie-crumblin", name, 24)) {
|
|
|
|
return SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("backend-http2-window-bit", name, 24)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS;
|
|
|
|
}
|
2016-02-06 09:22:23 +01:00
|
|
|
if (util::strieq_l("max-request-header-field", name, 24)) {
|
|
|
|
return SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 26:
|
|
|
|
switch (name[25]) {
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("frontend-http2-window-bit", name, 25)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS;
|
|
|
|
}
|
2016-02-06 04:25:34 +01:00
|
|
|
if (util::strieq_l("max-response-header-field", name, 25)) {
|
|
|
|
return SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("backend-keep-alive-timeou", name, 25)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT;
|
|
|
|
}
|
2016-02-06 09:05:14 +01:00
|
|
|
if (util::strieq_l("no-http2-cipher-black-lis", name, 25)) {
|
|
|
|
return SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 27:
|
|
|
|
switch (name[26]) {
|
2015-07-25 15:22:17 +02:00
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("tls-session-cache-memcache", name, 26)) {
|
|
|
|
return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED;
|
|
|
|
}
|
|
|
|
break;
|
2016-02-06 09:22:23 +01:00
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("request-header-field-buffe", name, 26)) {
|
|
|
|
return SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("worker-frontend-connection", name, 26)) {
|
|
|
|
return SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("frontend-http2-read-timeou", name, 26)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 28:
|
|
|
|
switch (name[27]) {
|
2015-10-21 12:22:46 +02:00
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("tls-dyn-rec-warmup-threshol", name, 27)) {
|
|
|
|
return SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD;
|
|
|
|
}
|
|
|
|
break;
|
2016-02-06 04:25:34 +01:00
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("response-header-field-buffe", name, 27)) {
|
|
|
|
return SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("http2-max-concurrent-stream", name, 27)) {
|
|
|
|
return SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS;
|
|
|
|
}
|
2016-02-13 10:17:11 +01:00
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-tl", name, 27)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 30:
|
|
|
|
switch (name[29]) {
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("strip-incoming-x-forwarded-fo", name, 29)) {
|
|
|
|
return SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2016-02-11 14:56:45 +01:00
|
|
|
case 31:
|
|
|
|
switch (name[30]) {
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("tls-session-cache-memcached-tl", name, 30)) {
|
|
|
|
return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_TLS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-27 18:02:33 +02:00
|
|
|
case 33:
|
|
|
|
switch (name[32]) {
|
|
|
|
case 'l':
|
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-interva", name, 32)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_INTERVAL;
|
|
|
|
}
|
2015-07-27 18:17:29 +02:00
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-max-fai", name, 32)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL;
|
|
|
|
}
|
2015-07-27 18:02:33 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 34:
|
|
|
|
switch (name[33]) {
|
2016-02-13 10:17:11 +01:00
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-cert-fil", name, 33)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("frontend-http2-dump-request-heade", name, 33)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (util::strieq_l("backend-http1-connections-per-hos", name, 33)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-27 18:17:29 +02:00
|
|
|
case 'y':
|
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-max-retr", name, 33)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 35:
|
|
|
|
switch (name[34]) {
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("frontend-http2-dump-response-heade", name, 34)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 36:
|
|
|
|
switch (name[35]) {
|
|
|
|
case 'r':
|
|
|
|
if (util::strieq_l("backend-http2-connections-per-worke", name, 35)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER;
|
|
|
|
}
|
2016-02-06 16:16:14 +01:00
|
|
|
if (util::strieq_l("backend-tls-session-cache-per-worke", name, 35)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_TLS_SESSION_CACHE_PER_WORKER;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("backend-http2-connection-window-bit", name, 35)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 37:
|
|
|
|
switch (name[36]) {
|
2016-02-12 16:20:38 +01:00
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("tls-session-cache-memcached-cert-fil", name, 36)) {
|
|
|
|
return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
case 's':
|
|
|
|
if (util::strieq_l("frontend-http2-connection-window-bit", name, 36)) {
|
|
|
|
return SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 38:
|
|
|
|
switch (name[37]) {
|
|
|
|
case 'd':
|
|
|
|
if (util::strieq_l("backend-http1-connections-per-fronten", name, 37)) {
|
|
|
|
return SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2016-02-13 10:17:11 +01:00
|
|
|
case 41:
|
|
|
|
switch (name[40]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("tls-ticket-key-memcached-private-key-fil", name,
|
|
|
|
40)) {
|
|
|
|
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2016-02-12 16:20:38 +01:00
|
|
|
case 44:
|
|
|
|
switch (name[43]) {
|
|
|
|
case 'e':
|
|
|
|
if (util::strieq_l("tls-session-cache-memcached-private-key-fil", name,
|
|
|
|
43)) {
|
|
|
|
return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-14 16:21:38 +02:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2015-07-13 14:44:06 +02:00
|
|
|
int parse_config(const char *opt, const char *optarg,
|
|
|
|
std::set<std::string> &included_set) {
|
2012-08-01 17:06:41 +02:00
|
|
|
char host[NI_MAXHOST];
|
|
|
|
uint16_t port;
|
2015-07-09 19:52:11 +02:00
|
|
|
|
2015-07-14 16:21:38 +02:00
|
|
|
auto optid = option_lookup_token(opt, strlen(opt));
|
|
|
|
|
|
|
|
switch (optid) {
|
|
|
|
case SHRPX_OPTID_BACKEND: {
|
2015-07-09 19:52:11 +02:00
|
|
|
auto optarglen = strlen(optarg);
|
2015-07-10 19:08:16 +02:00
|
|
|
const char *pat_delim = strchr(optarg, ';');
|
2015-07-09 19:52:11 +02:00
|
|
|
if (!pat_delim) {
|
|
|
|
pat_delim = optarg + optarglen;
|
|
|
|
}
|
|
|
|
DownstreamAddr addr;
|
2015-11-27 16:31:42 +01:00
|
|
|
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
2015-02-22 09:12:00 +01:00
|
|
|
auto path = optarg + str_size(SHRPX_UNIX_PATH_PREFIX);
|
2016-01-17 03:33:45 +01:00
|
|
|
addr.host = ImmutableString(path, pat_delim);
|
2015-02-22 09:12:00 +01:00
|
|
|
addr.host_unix = true;
|
2015-07-09 19:52:11 +02:00
|
|
|
} else {
|
|
|
|
if (split_host_port(host, sizeof(host), &port, optarg,
|
|
|
|
pat_delim - optarg) == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
2015-02-22 04:27:51 +01:00
|
|
|
|
2016-01-17 03:33:45 +01:00
|
|
|
addr.host = ImmutableString(host);
|
2015-07-09 19:52:11 +02:00
|
|
|
addr.port = port;
|
2015-02-22 04:27:51 +01:00
|
|
|
}
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
auto mapping = pat_delim < optarg + optarglen ? pat_delim + 1 : pat_delim;
|
|
|
|
// We may introduce new parameter after additional ';', so don't
|
|
|
|
// allow extra ';' in pattern for now.
|
|
|
|
if (strchr(mapping, ';') != nullptr) {
|
|
|
|
LOG(ERROR) << opt << ": ';' must not be used in pattern";
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2015-07-11 10:30:38 +02:00
|
|
|
parse_mapping(addr, mapping);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND: {
|
2016-01-19 08:56:12 +01:00
|
|
|
auto &listenerconf = mod_config()->conn.listener;
|
|
|
|
|
2016-02-07 09:51:53 +01:00
|
|
|
UpstreamAddr addr{};
|
2016-01-31 11:41:56 +01:00
|
|
|
addr.fd = -1;
|
|
|
|
|
2015-11-27 16:31:42 +01:00
|
|
|
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
2015-02-22 09:01:19 +01:00
|
|
|
auto path = optarg + str_size(SHRPX_UNIX_PATH_PREFIX);
|
2016-01-31 11:41:56 +01:00
|
|
|
addr.host = ImmutableString(path);
|
|
|
|
addr.host_unix = true;
|
|
|
|
|
|
|
|
listenerconf.addrs.push_back(std::move(addr));
|
2015-02-22 09:01:19 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
if (split_host_port(host, sizeof(host), &port, optarg, strlen(optarg)) ==
|
|
|
|
-1) {
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2014-06-08 14:02:40 +02:00
|
|
|
|
2016-01-31 11:41:56 +01:00
|
|
|
addr.host = ImmutableString(host);
|
|
|
|
addr.port = port;
|
|
|
|
|
|
|
|
if (util::numeric_host(host, AF_INET)) {
|
|
|
|
addr.family = AF_INET;
|
|
|
|
listenerconf.addrs.push_back(std::move(addr));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (util::numeric_host(host, AF_INET6)) {
|
|
|
|
addr.family = AF_INET6;
|
|
|
|
listenerconf.addrs.push_back(std::move(addr));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr.family = AF_INET;
|
|
|
|
listenerconf.addrs.push_back(addr);
|
|
|
|
|
|
|
|
addr.family = AF_INET6;
|
|
|
|
listenerconf.addrs.push_back(std::move(addr));
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKERS:
|
2015-09-06 09:59:57 +02:00
|
|
|
#ifdef NOTHREADS
|
|
|
|
LOG(WARN) << "Threading disabled at build time, no threads created.";
|
|
|
|
return 0;
|
|
|
|
#else // !NOTHREADS
|
2014-08-27 16:36:36 +02:00
|
|
|
return parse_uint(&mod_config()->num_worker, opt, optarg);
|
2015-09-06 09:59:57 +02:00
|
|
|
#endif // !NOTHREADS
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS:
|
2016-01-18 09:00:20 +01:00
|
|
|
return parse_uint(&mod_config()->http2.max_concurrent_streams, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_LOG_LEVEL:
|
2014-11-27 15:39:04 +01:00
|
|
|
if (Log::set_severity_level_by_name(optarg) == -1) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": Invalid severity level: " << optarg;
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_DAEMON:
|
2012-08-01 17:06:41 +02:00
|
|
|
mod_config()->daemon = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_HTTP2_PROXY:
|
2013-11-04 10:14:05 +01:00
|
|
|
mod_config()->http2_proxy = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_HTTP2_BRIDGE:
|
2013-11-04 10:14:05 +01:00
|
|
|
mod_config()->http2_bridge = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CLIENT_PROXY:
|
2012-11-21 14:10:35 +01:00
|
|
|
mod_config()->client_proxy = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ADD_X_FORWARDED_FOR:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.xff.add = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.xff.strip_incoming = util::strieq(optarg, "yes");
|
2014-10-24 15:24:17 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NO_VIA:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.no_via = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.upstream.timeout.http2_read, opt,
|
2015-01-27 16:36:44 +01:00
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_READ_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.upstream.timeout.read, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.upstream.timeout.write, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_READ_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.downstream.timeout.read, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_WRITE_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.downstream.timeout.write, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_STREAM_READ_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->http2.timeout.stream_read, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_STREAM_WRITE_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->http2.timeout.stream_write, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ACCESSLOG_FILE:
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.access.file = strcopy(optarg);
|
2014-07-05 11:22:40 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ACCESSLOG_SYSLOG:
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.access.syslog = util::strieq(optarg, "yes");
|
2014-07-05 11:22:40 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ACCESSLOG_FORMAT:
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.access.format = parse_log_format(optarg);
|
2014-11-18 16:56:44 +01:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ERRORLOG_FILE:
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.error.file = strcopy(optarg);
|
2014-07-05 11:22:40 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ERRORLOG_SYSLOG:
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.error.syslog = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-10-03 00:32:58 +02:00
|
|
|
case SHRPX_OPTID_FASTOPEN: {
|
|
|
|
int n;
|
|
|
|
if (parse_int(&n, opt, optarg) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n < 0) {
|
|
|
|
LOG(ERROR) << opt << ": " << optarg << " is not allowed";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.listener.fastopen = n;
|
2015-10-03 00:32:58 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-10-15 14:42:11 +02:00
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.downstream.timeout.idle_read, opt,
|
2015-01-27 16:36:44 +01:00
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS:
|
|
|
|
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS: {
|
2012-11-21 15:47:48 +01:00
|
|
|
size_t *resp;
|
2014-08-27 16:36:36 +02:00
|
|
|
|
2015-07-14 16:21:38 +02:00
|
|
|
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS) {
|
2016-01-18 09:00:20 +01:00
|
|
|
resp = &mod_config()->http2.upstream.window_bits;
|
2012-11-21 15:47:48 +01:00
|
|
|
} else {
|
2016-01-18 09:00:20 +01:00
|
|
|
resp = &mod_config()->http2.downstream.window_bits;
|
2012-11-21 15:47:48 +01:00
|
|
|
}
|
2014-08-27 16:36:36 +02:00
|
|
|
|
2012-08-01 17:06:41 +02:00
|
|
|
errno = 0;
|
2014-08-27 16:36:36 +02:00
|
|
|
|
|
|
|
int n;
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (parse_uint(&n, opt, optarg) != 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (n >= 31) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt
|
|
|
|
<< ": specify the integer in the range [0, 30], inclusive";
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
2014-08-27 16:36:36 +02:00
|
|
|
*resp = n;
|
|
|
|
|
2014-06-08 16:01:48 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS:
|
|
|
|
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_BITS: {
|
2013-11-20 16:15:17 +01:00
|
|
|
size_t *resp;
|
2014-08-27 16:36:36 +02:00
|
|
|
|
2015-07-14 16:21:38 +02:00
|
|
|
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS) {
|
2016-01-18 09:00:20 +01:00
|
|
|
resp = &mod_config()->http2.upstream.connection_window_bits;
|
2013-11-20 16:15:17 +01:00
|
|
|
} else {
|
2016-01-18 09:00:20 +01:00
|
|
|
resp = &mod_config()->http2.downstream.connection_window_bits;
|
2013-11-20 16:15:17 +01:00
|
|
|
}
|
2014-08-27 16:36:36 +02:00
|
|
|
|
2013-11-20 16:15:17 +01:00
|
|
|
errno = 0;
|
2014-08-27 16:36:36 +02:00
|
|
|
|
|
|
|
int n;
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (parse_uint(&n, opt, optarg) != 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (n < 16 || n >= 31) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt
|
|
|
|
<< ": specify the integer in the range [16, 30], inclusive";
|
2013-11-20 16:15:17 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
2014-08-27 16:36:36 +02:00
|
|
|
*resp = n;
|
|
|
|
|
2014-06-08 16:01:48 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_NO_TLS:
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.upstream.no_tls = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_NO_TLS:
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.no_tls = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_TLS_SNI_FIELD:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.backend_sni_name = optarg;
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_PID_FILE:
|
2014-06-08 14:02:40 +02:00
|
|
|
mod_config()->pid_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_USER: {
|
2013-10-02 16:13:25 +02:00
|
|
|
auto pwd = getpwnam(optarg);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!pwd) {
|
|
|
|
LOG(ERROR) << opt << ": failed to get uid from " << optarg << ": "
|
|
|
|
<< strerror(errno);
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2015-01-26 15:41:38 +01:00
|
|
|
mod_config()->user = strcopy(pwd->pw_name);
|
2012-08-01 17:06:41 +02:00
|
|
|
mod_config()->uid = pwd->pw_uid;
|
|
|
|
mod_config()->gid = pwd->pw_gid;
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_PRIVATE_KEY_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.private_key_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE: {
|
2013-10-02 16:13:25 +02:00
|
|
|
auto passwd = read_passwd_from_file(optarg);
|
2012-12-03 07:33:04 +01:00
|
|
|
if (passwd.empty()) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": Couldn't read key file's passwd from " << optarg;
|
2012-12-03 07:33:04 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.private_key_passwd = strcopy(passwd);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CERTIFICATE_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.cert_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_DH_PARAM_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.dh_param_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_SUBCERT: {
|
2013-02-06 15:27:05 +01:00
|
|
|
// Private Key file and certificate file separated by ':'.
|
|
|
|
const char *sp = strchr(optarg, ':');
|
2014-11-27 15:39:04 +01:00
|
|
|
if (sp) {
|
2013-02-06 15:27:05 +01:00
|
|
|
std::string keyfile(optarg, sp);
|
|
|
|
// TODO Do we need private key for subcert?
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.subcerts.emplace_back(keyfile, sp + 1);
|
2013-02-06 15:27:05 +01:00
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_SYSLOG_FACILITY: {
|
2012-08-01 18:20:18 +02:00
|
|
|
int facility = int_syslog_facility(optarg);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (facility == -1) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": Unknown syslog facility: " << optarg;
|
2012-08-01 18:20:18 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2016-01-18 09:26:27 +01:00
|
|
|
mod_config()->logging.syslog_facility = facility;
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKLOG: {
|
2014-08-27 16:36:36 +02:00
|
|
|
int n;
|
2014-11-27 15:39:04 +01:00
|
|
|
if (parse_int(&n, opt, optarg) != 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (n < -1) {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": " << optarg << " is not allowed";
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.listener.backlog = n;
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CIPHERS:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ciphers = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CLIENT:
|
2012-11-21 14:10:35 +01:00
|
|
|
mod_config()->client = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_INSECURE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.insecure = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CACERT:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.cacert = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_IPV4:
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.ipv4 = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_IPV6:
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.ipv6 = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
2016-01-17 14:51:40 +01:00
|
|
|
auto &proxy = mod_config()->downstream_http_proxy;
|
|
|
|
// Reset here so that multiple option occurrence does not merge
|
|
|
|
// the results.
|
|
|
|
proxy = {};
|
2013-02-09 08:42:01 +01:00
|
|
|
// parse URI and get hostname, port and optionally userinfo.
|
2015-07-19 10:55:37 +02:00
|
|
|
http_parser_url u{};
|
2013-02-09 08:42:01 +01:00
|
|
|
int rv = http_parser_parse_url(optarg, strlen(optarg), 0, &u);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (rv == 0) {
|
2013-02-09 08:42:01 +01:00
|
|
|
std::string val;
|
2014-11-27 15:39:04 +01:00
|
|
|
if (u.field_set & UF_USERINFO) {
|
2013-08-27 19:47:22 +02:00
|
|
|
http2::copy_url_component(val, &u, UF_USERINFO, optarg);
|
2013-02-22 13:23:59 +01:00
|
|
|
// Surprisingly, u.field_set & UF_USERINFO is nonzero even if
|
|
|
|
// userinfo component is empty string.
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!val.empty()) {
|
2016-01-17 14:51:40 +01:00
|
|
|
proxy.userinfo = util::percent_decode(std::begin(val), std::end(val));
|
2013-02-22 13:23:59 +01:00
|
|
|
}
|
2013-02-09 08:42:01 +01:00
|
|
|
}
|
2014-11-27 15:39:04 +01:00
|
|
|
if (u.field_set & UF_HOST) {
|
2016-01-17 14:51:40 +01:00
|
|
|
http2::copy_url_component(proxy.host, &u, UF_HOST, optarg);
|
2013-02-09 08:42:01 +01:00
|
|
|
} else {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": no hostname specified";
|
2013-02-09 08:42:01 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2014-11-27 15:39:04 +01:00
|
|
|
if (u.field_set & UF_PORT) {
|
2016-01-17 14:51:40 +01:00
|
|
|
proxy.port = u.port;
|
2013-02-09 08:42:01 +01:00
|
|
|
} else {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": no port specified";
|
2013-02-09 08:42:01 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": parse error";
|
|
|
|
return -1;
|
2013-02-09 08:42:01 +01:00
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_READ_RATE:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint_with_unit(
|
|
|
|
&mod_config()->conn.upstream.ratelimit.read.rate, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_READ_BURST:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint_with_unit(
|
|
|
|
&mod_config()->conn.upstream.ratelimit.read.burst, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WRITE_RATE:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint_with_unit(
|
|
|
|
&mod_config()->conn.upstream.ratelimit.write.rate, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WRITE_BURST:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint_with_unit(
|
|
|
|
&mod_config()->conn.upstream.ratelimit.write.burst, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKER_READ_RATE:
|
2015-01-02 03:22:39 +01:00
|
|
|
LOG(WARN) << opt << ": not implemented yet";
|
2016-01-19 08:56:12 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKER_READ_BURST:
|
2015-01-02 03:22:39 +01:00
|
|
|
LOG(WARN) << opt << ": not implemented yet";
|
2016-01-19 08:56:12 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKER_WRITE_RATE:
|
2015-01-02 03:22:39 +01:00
|
|
|
LOG(WARN) << opt << ": not implemented yet";
|
2016-01-19 08:56:12 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKER_WRITE_BURST:
|
2015-01-02 03:22:39 +01:00
|
|
|
LOG(WARN) << opt << ": not implemented yet";
|
2016-01-19 08:56:12 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NPN_LIST:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.npn_list = util::parse_config_str_list(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_TLS_PROTO_LIST:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.tls_proto_list = util::parse_config_str_list(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_VERIFY_CLIENT:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.client_verify.enabled = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_VERIFY_CLIENT_CACERT:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.client_verify.cacert = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.client.private_key_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CLIENT_CERT_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.client.cert_file = strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http2.upstream.debug.dump.request_header_file =
|
|
|
|
strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http2.upstream.debug.dump.response_header_file =
|
|
|
|
strcopy(optarg);
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http2.no_cookie_crumbling = util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FRONTEND_FRAME_DEBUG:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http2.upstream.debug.frame_debug =
|
|
|
|
util::strieq(optarg, "yes");
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_PADDING:
|
2014-08-27 16:36:36 +02:00
|
|
|
return parse_uint(&mod_config()->padding, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ALTSVC: {
|
2015-09-14 15:33:48 +02:00
|
|
|
auto tokens = util::parse_config_str_list(optarg);
|
2014-04-03 06:20:50 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (tokens.size() < 2) {
|
2014-04-08 15:28:50 +02:00
|
|
|
// Requires at least protocol_id and port
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": too few parameters: " << optarg;
|
2014-04-08 15:28:50 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2014-04-03 06:20:50 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (tokens.size() > 4) {
|
2014-04-08 15:28:50 +02:00
|
|
|
// We only need protocol_id, port, host and origin
|
2014-08-27 16:36:36 +02:00
|
|
|
LOG(ERROR) << opt << ": too many parameters: " << optarg;
|
2014-04-03 06:20:50 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-08-27 16:36:36 +02:00
|
|
|
int port;
|
2014-04-08 15:28:50 +02:00
|
|
|
|
2015-07-20 15:37:26 +02:00
|
|
|
if (parse_uint(&port, opt, tokens[1].c_str()) != 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (port < 1 ||
|
|
|
|
port > static_cast<int>(std::numeric_limits<uint16_t>::max())) {
|
2015-07-20 15:37:26 +02:00
|
|
|
LOG(ERROR) << opt << ": port is invalid: " << tokens[1];
|
2014-04-08 15:28:50 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
AltSvc altsvc;
|
|
|
|
|
2015-07-20 14:37:23 +02:00
|
|
|
altsvc.protocol_id = std::move(tokens[0]);
|
2015-07-20 15:37:26 +02:00
|
|
|
|
|
|
|
altsvc.port = port;
|
|
|
|
altsvc.service = std::move(tokens[1]);
|
2014-04-08 15:28:50 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (tokens.size() > 2) {
|
2015-07-20 14:37:23 +02:00
|
|
|
altsvc.host = std::move(tokens[2]);
|
2014-04-08 15:28:50 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (tokens.size() > 3) {
|
2015-07-20 14:37:23 +02:00
|
|
|
altsvc.origin = std::move(tokens[3]);
|
2014-04-08 15:28:50 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-03 06:20:50 +02:00
|
|
|
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.altsvcs.push_back(std::move(altsvc));
|
2014-04-03 06:20:50 +02:00
|
|
|
|
2014-06-08 16:01:48 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_ADD_REQUEST_HEADER:
|
|
|
|
case SHRPX_OPTID_ADD_RESPONSE_HEADER: {
|
2014-04-26 07:56:08 +02:00
|
|
|
auto p = parse_header(optarg);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (p.first.empty()) {
|
2015-12-25 12:57:24 +01:00
|
|
|
LOG(ERROR) << opt << ": invalid header field: " << optarg;
|
2014-04-26 07:56:08 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
if (optid == SHRPX_OPTID_ADD_REQUEST_HEADER) {
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.add_request_headers.push_back(std::move(p));
|
2015-06-05 16:04:20 +02:00
|
|
|
} else {
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.add_response_headers.push_back(std::move(p));
|
2015-06-05 16:04:20 +02:00
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint(&mod_config()->conn.upstream.worker_connections, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NO_LOCATION_REWRITE:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.no_location_rewrite = util::strieq(optarg, "yes");
|
2014-08-10 05:39:27 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NO_HOST_REWRITE:
|
2015-07-23 16:54:56 +02:00
|
|
|
LOG(WARN) << SHRPX_OPT_NO_HOST_REWRITE
|
|
|
|
<< ": deprecated. :authority and host header fields are NOT "
|
|
|
|
"altered by default. To rewrite these headers, use "
|
|
|
|
"--host-rewrite option.";
|
2015-02-03 17:41:20 +01:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_HOST: {
|
2014-08-27 16:36:36 +02:00
|
|
|
int n;
|
2014-08-16 14:29:20 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (parse_uint(&n, opt, optarg) != 0) {
|
2014-08-27 16:36:36 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-01-13 15:23:35 +01:00
|
|
|
if (n == 0) {
|
|
|
|
LOG(ERROR) << opt << ": specify an integer strictly more than 0";
|
2014-08-16 14:29:20 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.connections_per_host = n;
|
2014-08-16 14:29:20 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_uint(&mod_config()->conn.downstream.connections_per_frontend,
|
|
|
|
opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT:
|
2016-01-19 08:56:12 +01:00
|
|
|
return parse_duration(&mod_config()->conn.listener.timeout.sleep, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ticket.files.push_back(optarg);
|
2015-01-07 17:26:30 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_RLIMIT_NOFILE: {
|
2015-01-10 15:17:48 +01:00
|
|
|
int n;
|
|
|
|
|
|
|
|
if (parse_uint(&n, opt, optarg) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n < 0) {
|
|
|
|
LOG(ERROR) << opt << ": specify the integer more than or equal to 0";
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod_config()->rlimit_nofile = n;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_REQUEST_BUFFER:
|
|
|
|
case SHRPX_OPTID_BACKEND_RESPONSE_BUFFER: {
|
2015-01-13 15:20:06 +01:00
|
|
|
size_t n;
|
|
|
|
if (parse_uint_with_unit(&n, opt, optarg) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n == 0) {
|
|
|
|
LOG(ERROR) << opt << ": specify an integer strictly more than 0";
|
2015-01-13 15:23:35 +01:00
|
|
|
|
2015-01-13 15:20:06 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-07-14 16:21:38 +02:00
|
|
|
if (optid == SHRPX_OPTID_BACKEND_REQUEST_BUFFER) {
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.request_buffer_size = n;
|
2015-01-13 15:30:28 +01:00
|
|
|
} else {
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.downstream.response_buffer_size = n;
|
2015-01-13 15:30:28 +01:00
|
|
|
}
|
2015-01-13 15:20:06 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NO_SERVER_PUSH:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http2.no_server_push = util::strieq(optarg, "yes");
|
2015-02-08 08:19:12 +01:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER:
|
2016-01-18 09:00:20 +01:00
|
|
|
return parse_uint(&mod_config()->http2.downstream.connections_per_worker,
|
2015-03-10 15:43:25 +01:00
|
|
|
opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ocsp.fetch_ocsp_response_file = strcopy(optarg);
|
2015-03-30 16:20:40 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_OCSP_UPDATE_INTERVAL:
|
2016-01-18 06:21:09 +01:00
|
|
|
return parse_duration(&mod_config()->tls.ocsp.update_interval, opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_NO_OCSP:
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ocsp.disabled = util::strieq(optarg, "yes");
|
2015-03-30 16:20:40 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_HEADER_FIELD_BUFFER:
|
2016-02-06 09:22:23 +01:00
|
|
|
LOG(WARN) << opt
|
|
|
|
<< ": deprecated. Use request-header-field-buffer instead.";
|
|
|
|
// fall through
|
|
|
|
case SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER:
|
|
|
|
return parse_uint_with_unit(&mod_config()->http.request_header_field_buffer,
|
|
|
|
opt, optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_MAX_HEADER_FIELDS:
|
2016-02-06 09:22:23 +01:00
|
|
|
LOG(WARN) << opt << ": deprecated. Use max-request-header-fields instead.";
|
|
|
|
// fall through
|
|
|
|
case SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS:
|
|
|
|
return parse_uint(&mod_config()->http.max_request_header_fields, opt,
|
|
|
|
optarg);
|
2016-02-06 04:25:34 +01:00
|
|
|
case SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER:
|
|
|
|
return parse_uint_with_unit(
|
|
|
|
&mod_config()->http.response_header_field_buffer, opt, optarg);
|
|
|
|
case SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS:
|
|
|
|
return parse_uint(&mod_config()->http.max_response_header_fields, opt,
|
|
|
|
optarg);
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_INCLUDE: {
|
2015-07-13 14:44:06 +02:00
|
|
|
if (included_set.count(optarg)) {
|
|
|
|
LOG(ERROR) << opt << ": " << optarg << " has already been included";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-07-19 13:50:14 +02:00
|
|
|
included_set.insert(optarg);
|
2015-07-13 14:44:06 +02:00
|
|
|
auto rv = load_config(optarg, included_set);
|
|
|
|
included_set.erase(optarg);
|
|
|
|
|
|
|
|
if (rv != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2015-07-12 16:18:36 +02:00
|
|
|
}
|
2015-07-28 16:49:37 +02:00
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_CIPHER:
|
2015-07-17 18:49:20 +02:00
|
|
|
if (util::strieq(optarg, "aes-128-cbc")) {
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ticket.cipher = EVP_aes_128_cbc();
|
2015-07-17 18:49:20 +02:00
|
|
|
} else if (util::strieq(optarg, "aes-256-cbc")) {
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ticket.cipher = EVP_aes_256_cbc();
|
2015-07-17 18:49:20 +02:00
|
|
|
} else {
|
|
|
|
LOG(ERROR) << opt
|
|
|
|
<< ": unsupported cipher for ticket encryption: " << optarg;
|
|
|
|
return -1;
|
|
|
|
}
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ticket.cipher_given = true;
|
2015-07-17 18:49:20 +02:00
|
|
|
|
2015-07-23 16:54:56 +02:00
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_HOST_REWRITE:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.no_host_rewrite = !util::strieq(optarg, "yes");
|
2015-07-23 16:54:56 +02:00
|
|
|
|
2015-07-17 18:49:20 +02:00
|
|
|
return 0;
|
2015-07-25 15:22:17 +02:00
|
|
|
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: {
|
|
|
|
if (split_host_port(host, sizeof(host), &port, optarg, strlen(optarg)) ==
|
|
|
|
-1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:09 +01:00
|
|
|
auto &memcachedconf = mod_config()->tls.session_cache.memcached;
|
|
|
|
memcachedconf.host = strcopy(host);
|
|
|
|
memcachedconf.port = port;
|
2015-07-25 15:22:17 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-27 17:54:44 +02:00
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED: {
|
|
|
|
if (split_host_port(host, sizeof(host), &port, optarg, strlen(optarg)) ==
|
|
|
|
-1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:09 +01:00
|
|
|
auto &memcachedconf = mod_config()->tls.ticket.memcached;
|
|
|
|
memcachedconf.host = strcopy(host);
|
|
|
|
memcachedconf.port = port;
|
2015-07-27 17:54:44 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-27 18:02:33 +02:00
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_INTERVAL:
|
2016-01-18 06:21:09 +01:00
|
|
|
return parse_duration(&mod_config()->tls.ticket.memcached.interval, opt,
|
2015-07-27 18:02:33 +02:00
|
|
|
optarg);
|
2015-07-27 18:17:29 +02:00
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY: {
|
|
|
|
int n;
|
|
|
|
if (parse_uint(&n, opt, optarg) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n > 30) {
|
|
|
|
LOG(ERROR) << opt << ": must be smaller than or equal to 30";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.ticket.memcached.max_retry = n;
|
2015-07-27 18:17:29 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL:
|
2016-01-18 06:21:09 +01:00
|
|
|
return parse_uint(&mod_config()->tls.ticket.memcached.max_fail, opt,
|
2015-07-27 18:17:29 +02:00
|
|
|
optarg);
|
2015-10-21 12:22:46 +02:00
|
|
|
case SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD: {
|
|
|
|
size_t n;
|
|
|
|
if (parse_uint_with_unit(&n, opt, optarg) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:09 +01:00
|
|
|
mod_config()->tls.dyn_rec.warmup_threshold = n;
|
2015-10-21 12:22:46 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT:
|
2016-01-18 06:21:09 +01:00
|
|
|
return parse_duration(&mod_config()->tls.dyn_rec.idle_timeout, opt, optarg);
|
2015-10-21 12:22:46 +02:00
|
|
|
|
2015-10-05 17:10:42 +02:00
|
|
|
case SHRPX_OPTID_MRUBY_FILE:
|
2015-09-06 09:59:57 +02:00
|
|
|
#ifdef HAVE_MRUBY
|
2015-10-05 17:10:42 +02:00
|
|
|
mod_config()->mruby_file = strcopy(optarg);
|
2015-09-06 09:59:57 +02:00
|
|
|
#else // !HAVE_MRUBY
|
|
|
|
LOG(WARN) << opt
|
|
|
|
<< ": ignored because mruby support is disabled at build time.";
|
|
|
|
#endif // !HAVE_MRUBY
|
2015-09-06 11:39:32 +02:00
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL:
|
2016-01-19 08:56:12 +01:00
|
|
|
mod_config()->conn.upstream.accept_proxy_protocol =
|
|
|
|
util::strieq(optarg, "yes");
|
2015-09-06 11:39:32 +02:00
|
|
|
|
2015-09-01 17:19:32 +02:00
|
|
|
return 0;
|
2016-01-18 09:00:20 +01:00
|
|
|
case SHRPX_OPTID_ADD_FORWARDED: {
|
|
|
|
auto &fwdconf = mod_config()->http.forwarded;
|
|
|
|
fwdconf.params = FORWARDED_NONE;
|
2016-01-15 15:04:58 +01:00
|
|
|
for (const auto ¶m : util::parse_config_str_list(optarg)) {
|
|
|
|
if (util::strieq(param, "by")) {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.params |= FORWARDED_BY;
|
2016-01-15 15:04:58 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (util::strieq(param, "for")) {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.params |= FORWARDED_FOR;
|
2016-01-15 15:04:58 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (util::strieq(param, "host")) {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.params |= FORWARDED_HOST;
|
2016-01-15 15:04:58 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (util::strieq(param, "proto")) {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.params |= FORWARDED_PROTO;
|
2016-01-15 15:04:58 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOG(ERROR) << opt << ": unknown parameter " << optarg;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2016-01-18 09:00:20 +01:00
|
|
|
}
|
2016-01-15 15:04:58 +01:00
|
|
|
case SHRPX_OPTID_STRIP_INCOMING_FORWARDED:
|
2016-01-18 09:00:20 +01:00
|
|
|
mod_config()->http.forwarded.strip_incoming = util::strieq(optarg, "yes");
|
2016-01-15 15:04:58 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_FORWARDED_BY:
|
|
|
|
case SHRPX_OPTID_FORWARDED_FOR: {
|
|
|
|
auto type = parse_forwarded_node_type(optarg);
|
|
|
|
|
2016-01-21 13:05:07 +01:00
|
|
|
if (type == -1 ||
|
|
|
|
(optid == SHRPX_OPTID_FORWARDED_FOR && optarg[0] == '_')) {
|
2016-01-15 15:18:27 +01:00
|
|
|
LOG(ERROR) << opt << ": unknown node type or illegal obfuscated string "
|
|
|
|
<< optarg;
|
2016-01-15 15:04:58 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-18 09:00:20 +01:00
|
|
|
auto &fwdconf = mod_config()->http.forwarded;
|
|
|
|
|
2016-01-15 15:04:58 +01:00
|
|
|
switch (optid) {
|
|
|
|
case SHRPX_OPTID_FORWARDED_BY:
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.by_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
2016-01-15 15:18:27 +01:00
|
|
|
if (optarg[0] == '_') {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.by_obfuscated = optarg;
|
2016-01-16 03:53:18 +01:00
|
|
|
} else {
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.by_obfuscated = "";
|
2016-01-15 15:18:27 +01:00
|
|
|
}
|
2016-01-15 15:04:58 +01:00
|
|
|
break;
|
|
|
|
case SHRPX_OPTID_FORWARDED_FOR:
|
2016-01-18 09:00:20 +01:00
|
|
|
fwdconf.for_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
2016-01-15 15:04:58 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-02-06 09:05:14 +01:00
|
|
|
case SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST:
|
|
|
|
mod_config()->tls.no_http2_cipher_black_list = util::strieq(optarg, "yes");
|
|
|
|
|
2016-02-06 11:50:21 +01:00
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_BACKEND_HTTP1_TLS:
|
|
|
|
mod_config()->conn.downstream.http1_tls = util::strieq(optarg, "yes");
|
|
|
|
|
2016-02-06 09:05:14 +01:00
|
|
|
return 0;
|
2016-02-06 16:16:14 +01:00
|
|
|
case SHRPX_OPTID_BACKEND_TLS_SESSION_CACHE_PER_WORKER:
|
2016-02-07 09:32:34 +01:00
|
|
|
return parse_uint(&mod_config()->tls.downstream_session_cache_per_worker,
|
|
|
|
opt, optarg);
|
2016-02-11 14:56:45 +01:00
|
|
|
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_TLS:
|
|
|
|
mod_config()->tls.session_cache.memcached.tls = util::strieq(optarg, "yes");
|
|
|
|
|
2016-02-12 16:20:38 +01:00
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE:
|
|
|
|
mod_config()->tls.session_cache.memcached.cert_file = optarg;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE:
|
|
|
|
mod_config()->tls.session_cache.memcached.private_key_file = optarg;
|
|
|
|
|
2016-02-13 10:17:11 +01:00
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS:
|
|
|
|
mod_config()->tls.ticket.memcached.tls = util::strieq(optarg, "yes");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE:
|
|
|
|
mod_config()->tls.ticket.memcached.cert_file = optarg;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE:
|
|
|
|
mod_config()->tls.ticket.memcached.private_key_file = optarg;
|
|
|
|
|
2016-02-11 14:56:45 +01:00
|
|
|
return 0;
|
2015-07-14 16:21:38 +02:00
|
|
|
case SHRPX_OPTID_CONF:
|
2014-11-08 02:51:56 +01:00
|
|
|
LOG(WARN) << "conf: ignored";
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
return 0;
|
2012-08-01 17:06:41 +02:00
|
|
|
}
|
2014-06-08 16:01:48 +02:00
|
|
|
|
|
|
|
LOG(ERROR) << "Unknown option: " << opt;
|
|
|
|
|
|
|
|
return -1;
|
2012-08-01 17:06:41 +02:00
|
|
|
}
|
|
|
|
|
2015-07-13 14:44:06 +02:00
|
|
|
int load_config(const char *filename, std::set<std::string> &include_set) {
|
2012-08-01 17:06:41 +02:00
|
|
|
std::ifstream in(filename, std::ios::binary);
|
2014-11-27 15:39:04 +01:00
|
|
|
if (!in) {
|
2012-08-01 17:26:24 +02:00
|
|
|
LOG(ERROR) << "Could not open config file " << filename;
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
std::string line;
|
|
|
|
int linenum = 0;
|
2014-11-27 15:39:04 +01:00
|
|
|
while (std::getline(in, line)) {
|
2012-08-01 17:06:41 +02:00
|
|
|
++linenum;
|
2014-11-27 15:39:04 +01:00
|
|
|
if (line.empty() || line[0] == '#') {
|
2012-08-01 17:06:41 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
size_t i;
|
|
|
|
size_t size = line.size();
|
2014-11-27 15:39:04 +01:00
|
|
|
for (i = 0; i < size && line[i] != '='; ++i)
|
|
|
|
;
|
|
|
|
if (i == size) {
|
2015-07-12 16:18:36 +02:00
|
|
|
LOG(ERROR) << "Bad configuration format in " << filename << " at line "
|
|
|
|
<< linenum;
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
line[i] = '\0';
|
2013-10-02 16:13:25 +02:00
|
|
|
auto s = line.c_str();
|
2015-07-13 14:44:06 +02:00
|
|
|
if (parse_config(s, s + i + 1, include_set) == -1) {
|
2012-08-01 17:06:41 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
const char *str_syslog_facility(int facility) {
|
|
|
|
switch (facility) {
|
|
|
|
case (LOG_AUTH):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "auth";
|
2015-06-27 10:51:07 +02:00
|
|
|
#ifdef LOG_AUTHPRIV
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_AUTHPRIV):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "authpriv";
|
2015-06-27 10:51:07 +02:00
|
|
|
#endif // LOG_AUTHPRIV
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_CRON):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "cron";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_DAEMON):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "daemon";
|
2015-06-27 10:51:07 +02:00
|
|
|
#ifdef LOG_FTP
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_FTP):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "ftp";
|
2015-06-27 10:51:07 +02:00
|
|
|
#endif // LOG_FTP
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_KERN):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "kern";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL0):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local0";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL1):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local1";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL2):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local2";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL3):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local3";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL4):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local4";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL5):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local5";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL6):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local6";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LOCAL7):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "local7";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_LPR):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "lpr";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_MAIL):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "mail";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_SYSLOG):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "syslog";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_USER):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "user";
|
2014-11-27 15:39:04 +01:00
|
|
|
case (LOG_UUCP):
|
2012-08-01 18:20:18 +02:00
|
|
|
return "uucp";
|
|
|
|
default:
|
|
|
|
return "(unknown)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
int int_syslog_facility(const char *strfacility) {
|
|
|
|
if (util::strieq(strfacility, "auth")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_AUTH;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2015-06-27 10:51:07 +02:00
|
|
|
#ifdef LOG_AUTHPRIV
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "authpriv")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_AUTHPRIV;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
2015-06-27 10:51:07 +02:00
|
|
|
#endif // LOG_AUTHPRIV
|
2014-06-08 16:03:26 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "cron")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_CRON;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "daemon")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_DAEMON;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2015-06-27 10:51:07 +02:00
|
|
|
#ifdef LOG_FTP
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "ftp")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_FTP;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
2015-06-27 10:51:07 +02:00
|
|
|
#endif // LOG_FTP
|
2014-06-08 16:03:26 +02:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "kern")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_KERN;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local0")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL0;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local1")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL1;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local2")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL2;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local3")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL3;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local4")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL4;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local5")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL5;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local6")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL6;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "local7")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LOCAL7;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "lpr")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_LPR;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "mail")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_MAIL;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "news")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_NEWS;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "syslog")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_SYSLOG;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "user")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_USER;
|
2014-06-08 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
if (util::strieq(strfacility, "uucp")) {
|
2012-08-01 18:20:18 +02:00
|
|
|
return LOG_UUCP;
|
|
|
|
}
|
2014-06-08 16:03:26 +02:00
|
|
|
|
|
|
|
return -1;
|
2012-08-01 18:20:18 +02:00
|
|
|
}
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
namespace {
|
2015-09-25 19:38:45 +02:00
|
|
|
size_t
|
|
|
|
match_downstream_addr_group_host(const Router &router, const std::string &host,
|
|
|
|
const char *path, size_t pathlen,
|
|
|
|
const std::vector<DownstreamAddrGroup> &groups,
|
|
|
|
size_t catch_all) {
|
|
|
|
if (pathlen == 0 || *path != '/') {
|
|
|
|
auto group = router.match(host, "/", 1);
|
2015-07-09 19:52:11 +02:00
|
|
|
if (group != -1) {
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
|
|
|
LOG(INFO) << "Found pattern with query " << host
|
2015-09-25 19:38:45 +02:00
|
|
|
<< ", matched pattern=" << groups[group].pattern.get();
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
return catch_all;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
|
|
|
LOG(INFO) << "Perform mapping selection, using host=" << host
|
2015-09-25 19:38:45 +02:00
|
|
|
<< ", path=" << std::string(path, pathlen);
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
|
2015-09-25 19:38:45 +02:00
|
|
|
auto group = router.match(host, path, pathlen);
|
2015-07-09 19:52:11 +02:00
|
|
|
if (group != -1) {
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
2015-07-11 09:42:23 +02:00
|
|
|
LOG(INFO) << "Found pattern with query " << host
|
2015-09-25 19:38:45 +02:00
|
|
|
<< std::string(path, pathlen)
|
|
|
|
<< ", matched pattern=" << groups[group].pattern.get();
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
2015-09-25 19:38:45 +02:00
|
|
|
group = router.match("", path, pathlen);
|
2015-07-09 19:52:11 +02:00
|
|
|
if (group != -1) {
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
2015-09-25 19:38:45 +02:00
|
|
|
LOG(INFO) << "Found pattern with query " << std::string(path, pathlen)
|
|
|
|
<< ", matched pattern=" << groups[group].pattern.get();
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LOG_ENABLED(INFO)) {
|
|
|
|
LOG(INFO) << "None match. Use catch-all pattern";
|
|
|
|
}
|
|
|
|
return catch_all;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2015-09-25 19:38:45 +02:00
|
|
|
size_t
|
|
|
|
match_downstream_addr_group(const Router &router, const std::string &hostport,
|
|
|
|
const std::string &raw_path,
|
|
|
|
const std::vector<DownstreamAddrGroup> &groups,
|
|
|
|
size_t catch_all) {
|
2015-07-11 09:12:35 +02:00
|
|
|
if (std::find(std::begin(hostport), std::end(hostport), '/') !=
|
|
|
|
std::end(hostport)) {
|
2015-07-09 19:52:11 +02:00
|
|
|
// We use '/' specially, and if '/' is included in host, it breaks
|
|
|
|
// our code. Select catch-all case.
|
|
|
|
return catch_all;
|
|
|
|
}
|
2015-07-11 09:12:35 +02:00
|
|
|
|
|
|
|
auto fragment = std::find(std::begin(raw_path), std::end(raw_path), '#');
|
|
|
|
auto query = std::find(std::begin(raw_path), fragment, '?');
|
2015-09-25 19:38:45 +02:00
|
|
|
auto path = raw_path.c_str();
|
|
|
|
auto pathlen = query - std::begin(raw_path);
|
2015-07-11 09:12:35 +02:00
|
|
|
|
|
|
|
if (hostport.empty()) {
|
2015-09-25 19:38:45 +02:00
|
|
|
return match_downstream_addr_group_host(router, hostport, path, pathlen,
|
2015-07-11 09:42:23 +02:00
|
|
|
groups, catch_all);
|
2015-07-11 09:12:35 +02:00
|
|
|
}
|
|
|
|
|
2015-07-09 19:52:11 +02:00
|
|
|
std::string host;
|
|
|
|
if (hostport[0] == '[') {
|
|
|
|
// assume this is IPv6 numeric address
|
|
|
|
auto p = std::find(std::begin(hostport), std::end(hostport), ']');
|
|
|
|
if (p == std::end(hostport)) {
|
|
|
|
return catch_all;
|
|
|
|
}
|
|
|
|
if (p + 1 < std::end(hostport) && *(p + 1) != ':') {
|
|
|
|
return catch_all;
|
|
|
|
}
|
|
|
|
host.assign(std::begin(hostport), p + 1);
|
|
|
|
} else {
|
|
|
|
auto p = std::find(std::begin(hostport), std::end(hostport), ':');
|
|
|
|
if (p == std::begin(hostport)) {
|
|
|
|
return catch_all;
|
|
|
|
}
|
|
|
|
host.assign(std::begin(hostport), p);
|
|
|
|
}
|
|
|
|
|
|
|
|
util::inp_strlower(host);
|
2015-09-25 19:38:45 +02:00
|
|
|
return match_downstream_addr_group_host(router, host, path, pathlen, groups,
|
2015-07-11 09:42:23 +02:00
|
|
|
catch_all);
|
2015-07-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
|
2012-06-04 16:48:31 +02:00
|
|
|
} // namespace shrpx
|