shrpx: Support configuration file
By default, configuration file is /etc/shrpx/shrpx.conf. It can be overridden using --conf option. See shrpx.conf.sample to know how to write shrpx.conf. The configurations given in shrpx.conf will be overridden by the options specified in cmmand-line.
This commit is contained in:
parent
28e477eb3a
commit
1dd61d5973
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
|
@ -33,12 +34,12 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <limits>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
@ -248,13 +249,23 @@ void save_pid()
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
// Returns true if regular file or symbolic link |path| exists.
|
||||
bool conf_exists(const char *path)
|
||||
{
|
||||
struct stat buf;
|
||||
int rv = stat(path, &buf);
|
||||
return rv == 0 && (buf.st_mode & (S_IFREG | S_IFLNK));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void fill_default_config()
|
||||
{
|
||||
mod_config()->daemon = false;
|
||||
|
||||
mod_config()->server_name = "shrpx spdylay/"SPDYLAY_VERSION;
|
||||
mod_config()->host = "localhost";
|
||||
set_config_str(&mod_config()->host, "localhost");
|
||||
mod_config()->port = 3000;
|
||||
mod_config()->private_key_file = 0;
|
||||
mod_config()->cert_file = 0;
|
||||
|
@ -284,43 +295,15 @@ void fill_default_config()
|
|||
// 2**16 = 64KiB, which is SPDY/3 default.
|
||||
mod_config()->spdy_upstream_window_bits = 16;
|
||||
|
||||
mod_config()->downstream_host = "localhost";
|
||||
set_config_str(&mod_config()->downstream_host, "localhost");
|
||||
mod_config()->downstream_port = 80;
|
||||
|
||||
mod_config()->num_worker = 1;
|
||||
|
||||
mod_config()->spdy_max_concurrent_streams =
|
||||
SPDYLAY_INITIAL_MAX_CONCURRENT_STREAMS;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
int split_host_port(char *host, size_t hostlen, uint16_t *port_ptr,
|
||||
const char *hostport)
|
||||
{
|
||||
// host and port in |hostport| is separated by single ','.
|
||||
const char *p = strchr(hostport, ',');
|
||||
if(!p) {
|
||||
std::cerr << "Invalid host, port: " << hostport << std::endl;
|
||||
return -1;
|
||||
}
|
||||
size_t len = p-hostport;
|
||||
if(hostlen < len+1) {
|
||||
std::cerr << "Hostname too long: " << hostport << std::endl;
|
||||
return -1;
|
||||
}
|
||||
memcpy(host, hostport, len);
|
||||
host[len] = '\0';
|
||||
|
||||
errno = 0;
|
||||
unsigned long d = strtoul(p+1, 0, 10);
|
||||
if(errno == 0 && 1 <= d && d <= std::numeric_limits<uint16_t>::max()) {
|
||||
*port_ptr = d;
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "Port is invalid: " << p+1 << std::endl;
|
||||
return -1;
|
||||
}
|
||||
set_config_str(&mod_config()->conf_path, "/etc/shrpx/shrpx.conf");
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -339,7 +322,6 @@ void print_usage(std::ostream& out)
|
|||
namespace {
|
||||
void print_help(std::ostream& out)
|
||||
{
|
||||
fill_default_config();
|
||||
print_usage(out);
|
||||
out << "\n"
|
||||
<< "OPTIONS:\n"
|
||||
|
@ -405,6 +387,9 @@ void print_help(std::ostream& out)
|
|||
<< " --pid-file=<PATH> Set path to save PID of this program.\n"
|
||||
<< " --user=<USER> Run this program as USER. This option is\n"
|
||||
<< " intended to be used to drop root privileges.\n"
|
||||
<< " --conf=<PATH> Load configuration from PATH.\n"
|
||||
<< " Default: "
|
||||
<< get_config()->conf_path << "\n"
|
||||
<< " -h, --help Print this help.\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
@ -416,11 +401,7 @@ int main(int argc, char **argv)
|
|||
create_config();
|
||||
fill_default_config();
|
||||
|
||||
char frontend_host[NI_MAXHOST];
|
||||
uint16_t frontend_port;
|
||||
char backend_host[NI_MAXHOST];
|
||||
uint16_t backend_port;
|
||||
|
||||
std::vector<std::pair<const char*, const char*> > cmdcfgs;
|
||||
while(1) {
|
||||
int flag;
|
||||
static option long_options[] = {
|
||||
|
@ -442,6 +423,7 @@ int main(int argc, char **argv)
|
|||
{"frontend-spdy-window-bits", required_argument, &flag, 9 },
|
||||
{"pid-file", required_argument, &flag, 10 },
|
||||
{"user", required_argument, &flag, 11 },
|
||||
{"conf", required_argument, &flag, 12 },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
@ -453,43 +435,29 @@ int main(int argc, char **argv)
|
|||
}
|
||||
switch(c) {
|
||||
case 'D':
|
||||
mod_config()->daemon = true;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_DAEMON, "yes"));
|
||||
break;
|
||||
case 'h':
|
||||
print_help(std::cout);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'L':
|
||||
if(Log::set_severity_level_by_name(optarg) == -1) {
|
||||
std::cerr << "Invalid severity level: " << optarg << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_LOG_LEVEL, optarg));
|
||||
break;
|
||||
case 'b':
|
||||
if(split_host_port(backend_host, sizeof(backend_host),
|
||||
&backend_port, optarg) == -1) {
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
mod_config()->downstream_host = backend_host;
|
||||
mod_config()->downstream_port = backend_port;
|
||||
}
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND, optarg));
|
||||
break;
|
||||
case 'f':
|
||||
if(split_host_port(frontend_host, sizeof(frontend_host),
|
||||
&frontend_port, optarg) == -1) {
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
mod_config()->host = frontend_host;
|
||||
mod_config()->port = frontend_port;
|
||||
}
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND, optarg));
|
||||
break;
|
||||
case 'n':
|
||||
mod_config()->num_worker = strtol(optarg, 0, 10);
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_WORKERS, optarg));
|
||||
break;
|
||||
case 'c':
|
||||
mod_config()->spdy_max_concurrent_streams = strtol(optarg, 0, 10);
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_SPDY_MAX_CONCURRENT_STREAMS,
|
||||
optarg));
|
||||
break;
|
||||
case 's':
|
||||
mod_config()->spdy_proxy = true;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_SPDY_PROXY, "yes"));
|
||||
break;
|
||||
case '?':
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -497,74 +465,57 @@ int main(int argc, char **argv)
|
|||
switch(flag) {
|
||||
case 1:
|
||||
// --add-x-forwarded-for
|
||||
mod_config()->add_x_forwarded_for = true;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_ADD_X_FORWARDED_FOR,
|
||||
"yes"));
|
||||
break;
|
||||
case 2: {
|
||||
case 2:
|
||||
// --frontend-spdy-read-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->spdy_upstream_read_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_SPDY_READ_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
case 3:
|
||||
// --frontend-read-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->upstream_read_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_READ_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
case 4:
|
||||
// --frontend-write-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->upstream_write_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_WRITE_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
case 5:
|
||||
// --backend-read-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_read_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND_READ_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
case 6:
|
||||
// --backend-write-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_write_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND_WRITE_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
mod_config()->accesslog = true;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_ACCESSLOG, "yes"));
|
||||
break;
|
||||
case 8: {
|
||||
case 8:
|
||||
// --backend-keep-alive-timeout
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_idle_read_timeout = tv;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 9: {
|
||||
case 9:
|
||||
// --frontend-spdy-window-bits
|
||||
errno = 0;
|
||||
unsigned long int n = strtoul(optarg, 0, 10);
|
||||
if(errno == 0 && n < 31) {
|
||||
mod_config()->spdy_upstream_window_bits = n;
|
||||
} else {
|
||||
std::cerr << "-w: specify the integer in the range [0, 30], inclusive"
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS,
|
||||
optarg));
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
mod_config()->pid_file = optarg;
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_PID_FILE, optarg));
|
||||
break;
|
||||
case 11: {
|
||||
passwd *pwd = getpwnam(optarg);
|
||||
if(pwd == 0) {
|
||||
std::cerr << "--user: failed to get uid from " << optarg
|
||||
<< ": " << strerror(errno) << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mod_config()->uid = pwd->pw_uid;
|
||||
mod_config()->gid = pwd->pw_gid;
|
||||
case 11:
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_USER, optarg));
|
||||
break;
|
||||
case 12:
|
||||
// --conf
|
||||
set_config_str(&mod_config()->conf_path, optarg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -574,14 +525,33 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if(argc-optind < 2) {
|
||||
if(conf_exists(get_config()->conf_path)) {
|
||||
if(load_config(get_config()->conf_path) == -1) {
|
||||
std::cerr << "Failed to load configuration from "
|
||||
<< get_config()->conf_path << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if((!get_config()->private_key_file || !get_config()->cert_file) &&
|
||||
argc - optind < 2) {
|
||||
print_usage(std::cerr);
|
||||
std::cerr << "Too few arguments" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(argc - optind >= 2) {
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_PRIVATE_KEY_FILE,
|
||||
argv[optind++]));
|
||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_CERTIFICATE_FILE,
|
||||
argv[optind++]));
|
||||
}
|
||||
|
||||
mod_config()->private_key_file = argv[optind++];
|
||||
mod_config()->cert_file = argv[optind++];
|
||||
for(size_t i = 0, len = cmdcfgs.size(); i < len; ++i) {
|
||||
if(parse_config(cmdcfgs[i].first, cmdcfgs[i].second) == -1) {
|
||||
std::cerr << "Failed to parse command-line argument." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
char hostport[NI_MAXHOST+16];
|
||||
bool downstream_ipv6_addr =
|
||||
|
@ -598,7 +568,7 @@ int main(int argc, char **argv)
|
|||
downstream_ipv6_addr ? "]" : "",
|
||||
get_config()->downstream_port);
|
||||
}
|
||||
mod_config()->downstream_hostport = hostport;
|
||||
set_config_str(&mod_config()->downstream_hostport, hostport);
|
||||
|
||||
if(cache_downstream_host_address() == -1) {
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
@ -24,8 +24,46 @@
|
|||
*/
|
||||
#include "shrpx_config.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <limits>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
using namespace spdylay;
|
||||
|
||||
namespace shrpx {
|
||||
|
||||
const char SHRPX_OPT_PRIVATE_KEY_FILE[] = "private-key-file";
|
||||
const char SHRPX_OPT_CERTIFICATE_FILE[] = "certificate-file";
|
||||
|
||||
const char SHRPX_OPT_BACKEND[] = "backend";
|
||||
const char SHRPX_OPT_FRONTEND[] = "frontend";
|
||||
const char SHRPX_OPT_WORKERS[] = "workers";
|
||||
const char
|
||||
SHRPX_OPT_SPDY_MAX_CONCURRENT_STREAMS[] = "spdy-max-concurrent-streams";
|
||||
const char SHRPX_OPT_LOG_LEVEL[] = "log-level";
|
||||
const char SHRPX_OPT_DAEMON[] = "daemon";
|
||||
const char SHRPX_OPT_SPDY_PROXY[] = "spdy-proxy";
|
||||
const char SHRPX_OPT_ADD_X_FORWARDED_FOR[] = "add-x-forwarded-for";
|
||||
const char
|
||||
SHRPX_OPT_FRONTEND_SPDY_READ_TIMEOUT[] = "frontend-spdy-read-timeout";
|
||||
const char SHRPX_OPT_FRONTEND_READ_TIMEOUT[] = "frontend-read-timeout";
|
||||
const char SHRPX_OPT_FRONTEND_WRITE_TIMEOUT[] = "frontend-write-timeout";
|
||||
const char SHRPX_OPT_BACKEND_READ_TIMEOUT[] = "backend-read-timeout";
|
||||
const char SHRPX_OPT_BACKEND_WRITE_TIMEOUT[] = "backend-write-timeout";
|
||||
const char SHRPX_OPT_ACCESSLOG[] = "accesslog";
|
||||
const char
|
||||
SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[] = "backend-keep-alive-timeout";
|
||||
const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[] = "frontend-spdy-window-bits";
|
||||
const char SHRPX_OPT_PID_FILE[] = "pid-file";
|
||||
const char SHRPX_OPT_USER[] = "user";
|
||||
|
||||
Config::Config()
|
||||
: verbose(false),
|
||||
daemon(false),
|
||||
|
@ -47,7 +85,8 @@ Config::Config()
|
|||
spdy_upstream_window_bits(0),
|
||||
pid_file(0),
|
||||
uid(0),
|
||||
gid(0)
|
||||
gid(0),
|
||||
conf_path(0)
|
||||
{}
|
||||
|
||||
namespace {
|
||||
|
@ -69,4 +108,159 @@ void create_config()
|
|||
config = new Config();
|
||||
}
|
||||
|
||||
namespace {
|
||||
int split_host_port(char *host, size_t hostlen, uint16_t *port_ptr,
|
||||
const char *hostport)
|
||||
{
|
||||
// host and port in |hostport| is separated by single ','.
|
||||
const char *p = strchr(hostport, ',');
|
||||
if(!p) {
|
||||
std::cerr << "Invalid host, port: " << hostport << std::endl;
|
||||
return -1;
|
||||
}
|
||||
size_t len = p-hostport;
|
||||
if(hostlen < len+1) {
|
||||
std::cerr << "Hostname too long: " << hostport << std::endl;
|
||||
return -1;
|
||||
}
|
||||
memcpy(host, hostport, len);
|
||||
host[len] = '\0';
|
||||
|
||||
errno = 0;
|
||||
unsigned long d = strtoul(p+1, 0, 10);
|
||||
if(errno == 0 && 1 <= d && d <= std::numeric_limits<uint16_t>::max()) {
|
||||
*port_ptr = d;
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "Port is invalid: " << p+1 << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void set_config_str(char **destp, const char *val)
|
||||
{
|
||||
if(*destp) {
|
||||
free(*destp);
|
||||
}
|
||||
*destp = strdup(val);
|
||||
}
|
||||
|
||||
int parse_config(const char *opt, const char *optarg)
|
||||
{
|
||||
char host[NI_MAXHOST];
|
||||
uint16_t port;
|
||||
if(util::strieq(opt, SHRPX_OPT_BACKEND)) {
|
||||
if(split_host_port(host, sizeof(host), &port, optarg) == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
set_config_str(&mod_config()->downstream_host, host);
|
||||
mod_config()->downstream_port = port;
|
||||
}
|
||||
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND)) {
|
||||
if(split_host_port(host, sizeof(host), &port, optarg) == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
set_config_str(&mod_config()->host, host);
|
||||
mod_config()->port = port;
|
||||
}
|
||||
} else if(util::strieq(opt, SHRPX_OPT_WORKERS)) {
|
||||
mod_config()->num_worker = strtol(optarg, 0, 10);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_SPDY_MAX_CONCURRENT_STREAMS)) {
|
||||
mod_config()->spdy_max_concurrent_streams = strtol(optarg, 0, 10);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_LOG_LEVEL)) {
|
||||
if(Log::set_severity_level_by_name(optarg) == -1) {
|
||||
std::cerr << "Invalid severity level: " << optarg << std::endl;
|
||||
return -1;
|
||||
}
|
||||
} else if(util::strieq(opt, SHRPX_OPT_DAEMON)) {
|
||||
mod_config()->daemon = util::strieq(optarg, "yes");
|
||||
} else if(util::strieq(opt, SHRPX_OPT_SPDY_PROXY)) {
|
||||
mod_config()->spdy_proxy = util::strieq(optarg, "yes");
|
||||
} else if(util::strieq(opt, SHRPX_OPT_ADD_X_FORWARDED_FOR)) {
|
||||
mod_config()->add_x_forwarded_for = util::strieq(optarg, "yes");
|
||||
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_SPDY_READ_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->spdy_upstream_read_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_READ_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->upstream_read_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_WRITE_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->upstream_write_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_READ_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_read_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_WRITE_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_write_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_ACCESSLOG)) {
|
||||
mod_config()->accesslog = util::strieq(optarg, "yes");
|
||||
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT)) {
|
||||
timeval tv = {strtol(optarg, 0, 10), 0};
|
||||
mod_config()->downstream_idle_read_timeout = tv;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS)) {
|
||||
errno = 0;
|
||||
unsigned long int n = strtoul(optarg, 0, 10);
|
||||
if(errno == 0 && n < 31) {
|
||||
mod_config()->spdy_upstream_window_bits = n;
|
||||
} else {
|
||||
std::cerr << "-w: specify the integer in the range [0, 30], inclusive"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
} else if(util::strieq(opt, SHRPX_OPT_PID_FILE)) {
|
||||
set_config_str(&mod_config()->pid_file, optarg);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_USER)) {
|
||||
passwd *pwd = getpwnam(optarg);
|
||||
if(pwd == 0) {
|
||||
std::cerr << "--user: failed to get uid from " << optarg
|
||||
<< ": " << strerror(errno) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
mod_config()->uid = pwd->pw_uid;
|
||||
mod_config()->gid = pwd->pw_gid;
|
||||
} else if(util::strieq(opt, SHRPX_OPT_PRIVATE_KEY_FILE)) {
|
||||
set_config_str(&mod_config()->private_key_file, optarg);
|
||||
} else if(util::strieq(opt, SHRPX_OPT_CERTIFICATE_FILE)) {
|
||||
set_config_str(&mod_config()->cert_file, optarg);
|
||||
} else if(util::strieq(opt, "conf")) {
|
||||
std::cerr << "conf is ignored" << std::endl;
|
||||
} else {
|
||||
std::cerr << "Unknown option: " << opt << std::endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_config(const char *filename)
|
||||
{
|
||||
std::ifstream in(filename, std::ios::binary);
|
||||
if(!in) {
|
||||
std::cerr << "Could not open config file " << filename << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::string line;
|
||||
int linenum = 0;
|
||||
while(std::getline(in, line)) {
|
||||
++linenum;
|
||||
if(line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
size_t i;
|
||||
size_t size = line.size();
|
||||
for(i = 0; i < size && line[i] != '='; ++i);
|
||||
if(i == size) {
|
||||
std::cerr << "Bad configuration format at line " << linenum << std::endl;
|
||||
return -1;
|
||||
}
|
||||
line[i] = '\0';
|
||||
const char *s = line.c_str();
|
||||
if(parse_config(s, s+i+1) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
|
@ -33,10 +33,30 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace shrpx {
|
||||
|
||||
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
||||
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
||||
|
||||
extern const char SHRPX_OPT_BACKEND[];
|
||||
extern const char SHRPX_OPT_FRONTEND[];
|
||||
extern const char SHRPX_OPT_WORKERS[];
|
||||
extern const char SHRPX_OPT_SPDY_MAX_CONCURRENT_STREAMS[];
|
||||
extern const char SHRPX_OPT_LOG_LEVEL[];
|
||||
extern const char SHRPX_OPT_DAEMON[];
|
||||
extern const char SHRPX_OPT_SPDY_PROXY[];
|
||||
extern const char SHRPX_OPT_ADD_X_FORWARDED_FOR[];
|
||||
extern const char SHRPX_OPT_FRONTEND_SPDY_READ_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_FRONTEND_READ_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_FRONTEND_WRITE_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_BACKEND_READ_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_BACKEND_WRITE_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_ACCESSLOG[];
|
||||
extern const char SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[];
|
||||
extern const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[];
|
||||
extern const char SHRPX_OPT_PID_FILE[];
|
||||
extern const char SHRPX_OPT_USER[];
|
||||
|
||||
union sockaddr_union {
|
||||
sockaddr sa;
|
||||
sockaddr_storage storage;
|
||||
|
@ -47,15 +67,15 @@ union sockaddr_union {
|
|||
struct Config {
|
||||
bool verbose;
|
||||
bool daemon;
|
||||
const char *host;
|
||||
char *host;
|
||||
uint16_t port;
|
||||
const char *private_key_file;
|
||||
const char *cert_file;
|
||||
char *private_key_file;
|
||||
char *cert_file;
|
||||
bool verify_client;
|
||||
const char *server_name;
|
||||
const char *downstream_host;
|
||||
char *downstream_host;
|
||||
uint16_t downstream_port;
|
||||
const char *downstream_hostport;
|
||||
char *downstream_hostport;
|
||||
sockaddr_union downstream_addr;
|
||||
size_t downstream_addrlen;
|
||||
timeval spdy_upstream_read_timeout;
|
||||
|
@ -70,9 +90,10 @@ struct Config {
|
|||
bool add_x_forwarded_for;
|
||||
bool accesslog;
|
||||
size_t spdy_upstream_window_bits;
|
||||
const char* pid_file;
|
||||
char *pid_file;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *conf_path;
|
||||
Config();
|
||||
};
|
||||
|
||||
|
@ -80,6 +101,20 @@ const Config* get_config();
|
|||
Config* mod_config();
|
||||
void create_config();
|
||||
|
||||
// Parses option name |opt| and value |optarg|. The results are
|
||||
// stored into statically allocated Config object. This function
|
||||
// returns 0 if it succeeds, or -1.
|
||||
int parse_config(const char *opt, const char *optarg);
|
||||
|
||||
// Loads configurations from |filename| and stores them in statically
|
||||
// allocated Config object. This function returns 0 if it succeeds, or
|
||||
// -1.
|
||||
int load_config(const char *filename);
|
||||
|
||||
// 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);
|
||||
|
||||
} // namespace shrpx
|
||||
|
||||
#endif // SHRPX_CONFIG_H
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Sample configuration file for Shrpx.
|
||||
#
|
||||
# * Line staring '#' is treated as comment.
|
||||
#
|
||||
# * The option name in the configuration file is the long command-line
|
||||
# option name, stripped leading '--' (e.g., frontend). Put '='
|
||||
# between option name and value. Don't put extra leading or trailing
|
||||
# spaces.
|
||||
#
|
||||
# * The options which do not take argument in the command-line *take*
|
||||
# argument in the configuration file. Specify 'yes' as argument
|
||||
# (e.g., spdy-proxy=yes). If other string is given, it disables the
|
||||
# option.
|
||||
#
|
||||
# * To specify private key and certificate file, use private-key-file
|
||||
# and certificate-file. See the examples below.
|
||||
#
|
||||
# * conf option cannot be used in the configuration file. It will be
|
||||
# ignored.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# frontend=localhost,3000
|
||||
# backend=localhost,80
|
||||
# private-key-file=/path/to/server.key
|
||||
# certificate-file=/path/to/server.crt
|
||||
# spdy-proxy=no
|
||||
# workers=1
|
Loading…
Reference in New Issue