nghttpx: Add --npn-list option

This commit is contained in:
Tatsuhiro Tsujikawa 2013-09-23 20:55:39 +09:00
parent e5e1e9b76e
commit ab39ae849f
4 changed files with 71 additions and 10 deletions

View File

@ -318,6 +318,14 @@ bool conf_exists(const char *path)
} }
} // namespace } // 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 { namespace {
void fill_default_config() void fill_default_config()
{ {
@ -405,6 +413,7 @@ void fill_default_config()
mod_config()->read_burst = 4*1024*1024; mod_config()->read_burst = 4*1024*1024;
mod_config()->write_rate = 0; mod_config()->write_rate = 0;
mod_config()->write_burst = 0; mod_config()->write_burst = 0;
mod_config()->npn_list = nullptr;
} }
} // namespace } // namespace
@ -573,7 +582,14 @@ void print_help(std::ostream& out)
<< " --dh-param-file=<PATH>\n" << " --dh-param-file=<PATH>\n"
<< " Path to file that contains DH parameters in\n" << " Path to file that contains DH parameters in\n"
<< " PEM format. Without this option, DHE cipher\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" << "\n"
<< " HTTP/2.0 and SPDY:\n" << " HTTP/2.0 and SPDY:\n"
<< " -c, --spdy-max-concurrent-streams=<NUM>\n" << " -c, --spdy-max-concurrent-streams=<NUM>\n"
@ -710,6 +726,7 @@ int main(int argc, char **argv)
{"read-burst", required_argument, &flag, 35}, {"read-burst", required_argument, &flag, 35},
{"write-rate", required_argument, &flag, 36}, {"write-rate", required_argument, &flag, 36},
{"write-burst", required_argument, &flag, 37}, {"write-burst", required_argument, &flag, 37},
{"npn-list", required_argument, &flag, 38},
{nullptr, 0, nullptr, 0 } {nullptr, 0, nullptr, 0 }
}; };
int option_index = 0; int option_index = 0;
@ -909,6 +926,10 @@ int main(int argc, char **argv)
// --write-burst // --write-burst
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_WRITE_BURST, optarg)); cmdcfgs.push_back(std::make_pair(SHRPX_OPT_WRITE_BURST, optarg));
break; break;
case 38:
// --npn-list
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_NPN_LIST, optarg));
break;
default: default:
break; 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) { if(get_config()->cert_file && get_config()->private_key_file) {
mod_config()->default_ssl_ctx = mod_config()->default_ssl_ctx =
ssl::create_ssl_context(get_config()->private_key_file, ssl::create_ssl_context(get_config()->private_key_file,

View 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_READ_BURST[] = "read-burst";
const char SHRPX_OPT_WRITE_RATE[] = "write-rate"; const char SHRPX_OPT_WRITE_RATE[] = "write-rate";
const char SHRPX_OPT_WRITE_BURST[] = "write-burst"; const char SHRPX_OPT_WRITE_BURST[] = "write-burst";
const char SHRPX_OPT_NPN_LIST[] = "npn-list";
namespace { namespace {
Config *config = 0; Config *config = 0;
@ -194,6 +195,31 @@ void set_config_str(char **destp, const char *val)
*destp = strdup(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) int parse_config(const char *opt, const char *optarg)
{ {
char host[NI_MAXHOST]; 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); mod_config()->write_rate = strtoul(optarg, nullptr, 10);
} else if(util::strieq(opt, SHRPX_OPT_WRITE_BURST)) { } else if(util::strieq(opt, SHRPX_OPT_WRITE_BURST)) {
mod_config()->write_burst = strtoul(optarg, nullptr, 10); 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")) { } else if(util::strieq(opt, "conf")) {
LOG(WARNING) << "conf is ignored"; LOG(WARNING) << "conf is ignored";
} else { } else {

View File

@ -90,6 +90,7 @@ extern const char SHRPX_OPT_READ_RATE[];
extern const char SHRPX_OPT_READ_BURST[]; extern const char SHRPX_OPT_READ_BURST[];
extern const char SHRPX_OPT_WRITE_RATE[]; extern const char SHRPX_OPT_WRITE_RATE[];
extern const char SHRPX_OPT_WRITE_BURST[]; extern const char SHRPX_OPT_WRITE_BURST[];
extern const char SHRPX_OPT_NPN_LIST[];
union sockaddr_union { union sockaddr_union {
sockaddr sa; sockaddr sa;
@ -178,6 +179,11 @@ struct Config {
size_t read_burst; size_t read_burst;
size_t write_rate; size_t write_rate;
size_t write_burst; 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(); const Config* get_config();
@ -197,6 +203,14 @@ int load_config(const char *filename);
// Read passwd from |filename| // Read passwd from |filename|
std::string read_passwd_from_file(const char *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 // Copies NULL-terminated string |val| to |*destp|. If |*destp| is not
// NULL, it is freed before copying. // NULL, it is freed before copying.
void set_config_str(char **destp, const char *val); void set_config_str(char **destp, const char *val);

View File

@ -80,7 +80,7 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
} // namespace } // namespace
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; unsigned char *ptr = out;
size_t listlen = 0; 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); SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
const char *protos[] = { NGHTTP2_PROTO_VERSION_ID, get_config()->npn_list_len);
#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]));
next_proto.first = proto_list; next_proto.first = proto_list;
next_proto.second = proto_list_len; next_proto.second = proto_list_len;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto); SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);