Merge branch 'bcard-bcard/address-nghttp2-server'

This commit is contained in:
Tatsuhiro Tsujikawa 2015-02-27 00:04:58 +09:00
commit 30acb41561
6 changed files with 40 additions and 21 deletions

View File

@ -31,6 +31,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h>
#include <cassert> #include <cassert>
#include <set> #include <set>
@ -1412,6 +1413,7 @@ int start_listen(struct ev_loop *loop, Sessions *sessions,
addrinfo hints; addrinfo hints;
int r; int r;
bool ok = false; bool ok = false;
const char *addr = nullptr;
auto acceptor = std::make_shared<AcceptHandler>(sessions, config); auto acceptor = std::make_shared<AcceptHandler>(sessions, config);
auto service = util::utos(config->port); auto service = util::utos(config->port);
@ -1424,12 +1426,17 @@ int start_listen(struct ev_loop *loop, Sessions *sessions,
hints.ai_flags |= AI_ADDRCONFIG; hints.ai_flags |= AI_ADDRCONFIG;
#endif // AI_ADDRCONFIG #endif // AI_ADDRCONFIG
if (!config->address.empty()) {
addr = config->address.c_str();
}
addrinfo *res, *rp; addrinfo *res, *rp;
r = getaddrinfo(nullptr, service.c_str(), &hints, &res); r = getaddrinfo(addr, service.c_str(), &hints, &res);
if (r != 0) { if (r != 0) {
std::cerr << "getaddrinfo() failed: " << gai_strerror(r) << std::endl; std::cerr << "getaddrinfo() failed: " << gai_strerror(r) << std::endl;
return -1; return -1;
} }
for (rp = res; rp; rp = rp->ai_next) { for (rp = res; rp; rp = rp->ai_next) {
int fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); int fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (fd == -1) { if (fd == -1) {
@ -1455,8 +1462,9 @@ int start_listen(struct ev_loop *loop, Sessions *sessions,
new ListenEventHandler(sessions, fd, acceptor); new ListenEventHandler(sessions, fd, acceptor);
if (config->verbose) { if (config->verbose) {
std::cout << (rp->ai_family == AF_INET ? "IPv4" : "IPv6") std::string s = util::numeric_name(rp->ai_addr, rp->ai_addrlen);
<< ": listen on port " << config->port << std::endl; std::cout << (rp->ai_family == AF_INET ? "IPv4" : "IPv6") << ": listen "
<< s << ":" << config->port << std::endl;
} }
ok = true; ok = true;
continue; continue;

View File

@ -55,6 +55,7 @@ struct Config {
std::string private_key_file; std::string private_key_file;
std::string cert_file; std::string cert_file;
std::string dh_param_file; std::string dh_param_file;
std::string address;
ev_tstamp stream_read_timeout; ev_tstamp stream_read_timeout;
ev_tstamp stream_write_timeout; ev_tstamp stream_write_timeout;
nghttp2_option *session_option; nghttp2_option *session_option;

View File

@ -109,20 +109,6 @@ std::string strip_fragment(const char *raw_uri) {
} }
} // namespace } // namespace
namespace {
// Returns numeric address string of |addr|. If getnameinfo() is
// failed, "unknown" is returned.
std::string numeric_name(addrinfo *addr) {
std::array<char, NI_MAXHOST> host;
auto rv = getnameinfo(addr->ai_addr, addr->ai_addrlen, host.data(),
host.size(), nullptr, 0, NI_NUMERICHOST);
if (rv != 0) {
return "unknown";
}
return host.data();
}
} // namespace
Request::Request(const std::string &uri, const http_parser_url &u, Request::Request(const std::string &uri, const http_parser_url &u,
const nghttp2_data_provider *data_prd, int64_t data_length, const nghttp2_data_provider *data_prd, int64_t data_length,
const nghttp2_priority_spec &pri_spec, const nghttp2_priority_spec &pri_spec,
@ -686,13 +672,15 @@ int HttpClient::noop() { return 0; }
void HttpClient::on_connect_fail() { void HttpClient::on_connect_fail() {
if (state == ClientState::IDLE) { if (state == ClientState::IDLE) {
std::cerr << "[ERROR] Could not connect to the address " std::cerr << "[ERROR] Could not connect to the address "
<< numeric_name(cur_addr) << std::endl; << util::numeric_name(cur_addr->ai_addr, cur_addr->ai_addrlen)
<< std::endl;
} }
auto cur_state = state; auto cur_state = state;
disconnect(); disconnect();
if (cur_state == ClientState::IDLE) { if (cur_state == ClientState::IDLE) {
if (initiate_connection() == 0) { if (initiate_connection() == 0) {
std::cerr << "Trying next address " << numeric_name(cur_addr) std::cerr << "Trying next address "
<< util::numeric_name(cur_addr->ai_addr, cur_addr->ai_addrlen)
<< std::endl; << std::endl;
} }
} }

View File

@ -97,6 +97,9 @@ void print_help(std::ostream &out) {
<CERT> Set path to server's certificate. Required unless <CERT> Set path to server's certificate. Required unless
--no-tls is specified. --no-tls is specified.
Options: Options:
-a --address
The address to bind to. If not specified the default IP
address determined by getaddrinfo is used.
-D, --daemon -D, --daemon
Run in a background. If -D is used, the current working Run in a background. If -D is used, the current working
directory is changed to '/'. Therefore if this option directory is changed to '/'. Therefore if this option
@ -151,6 +154,7 @@ int main(int argc, char **argv) {
while (1) { while (1) {
static int flag = 0; static int flag = 0;
static option long_options[] = { static option long_options[] = {
{"address", required_argument, nullptr, 'a'},
{"daemon", no_argument, nullptr, 'D'}, {"daemon", no_argument, nullptr, 'D'},
{"htdocs", required_argument, nullptr, 'd'}, {"htdocs", required_argument, nullptr, 'd'},
{"help", no_argument, nullptr, 'h'}, {"help", no_argument, nullptr, 'h'},
@ -168,13 +172,16 @@ int main(int argc, char **argv) {
{"early-response", no_argument, &flag, 5}, {"early-response", no_argument, &flag, 5},
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
int option_index = 0; int option_index = 0;
int c = int c = getopt_long(argc, argv, "DVb:c:d:ehn:p:va:", long_options,
getopt_long(argc, argv, "DVb:c:d:ehn:p:v", long_options, &option_index); &option_index);
char *end; char *end;
if (c == -1) { if (c == -1) {
break; break;
} }
switch (c) { switch (c) {
case 'a':
config.address = optarg;
break;
case 'D': case 'D':
config.daemon = true; config.daemon = true;
break; break;

View File

@ -658,6 +658,16 @@ bool numeric_host(const char *hostname) {
return true; return true;
} }
std::string numeric_name(const struct sockaddr *sa, socklen_t salen) {
std::array<char, NI_MAXHOST> host;
auto rv = getnameinfo(sa, salen, host.data(), host.size(), nullptr, 0,
NI_NUMERICHOST);
if (rv != 0) {
return "unknown";
}
return host.data();
}
int reopen_log_file(const char *path) { int reopen_log_file(const char *path) {
#if defined(__ANDROID__) || defined(ANDROID) #if defined(__ANDROID__) || defined(ANDROID)
int fd; int fd;

View File

@ -29,6 +29,7 @@
#include <unistd.h> #include <unistd.h>
#include <getopt.h> #include <getopt.h>
#include <netdb.h>
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
@ -470,6 +471,10 @@ void write_uri_field(std::ostream &o, const char *uri, const http_parser_url &u,
bool numeric_host(const char *hostname); bool numeric_host(const char *hostname);
// Returns numeric address string of |addr|. If getnameinfo() is
// failed, "unknown" is returned.
std::string numeric_name(const struct sockaddr *sa, socklen_t salen);
// Opens |path| with O_APPEND enabled. If file does not exist, it is // Opens |path| with O_APPEND enabled. If file does not exist, it is
// created first. This function returns file descriptor referring the // created first. This function returns file descriptor referring the
// opened file if it succeeds, or -1. // opened file if it succeeds, or -1.