diff --git a/src/shrpx.cc b/src/shrpx.cc index b8c67ccf..f561b583 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -86,6 +86,7 @@ #include "app_helper.h" #include "ssl.h" #include "template.h" +#include "allocator.h" extern char **environ; @@ -151,7 +152,7 @@ StartupConfig suconfig; struct InheritedAddr { // IP address if TCP socket. Otherwise, UNIX domain socket path. - ImmutableString host; + StringRef host; uint16_t port; // true if UNIX domain socket path bool host_unix; @@ -574,7 +575,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr, << (faddr.tls ? ", tls" : ""); (*found).used = true; faddr.fd = (*found).fd; - faddr.hostport = ImmutableString::from_lit("localhost"); + faddr.hostport = StringRef::from_lit("localhost"); return 0; } @@ -639,7 +640,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr, << (faddr.tls ? ", tls" : ""); faddr.fd = fd; - faddr.hostport = ImmutableString::from_lit("localhost"); + faddr.hostport = StringRef::from_lit("localhost"); return 0; } @@ -791,8 +792,8 @@ int create_tcp_server_socket(UpstreamAddr &faddr, } faddr.fd = fd; - faddr.hostport = ImmutableString{ - util::make_http_hostport(StringRef{host.data()}, faddr.port)}; + faddr.hostport = util::make_http_hostport(mod_config()->balloc, + StringRef{host.data()}, faddr.port); LOG(NOTICE) << "Listening on " << faddr.hostport << (faddr.tls ? ", tls" : ""); @@ -805,8 +806,7 @@ namespace { // Returns array of InheritedAddr constructed from |config|. This // function is intended to be used when reloading configuration, and // |config| is usually a current configuration. -std::vector -get_inherited_addr_from_config(const Config *config) { +std::vector get_inherited_addr_from_config(Config *config) { int rv; auto &listenerconf = config->conn.listener; @@ -856,7 +856,7 @@ get_inherited_addr_from_config(const Config *config) { continue; } - iaddr.host = ImmutableString{host.data()}; + iaddr.host = make_string_ref(config->balloc, StringRef{host.data()}); } return iaddrs; @@ -867,7 +867,7 @@ namespace { // Returns array of InheritedAddr constructed from environment // variables. This function handles the old environment variable // names used in 1.7.0 or earlier. -std::vector get_inherited_addr_from_env() { +std::vector get_inherited_addr_from_env(Config *config) { int rv; std::vector iaddrs; @@ -888,15 +888,13 @@ std::vector get_inherited_addr_from_env() { } } } else { - auto pathenv = getenv(ENV_UNIX_PATH.c_str()); - auto fdenv = getenv(ENV_UNIX_FD.c_str()); - if (pathenv && fdenv) { + if (getenv(ENV_UNIX_PATH.c_str()) && getenv(ENV_UNIX_FD.c_str())) { auto name = ENV_ACCEPT_PREFIX.str(); name += '1'; std::string value = "unix,"; - value += fdenv; + value += getenv(ENV_UNIX_FD.c_str()); value += ','; - value += pathenv; + value += getenv(ENV_UNIX_PATH.c_str()); setenv(name.c_str(), value.c_str(), 0); } } @@ -948,7 +946,7 @@ std::vector get_inherited_addr_from_env() { } InheritedAddr addr{}; - addr.host = ImmutableString{path}; + addr.host = make_string_ref(config->balloc, StringRef{path}); addr.host_unix = true; addr.fd = static_cast(fd); iaddrs.push_back(std::move(addr)); @@ -1002,7 +1000,7 @@ std::vector get_inherited_addr_from_env() { } InheritedAddr addr{}; - addr.host = ImmutableString{host.data()}; + addr.host = make_string_ref(config->balloc, StringRef{host.data()}); addr.port = static_cast(port); addr.fd = static_cast(fd); iaddrs.push_back(std::move(addr)); @@ -1209,7 +1207,7 @@ int event_loop() { redirect_stderr_to_errorlog(); } - auto iaddrs = get_inherited_addr_from_env(); + auto iaddrs = get_inherited_addr_from_env(mod_config()); if (create_acceptor_socket(mod_config(), iaddrs) != 0) { return -1; @@ -1274,7 +1272,7 @@ constexpr auto DEFAULT_ACCESSLOG_FORMAT = StringRef::from_lit( namespace { void fill_default_config(Config *config) { config->num_worker = 1; - config->conf_path = ImmutableString::from_lit("/etc/nghttpx/nghttpx.conf"); + config->conf_path = StringRef::from_lit("/etc/nghttpx/nghttpx.conf"); config->pid = getpid(); if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) { @@ -1306,7 +1304,7 @@ void fill_default_config(Config *config) { // ocsp update interval = 14400 secs = 4 hours, borrowed from h2o ocspconf.update_interval = 4_h; ocspconf.fetch_ocsp_response_file = - ImmutableString::from_lit(PKGDATADIR "/fetch-ocsp-response"); + StringRef::from_lit(PKGDATADIR "/fetch-ocsp-response"); } { @@ -1319,7 +1317,7 @@ void fill_default_config(Config *config) { auto &httpconf = config->http; httpconf.server_name = - ImmutableString::from_lit("nghttpx nghttp2/" NGHTTP2_VERSION); + StringRef::from_lit("nghttpx nghttp2/" NGHTTP2_VERSION); httpconf.no_host_rewrite = true; httpconf.request_header_field_buffer = 64_k; httpconf.max_request_header_fields = 100; @@ -1387,10 +1385,11 @@ void fill_default_config(Config *config) { auto &loggingconf = config->logging; { auto &accessconf = loggingconf.access; - accessconf.format = parse_log_format(DEFAULT_ACCESSLOG_FORMAT); + accessconf.format = + parse_log_format(config->balloc, DEFAULT_ACCESSLOG_FORMAT); auto &errorconf = loggingconf.error; - errorconf.file = ImmutableString::from_lit("/dev/stderr"); + errorconf.file = StringRef::from_lit("/dev/stderr"); } loggingconf.syslog_facility = LOG_DAEMON; @@ -2466,7 +2465,7 @@ int process_options(Config *config, if (listenerconf.addrs.empty()) { UpstreamAddr addr{}; - addr.host = ImmutableString::from_lit("*"); + addr.host = StringRef::from_lit("*"); addr.port = 3000; addr.tls = true; addr.family = AF_INET; @@ -2567,12 +2566,14 @@ int process_options(Config *config, if (fwdconf.by_node_type == FORWARDED_NODE_OBFUSCATED && fwdconf.by_obfuscated.empty()) { - std::mt19937 gen(rd()); - auto &dst = fwdconf.by_obfuscated; - dst.resize(1 + SHRPX_OBFUSCATED_NODE_LENGTH); - auto p = std::begin(dst); + // 2 for '_' and terminal NULL + auto iov = make_byte_ref(config->balloc, SHRPX_OBFUSCATED_NODE_LENGTH + 2); + auto p = iov.base; *p++ = '_'; - util::random_alpha_digit(p, std::end(dst), gen); + std::mt19937 gen(rd()); + p = util::random_alpha_digit(p, p + SHRPX_OBFUSCATED_NODE_LENGTH, gen); + *p = '\0'; + fwdconf.by_obfuscated = StringRef{iov.base, p}; } if (config->http2.upstream.debug.frame_debug) { @@ -2618,12 +2619,13 @@ void reload_config(WorkerProcess *wp) { LOG(NOTICE) << "Reloading configuration"; - auto cur_config = get_config(); + auto cur_config = mod_config(); auto new_config = make_unique(); fill_default_config(new_config.get()); - new_config->conf_path = cur_config->conf_path; + new_config->conf_path = + make_string_ref(new_config->balloc, cur_config->conf_path); // daemon option is ignored here. new_config->daemon = cur_config->daemon; // loop is reused, and ev_loop_flags gets ignored @@ -3029,7 +3031,8 @@ int main(int argc, char **argv) { break; case 12: // --conf - mod_config()->conf_path = ImmutableString{optarg}; + mod_config()->conf_path = + make_string_ref(mod_config()->balloc, StringRef{optarg}); break; case 14: // --syslog-facility diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 9b62f47f..1948faad 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -1504,10 +1504,10 @@ StringRef ClientHandler::get_forwarded_by() const { auto &fwdconf = get_config()->http.forwarded; if (fwdconf.by_node_type == FORWARDED_NODE_OBFUSCATED) { - return StringRef(fwdconf.by_obfuscated); + return fwdconf.by_obfuscated; } - return StringRef{faddr_->hostport}; + return faddr_->hostport; } StringRef ClientHandler::get_forwarded_for() const { return forwarded_for_; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index dc1de8ba..3e62a5b1 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -490,7 +490,8 @@ bool var_token(char c) { } } // namespace -std::vector parse_log_format(const StringRef &optarg) { +std::vector parse_log_format(BlockAllocator &balloc, + const StringRef &optarg) { auto literal_start = std::begin(optarg); auto p = literal_start; auto eop = std::end(optarg); @@ -553,8 +554,9 @@ std::vector parse_log_format(const StringRef &optarg) { } if (literal_start < var_start) { - res.emplace_back(SHRPX_LOGF_LITERAL, - ImmutableString(literal_start, var_start)); + res.emplace_back( + SHRPX_LOGF_LITERAL, + make_string_ref(balloc, StringRef{literal_start, var_start})); } literal_start = p; @@ -564,18 +566,24 @@ std::vector parse_log_format(const StringRef &optarg) { continue; } - auto name = std::string(value, var_name + var_namelen); - for (auto &c : name) { - if (c == '_') { - c = '-'; + { + auto iov = make_byte_ref( + balloc, std::distance(value, var_name + var_namelen) + 1); + auto p = iov.base; + p = std::copy(value, var_name + var_namelen, p); + for (auto cp = iov.base; cp != p; ++cp) { + if (*cp == '_') { + *cp = '-'; + } } + *p = '\0'; + res.emplace_back(type, StringRef{iov.base, p}); } - - res.emplace_back(type, ImmutableString(name)); } if (literal_start != eop) { - res.emplace_back(SHRPX_LOGF_LITERAL, ImmutableString(literal_start, eop)); + res.emplace_back(SHRPX_LOGF_LITERAL, + make_string_ref(balloc, StringRef{literal_start, eop})); } return res; @@ -1877,7 +1885,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) { auto path = std::begin(optarg) + SHRPX_UNIX_PATH_PREFIX.size(); - addr.host = ImmutableString{path, addr_end}; + addr.host = make_string_ref(config->balloc, StringRef{path, addr_end}); addr.host_unix = true; listenerconf.addrs.push_back(std::move(addr)); @@ -1890,7 +1898,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, return -1; } - addr.host = ImmutableString(host); + addr.host = make_string_ref(config->balloc, StringRef{host}); addr.port = port; if (util::numeric_host(host, AF_INET)) { @@ -1987,8 +1995,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_STREAM_WRITE_TIMEOUT: return parse_duration(&config->http2.timeout.stream_write, opt, optarg); case SHRPX_OPTID_ACCESSLOG_FILE: - config->logging.access.file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->logging.access.file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_ACCESSLOG_SYSLOG: @@ -1996,12 +2003,11 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_ACCESSLOG_FORMAT: - config->logging.access.format = parse_log_format(optarg); + config->logging.access.format = parse_log_format(config->balloc, optarg); return 0; case SHRPX_OPTID_ERRORLOG_FILE: - config->logging.error.file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->logging.error.file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_ERRORLOG_SYSLOG: @@ -2105,11 +2111,11 @@ int parse_config(Config *config, int optid, const StringRef &opt, LOG(WARN) << opt << ": deprecated. Use sni keyword in --backend option. " "For now, all sni values of all backends are " "overridden by the given value " << optarg; - config->tls.backend_sni_name = optarg.str(); + config->tls.backend_sni_name = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_PID_FILE: - config->pid_file = ImmutableString{std::begin(optarg), std::end(optarg)}; + config->pid_file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_USER: { @@ -2119,15 +2125,14 @@ int parse_config(Config *config, int optid, const StringRef &opt, << strerror(errno); return -1; } - config->user = ImmutableString{pwd->pw_name}; + config->user = make_string_ref(config->balloc, StringRef{pwd->pw_name}); config->uid = pwd->pw_uid; config->gid = pwd->pw_gid; return 0; } case SHRPX_OPTID_PRIVATE_KEY_FILE: - config->tls.private_key_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.private_key_file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE: { @@ -2136,18 +2141,17 @@ int parse_config(Config *config, int optid, const StringRef &opt, LOG(ERROR) << opt << ": Couldn't read key file's passwd from " << optarg; return -1; } - config->tls.private_key_passwd = ImmutableString{passwd}; + config->tls.private_key_passwd = + make_string_ref(config->balloc, StringRef{passwd}); return 0; } case SHRPX_OPTID_CERTIFICATE_FILE: - config->tls.cert_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.cert_file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_DH_PARAM_FILE: - config->tls.dh_param_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.dh_param_file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_SUBCERT: { @@ -2203,7 +2207,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; } case SHRPX_OPTID_CIPHERS: - config->tls.ciphers = ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.ciphers = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_CLIENT: @@ -2215,7 +2219,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_CACERT: - config->tls.cacert = ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.cacert = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_BACKEND_IPV4: @@ -2305,28 +2309,26 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_VERIFY_CLIENT_CACERT: - config->tls.client_verify.cacert = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.client_verify.cacert = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE: config->tls.client.private_key_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_CLIENT_CERT_FILE: - config->tls.client.cert_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->tls.client.cert_file = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER: config->http2.upstream.debug.dump.request_header_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER: config->http2.upstream.debug.dump.response_header_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING: @@ -2493,7 +2495,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE: config->tls.ocsp.fetch_ocsp_response_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_OCSP_UPDATE_INTERVAL: @@ -2571,14 +2573,14 @@ int parse_config(Config *config, int optid, const StringRef &opt, switch (optid) { case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: { auto &memcachedconf = config->tls.session_cache.memcached; - memcachedconf.host = ImmutableString{host}; + memcachedconf.host = make_string_ref(config->balloc, StringRef{host}); memcachedconf.port = port; memcachedconf.tls = params.tls; break; } case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED: { auto &memcachedconf = config->tls.ticket.memcached; - memcachedconf.host = ImmutableString{host}; + memcachedconf.host = make_string_ref(config->balloc, StringRef{host}); memcachedconf.port = port; memcachedconf.tls = params.tls; break; @@ -2621,7 +2623,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_MRUBY_FILE: #ifdef HAVE_MRUBY - config->mruby_file = ImmutableString{std::begin(optarg), std::end(optarg)}; + config->mruby_file = make_string_ref(config->balloc, optarg); #else // !HAVE_MRUBY LOG(WARN) << opt << ": ignored because mruby support is disabled at build time."; @@ -2680,9 +2682,9 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_FORWARDED_BY: fwdconf.by_node_type = static_cast(type); if (optarg[0] == '_') { - fwdconf.by_obfuscated = optarg.str(); + fwdconf.by_obfuscated = make_string_ref(config->balloc, optarg); } else { - fwdconf.by_obfuscated = ""; + fwdconf.by_obfuscated = StringRef::from_lit(""); } break; case SHRPX_OPTID_FORWARDED_FOR: @@ -2707,12 +2709,12 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE: config->tls.session_cache.memcached.cert_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_PRIVATE_KEY_FILE: config->tls.session_cache.memcached.private_key_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_TLS: @@ -2721,12 +2723,12 @@ int parse_config(Config *config, int optid, const StringRef &opt, return 0; case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_CERT_FILE: config->tls.ticket.memcached.cert_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE: config->tls.ticket.memcached.private_key_file = - ImmutableString{std::begin(optarg), std::end(optarg)}; + make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_ADDRESS_FAMILY: @@ -2766,8 +2768,7 @@ int parse_config(Config *config, int optid, const StringRef &opt, return parse_duration(&config->conn.downstream->timeout.max_backoff, opt, optarg); case SHRPX_OPTID_SERVER_NAME: - config->http.server_name = - ImmutableString{std::begin(optarg), std::end(optarg)}; + config->http.server_name = make_string_ref(config->balloc, optarg); return 0; case SHRPX_OPTID_NO_SERVER_REWRITE: diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 8387dfe7..a633b4fd 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -353,12 +353,13 @@ enum UpstreamAltMode { struct UpstreamAddr { // The frontend address (e.g., FQDN, hostname, IP address). If - // |host_unix| is true, this is UNIX domain socket path. - ImmutableString host; + // |host_unix| is true, this is UNIX domain socket path. This must + // be NULL terminated string. + StringRef host; // For TCP socket, this is :. For IPv6 address, // address is surrounded by square brackets. If socket is UNIX // domain socket, this is "localhost". - ImmutableString hostport; + StringRef hostport; // frontend port. 0 if |host_unix| is true. uint16_t port; // For TCP socket, this is either AF_INET or AF_INET6. For UNIX @@ -453,10 +454,10 @@ struct TLSConfig { uint16_t port; // Hostname of memcached server. This is also used as SNI field // if TLS is enabled. - ImmutableString host; + StringRef host; // Client private key and certificate for authentication - ImmutableString private_key_file; - ImmutableString cert_file; + StringRef private_key_file; + StringRef cert_file; ev_tstamp interval; // Maximum number of retries when getting TLS ticket key from // mamcached, due to network error. @@ -482,10 +483,10 @@ struct TLSConfig { uint16_t port; // Hostname of memcached server. This is also used as SNI field // if TLS is enabled. - ImmutableString host; + StringRef host; // Client private key and certificate for authentication - ImmutableString private_key_file; - ImmutableString cert_file; + StringRef private_key_file; + StringRef cert_file; // Address family of memcached connection. One of either // AF_INET, AF_INET6 or AF_UNSPEC. int family; @@ -502,7 +503,7 @@ struct TLSConfig { // OCSP realted configurations struct { ev_tstamp update_interval; - ImmutableString fetch_ocsp_response_file; + StringRef fetch_ocsp_response_file; bool disabled; } ocsp; @@ -510,14 +511,14 @@ struct TLSConfig { struct { // Path to file containing CA certificate solely used for client // certificate validation - ImmutableString cacert; + StringRef cacert; bool enabled; } client_verify; // Client private key and certificate used in backend connections. struct { - ImmutableString private_key_file; - ImmutableString cert_file; + StringRef private_key_file; + StringRef cert_file; } client; // The list of (private key file, certificate file) pair @@ -532,14 +533,14 @@ struct TLSConfig { // Bit mask to disable SSL/TLS protocol versions. This will be // passed to SSL_CTX_set_options(). long int tls_proto_mask; - std::string backend_sni_name; + StringRef backend_sni_name; std::chrono::seconds session_timeout; - ImmutableString private_key_file; - ImmutableString private_key_passwd; - ImmutableString cert_file; - ImmutableString dh_param_file; - ImmutableString ciphers; - ImmutableString cacert; + StringRef private_key_file; + StringRef private_key_passwd; + StringRef cert_file; + StringRef dh_param_file; + StringRef ciphers; + StringRef cacert; bool insecure; bool no_http2_cipher_black_list; }; @@ -557,7 +558,7 @@ struct HttpConfig { // obfuscated value used in "by" parameter of Forwarded header // field. This is only used when user defined static obfuscated // string is provided. - std::string by_obfuscated; + StringRef by_obfuscated; // bitwise-OR of one or more of shrpx_forwarded_param values. uint32_t params; // type of value recorded in "by" parameter of Forwarded header @@ -576,7 +577,7 @@ struct HttpConfig { std::vector error_pages; Headers add_request_headers; Headers add_response_headers; - ImmutableString server_name; + StringRef server_name; size_t request_header_field_buffer; size_t max_request_header_fields; size_t response_header_field_buffer; @@ -591,8 +592,8 @@ struct Http2Config { struct { struct { struct { - ImmutableString request_header_file; - ImmutableString response_header_file; + StringRef request_header_file; + StringRef response_header_file; FILE *request_header; FILE *response_header; } dump; @@ -635,12 +636,12 @@ struct Http2Config { struct LoggingConfig { struct { std::vector format; - ImmutableString file; + StringRef file; // Send accesslog to syslog, ignoring accesslog_file. bool syslog; } access; struct { - ImmutableString file; + StringRef file; // Send errorlog to syslog, ignoring errorlog_file. bool syslog; } error; @@ -754,7 +755,25 @@ struct APIConfig { }; struct Config { - Config() = default; + Config() + : balloc(4096, 4096), + downstream_http_proxy{}, + http{}, + http2{}, + tls{}, + logging{}, + conn{}, + api{}, + num_worker{0}, + padding{0}, + rlimit_nofile{0}, + uid{0}, + gid{0}, + pid{0}, + verbose{false}, + daemon{false}, + http2_proxy{false}, + ev_loop_flags{0} {} ~Config(); Config(Config &&) = delete; @@ -762,6 +781,7 @@ struct Config { Config &operator=(Config &&) = delete; Config &operator=(const Config &&) = delete; + BlockAllocator balloc; HttpProxy downstream_http_proxy; HttpConfig http; Http2Config http2; @@ -769,10 +789,10 @@ struct Config { LoggingConfig logging; ConnectionConfig conn; APIConfig api; - ImmutableString pid_file; - ImmutableString conf_path; - ImmutableString user; - ImmutableString mruby_file; + StringRef pid_file; + StringRef conf_path; + StringRef user; + StringRef mruby_file; size_t num_worker; size_t padding; size_t rlimit_nofile; @@ -969,7 +989,8 @@ int load_config(Config *config, const char *filename, // allowed. This function returns pair of NAME and VALUE. Headers::value_type parse_header(const StringRef &optarg); -std::vector parse_log_format(const StringRef &optarg); +std::vector parse_log_format(BlockAllocator &balloc, + const StringRef &optarg); // Returns string for syslog |facility|. StringRef str_syslog_facility(int facility); diff --git a/src/shrpx_config_test.cc b/src/shrpx_config_test.cc index 5317fe00..224535d9 100644 --- a/src/shrpx_config_test.cc +++ b/src/shrpx_config_test.cc @@ -67,10 +67,13 @@ void test_shrpx_config_parse_header(void) { } void test_shrpx_config_parse_log_format(void) { - auto res = parse_log_format(StringRef::from_lit( - R"($remote_addr - $remote_user [$time_local] )" - R"("$request" $status $body_bytes_sent )" - R"("${http_referer}" $http_host "$http_user_agent")")); + BlockAllocator balloc(4096, 4096); + + auto res = parse_log_format( + balloc, StringRef::from_lit( + R"($remote_addr - $remote_user [$time_local] )" + R"("$request" $status $body_bytes_sent )" + R"("${http_referer}" $http_host "$http_user_agent")")); CU_ASSERT(16 == res.size()); CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[0].type); @@ -115,35 +118,35 @@ void test_shrpx_config_parse_log_format(void) { CU_ASSERT(SHRPX_LOGF_LITERAL == res[15].type); CU_ASSERT("\"" == res[15].value); - res = parse_log_format(StringRef::from_lit("$")); + res = parse_log_format(balloc, StringRef::from_lit("$")); CU_ASSERT(1 == res.size()); CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type); CU_ASSERT("$" == res[0].value); - res = parse_log_format(StringRef::from_lit("${")); + res = parse_log_format(balloc, StringRef::from_lit("${")); CU_ASSERT(1 == res.size()); CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type); CU_ASSERT("${" == res[0].value); - res = parse_log_format(StringRef::from_lit("${a")); + res = parse_log_format(balloc, StringRef::from_lit("${a")); CU_ASSERT(1 == res.size()); CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type); CU_ASSERT("${a" == res[0].value); - res = parse_log_format(StringRef::from_lit("${a ")); + res = parse_log_format(balloc, StringRef::from_lit("${a ")); CU_ASSERT(1 == res.size()); CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type); CU_ASSERT("${a " == res[0].value); - res = parse_log_format(StringRef::from_lit("$$remote_addr")); + res = parse_log_format(balloc, StringRef::from_lit("$$remote_addr")); CU_ASSERT(2 == res.size()); diff --git a/src/shrpx_connection_handler.cc b/src/shrpx_connection_handler.cc index 3199f6e3..5f8e49a6 100644 --- a/src/shrpx_connection_handler.cc +++ b/src/shrpx_connection_handler.cc @@ -224,8 +224,8 @@ int ConnectionHandler::create_single_worker() { #ifdef HAVE_NEVERBLEED nb_.get(), #endif // HAVE_NEVERBLEED - StringRef{tlsconf.cacert}, StringRef{memcachedconf.cert_file}, - StringRef{memcachedconf.private_key_file}, nullptr); + tlsconf.cacert, memcachedconf.cert_file, memcachedconf.private_key_file, + nullptr); all_ssl_ctx_.push_back(session_cache_ssl_ctx); } @@ -280,8 +280,8 @@ int ConnectionHandler::create_worker_thread(size_t num) { #ifdef HAVE_NEVERBLEED nb_.get(), #endif // HAVE_NEVERBLEED - StringRef{tlsconf.cacert}, StringRef{memcachedconf.cert_file}, - StringRef{memcachedconf.private_key_file}, nullptr); + tlsconf.cacert, memcachedconf.cert_file, + memcachedconf.private_key_file, nullptr); all_ssl_ctx_.push_back(session_cache_ssl_ctx); } auto worker = make_unique( @@ -835,8 +835,8 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() { #ifdef HAVE_NEVERBLEED nb_.get(), #endif // HAVE_NEVERBLEED - StringRef{tlsconf.cacert}, StringRef{memcachedconf.cert_file}, - StringRef{memcachedconf.private_key_file}, nullptr); + tlsconf.cacert, memcachedconf.cert_file, memcachedconf.private_key_file, + nullptr); all_ssl_ctx_.push_back(ssl_ctx); diff --git a/src/shrpx_http.cc b/src/shrpx_http.cc index e54040bf..77a641e3 100644 --- a/src/shrpx_http.cc +++ b/src/shrpx_http.cc @@ -46,12 +46,11 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) { } auto status_string = http2::get_status_string(balloc, http_status); - const auto &server_name = httpconf.server_name; return concat_string_ref( balloc, StringRef::from_lit(R"()"), status_string, StringRef::from_lit("

"), status_string, - StringRef::from_lit("