[core] use config_plugin_values_init()
This commit is contained in:
parent
83633a9f06
commit
ed62e354ff
154
src/base.h
154
src/base.h
|
@ -13,7 +13,6 @@
|
|||
#include "chunk.h"
|
||||
#include "http_kv.h"
|
||||
#include "sock_addr.h"
|
||||
#include "etag.h"
|
||||
|
||||
struct fdevents; /* declaration */
|
||||
struct stat_cache; /* declaration */
|
||||
|
@ -76,57 +75,52 @@ typedef struct {
|
|||
} physical;
|
||||
|
||||
typedef struct {
|
||||
array *mimetypes;
|
||||
const array *mimetypes;
|
||||
|
||||
/* virtual-servers */
|
||||
buffer *document_root;
|
||||
buffer *server_name;
|
||||
buffer *error_handler;
|
||||
buffer *error_handler_404;
|
||||
buffer *server_tag;
|
||||
buffer *errorfile_prefix;
|
||||
const buffer *document_root;
|
||||
const buffer *server_name;
|
||||
const buffer *server_tag;
|
||||
const buffer *error_handler;
|
||||
const buffer *error_handler_404;
|
||||
const buffer *errorfile_prefix;
|
||||
|
||||
unsigned short high_precision_timestamps;
|
||||
unsigned short max_keep_alive_requests;
|
||||
unsigned short max_keep_alive_idle;
|
||||
unsigned short max_read_idle;
|
||||
unsigned short max_write_idle;
|
||||
unsigned short use_xattr;
|
||||
unsigned short follow_symlink;
|
||||
unsigned short range_requests;
|
||||
unsigned short stream_request_body;
|
||||
unsigned short stream_response_body;
|
||||
unsigned short error_intercept;
|
||||
unsigned char high_precision_timestamps;
|
||||
unsigned char allow_http11;
|
||||
unsigned char follow_symlink;
|
||||
unsigned char etag_flags;
|
||||
unsigned char force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */
|
||||
unsigned char use_xattr;
|
||||
unsigned char range_requests;
|
||||
unsigned char error_intercept;
|
||||
|
||||
/* debug */
|
||||
|
||||
unsigned short log_file_not_found;
|
||||
unsigned short log_request_header;
|
||||
unsigned short log_request_handling;
|
||||
unsigned short log_response_header;
|
||||
unsigned short log_condition_handling;
|
||||
unsigned short log_timeouts;
|
||||
unsigned char log_file_not_found;
|
||||
unsigned char log_request_header;
|
||||
unsigned char log_request_handling;
|
||||
unsigned char log_response_header;
|
||||
unsigned char log_condition_handling;
|
||||
unsigned char log_timeouts;
|
||||
|
||||
unsigned short allow_http11;
|
||||
unsigned short etag_use_inode;
|
||||
unsigned short etag_use_mtime;
|
||||
unsigned short etag_use_size;
|
||||
unsigned short force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */
|
||||
unsigned int http_parseopts;
|
||||
unsigned int max_request_size;
|
||||
|
||||
unsigned short kbytes_per_second; /* connection kb/s limit */
|
||||
unsigned int bytes_per_second; /* connection bytes/sec limit */
|
||||
unsigned int global_bytes_per_second;/*total bytes/sec limit for scope*/
|
||||
|
||||
/* configside */
|
||||
unsigned short global_kbytes_per_second; /* */
|
||||
|
||||
off_t global_bytes_per_second_cnt;
|
||||
/* server-wide traffic-shaper
|
||||
*
|
||||
* each context has the counter which is inited once
|
||||
* a second by the global_kbytes_per_second config-var
|
||||
* a second by the global_bytes_per_second config-var
|
||||
*
|
||||
* as soon as global_kbytes_per_second gets below 0
|
||||
* as soon as global_bytes_per_second gets below 0
|
||||
* the connected conns are "offline" a little bit
|
||||
*
|
||||
* the problem:
|
||||
|
@ -135,25 +129,6 @@ typedef struct {
|
|||
*
|
||||
*/
|
||||
off_t *global_bytes_per_second_cnt_ptr; /* */
|
||||
|
||||
/*
|
||||
* global_bytes_per_second_cnt_ptr must be the final member above this point
|
||||
* members above this point are patched per connection
|
||||
*/
|
||||
|
||||
/* global or per-socket config; not patched per connection */
|
||||
|
||||
unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */
|
||||
unsigned short defer_accept;
|
||||
unsigned short ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
|
||||
int listen_backlog;
|
||||
buffer *socket_perms;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
buffer *bsd_accept_filter;
|
||||
#endif
|
||||
|
||||
} specific_config;
|
||||
|
||||
/* the order of the items should be the same as they are processed
|
||||
|
@ -193,9 +168,9 @@ typedef struct cond_cache_t {
|
|||
cond_result_t result;
|
||||
/* result without preconditions (must never be "skip") */
|
||||
cond_result_t local_result;
|
||||
const buffer *comp_value; /* just a pointer */
|
||||
int patterncount;
|
||||
int matches[3 * 10];
|
||||
const buffer *comp_value; /* just a pointer */
|
||||
} cond_cache_t;
|
||||
|
||||
struct connection {
|
||||
|
@ -280,9 +255,6 @@ struct connection {
|
|||
struct server_socket *srv_socket; /* reference to the server-socket */
|
||||
int (* network_write)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
|
||||
int (* network_read)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
|
||||
|
||||
/* etag handling */
|
||||
etag_flags_t etag_flags;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -297,56 +269,52 @@ typedef struct {
|
|||
} mtime_cache_type;
|
||||
|
||||
typedef struct {
|
||||
void *ptr;
|
||||
void *ptr;
|
||||
uint32_t used;
|
||||
uint32_t size;
|
||||
} buffer_plugin;
|
||||
|
||||
typedef struct {
|
||||
unsigned int max_request_field_size;
|
||||
int stat_cache_engine;
|
||||
const char *xattr_name;
|
||||
unsigned int log_state_handling;
|
||||
unsigned char log_request_header_on_error;
|
||||
|
||||
unsigned short http_header_strict;
|
||||
unsigned short http_host_strict;
|
||||
unsigned short http_host_normalize;
|
||||
/*(used sparsely, if at all, after config at startup)*/
|
||||
|
||||
unsigned char http_header_strict;
|
||||
unsigned char http_host_strict;
|
||||
unsigned char http_host_normalize;
|
||||
unsigned char http_method_get_body;
|
||||
unsigned char high_precision_timestamps;
|
||||
unsigned short http_url_normalize;
|
||||
unsigned short http_method_get_body;
|
||||
unsigned short high_precision_timestamps;
|
||||
|
||||
unsigned short max_worker;
|
||||
unsigned short max_fds;
|
||||
unsigned short max_conns;
|
||||
|
||||
unsigned short log_state_handling;
|
||||
unsigned short log_request_header_on_error;
|
||||
unsigned short port;
|
||||
|
||||
time_t loadts;
|
||||
double loadavg[3];
|
||||
|
||||
int stat_cache_engine;
|
||||
|
||||
unsigned int upload_temp_file_size;
|
||||
array *upload_tempdirs;
|
||||
buffer *xattr_name;
|
||||
|
||||
unsigned short dont_daemonize;
|
||||
unsigned short preflight_check;
|
||||
unsigned short enable_cores;
|
||||
unsigned short reject_expect_100_with_417; /*(ignored)*/
|
||||
unsigned short compat_module_load;
|
||||
unsigned short systemd_socket_activation;
|
||||
unsigned short errorlog_use_syslog;
|
||||
buffer *errorlog_file;
|
||||
buffer *breakagelog_file;
|
||||
buffer *syslog_facility;
|
||||
buffer *bindhost;
|
||||
buffer *changeroot;
|
||||
buffer *username;
|
||||
buffer *groupname;
|
||||
unsigned char dont_daemonize;
|
||||
unsigned char preflight_check;
|
||||
unsigned char enable_cores;
|
||||
unsigned char compat_module_load;
|
||||
unsigned char systemd_socket_activation;
|
||||
unsigned char errorlog_use_syslog;
|
||||
const buffer *errorlog_file;
|
||||
const buffer *breakagelog_file;
|
||||
const buffer *syslog_facility;
|
||||
const buffer *bindhost;
|
||||
const buffer *changeroot;
|
||||
const buffer *username;
|
||||
const buffer *groupname;
|
||||
const buffer *network_backend;
|
||||
const char *event_handler;
|
||||
buffer *pid_file;
|
||||
buffer *event_handler;
|
||||
buffer *modules_dir;
|
||||
buffer *network_backend;
|
||||
array *modules;
|
||||
} server_config;
|
||||
|
||||
|
@ -406,10 +374,6 @@ struct server {
|
|||
buffer *ts_date_str;
|
||||
log_error_st *errh;
|
||||
|
||||
/* config-file */
|
||||
array *config_context;
|
||||
specific_config **config_storage;
|
||||
|
||||
/**
|
||||
* The status array can carry all the status information you want
|
||||
* the key to the array is <module-prefix>.<name>
|
||||
|
@ -430,14 +394,22 @@ struct server {
|
|||
/* caches */
|
||||
mtime_cache_type mtime_cache[FILE_CACHE_MAX];
|
||||
|
||||
time_t loadts;
|
||||
double loadavg[3];
|
||||
|
||||
/* config-file */
|
||||
void *config_data_base;
|
||||
array *config_context;
|
||||
array empty_array;
|
||||
|
||||
/* members used at start-up or rarely used */
|
||||
server_socket_array srv_sockets;
|
||||
server_socket_array srv_sockets_inherited;
|
||||
buffer_plugin plugins;
|
||||
|
||||
array *config_touched;
|
||||
short int config_deprecated;
|
||||
short int config_unsupported;
|
||||
unsigned char config_deprecated;
|
||||
unsigned char config_unsupported;
|
||||
|
||||
int event_handler;
|
||||
time_t startup_ts;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
static size_t chunk_buf_sz = 4096;
|
||||
static chunk *chunks, *chunks_oversized;
|
||||
static chunk *chunk_buffers;
|
||||
static array *chunkqueue_default_tempdirs = NULL;
|
||||
static const array *chunkqueue_default_tempdirs = NULL;
|
||||
static off_t chunkqueue_default_tempfile_size = DEFAULT_TEMPFILE_SIZE;
|
||||
|
||||
void chunkqueue_set_chunk_size (size_t sz)
|
||||
|
@ -438,7 +438,7 @@ void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void chunkqueue_set_tempdirs_default (array *tempdirs, off_t upload_temp_file_size) {
|
||||
void chunkqueue_set_tempdirs_default (const array *tempdirs, off_t upload_temp_file_size) {
|
||||
chunkqueue_default_tempdirs = tempdirs;
|
||||
chunkqueue_default_tempfile_size
|
||||
= (0 == upload_temp_file_size) ? DEFAULT_TEMPFILE_SIZE
|
||||
|
@ -446,7 +446,7 @@ void chunkqueue_set_tempdirs_default (array *tempdirs, off_t upload_temp_file_si
|
|||
: upload_temp_file_size;
|
||||
}
|
||||
|
||||
void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs, off_t upload_temp_file_size) {
|
||||
void chunkqueue_set_tempdirs(chunkqueue *cq, const array *tempdirs, off_t upload_temp_file_size) {
|
||||
force_assert(NULL != cq);
|
||||
cq->tempdirs = tempdirs;
|
||||
cq->upload_temp_file_size
|
||||
|
|
|
@ -42,7 +42,7 @@ typedef struct {
|
|||
|
||||
off_t bytes_in, bytes_out;
|
||||
|
||||
array *tempdirs;
|
||||
const array *tempdirs;
|
||||
off_t upload_temp_file_size;
|
||||
unsigned int tempdir_idx;
|
||||
} chunkqueue;
|
||||
|
@ -60,8 +60,8 @@ chunkqueue *chunkqueue_init(void);
|
|||
|
||||
void chunkqueue_set_chunk_size (size_t sz);
|
||||
void chunkqueue_set_tempdirs_default_reset (void);
|
||||
void chunkqueue_set_tempdirs_default (array *tempdirs, off_t upload_temp_file_size);
|
||||
void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs, off_t upload_temp_file_size);
|
||||
void chunkqueue_set_tempdirs_default (const array *tempdirs, off_t upload_temp_file_size);
|
||||
void chunkqueue_set_tempdirs(chunkqueue *cq, const array *tempdirs, off_t upload_temp_file_size);
|
||||
void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); /* copies "fn" */
|
||||
void chunkqueue_append_file_fd(chunkqueue *cq, buffer *fn, int fd, off_t offset, off_t len); /* copies "fn" */
|
||||
void chunkqueue_append_mem(chunkqueue *cq, const char *mem, size_t len); /* copies memory */
|
||||
|
|
1438
src/configfile.c
1438
src/configfile.c
File diff suppressed because it is too large
Load Diff
|
@ -128,7 +128,13 @@ int config_parse_file(server *srv, config_t *context, const char *fn);
|
|||
__attribute_cold__
|
||||
int config_parse_cmd(server *srv, config_t *context, const char *cmd);
|
||||
|
||||
void config_patch_connection(server *srv, connection *con);
|
||||
__attribute_cold__
|
||||
void config_free_config(void *p);
|
||||
|
||||
void config_reset_config_bytes_sec(void *p);
|
||||
|
||||
void config_reset_config(server *srv, connection *con);
|
||||
void config_patch_config(server *srv, connection *con);
|
||||
|
||||
void config_cond_cache_reset(server *srv, connection *con);
|
||||
void config_cond_cache_reset_item(server *srv, connection *con, comp_key_t item);
|
||||
|
@ -150,7 +156,7 @@ typedef enum { T_CONFIG_SCOPE_UNSET,
|
|||
T_CONFIG_SCOPE_CONNECTION
|
||||
} config_scope_type_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct config_plugin_value {
|
||||
int k_id;
|
||||
config_values_type_t vtype;
|
||||
union v_u {
|
||||
|
|
|
@ -290,8 +290,8 @@ static handler_t connection_handle_read_body_unknown(server *srv, connection *co
|
|||
|
||||
static off_t connection_write_throttle(server *srv, connection *con, off_t max_bytes) {
|
||||
UNUSED(srv);
|
||||
if (con->conf.global_kbytes_per_second) {
|
||||
off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
|
||||
if (con->conf.global_bytes_per_second) {
|
||||
off_t limit = (off_t)con->conf.global_bytes_per_second - *(con->conf.global_bytes_per_second_cnt_ptr);
|
||||
if (limit <= 0) {
|
||||
/* we reached the global traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
@ -302,8 +302,8 @@ static off_t connection_write_throttle(server *srv, connection *con, off_t max_b
|
|||
}
|
||||
}
|
||||
|
||||
if (con->conf.kbytes_per_second) {
|
||||
off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second;
|
||||
if (con->conf.bytes_per_second) {
|
||||
off_t limit = (off_t)con->conf.bytes_per_second - con->bytes_written_cur_second;
|
||||
if (limit <= 0) {
|
||||
/* we reached the traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
@ -362,7 +362,8 @@ int connection_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, of
|
|||
written = cq->bytes_out - written;
|
||||
con->bytes_written += written;
|
||||
con->bytes_written_cur_second += written;
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
if (con->conf.global_bytes_per_second_cnt_ptr)
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -391,7 +392,8 @@ static int connection_write_100_continue(server *srv, connection *con) {
|
|||
written = cq->bytes_out - written;
|
||||
con->bytes_written += written;
|
||||
con->bytes_written_cur_second += written;
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
if (con->conf.global_bytes_per_second_cnt_ptr)
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
|
||||
if (rc < 0) {
|
||||
con->state = CON_STATE_ERROR;
|
||||
|
|
|
@ -535,17 +535,6 @@ static void connection_handle_write_state(server *srv, connection *con) {
|
|||
}
|
||||
|
||||
|
||||
static void connection_reset_config(server *srv, connection *con) {
|
||||
/* initialize specific_config (con->conf) from top-level specific_config */
|
||||
specific_config * const s = srv->config_storage[0];
|
||||
const size_t len = /* offsetof() */
|
||||
(uintptr_t)&((specific_config *)0)->global_bytes_per_second_cnt_ptr;
|
||||
con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
|
||||
con->server_name = s->server_name;
|
||||
memcpy(&con->conf, s, len);
|
||||
}
|
||||
|
||||
|
||||
__attribute_cold__
|
||||
static connection *connection_init(server *srv) {
|
||||
connection *con;
|
||||
|
@ -599,7 +588,7 @@ static connection *connection_init(server *srv) {
|
|||
|
||||
con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
|
||||
force_assert(NULL != con->cond_cache);
|
||||
connection_reset_config(srv, con);
|
||||
config_reset_config(srv, con);
|
||||
|
||||
return con;
|
||||
}
|
||||
|
@ -710,7 +699,7 @@ static int connection_reset(server *srv, connection *con) {
|
|||
/*con->error_handler_saved_method = HTTP_METHOD_UNSET;*/
|
||||
/*(error_handler_saved_method value is not valid unless error_handler_saved_status is set)*/
|
||||
|
||||
connection_reset_config(srv, con);
|
||||
config_reset_config(srv, con);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1177,7 +1166,7 @@ static int connection_handle_request(server *srv, connection *con) {
|
|||
con->error_handler_saved_status = 65535; /* >= 1000 */
|
||||
}
|
||||
} else if (con->http_status >= 400) {
|
||||
buffer *error_handler = NULL;
|
||||
const buffer *error_handler = NULL;
|
||||
if (!buffer_string_is_empty(con->conf.error_handler)) {
|
||||
error_handler = con->conf.error_handler;
|
||||
} else if ((con->http_status == 404 || con->http_status == 403)
|
||||
|
@ -1236,7 +1225,7 @@ static int connection_handle_request(server *srv, connection *con) {
|
|||
break;
|
||||
case HANDLER_COMEBACK:
|
||||
if (con->mode == DIRECT && buffer_is_empty(con->physical.path)) {
|
||||
connection_reset_config(srv, con);
|
||||
config_reset_config(srv, con);
|
||||
}
|
||||
return 1;
|
||||
case HANDLER_ERROR:
|
||||
|
@ -1464,12 +1453,11 @@ static void connection_check_timeout (server * const srv, const time_t cur_ts, c
|
|||
}
|
||||
}
|
||||
|
||||
/* we don't like div by zero */
|
||||
if (0 == (t_diff = cur_ts - con->connection_start)) t_diff = 1;
|
||||
|
||||
if (con->traffic_limit_reached &&
|
||||
(con->conf.kbytes_per_second == 0 ||
|
||||
((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))){
|
||||
(con->conf.bytes_per_second == 0 ||
|
||||
con->bytes_written < (off_t)con->conf.bytes_per_second * t_diff)) {
|
||||
/* enable connection again */
|
||||
con->traffic_limit_reached = 0;
|
||||
|
||||
|
@ -1514,8 +1502,8 @@ void connection_graceful_shutdown_maint (server *srv) {
|
|||
|
||||
con->keep_alive = 0; /* disable keep-alive */
|
||||
|
||||
con->conf.kbytes_per_second = 0; /* disable rate limit */
|
||||
con->conf.global_kbytes_per_second = 0; /* disable rate limit */
|
||||
con->conf.bytes_per_second = 0; /* disable rate limit */
|
||||
con->conf.global_bytes_per_second = 0; /* disable rate limit */
|
||||
if (con->traffic_limit_reached) {
|
||||
con->traffic_limit_reached = 0;
|
||||
changed = 1;
|
||||
|
|
|
@ -143,7 +143,7 @@ int etag_is_equal(const buffer *etag, const char *line, int weak_ok) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int etag_create(buffer *etag, const struct stat *st, etag_flags_t flags) {
|
||||
int etag_create(buffer *etag, const struct stat *st, int flags) {
|
||||
if (0 == flags) return 0;
|
||||
|
||||
buffer_clear(etag);
|
||||
|
|
|
@ -9,7 +9,7 @@ struct stat; /* declaration */
|
|||
typedef enum { ETAG_USE_INODE = 1, ETAG_USE_MTIME = 2, ETAG_USE_SIZE = 4 } etag_flags_t;
|
||||
|
||||
int etag_is_equal(const buffer *etag, const char *matches, int weak_ok);
|
||||
int etag_create(buffer *etag, const struct stat *st, etag_flags_t flags);
|
||||
int etag_create(buffer *etag, const struct stat *st, int flags);
|
||||
int etag_mutate(buffer *mut, buffer *etag);
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ int fdevent_config(server *srv) {
|
|||
{ FDEVENT_HANDLER_UNSET, NULL }
|
||||
};
|
||||
|
||||
if (buffer_string_is_empty(srv->srvconf.event_handler)) {
|
||||
if (NULL == srv->srvconf.event_handler) {
|
||||
/* choose a good default
|
||||
*
|
||||
* the event_handler list is sorted by 'goodness'
|
||||
|
@ -71,24 +71,23 @@ int fdevent_config(server *srv) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
buffer_copy_string(srv->srvconf.event_handler, event_handlers[0].name);
|
||||
srv->srvconf.event_handler = event_handlers[0].name;
|
||||
} else {
|
||||
/*
|
||||
* User override
|
||||
*/
|
||||
|
||||
for (size_t i = 0; event_handlers[i].name; i++) {
|
||||
if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) {
|
||||
if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler)) {
|
||||
srv->event_handler = event_handlers[i].et;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sb",
|
||||
"the selected event-handler in unknown or not supported:",
|
||||
srv->srvconf.event_handler );
|
||||
|
||||
log_error(srv->errh, __FILE__, __LINE__,
|
||||
"the selected event-handler in unknown or not supported: %s",
|
||||
srv->srvconf.event_handler);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -245,8 +244,10 @@ fdevents *fdevent_init(server *srv) {
|
|||
free(ev->fdarray);
|
||||
free(ev);
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "sBS",
|
||||
"event-handler failed:", srv->srvconf.event_handler, "; try to set server.event-handler = \"poll\" or \"select\"");
|
||||
log_error(srv->errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
srv->srvconf.event_handler);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -270,8 +271,11 @@ void fdevent_free(fdevents *ev) {
|
|||
int fdevent_reset(fdevents *ev) {
|
||||
int rc = (NULL != ev->reset) ? ev->reset(ev) : 0;
|
||||
if (-1 == rc) {
|
||||
log_error_write(ev->srv, __FILE__, __LINE__, "sBS",
|
||||
"event-handler failed:", ev->srv->srvconf.event_handler, "; try to set server.event-handler = \"poll\" or \"select\"");
|
||||
const char *event_handler = ev->srv->srvconf.event_handler;
|
||||
log_error(ev->srv->errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
event_handler ? event_handler : "");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -510,7 +510,7 @@ void http_response_send_file (server *srv, connection *con, buffer *path) {
|
|||
}
|
||||
|
||||
if (allow_caching) {
|
||||
if (con->etag_flags != 0 && !buffer_string_is_empty(stat_cache_etag_get(sce, con->etag_flags))) {
|
||||
if (con->conf.etag_flags != 0 && !buffer_string_is_empty(stat_cache_etag_get(sce, con->conf.etag_flags))) {
|
||||
if (NULL == http_header_response_get(con, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"))) {
|
||||
/* generate e-tag */
|
||||
etag_mutate(con->physical.etag, sce->etag);
|
||||
|
|
|
@ -563,7 +563,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, in
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->srvconf.loadavg[0]) {
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->loadavg[0]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -699,7 +699,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
|
|||
|
||||
if (sce->st.st_size > 128 * 1024 * 1024) return -1;
|
||||
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->srvconf.loadavg[0]) {
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->loadavg[0]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -851,7 +851,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
|
|||
*/
|
||||
if (sce->st.st_size < 128) return HANDLER_GO_ON;
|
||||
|
||||
stat_cache_etag_get(sce, con->etag_flags);
|
||||
stat_cache_etag_get(sce, con->conf.etag_flags);
|
||||
|
||||
/* check if mimetype is in compress-config */
|
||||
content_type = NULL;
|
||||
|
|
|
@ -1198,7 +1198,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
|
|||
}
|
||||
}
|
||||
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->srvconf.loadavg[0]) {
|
||||
if (0.0 < p->conf.max_loadavg && p->conf.max_loadavg < srv->loadavg[0]) {
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
|
|
@ -997,7 +997,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
|
|||
if (con->conf.use_xattr) {
|
||||
memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
|
||||
attrlen = sizeof(attrval) - 1;
|
||||
if (attr_get(path, srv->srvconf.xattr_name->ptr, attrval, &attrlen, 0) == 0) {
|
||||
if (attr_get(path, srv->srvconf.xattr_name, attrval, &attrlen, 0) == 0) {
|
||||
attrval[attrlen] = '\0';
|
||||
content_type = attrval;
|
||||
}
|
||||
|
@ -1005,7 +1005,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
|
|||
#elif defined(HAVE_EXTATTR)
|
||||
if (con->conf.use_xattr) {
|
||||
memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
|
||||
if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, srv->srvconf.xattr_name->ptr, attrval, sizeof(attrval)-1))) {
|
||||
if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, srv->srvconf.xattr_name, attrval, sizeof(attrval)-1))) {
|
||||
attrval[attrlen] = '\0';
|
||||
content_type = attrval;
|
||||
}
|
||||
|
|
|
@ -361,7 +361,7 @@ static int magnet_stat(lua_State *L) {
|
|||
lua_pushinteger(L, sce->st.st_ino);
|
||||
lua_setfield(L, -2, "st_ino");
|
||||
|
||||
if (!buffer_string_is_empty(stat_cache_etag_get(sce, con->etag_flags))) {
|
||||
if (!buffer_string_is_empty(stat_cache_etag_get(sce, con->conf.etag_flags))) {
|
||||
/* we have to mutate the etag */
|
||||
etag_mutate(srv->tmp_buf, sce->etag);
|
||||
lua_pushlstring(L, CONST_BUF_LEN(srv->tmp_buf));
|
||||
|
|
|
@ -74,7 +74,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
|
|||
break;
|
||||
}
|
||||
|
||||
stat_cache_etag_get(sce, con->etag_flags);
|
||||
stat_cache_etag_get(sce, con->conf.etag_flags);
|
||||
if (!buffer_is_equal(sce->etag, sc->etag)) {
|
||||
/* the etag is outdated, reload the function */
|
||||
lua_pop(sc->L, 1);
|
||||
|
@ -115,7 +115,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
|
|||
}
|
||||
|
||||
if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
|
||||
buffer_copy_buffer(sc->etag, stat_cache_etag_get(sce, con->etag_flags));
|
||||
buffer_copy_buffer(sc->etag, stat_cache_etag_get(sce, con->conf.etag_flags));
|
||||
}
|
||||
|
||||
force_assert(lua_isfunction(sc->L, -1));
|
||||
|
|
|
@ -1266,7 +1266,7 @@ static int mod_ssi_handle_request(server *srv, connection *con, handler_ctx *p)
|
|||
if (st.st_mtime < include_file_last_mtime)
|
||||
st.st_mtime = include_file_last_mtime;
|
||||
|
||||
etag_create(con->physical.etag, &st, con->etag_flags);
|
||||
etag_create(con->physical.etag, &st, con->conf.etag_flags);
|
||||
etag_mutate(con->physical.etag, con->physical.etag);
|
||||
http_header_response_set(con, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
|
|||
log_error_write(srv, __FILE__, __LINE__, "s", "-- handling file as static file");
|
||||
}
|
||||
|
||||
if (!p->conf.etags_used) con->etag_flags = 0;
|
||||
if (!p->conf.etags_used) con->conf.etag_flags = 0;
|
||||
http_response_send_file(srv, con, con->physical.path);
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
|
|
|
@ -797,7 +797,7 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con) {
|
|||
#endif
|
||||
mod_status_header_append(b, "Network Engine");
|
||||
|
||||
mod_status_row_append(b, "fd-Event-Handler", srv->srvconf.event_handler->ptr);
|
||||
mod_status_row_append(b, "fd-Event-Handler", srv->srvconf.event_handler);
|
||||
|
||||
mod_status_header_append(b, "Config-File-Settings");
|
||||
|
||||
|
|
|
@ -2129,12 +2129,12 @@ webdav_fcopyfile_sz (int ifd, int ofd, off_t isz)
|
|||
static int
|
||||
webdav_if_match_or_unmodified_since (connection * const con, struct stat *st)
|
||||
{
|
||||
const buffer *im = (0 != con->etag_flags)
|
||||
const buffer *im = (0 != con->conf.etag_flags)
|
||||
? http_header_request_get(con, HTTP_HEADER_OTHER,
|
||||
CONST_STR_LEN("If-Match"))
|
||||
: NULL;
|
||||
|
||||
const buffer *inm = (0 != con->etag_flags)
|
||||
const buffer *inm = (0 != con->conf.etag_flags)
|
||||
? http_header_request_get(con, HTTP_HEADER_IF_NONE_MATCH,
|
||||
CONST_STR_LEN("If-None-Match"))
|
||||
: NULL;
|
||||
|
@ -2151,7 +2151,7 @@ webdav_if_match_or_unmodified_since (connection * const con, struct stat *st)
|
|||
|
||||
buffer *etagb = con->physical.etag;
|
||||
if (NULL != st && (NULL != im || NULL != inm)) {
|
||||
etag_create(etagb, st, con->etag_flags);
|
||||
etag_create(etagb, st, con->conf.etag_flags);
|
||||
etag_mutate(etagb, etagb);
|
||||
}
|
||||
|
||||
|
@ -2187,9 +2187,9 @@ webdav_response_etag (const plugin_config * const pconf,
|
|||
connection * const con, struct stat *st)
|
||||
{
|
||||
server *srv = pconf->srv;
|
||||
if (0 != con->etag_flags) {
|
||||
if (0 != con->conf.etag_flags) {
|
||||
buffer *etagb = con->physical.etag;
|
||||
etag_create(etagb, st, con->etag_flags);
|
||||
etag_create(etagb, st, con->conf.etag_flags);
|
||||
stat_cache_update_entry(srv,CONST_BUF_LEN(con->physical.path),st,etagb);
|
||||
etag_mutate(etagb, etagb);
|
||||
http_header_response_set(con, HTTP_HEADER_ETAG,
|
||||
|
@ -3056,9 +3056,9 @@ webdav_propfind_live_props (const webdav_propfind_bufs * const restrict pb,
|
|||
if (pnum != WEBDAV_PROP_ALL) return 0;/* found *//*(else fall through)*/
|
||||
__attribute_fallthrough__
|
||||
case WEBDAV_PROP_GETETAG:
|
||||
if (0 != pb->con->etag_flags) {
|
||||
if (0 != pb->con->conf.etag_flags) {
|
||||
buffer *etagb = pb->con->physical.etag;
|
||||
etag_create(etagb, &pb->st, pb->con->etag_flags);
|
||||
etag_create(etagb, &pb->st, pb->con->conf.etag_flags);
|
||||
etag_mutate(etagb, etagb);
|
||||
buffer_append_string_len(b, CONST_STR_LEN(
|
||||
"<D:getetag>"));
|
||||
|
@ -3643,7 +3643,7 @@ webdav_has_lock (connection * const con,
|
|||
if (*p != ']') break; /* invalid syntax */
|
||||
if (p == etag) continue; /* ignore entity-tag if empty */
|
||||
if (notflag) continue;/* ignore entity-tag in NOT context */
|
||||
if (0 == con->etag_flags) continue; /* ignore entity-tag */
|
||||
if (0==con->conf.etag_flags) continue; /*ignore entity-tag*/
|
||||
struct stat st;
|
||||
if (0 != lstat(con->physical.path->ptr, &st)) {
|
||||
http_status_set_error(con,412);/* Precondition Failed */
|
||||
|
@ -3651,7 +3651,7 @@ webdav_has_lock (connection * const con,
|
|||
}
|
||||
if (S_ISDIR(st.st_mode)) continue;/*we ignore etag if dir*/
|
||||
buffer *etagb = con->physical.etag;
|
||||
etag_create(etagb, &st, con->etag_flags);
|
||||
etag_create(etagb, &st, con->conf.etag_flags);
|
||||
etag_mutate(etagb, etagb);
|
||||
*p = '\0';
|
||||
int ematch = etag_is_equal(etagb, etag, 0);
|
||||
|
@ -4201,7 +4201,7 @@ mod_webdav_put_0 (connection * const con, const plugin_config * const pconf)
|
|||
O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
|
||||
WEBDAV_FILE_MODE);
|
||||
if (fd >= 0) {
|
||||
if (0 != con->etag_flags) {
|
||||
if (0 != con->conf.etag_flags) {
|
||||
/*(skip sending etag if fstat() error; not expected)*/
|
||||
struct stat st;
|
||||
if (0 == fstat(fd, &st)) webdav_response_etag(pconf, con, &st);
|
||||
|
@ -4358,7 +4358,8 @@ mod_webdav_put_linkat_rename (connection * const con,
|
|||
unlink(pathtemp);
|
||||
}
|
||||
|
||||
if (0 != con->etag_flags && http_status_get(con) < 300) { /*(201, 204)*/
|
||||
if (0 != con->conf.etag_flags
|
||||
&& http_status_get(con) < 300) { /*(201, 204)*/
|
||||
/*(skip sending etag if fstat() error; not expected)*/
|
||||
if (0 == fstat(c->file.fd, &st))
|
||||
webdav_response_etag(pconf, con, &st);
|
||||
|
@ -4415,9 +4416,9 @@ mod_webdav_put_deprecated_unsafe_partial_put_compat (connection * const con,
|
|||
mod_webdav_write_cq(con, con->request_content_queue, fd);
|
||||
|
||||
struct stat st;
|
||||
if (0 != con->etag_flags && !http_status_is_set(con)) {
|
||||
if (0 != con->conf.etag_flags && !http_status_is_set(con)) {
|
||||
/*(skip sending etag if fstat() error; not expected)*/
|
||||
if (0 != fstat(fd, &st)) con->etag_flags = 0;
|
||||
if (0 != fstat(fd, &st)) con->conf.etag_flags = 0;
|
||||
}
|
||||
|
||||
const int wc = close(fd);
|
||||
|
@ -4426,7 +4427,7 @@ mod_webdav_put_deprecated_unsafe_partial_put_compat (connection * const con,
|
|||
|
||||
if (!http_status_is_set(con)) {
|
||||
http_status_set_fin(con, 204); /* No Content */
|
||||
if (0 != con->etag_flags) webdav_response_etag(pconf, con, &st);
|
||||
if (0 != con->conf.etag_flags) webdav_response_etag(pconf, con, &st);
|
||||
}
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
|
@ -4530,9 +4531,9 @@ mod_webdav_put (connection * const con, const plugin_config * const pconf)
|
|||
mod_webdav_write_cq(con, cq, fd);
|
||||
|
||||
struct stat st;
|
||||
if (0 != con->etag_flags && !http_status_is_set(con)) {
|
||||
if (0 != con->conf.etag_flags && !http_status_is_set(con)) {
|
||||
/*(skip sending etag if fstat() error; not expected)*/
|
||||
if (0 != fstat(fd, &st)) con->etag_flags = 0;
|
||||
if (0 != fstat(fd, &st)) con->conf.etag_flags = 0;
|
||||
}
|
||||
|
||||
const int wc = close(fd);
|
||||
|
@ -4547,7 +4548,7 @@ mod_webdav_put (connection * const con, const plugin_config * const pconf)
|
|||
if (201 == http_status_get(con))
|
||||
webdav_parent_modified(pconf, con->physical.path);
|
||||
if (0 == rename(pathtemp, con->physical.path->ptr)) {
|
||||
if (0 != con->etag_flags) webdav_response_etag(pconf, con, &st);
|
||||
if (0 != con->conf.etag_flags) webdav_response_etag(pconf,con,&st);
|
||||
}
|
||||
else {
|
||||
if (errno == EISDIR)
|
||||
|
@ -5371,7 +5372,7 @@ mod_webdav_lock (connection * const con, const plugin_config * const pconf)
|
|||
: -1;
|
||||
if (fd >= 0) {
|
||||
/*(skip sending etag if fstat() error; not expected)*/
|
||||
if (0 != fstat(fd, &st)) con->etag_flags = 0;
|
||||
if (0 != fstat(fd, &st)) con->conf.etag_flags = 0;
|
||||
close(fd);
|
||||
created = 1;
|
||||
webdav_parent_modified(pconf, con->physical.path);
|
||||
|
@ -5432,7 +5433,7 @@ mod_webdav_lock (connection * const con, const plugin_config * const pconf)
|
|||
CONST_STR_LEN("Lock-Token"),
|
||||
lockstr, sizeof(lockstr)-1);
|
||||
webdav_xml_doc_lock_acquired(con, pconf, &lockdata);
|
||||
if (0 != con->etag_flags && !S_ISDIR(st.st_mode))
|
||||
if (0 != con->conf.etag_flags && !S_ISDIR(st.st_mode))
|
||||
webdav_response_etag(pconf, con, &st);
|
||||
http_status_set_fin(con, created ? 201 : 200); /* Created | OK */
|
||||
}
|
||||
|
|
266
src/network.c
266
src/network.c
|
@ -5,6 +5,7 @@
|
|||
#include "fdevent.h"
|
||||
#include "log.h"
|
||||
#include "connections.h"
|
||||
#include "plugin.h"
|
||||
#include "configfile.h"
|
||||
#include "sock_addr.h"
|
||||
|
||||
|
@ -137,10 +138,60 @@ static void network_srv_sockets_append(server *srv, server_socket *srv_socket) {
|
|||
srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
|
||||
}
|
||||
|
||||
static int network_server_init(server *srv, buffer *host_token, size_t sidx, int stdin_fd) {
|
||||
typedef struct {
|
||||
/* global or per-socket config; not patched per connection */
|
||||
int listen_backlog;
|
||||
unsigned char ssl_enabled;
|
||||
unsigned char use_ipv6;
|
||||
unsigned char set_v6only; /* set_v6only is only a temporary option */
|
||||
unsigned char defer_accept;
|
||||
const buffer *socket_perms;
|
||||
const buffer *bsd_accept_filter;
|
||||
} network_socket_config;
|
||||
|
||||
typedef struct {
|
||||
PLUGIN_DATA;
|
||||
network_socket_config defaults;
|
||||
network_socket_config conf;
|
||||
} network_plugin_data;
|
||||
|
||||
static void network_merge_config_cpv(network_socket_config * const pconf, const config_plugin_value_t * const cpv) {
|
||||
switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
|
||||
case 0: /* ssl.engine */
|
||||
pconf->ssl_enabled = (0 != cpv->v.u);
|
||||
break;
|
||||
case 1: /* server.listen-backlog */
|
||||
pconf->listen_backlog = (int)cpv->v.u;
|
||||
break;
|
||||
case 2: /* server.socket-perms */
|
||||
pconf->socket_perms = cpv->v.b;
|
||||
break;
|
||||
case 3: /* server.bsd-accept-filter */
|
||||
pconf->bsd_accept_filter = cpv->v.b;
|
||||
break;
|
||||
case 4: /* server.defer-accept */
|
||||
pconf->defer_accept = (0 != cpv->v.u);
|
||||
break;
|
||||
case 5: /* server.use-ipv6 */
|
||||
pconf->use_ipv6 = (0 != cpv->v.u);
|
||||
break;
|
||||
case 6: /* server.set-v6only */
|
||||
pconf->set_v6only = (0 != cpv->v.u);
|
||||
break;
|
||||
default:/* should not happen */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void network_merge_config(network_socket_config * const pconf, const config_plugin_value_t *cpv) {
|
||||
do {
|
||||
network_merge_config_cpv(pconf, cpv);
|
||||
} while ((++cpv)->k_id != -1);
|
||||
}
|
||||
|
||||
static int network_server_init(server *srv, network_socket_config *s, buffer *host_token, size_t sidx, int stdin_fd) {
|
||||
server_socket *srv_socket;
|
||||
const char *host;
|
||||
specific_config *s = srv->config_storage[sidx];
|
||||
socklen_t addr_len = sizeof(sock_addr);
|
||||
sock_addr addr;
|
||||
int family = 0;
|
||||
|
@ -156,7 +207,6 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
|
|||
* binary addresses are matched further below) */
|
||||
for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) {
|
||||
if (buffer_is_equal(srv->srv_sockets.ptr[i]->srv_token, host_token)) {
|
||||
buffer_copy_buffer(host_token, srv->srv_sockets.ptr[i]->srv_token);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -398,7 +448,7 @@ int network_close(server *srv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int network_socket_activation_nfds(server *srv, int nfds) {
|
||||
static int network_socket_activation_nfds(server *srv, network_socket_config *s, int nfds) {
|
||||
buffer *host = buffer_init();
|
||||
socklen_t addr_len;
|
||||
sock_addr addr;
|
||||
|
@ -412,7 +462,7 @@ static int network_socket_activation_nfds(server *srv, int nfds) {
|
|||
break;
|
||||
}
|
||||
network_host_normalize_addr_str(host, &addr);
|
||||
rc = network_server_init(srv, host, 0, fd);
|
||||
rc = network_server_init(srv, s, host, 0, fd);
|
||||
if (0 != rc) break;
|
||||
srv->srv_sockets.ptr[srv->srv_sockets.used-1]->sidx = (unsigned short)~0u;
|
||||
}
|
||||
|
@ -422,13 +472,13 @@ static int network_socket_activation_nfds(server *srv, int nfds) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int network_socket_activation_from_env(server *srv) {
|
||||
static int network_socket_activation_from_env(server *srv, network_socket_config *s) {
|
||||
char *listen_pid = getenv("LISTEN_PID");
|
||||
char *listen_fds = getenv("LISTEN_FDS");
|
||||
pid_t lpid = listen_pid ? (pid_t)strtoul(listen_pid,NULL,10) : 0;
|
||||
int nfds = listen_fds ? atoi(listen_fds) : 0;
|
||||
int rc = (lpid == getpid() && nfds > 0)
|
||||
? network_socket_activation_nfds(srv, nfds)
|
||||
? network_socket_activation_nfds(srv, s, nfds)
|
||||
: 0;
|
||||
unsetenv("LISTEN_PID");
|
||||
unsetenv("LISTEN_FDS");
|
||||
|
@ -438,85 +488,151 @@ static int network_socket_activation_from_env(server *srv) {
|
|||
}
|
||||
|
||||
int network_init(server *srv, int stdin_fd) {
|
||||
#ifdef __WIN32
|
||||
WSADATA wsaData;
|
||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||
if (0 != WSAStartup(wVersionRequested, &wsaData)) {
|
||||
/* Tell the user that we could not find a usable WinSock DLL */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/*(network params used during setup (from $SERVER["socket"] condition))*/
|
||||
static const config_plugin_keys_t cpk[] = {
|
||||
{ CONST_STR_LEN("ssl.engine"),
|
||||
T_CONFIG_BOOL,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.listen-backlog"),
|
||||
T_CONFIG_INT,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.socket-perms"),
|
||||
T_CONFIG_STRING,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.bsd-accept-filter"),
|
||||
T_CONFIG_STRING,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.defer-accept"),
|
||||
T_CONFIG_BOOL,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.use-ipv6"),
|
||||
T_CONFIG_BOOL,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ CONST_STR_LEN("server.set-v6only"),
|
||||
T_CONFIG_BOOL,
|
||||
T_CONFIG_SCOPE_CONNECTION }
|
||||
,{ NULL, 0,
|
||||
T_CONFIG_UNSET,
|
||||
T_CONFIG_SCOPE_UNSET }
|
||||
};
|
||||
|
||||
if (0 != network_write_init(srv)) return -1;
|
||||
#ifdef __WIN32
|
||||
WSADATA wsaData;
|
||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||
if (0 != WSAStartup(wVersionRequested, &wsaData)) {
|
||||
/* Tell the user that we could not find a usable WinSock DLL */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (srv->srvconf.systemd_socket_activation) {
|
||||
for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
||||
srv->srv_sockets_inherited.ptr[i]->sidx = (unsigned short)~0u;
|
||||
}
|
||||
if (0 != network_socket_activation_from_env(srv)) return -1;
|
||||
if (0 == srv->srv_sockets_inherited.used) {
|
||||
srv->srvconf.systemd_socket_activation = 0;
|
||||
}
|
||||
}
|
||||
if (0 != network_write_init(srv)) return -1;
|
||||
|
||||
/* process srv->srvconf.bindhost
|
||||
* (skip if systemd socket activation is enabled and bindhost is empty; do not additionally listen on "*") */
|
||||
if (!srv->srvconf.systemd_socket_activation || !buffer_string_is_empty(srv->srvconf.bindhost)) {
|
||||
int rc;
|
||||
buffer *b = buffer_init();
|
||||
buffer_copy_buffer(b, srv->srvconf.bindhost);
|
||||
if (b->ptr[0] != '/') { /*(skip adding port if unix socket path)*/
|
||||
buffer_append_string_len(b, CONST_STR_LEN(":"));
|
||||
buffer_append_int(b, srv->srvconf.port);
|
||||
}
|
||||
network_plugin_data np;
|
||||
memset(&np, 0, sizeof(network_plugin_data));
|
||||
network_plugin_data *p = &np;
|
||||
|
||||
rc = (-1 == stdin_fd || 0 == srv->srv_sockets.used)
|
||||
? network_server_init(srv, b, 0, stdin_fd)
|
||||
: close(stdin_fd);/*(graceful restart listening to "/dev/stdin")*/
|
||||
buffer_free(b);
|
||||
if (0 != rc) return -1;
|
||||
}
|
||||
if (!config_plugin_values_init(srv, p, cpk, "network"))
|
||||
return HANDLER_ERROR;
|
||||
|
||||
/* check for $SERVER["socket"] */
|
||||
for (uint32_t i = 1; i < srv->config_context->used; ++i) {
|
||||
config_cond_info cfginfo;
|
||||
config_get_config_cond_info(srv, i, &cfginfo);
|
||||
buffer *host_token;
|
||||
*(const buffer **)&host_token = cfginfo.string;
|
||||
/*(cfginfo.string is modified during config)*/
|
||||
p->defaults.listen_backlog = 1024;
|
||||
p->defaults.defer_accept = 0;
|
||||
p->defaults.use_ipv6 = 0;
|
||||
p->defaults.set_v6only = 1;
|
||||
|
||||
/* not our stage */
|
||||
if (COMP_SERVER_SOCKET != cfginfo.comp) continue;
|
||||
/* initialize p->defaults from global config context */
|
||||
if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
|
||||
const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
|
||||
if (-1 != cpv->k_id)
|
||||
network_merge_config(&p->defaults, cpv);
|
||||
}
|
||||
|
||||
if (cfginfo.cond == CONFIG_COND_NE) {
|
||||
socklen_t addr_len = sizeof(sock_addr);
|
||||
sock_addr addr;
|
||||
if (0 != network_host_parse_addr(srv, &addr, &addr_len, host_token, srv->config_storage[i]->use_ipv6)) {
|
||||
return -1;
|
||||
}
|
||||
network_host_normalize_addr_str(host_token, &addr);
|
||||
continue;
|
||||
}
|
||||
int rc = 0;
|
||||
do {
|
||||
|
||||
if (cfginfo.cond != CONFIG_COND_EQ) continue;
|
||||
if (srv->srvconf.systemd_socket_activation) {
|
||||
for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
||||
srv->srv_sockets_inherited.ptr[i]->sidx = (unsigned short)~0u;
|
||||
}
|
||||
rc = network_socket_activation_from_env(srv, &p->defaults);
|
||||
if (0 != rc) break;
|
||||
if (0 == srv->srv_sockets_inherited.used) {
|
||||
srv->srvconf.systemd_socket_activation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != network_server_init(srv, host_token, i, -1)) return -1;
|
||||
}
|
||||
/* process srv->srvconf.bindhost
|
||||
* (skip if systemd socket activation is enabled and bindhost is empty;
|
||||
* do not additionally listen on "*") */
|
||||
if (!srv->srvconf.systemd_socket_activation
|
||||
|| !buffer_string_is_empty(srv->srvconf.bindhost)) {
|
||||
buffer *b = buffer_init();
|
||||
buffer_copy_buffer(b, srv->srvconf.bindhost);
|
||||
if (b->ptr[0] != '/') { /*(skip adding port if unix socket path)*/
|
||||
buffer_append_string_len(b, CONST_STR_LEN(":"));
|
||||
buffer_append_int(b, srv->srvconf.port);
|
||||
}
|
||||
|
||||
if (srv->srvconf.systemd_socket_activation) {
|
||||
/* activate any inherited sockets not explicitly listed in config file */
|
||||
server_socket *srv_socket;
|
||||
for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
||||
if ((unsigned short)~0u != srv->srv_sockets_inherited.ptr[i]->sidx) continue;
|
||||
srv->srv_sockets_inherited.ptr[i]->sidx = 0;
|
||||
srv_socket = calloc(1, sizeof(server_socket));
|
||||
force_assert(NULL != srv_socket);
|
||||
memcpy(srv_socket, srv->srv_sockets_inherited.ptr[i], sizeof(server_socket));
|
||||
network_srv_sockets_append(srv, srv_socket);
|
||||
}
|
||||
}
|
||||
rc = (-1 == stdin_fd || 0 == srv->srv_sockets.used)
|
||||
? network_server_init(srv, &p->defaults, b, 0, stdin_fd)
|
||||
: close(stdin_fd);/*(graceful restart listening to "/dev/stdin")*/
|
||||
buffer_free(b);
|
||||
if (0 != rc) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* check for $SERVER["socket"] */
|
||||
for (uint32_t i = 1; i < srv->config_context->used; ++i) {
|
||||
config_cond_info cfginfo;
|
||||
config_get_config_cond_info(srv, i, &cfginfo);
|
||||
if (COMP_SERVER_SOCKET != cfginfo.comp) continue;/* not our stage */
|
||||
|
||||
buffer *host_token;
|
||||
*(const buffer **)&host_token = cfginfo.string;
|
||||
/*(cfginfo.string is modified during config)*/
|
||||
|
||||
memcpy(&p->conf, &p->defaults, sizeof(network_socket_config));
|
||||
for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
|
||||
if ((int)i != p->cvlist[j].k_id) continue;
|
||||
const config_plugin_value_t *cpv =
|
||||
p->cvlist + p->cvlist[j].v.u2[0];
|
||||
network_merge_config(&p->conf, cpv);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cfginfo.cond == CONFIG_COND_EQ) {
|
||||
rc = network_server_init(srv, &p->conf, host_token, i, -1);
|
||||
if (0 != rc) break;
|
||||
}
|
||||
else if (cfginfo.cond == CONFIG_COND_NE) {
|
||||
socklen_t addr_len = sizeof(sock_addr);
|
||||
sock_addr addr;
|
||||
rc = network_host_parse_addr(srv, &addr, &addr_len,
|
||||
host_token, p->conf.use_ipv6);
|
||||
if (0 != rc) break;
|
||||
network_host_normalize_addr_str(host_token, &addr);
|
||||
}
|
||||
}
|
||||
if (0 != rc) break;
|
||||
|
||||
if (srv->srvconf.systemd_socket_activation) {
|
||||
/* activate any inherited sockets not explicitly listed in config */
|
||||
server_socket *srv_socket;
|
||||
for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
||||
if ((unsigned short)~0u
|
||||
!= srv->srv_sockets_inherited.ptr[i]->sidx)
|
||||
continue;
|
||||
srv->srv_sockets_inherited.ptr[i]->sidx = 0;
|
||||
srv_socket = calloc(1, sizeof(server_socket));
|
||||
force_assert(NULL != srv_socket);
|
||||
memcpy(srv_socket, srv->srv_sockets_inherited.ptr[i],
|
||||
sizeof(server_socket));
|
||||
network_srv_sockets_append(srv, srv_socket);
|
||||
}
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
free(p->cvlist);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void network_unregister_sock(server *srv, server_socket *srv_socket) {
|
||||
|
|
|
@ -35,12 +35,11 @@ static int http_response_omit_header(connection *con, const data_string * const
|
|||
&& buffer_eq_icase_ssn(ds->key.ptr+sizeof("X-LIGHTTPD-")-1,
|
||||
CONST_STR_LEN("KBytes-per-second"))) {
|
||||
/* "X-LIGHTTPD-KBytes-per-second" */
|
||||
long limit = strtol(ds->value.ptr, NULL, 10);
|
||||
off_t limit = strtol(ds->value.ptr, NULL, 10) << 10; /*(*=1024)*/
|
||||
if (limit > 0
|
||||
&& (limit < con->conf.kbytes_per_second
|
||||
|| 0 == con->conf.kbytes_per_second)) {
|
||||
if (limit > USHRT_MAX) limit= USHRT_MAX;
|
||||
con->conf.kbytes_per_second = limit;
|
||||
&& (limit < con->conf.bytes_per_second
|
||||
|| 0 == con->conf.bytes_per_second)) {
|
||||
con->conf.bytes_per_second = limit;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -59,6 +58,7 @@ int http_response_write_header(server *srv, connection *con) {
|
|||
http_status_append(b, con->http_status);
|
||||
|
||||
/* disable keep-alive if requested */
|
||||
|
||||
if (con->request_count > con->conf.max_keep_alive_requests || 0 == con->conf.max_keep_alive_idle) {
|
||||
con->keep_alive = 0;
|
||||
} else if (0 != con->request.content_length
|
||||
|
@ -435,7 +435,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
|
|||
| (1 << COMP_HTTP_URL)
|
||||