nghttpx: Refactor backend proxy configuration
This commit is contained in:
parent
f5b4fd23da
commit
b12af8c410
|
@ -972,8 +972,6 @@ void fill_default_config() {
|
||||||
mod_config()->pid = getpid();
|
mod_config()->pid = getpid();
|
||||||
mod_config()->backend_ipv4 = false;
|
mod_config()->backend_ipv4 = false;
|
||||||
mod_config()->backend_ipv6 = false;
|
mod_config()->backend_ipv6 = false;
|
||||||
mod_config()->downstream_http_proxy_userinfo = nullptr;
|
|
||||||
mod_config()->downstream_http_proxy_host = nullptr;
|
|
||||||
mod_config()->downstream_http_proxy_port = 0;
|
mod_config()->downstream_http_proxy_port = 0;
|
||||||
mod_config()->read_rate = 0;
|
mod_config()->read_rate = 0;
|
||||||
mod_config()->read_burst = 0;
|
mod_config()->read_burst = 0;
|
||||||
|
@ -2572,13 +2570,12 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->downstream_http_proxy_host) {
|
auto &proxy = mod_config()->downstream_http_proxy;
|
||||||
|
if (!proxy.host.empty()) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "Resolving backend http proxy address";
|
LOG(INFO) << "Resolving backend http proxy address";
|
||||||
}
|
}
|
||||||
if (resolve_hostname(&mod_config()->downstream_http_proxy_addr,
|
if (resolve_hostname(&proxy.addr, proxy.host.c_str(), proxy.port,
|
||||||
get_config()->downstream_http_proxy_host.get(),
|
|
||||||
get_config()->downstream_http_proxy_port,
|
|
||||||
AF_UNSPEC) == -1) {
|
AF_UNSPEC) == -1) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1705,6 +1705,10 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
||||||
|
auto &proxy = mod_config()->downstream_http_proxy;
|
||||||
|
// Reset here so that multiple option occurrence does not merge
|
||||||
|
// the results.
|
||||||
|
proxy = {};
|
||||||
// parse URI and get hostname, port and optionally userinfo.
|
// parse URI and get hostname, port and optionally userinfo.
|
||||||
http_parser_url u{};
|
http_parser_url u{};
|
||||||
int rv = http_parser_parse_url(optarg, strlen(optarg), 0, &u);
|
int rv = http_parser_parse_url(optarg, strlen(optarg), 0, &u);
|
||||||
|
@ -1715,19 +1719,17 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
// Surprisingly, u.field_set & UF_USERINFO is nonzero even if
|
// Surprisingly, u.field_set & UF_USERINFO is nonzero even if
|
||||||
// userinfo component is empty string.
|
// userinfo component is empty string.
|
||||||
if (!val.empty()) {
|
if (!val.empty()) {
|
||||||
val = util::percent_decode(std::begin(val), std::end(val));
|
proxy.userinfo = util::percent_decode(std::begin(val), std::end(val));
|
||||||
mod_config()->downstream_http_proxy_userinfo = strcopy(val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (u.field_set & UF_HOST) {
|
if (u.field_set & UF_HOST) {
|
||||||
http2::copy_url_component(val, &u, UF_HOST, optarg);
|
http2::copy_url_component(proxy.host, &u, UF_HOST, optarg);
|
||||||
mod_config()->downstream_http_proxy_host = strcopy(val);
|
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << opt << ": no hostname specified";
|
LOG(ERROR) << opt << ": no hostname specified";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (u.field_set & UF_PORT) {
|
if (u.field_set & UF_PORT) {
|
||||||
mod_config()->downstream_http_proxy_port = u.port;
|
proxy.port = u.port;
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << opt << ": no port specified";
|
LOG(ERROR) << opt << ": no port specified";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -283,6 +283,15 @@ struct TicketKeys {
|
||||||
std::vector<TicketKey> keys;
|
std::vector<TicketKey> keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HttpProxy {
|
||||||
|
Address addr;
|
||||||
|
// host in http proxy URI
|
||||||
|
std::string host;
|
||||||
|
// userinfo in http proxy URI, not percent-encoded form
|
||||||
|
std::string userinfo;
|
||||||
|
uint16_t port;
|
||||||
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
// The list of (private key file, certificate file) pair
|
// The list of (private key file, certificate file) pair
|
||||||
std::vector<std::pair<std::string, std::string>> subcerts;
|
std::vector<std::pair<std::string, std::string>> subcerts;
|
||||||
|
@ -298,11 +307,10 @@ struct Config {
|
||||||
std::vector<std::string> npn_list;
|
std::vector<std::string> npn_list;
|
||||||
// list of supported SSL/TLS protocol strings.
|
// list of supported SSL/TLS protocol strings.
|
||||||
std::vector<std::string> tls_proto_list;
|
std::vector<std::string> tls_proto_list;
|
||||||
// binary form of http proxy host and port
|
|
||||||
Address downstream_http_proxy_addr;
|
|
||||||
Address session_cache_memcached_addr;
|
Address session_cache_memcached_addr;
|
||||||
Address tls_ticket_key_memcached_addr;
|
Address tls_ticket_key_memcached_addr;
|
||||||
Router router;
|
Router router;
|
||||||
|
HttpProxy downstream_http_proxy;
|
||||||
// obfuscated value used in "by" parameter of Forwarded header
|
// obfuscated value used in "by" parameter of Forwarded header
|
||||||
// field.
|
// field.
|
||||||
std::string forwarded_by_obfuscated;
|
std::string forwarded_by_obfuscated;
|
||||||
|
@ -335,10 +343,6 @@ struct Config {
|
||||||
std::unique_ptr<char[]> conf_path;
|
std::unique_ptr<char[]> conf_path;
|
||||||
std::unique_ptr<char[]> ciphers;
|
std::unique_ptr<char[]> ciphers;
|
||||||
std::unique_ptr<char[]> cacert;
|
std::unique_ptr<char[]> cacert;
|
||||||
// userinfo in http proxy URI, not percent-encoded form
|
|
||||||
std::unique_ptr<char[]> downstream_http_proxy_userinfo;
|
|
||||||
// host in http proxy URI
|
|
||||||
std::unique_ptr<char[]> downstream_http_proxy_host;
|
|
||||||
std::unique_ptr<char[]> http2_upstream_dump_request_header_file;
|
std::unique_ptr<char[]> http2_upstream_dump_request_header_file;
|
||||||
std::unique_ptr<char[]> http2_upstream_dump_response_header_file;
|
std::unique_ptr<char[]> http2_upstream_dump_response_header_file;
|
||||||
// Path to file containing CA certificate solely used for client
|
// Path to file containing CA certificate solely used for client
|
||||||
|
|
|
@ -271,27 +271,24 @@ int Http2Session::initiate_connection() {
|
||||||
|
|
||||||
auto &downstream_addr = addrs[addr_idx_];
|
auto &downstream_addr = addrs[addr_idx_];
|
||||||
|
|
||||||
if (get_config()->downstream_http_proxy_host && state_ == DISCONNECTED) {
|
const auto &proxy = get_config()->downstream_http_proxy;
|
||||||
|
if (!proxy.host.empty() && state_ == DISCONNECTED) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
SSLOG(INFO, this) << "Connecting to the proxy "
|
SSLOG(INFO, this) << "Connecting to the proxy " << proxy.host << ":"
|
||||||
<< get_config()->downstream_http_proxy_host.get() << ":"
|
<< proxy.port;
|
||||||
<< get_config()->downstream_http_proxy_port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conn_.fd = util::create_nonblock_socket(
|
conn_.fd = util::create_nonblock_socket(proxy.addr.su.storage.ss_family);
|
||||||
get_config()->downstream_http_proxy_addr.su.storage.ss_family);
|
|
||||||
|
|
||||||
if (conn_.fd == -1) {
|
if (conn_.fd == -1) {
|
||||||
connect_blocker_->on_failure();
|
connect_blocker_->on_failure();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = connect(conn_.fd, &get_config()->downstream_http_proxy_addr.su.sa,
|
rv = connect(conn_.fd, &proxy.addr.su.sa, proxy.addr.len);
|
||||||
get_config()->downstream_http_proxy_addr.len);
|
|
||||||
if (rv != 0 && errno != EINPROGRESS) {
|
if (rv != 0 && errno != EINPROGRESS) {
|
||||||
SSLOG(ERROR, this) << "Failed to connect to the proxy "
|
SSLOG(ERROR, this) << "Failed to connect to the proxy " << proxy.host
|
||||||
<< get_config()->downstream_http_proxy_host.get()
|
<< ":" << proxy.port;
|
||||||
<< ":" << get_config()->downstream_http_proxy_port;
|
|
||||||
connect_blocker_->on_failure();
|
connect_blocker_->on_failure();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -523,12 +520,10 @@ int Http2Session::downstream_connect_proxy() {
|
||||||
req += " HTTP/1.1\r\nHost: ";
|
req += " HTTP/1.1\r\nHost: ";
|
||||||
req.append(downstream_addr.host.c_str(), downstream_addr.host.size());
|
req.append(downstream_addr.host.c_str(), downstream_addr.host.size());
|
||||||
req += "\r\n";
|
req += "\r\n";
|
||||||
if (get_config()->downstream_http_proxy_userinfo) {
|
const auto &proxy = get_config()->downstream_http_proxy;
|
||||||
|
if (!proxy.userinfo.empty()) {
|
||||||
req += "Proxy-Authorization: Basic ";
|
req += "Proxy-Authorization: Basic ";
|
||||||
size_t len = strlen(get_config()->downstream_http_proxy_userinfo.get());
|
req += base64::encode(std::begin(proxy.userinfo), std::end(proxy.userinfo));
|
||||||
req += base64::encode(get_config()->downstream_http_proxy_userinfo.get(),
|
|
||||||
get_config()->downstream_http_proxy_userinfo.get() +
|
|
||||||
len);
|
|
||||||
req += "\r\n";
|
req += "\r\n";
|
||||||
}
|
}
|
||||||
req += "\r\n";
|
req += "\r\n";
|
||||||
|
|
Loading…
Reference in New Issue