Commit ab39ae84 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Add --npn-list option

parent e5e1e9b7
......@@ -318,6 +318,14 @@ bool conf_exists(const char *path)
}
} // namespace
namespace {
const char *DEFAULT_NPN_LIST = NGHTTP2_PROTO_VERSION_ID ","
#ifdef HAVE_SPDYLAY
"spdy/3,spdy/2,"
#endif // HAVE_SPDYLAY
"http/1.1";
} // namespace
namespace {
void fill_default_config()
{
......@@ -405,6 +413,7 @@ void fill_default_config()
mod_config()->read_burst = 4*1024*1024;
mod_config()->write_rate = 0;
mod_config()->write_burst = 0;
mod_config()->npn_list = nullptr;
}
} // namespace
......@@ -573,7 +582,14 @@ void print_help(std::ostream& out)
<< " --dh-param-file=<PATH>\n"
<< " Path to file that contains DH parameters in\n"
<< " PEM format. Without this option, DHE cipher\n"
<< " suites are not available."
<< " suites are not available.\n"
<< " --npn-list=<LIST> Comma delimited list of NPN protocol sorted\n"
<< " in the order of preference. That means\n"
<< " most desirable protocol comes first.\n"
<< " The parameter must be delimited by a single\n"
<< " comma only and any white spaces are treated\n"
<< " as a part of protocol string.\n"
<< " Default: " << DEFAULT_NPN_LIST << "\n"
<< "\n"
<< " HTTP/2.0 and SPDY:\n"
<< " -c, --spdy-max-concurrent-streams=<NUM>\n"
......@@ -710,6 +726,7 @@ int main(int argc, char **argv)
{"read-burst", required_argument, &flag, 35},
{"write-rate", required_argument, &flag, 36},
{"write-burst", required_argument, &flag, 37},
{"npn-list", required_argument, &flag, 38},
{nullptr, 0, nullptr, 0 }
};
int option_index = 0;
......@@ -909,6 +926,10 @@ int main(int argc, char **argv)
// --write-burst
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_WRITE_BURST, optarg));
break;
case 38:
// --npn-list
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_NPN_LIST, optarg));
break;
default:
break;
}
......@@ -947,6 +968,10 @@ int main(int argc, char **argv)
}
}
if(!get_config()->npn_list) {
parse_config_npn_list(DEFAULT_NPN_LIST);
}
if(get_config()->cert_file && get_config()->private_key_file) {
mod_config()->default_ssl_ctx =
ssl::create_ssl_context(get_config()->private_key_file,
......
......@@ -99,6 +99,7 @@ const char SHRPX_OPT_READ_RATE[] = "read-rate";
const char SHRPX_OPT_READ_BURST[] = "read-burst";
const char SHRPX_OPT_WRITE_RATE[] = "write-rate";
const char SHRPX_OPT_WRITE_BURST[] = "write-burst";
const char SHRPX_OPT_NPN_LIST[] = "npn-list";
namespace {
Config *config = 0;
......@@ -194,6 +195,31 @@ void set_config_str(char **destp, const char *val)
*destp = strdup(val);
}
int parse_config_npn_list(const char *s)
{
delete [] mod_config()->npn_list;
size_t len = 1;
for(const char *first = s, *p = nullptr; (p = strchr(first, ','));
++len, first = p + 1);
auto list = new char*[len];
auto t = strdup(s);
auto first = t;
len = 0;
for(;;) {
auto p = strchr(first, ',');
if(p == nullptr) {
break;
}
list[len++] = first;
*p = '\0';
first = p + 1;
}
list[len++] = first;
mod_config()->npn_list = list;
mod_config()->npn_list_len = len;
return 0;
}
int parse_config(const char *opt, const char *optarg)
{
char host[NI_MAXHOST];
......@@ -385,6 +411,8 @@ int parse_config(const char *opt, const char *optarg)
mod_config()->write_rate = strtoul(optarg, nullptr, 10);
} else if(util::strieq(opt, SHRPX_OPT_WRITE_BURST)) {
mod_config()->write_burst = strtoul(optarg, nullptr, 10);
} else if(util::strieq(opt, SHRPX_OPT_NPN_LIST)) {
parse_config_npn_list(optarg);
} else if(util::strieq(opt, "conf")) {
LOG(WARNING) << "conf is ignored";
} else {
......
......@@ -90,6 +90,7 @@ extern const char SHRPX_OPT_READ_RATE[];
extern const char SHRPX_OPT_READ_BURST[];
extern const char SHRPX_OPT_WRITE_RATE[];
extern const char SHRPX_OPT_WRITE_BURST[];
extern const char SHRPX_OPT_NPN_LIST[];
union sockaddr_union {
sockaddr sa;
......@@ -178,6 +179,11 @@ struct Config {
size_t read_burst;
size_t write_rate;
size_t write_burst;
// Comma delimited list of NPN protocol strings in the order of
// preference.
char **npn_list;
// The number of elements in npn_list
size_t npn_list_len;
};
const Config* get_config();
......@@ -197,6 +203,14 @@ int load_config(const char *filename);
// Read passwd from |filename|
std::string read_passwd_from_file(const char *filename);
// Parses NPN protocol strings in |s| and stores the protocols list in
// mod_config()->npn_list and assigns the number of elements in
// mod_config()->npn_list_len. The |s| must be comma delimited list of
// protocol strings. The strings must be delimited by a single command
// and any white spaces around it are treated as a part of protocol
// strings. This function always succeeds and returns 0.
int parse_config_npn_list(const char *s);
// Copies NULL-terminated string |val| to |*destp|. If |*destp| is not
// NULL, it is freed before copying.
void set_config_str(char **destp, const char *val);
......
......@@ -80,7 +80,7 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
} // namespace
namespace {
size_t set_npn_prefs(unsigned char *out, const char **protos, size_t len)
size_t set_npn_prefs(unsigned char *out, char **protos, size_t len)
{
unsigned char *ptr = out;
size_t listlen = 0;
......@@ -220,14 +220,8 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
}
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
const char *protos[] = { NGHTTP2_PROTO_VERSION_ID,
#ifdef HAVE_SPDYLAY
"spdy/3", "spdy/2",
#endif // HAVE_SPDYLAY
"http/1.1" };
auto proto_list_len = set_npn_prefs(proto_list, protos,
sizeof(protos)/sizeof(protos[0]));
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
get_config()->npn_list_len);
next_proto.first = proto_list;
next_proto.second = proto_list_len;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment