#include "mod_core.h"
#include "mod_proxy.h"
#include "ap_listen.h"
+#include "ap_provider.h"
#include "mod_so.h" /* for ap_find_loaded_module_symbol */
AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
AP_DECLARE_DATA int ap_config_generation = 0;
+typedef struct {
+ apr_ipsubnet_t *subnet;
+ struct ap_logconf log;
+} conn_log_config;
+
static void *create_core_dir_config(apr_pool_t *a, char *dir)
{
core_dir_config *conf;
conf->d_is_fnmatch = new->d_is_fnmatch;
conf->d_components = new->d_components;
conf->r = new->r;
+ conf->refs = new->refs;
conf->condition = new->condition;
if (new->opts & OPT_UNSET) {
conf->enable_sendfile = new->enable_sendfile;
}
- conf->allow_encoded_slashes = new->allow_encoded_slashes;
- conf->decode_encoded_slashes = new->decode_encoded_slashes;
+ if (new->allow_encoded_slashes_set) {
+ conf->allow_encoded_slashes = new->allow_encoded_slashes;
+ }
+ if (new->decode_encoded_slashes_set) {
+ conf->decode_encoded_slashes = new->decode_encoded_slashes;
+ }
if (new->log) {
if (!conf->log) {
if (virt->trace_enable != AP_TRACE_UNSET)
conf->trace_enable = virt->trace_enable;
+ if (virt->http09_enable != AP_HTTP09_UNSET)
+ conf->http09_enable = virt->http09_enable;
+
+ if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
+ conf->http_conformance = virt->http_conformance;
+
+ if (virt->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_UNSET)
+ conf->http_cl_head_zero = virt->http_cl_head_zero;
+
+ if (virt->http_expect_strict != AP_HTTP_EXPECT_STRICT_UNSET)
+ conf->http_expect_strict = virt->http_expect_strict;
+
/* no action for virt->accf_map, not allowed per-vhost */
if (virt->protocol)
if (virt->error_log_req)
conf->error_log_req = virt->error_log_req;
+ if (virt->conn_log_level) {
+ if (!conf->conn_log_level) {
+ conf->conn_log_level = virt->conn_log_level;
+ }
+ else {
+ /* apr_array_append actually creates a new array */
+ conf->conn_log_level = apr_array_append(p, conf->conn_log_level,
+ virt->conn_log_level);
+ }
+ }
+
return conf;
}
#if APR_HAVE_IPV6
if (ap_strchr_c(plain_server_name, ':')) { /* IPv6 literal? */
- return apr_psprintf(r->pool, "[%s]", plain_server_name);
+ return apr_pstrcat(r->pool, "[", plain_server_name, "]", NULL);
}
#endif
return plain_server_name;
|| (found = find_parent(cmd->directive, "<LocationMatch"))))
|| ((forbidden & NOT_IN_FILES)
&& ((found = find_parent(cmd->directive, "<Files"))
- || (found = find_parent(cmd->directive, "<FilesMatch"))))) {
+ || (found = find_parent(cmd->directive, "<FilesMatch"))
+ || (found = find_parent(cmd->directive, "<If"))
+ || (found = find_parent(cmd->directive, "<ElseIf"))
+ || (found = find_parent(cmd->directive, "<Else"))))) {
return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
" cannot occur within ", found->directive,
"> section", NULL);
return NULL;
}
-static const char *generate_error(cmd_parms *cmd, void *dummy,
- const char *arg)
+static const char *generate_message(cmd_parms *cmd, void *dummy,
+ const char *arg)
{
+ /* cast with 64-bit warning avoidance */
+ int level = (cmd->info==(void*)APLOG_ERR)? APLOG_ERR: APLOG_WARNING;
+ char * msg;
+
+ /* get position information from wherever we can? */
+ ap_configfile_t * cf = cmd->config_file;
+ ap_directive_t const * ed1 = cmd->directive;
+ ap_directive_t const * ed2 = cmd->err_directive;
+
+ /* expect an argument */
if (!arg || !*arg) {
- return "The Error directive was used with no message.";
+ return "The Error or Warning directive was used with no message.";
}
- if (*arg == '"' || *arg == '\'') { /* strip off quotes */
+ /* set message, strip off quotes if necessary */
+ msg = (char *)arg;
+ if (*arg == '"' || *arg == '\'') {
apr_size_t len = strlen(arg);
char last = *(arg + len - 1);
if (*arg == last) {
- return apr_pstrndup(cmd->pool, arg + 1, len - 2);
+ msg = apr_pstrndup(cmd->pool, arg + 1, len - 2);
}
}
- return arg;
+ /* generate error or warning with a configuration file position.
+ * the log is displayed on the terminal as no log file is opened yet.
+ */
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|level, 0, NULL,
+ "%s on line %d of %s", msg,
+ cf? cf->line_number:
+ ed1? ed1->line_num:
+ ed2? ed2->line_num: -1,
+ cf? cf->name:
+ ed1? ed1->filename:
+ ed2? ed2->filename: "<UNKNOWN>");
+
+ /* message displayed above, return will stop configuration processing */
+ return level==APLOG_ERR?
+ "Configuration processing stopped by Error directive": NULL;
}
#ifdef GPROF
conf->ap_document_root = arg;
}
else {
- return "DocumentRoot must be a directory";
+ return apr_psprintf(cmd->pool,
+ "DocumentRoot '%s' is not a directory, or is not readable",
+ arg);
}
}
return NULL;
if (error_number == 401 && what == REMOTE_PATH) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(00113)
- "cannot use a full URL in a 401 ErrorDocument "
- "directive --- ignoring!");
+ "%s:%d cannot use a full URL in a 401 ErrorDocument "
+ "directive --- ignoring!", cmd->directive->filename, cmd->directive->line_num);
}
else { /* Store it... */
if (conf->response_code_strings == NULL) {
RESPONSE_CODES);
}
- if (strcmp(msg, "default") == 0) {
+ if (strcasecmp(msg, "default") == 0) {
/* special case: ErrorDocument 404 default restores the
* canned server error response
*/
* a msg and a (local) path.
*/
conf->response_code_strings[index_number] = (what == MSG) ?
- apr_pstrcat(cmd->pool, "\"",msg,NULL) :
+ apr_pstrcat(cmd->pool, "\"", msg, NULL) :
apr_pstrdup(cmd->pool, msg);
}
}
if (v)
set_allow_opts(cmd, &(d->override_opts), v);
else
- d->override_opts = OPT_SYM_LINKS;
+ d->override_opts = OPT_ALL;
}
else if (!strcasecmp(w, "FileInfo")) {
d->override |= OR_FILEINFO;
conf->d = cmd->path;
conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0);
+ if (r) {
+ conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
+ ap_regname(r, conf->refs, AP_REG_MATCH, 1);
+ }
+
/* Make this explicit - the "/" root has 0 elements, that is, we
* will always merge it, and it will always sort and merge first.
* All others are sorted and tested by the number of slashes.
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
conf->r = r;
+ if (r) {
+ conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
+ ap_regname(r, conf->refs, AP_REG_MATCH, 1);
+ }
+
ap_add_per_url_conf(cmd->server, new_url_conf);
if (*arg != '\0') {
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
conf->r = r;
+ if (r) {
+ conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
+ ap_regname(r, conf->refs, AP_REG_MATCH, 1);
+ }
+
ap_add_file_conf(cmd->pool, (core_dir_config *)mconfig, new_file_conf);
if (*arg != '\0') {
arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg);
-
+ /*
+ * Set a dummy value so that other directives notice that they are inside
+ * a config section.
+ */
+ cmd->path = "*If";
/* Only if not an .htaccess file */
if (!old_path) {
cmd->override = OR_ALL|ACCESS_CONF;
cmd->cmd->name, " must be On, Off, or NoDecode",
NULL);
}
+
+ d->allow_encoded_slashes_set = 1;
+ d->decode_encoded_slashes_set = 1;
+
return NULL;
}
return NULL;
}
-static const char *set_loglevel(cmd_parms *cmd, void *config_, const char *arg_)
+static const char *update_loglevel(cmd_parms *cmd, struct ap_logconf *log,
+ const char *arg)
{
- char *level_str;
- int level;
+ const char *level_str, *err;
module *module;
- char *arg = apr_pstrdup(cmd->temp_pool, arg_);
- struct ap_logconf *log;
- const char *err;
-
- if (cmd->path) {
- core_dir_config *dconf = config_;
- if (!dconf->log) {
- dconf->log = ap_new_log_config(cmd->pool, NULL);
- }
- log = dconf->log;
- }
- else {
- log = &cmd->server->log;
- }
-
- if (arg == NULL)
- return "LogLevel requires level keyword or module loglevel specifier";
+ int level;
- level_str = ap_strrchr(arg, ':');
+ level_str = ap_strrchr_c(arg, ':');
if (level_str == NULL) {
err = ap_parse_log_level(arg, &log->level);
return err;
ap_reset_module_loglevels(log, APLOG_NO_MODULE);
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
- "Setting LogLevel for all modules to %s", arg);
+ "Setting %s for all modules to %s", cmd->cmd->name, arg);
return NULL;
}
- *level_str++ = '\0';
+ arg = apr_pstrmemdup(cmd->temp_pool, arg, level_str - arg);
+ level_str++;
if (!*level_str) {
return apr_psprintf(cmd->temp_pool, "Module specifier '%s' must be "
"followed by a log level keyword", arg);
ap_set_module_loglevel(cmd->pool, log, module->module_index, level);
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
- "Setting LogLevel for module %s to %s", module->name,
- level_str);
+ "Setting %s for module %s to %s", cmd->cmd->name,
+ module->name, level_str);
return NULL;
}
+static const char *set_loglevel(cmd_parms *cmd, void *config_, const char *arg)
+{
+ struct ap_logconf *log;
+
+ if (cmd->path) {
+ core_dir_config *dconf = config_;
+ if (!dconf->log) {
+ dconf->log = ap_new_log_config(cmd->pool, NULL);
+ }
+ log = dconf->log;
+ }
+ else {
+ log = &cmd->server->log;
+ }
+
+ if (arg == NULL)
+ return "LogLevel requires level keyword or module loglevel specifier";
+
+ return update_loglevel(cmd, log, arg);
+}
+
+static const char *set_loglevel_override(cmd_parms *cmd, void *d_, int argc,
+ char *const argv[])
+{
+ core_server_config *sconf;
+ conn_log_config *entry;
+ int ret, i;
+ const char *addr, *mask, *err;
+
+ if (argc < 2)
+ return "LogLevelOverride requires at least two arguments";
+
+ entry = apr_pcalloc(cmd->pool, sizeof(conn_log_config));
+ sconf = ap_get_core_module_config(cmd->server->module_config);
+ if (!sconf->conn_log_level)
+ sconf->conn_log_level = apr_array_make(cmd->pool, 4, sizeof(entry));
+ APR_ARRAY_PUSH(sconf->conn_log_level, conn_log_config *) = entry;
+
+ addr = argv[0];
+ mask = ap_strchr_c(addr, '/');
+ if (mask) {
+ addr = apr_pstrmemdup(cmd->temp_pool, addr, mask - addr);
+ mask++;
+ }
+ ret = apr_ipsubnet_create(&entry->subnet, addr, mask, cmd->pool);
+ if (ret != APR_SUCCESS)
+ return "parsing of subnet/netmask failed";
+
+ for (i = 1; i < argc; i++) {
+ if ((err = update_loglevel(cmd, &entry->log, argv[i])) != NULL)
+ return err;
+ }
+ return NULL;
+}
+
AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r)
{
char sport[20];
SrvTk_MINIMAL, /* eg: Apache/2.0.41 */
SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */
SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */
- SrvTk_PRODUCT_ONLY /* eg: Apache */
+ SrvTk_PRODUCT_ONLY /* eg: Apache */
};
static enum server_token_type ap_server_tokens = SrvTk_FULL;
}
static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
- const char *arg1, const char *arg2)
+ const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
return err;
}
- if (!strcasecmp(arg1, "OS")) {
+ if (!strcasecmp(arg, "OS")) {
ap_server_tokens = SrvTk_OS;
}
- else if (!strcasecmp(arg1, "Min") || !strcasecmp(arg1, "Minimal")) {
+ else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) {
ap_server_tokens = SrvTk_MINIMAL;
}
- else if (!strcasecmp(arg1, "Major")) {
+ else if (!strcasecmp(arg, "Major")) {
ap_server_tokens = SrvTk_MAJOR;
}
- else if (!strcasecmp(arg1, "Minor") ) {
+ else if (!strcasecmp(arg, "Minor") ) {
ap_server_tokens = SrvTk_MINOR;
}
- else if (!strcasecmp(arg1, "Prod") || !strcasecmp(arg1, "ProductOnly")) {
+ else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) {
ap_server_tokens = SrvTk_PRODUCT_ONLY;
}
- else {
+ else if (!strcasecmp(arg, "Full")) {
ap_server_tokens = SrvTk_FULL;
}
+ else {
+ return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'";
+ }
return NULL;
}
return NULL;
}
+static const char *set_http_protocol(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ core_server_config *conf =
+ ap_get_core_module_config(cmd->server->module_config);
+
+ if (strncmp(arg, "min=", 4) == 0) {
+ arg += 4;
+ if (strcmp(arg, "0.9") == 0)
+ conf->http09_enable = AP_HTTP09_ENABLE;
+ else if (strcmp(arg, "1.0") == 0)
+ conf->http09_enable = AP_HTTP09_DISABLE;
+ else
+ return "HttpProtocol 'min' must be one of '0.9' and '1.0'";
+ return NULL;
+ }
+
+ if (strcmp(arg, "strict") == 0)
+ conf->http_conformance = AP_HTTP_CONFORMANCE_STRICT;
+ else if (strcmp(arg, "strict,log-only") == 0)
+ conf->http_conformance = AP_HTTP_CONFORMANCE_STRICT|
+ AP_HTTP_CONFORMANCE_LOGONLY;
+ else if (strcmp(arg, "liberal") == 0)
+ conf->http_conformance = AP_HTTP_CONFORMANCE_LIBERAL;
+ else
+ return "HttpProtocol accepts 'min=0.9', 'min=1.0', 'liberal', "
+ "'strict', 'strict,log-only'";
+
+ if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) &&
+ (conf->http_conformance & AP_HTTP_CONFORMANCE_LIBERAL)) {
+ return "HttpProtocol 'strict' and 'liberal' are mutually exclusive";
+ }
+
+ return NULL;
+}
+
+static const char *set_http_method(cmd_parms *cmd, void *conf, const char *arg)
+{
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL)
+ return err;
+ ap_method_register(cmd->pool, arg);
+ return NULL;
+}
+
+static const char *set_cl_head_zero(cmd_parms *cmd, void *dummy, int arg)
+{
+ core_server_config *conf =
+ ap_get_core_module_config(cmd->server->module_config);
+
+ if (arg) {
+ conf->http_cl_head_zero = AP_HTTP_CL_HEAD_ZERO_ENABLE;
+ } else {
+ conf->http_cl_head_zero = AP_HTTP_CL_HEAD_ZERO_DISABLE;
+ }
+ return NULL;
+}
+
+static const char *set_expect_strict(cmd_parms *cmd, void *dummy, int arg)
+{
+ core_server_config *conf =
+ ap_get_core_module_config(cmd->server->module_config);
+
+ if (arg) {
+ conf->http_expect_strict = AP_HTTP_EXPECT_STRICT_ENABLE;
+ } else {
+ conf->http_expect_strict = AP_HTTP_EXPECT_STRICT_DISABLE;
+ }
+ return NULL;
+}
+
static apr_hash_t *errorlog_hash;
static int log_constant_item(const ap_errorlog_info *info, const char *arg,
return a;
}
+static const char *set_errorlog(cmd_parms *cmd, void *dummy, const char *arg1,
+ const char *arg2)
+{
+ ap_errorlog_provider *provider;
+ const char *err;
+ cmd->server->errorlog_provider = NULL;
+
+ if (!arg2) {
+ /* Stay backward compatible and check for "syslog" */
+ if (strncmp("syslog", arg1, 6) == 0) {
+ arg2 = arg1 + 7; /* skip the ':' if any */
+ arg1 = "syslog";
+ }
+ else {
+ /* Admin can define only "ErrorLog provider" and we should
+ * still handle that using the defined provider, but with empty
+ * error_fname. */
+ provider = ap_lookup_provider(AP_ERRORLOG_PROVIDER_GROUP, arg1,
+ AP_ERRORLOG_PROVIDER_VERSION);
+ if (provider) {
+ arg2 = "";
+ }
+ else {
+ return set_server_string_slot(cmd, dummy, arg1);
+ }
+ }
+ }
+
+ if (strcmp("file", arg1) == 0) {
+ return set_server_string_slot(cmd, dummy, arg2);
+ }
+
+ provider = ap_lookup_provider(AP_ERRORLOG_PROVIDER_GROUP, arg1,
+ AP_ERRORLOG_PROVIDER_VERSION);
+ if (!provider) {
+ return apr_psprintf(cmd->pool,
+ "Unknown ErrorLog provider: %s",
+ arg1);
+ }
+
+ err = provider->parse_errorlog_arg(cmd, arg2);
+ if (err) {
+ return err;
+ }
+
+ cmd->server->errorlog_provider = provider;
+ return set_server_string_slot(cmd, dummy, arg2);
+}
+
static const char *set_errorlog_format(cmd_parms *cmd, void *dummy,
const char *arg1, const char *arg2)
{
"Define a variable, optionally to a value. Same as passing -D to the command line."),
AP_INIT_TAKE1("UnDefine", unset_define, NULL, EXEC_ON_READ|ACCESS_CONF|RSRC_CONF,
"Undefine the existence of a variable. Undo a Define."),
-AP_INIT_RAW_ARGS("Error", generate_error, NULL, OR_ALL,
- "Generate error message from within configuration"),
+AP_INIT_RAW_ARGS("Error", generate_message, (void*) APLOG_ERR, OR_ALL,
+ "Generate error message from within configuration."),
+AP_INIT_RAW_ARGS("Warning", generate_message, (void*) APLOG_WARNING, OR_ALL,
+ "Generate warning message from within configuration."),
AP_INIT_RAW_ARGS("<If", ifsection, COND_IF, OR_ALL,
"Container for directives to be conditionally applied"),
AP_INIT_RAW_ARGS("<ElseIf", ifsection, COND_ELSEIF, OR_ALL,
"Common directory of server-related files (logs, confs, etc.)"),
AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ,
"Common directory for run-time files (shared memory, locks, etc.)"),
-AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
+AP_INIT_TAKE12("ErrorLog", set_errorlog,
(void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF,
"The filename of the error log"),
AP_INIT_TAKE12("ErrorLogFormat", set_errorlog_format, NULL, RSRC_CONF,
"does not exist or the pattern does not match any files"),
AP_INIT_ITERATE("LogLevel", set_loglevel, NULL, RSRC_CONF|ACCESS_CONF,
"Level of verbosity in error logging"),
+AP_INIT_TAKE_ARGV("LogLevelOverride", set_loglevel_override, NULL, RSRC_CONF,
+ "Override LogLevel for clients with certain IPs"),
AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
"A numeric IP address:port, or the name of a host"),
-AP_INIT_TAKE12("ServerTokens", set_serv_tokens, NULL, RSRC_CONF,
+AP_INIT_TAKE1("ServerTokens", set_serv_tokens, NULL, RSRC_CONF,
"Determine tokens displayed in the Server: header - Min(imal), "
- "Major, Minor, Prod, OS or Full"),
+ "Major, Minor, Prod(uctOnly), OS, or Full"),
AP_INIT_TAKE1("LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF,
"Limit on maximum size of an HTTP request line"),
AP_INIT_TAKE1("LimitRequestFieldsize", set_limit_req_fieldsize, NULL,
#endif
AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF,
"'on' (default), 'off' or 'extended' to trace request body content"),
+AP_INIT_ITERATE("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
+ "'min=0.9' (default) or 'min=1.0' to allow/deny HTTP/0.9; "
+ "'liberal', 'strict', 'strict,log-only'"),
+AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
+ "Registers non-standard HTTP methods"),
+AP_INIT_FLAG("HttpContentLengthHeadZero", set_cl_head_zero, NULL, OR_OPTIONS,
+ "whether to permit Content-Length of 0 responses to HEAD requests"),
+AP_INIT_FLAG("HttpExpectStrict", set_expect_strict, NULL, OR_OPTIONS,
+ "whether to return a 417 if a client doesn't send 100-Continue"),
{ NULL }
};
if (r->method_number == M_GET || r->method_number == M_POST) {
if (r->finfo.filetype == APR_NOFILE) {
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00128)
- "File does not exist: %s", r->filename);
+ "File does not exist: %s",
+ apr_pstrcat(r->pool, r->filename, r->path_info, NULL));
return HTTP_NOT_FOUND;
}
static int check_errorlog_dir(apr_pool_t *p, server_rec *s)
{
if (!s->error_fname || s->error_fname[0] == '|'
- || strcmp(s->error_fname, "syslog") == 0) {
+ || s->errorlog_provider != NULL) {
return APR_SUCCESS;
}
else {
return core_create_req(pr);
}
-static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
+static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *s,
apr_socket_t *csd, long id, void *sbh,
apr_bucket_alloc_t *alloc)
{
apr_status_t rv;
+ apr_pool_t *pool;
conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec));
+ core_server_config *sconf = ap_get_core_module_config(s->module_config);
c->sbh = sbh;
(void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL);
/* Got a connection structure, so initialize what fields we can
* (the rest are zeroed out by pcalloc).
*/
- c->conn_config = ap_create_conn_config(ptrans);
- c->notes = apr_table_make(ptrans, 5);
+ apr_pool_create(&pool, ptrans);
+ apr_pool_tag(pool, "master_conn");
+ c->pool = pool;
+
+ c->conn_config = ap_create_conn_config(c->pool);
+ c->notes = apr_table_make(c->pool, 5);
+ c->slaves = apr_array_make(c->pool, 20, sizeof(conn_slave_rec *));
+
- c->pool = ptrans;
if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd))
!= APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00137)
+ ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(00137)
"apr_socket_addr_get(APR_LOCAL)");
apr_socket_close(csd);
return NULL;
apr_sockaddr_ip_get(&c->local_ip, c->local_addr);
if ((rv = apr_socket_addr_get(&c->client_addr, APR_REMOTE, csd))
!= APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00138)
+ ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(00138)
"apr_socket_addr_get(APR_REMOTE)");
apr_socket_close(csd);
return NULL;
}
apr_sockaddr_ip_get(&c->client_ip, c->client_addr);
- c->base_server = server;
+ c->base_server = s;
c->id = id;
c->bucket_alloc = alloc;
c->clogging_input_filters = 0;
+ if (sconf->conn_log_level) {
+ int i;
+ conn_log_config *conf;
+ const struct ap_logconf *log = NULL;
+ struct ap_logconf *merged;
+
+ for (i = 0; i < sconf->conn_log_level->nelts; i++) {
+ conf = APR_ARRAY_IDX(sconf->conn_log_level, i, conn_log_config *);
+ if (apr_ipsubnet_test(conf->subnet, c->client_addr))
+ log = &conf->log;
+ }
+ if (log) {
+ merged = ap_new_log_config(c->pool, log);
+ ap_merge_log_config(&s->log, merged);
+ c->log = merged;
+ }
+ }
+
return c;
}
net->client_socket = csd;
ap_set_core_module_config(net->c->conn_config, csd);
- ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c);
- ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c);
+ /* only the master connection talks to the network */
+ if (c->master == NULL) {
+ ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL,
+ net->c);
+ ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL,
+ net->c);
+ }
return DONE;
}
+AP_CORE_DECLARE(conn_rec *) ap_create_slave_connection(conn_rec *c)
+{
+ apr_pool_t *pool;
+ conn_slave_rec *new;
+ conn_rec *sc = (conn_rec *) apr_palloc(c->pool, sizeof(conn_rec));
+
+ apr_pool_create(&pool, c->pool);
+ apr_pool_tag(pool, "slave_conn");
+ memcpy(sc, c, sizeof(conn_rec));
+ sc->slaves = NULL;
+ sc->master = c;
+ sc->input_filters = NULL;
+ sc->output_filters = NULL;
+ sc->pool = pool;
+ new = apr_array_push(c->slaves);
+ new->c = sc;
+ return sc;
+}
+
AP_DECLARE(int) ap_state_query(int query)
{
switch (query) {
AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max)
{
apr_uint32_t number;
+#if (!__GNUC__ || __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || \
+ !__sparc__ || APR_SIZEOF_VOIDP != 8)
+ /* This triggers a gcc bug on sparc/64bit with gcc < 4.8, PR 52900 */
if (max < 16384) {
apr_uint16_t num16;
ap_random_insecure_bytes(&num16, sizeof(num16));
RAND_RANGE(num16, min, max, APR_UINT16_MAX);
number = num16;
}
- else {
+ else
+#endif
+ {
ap_random_insecure_bytes(&number, sizeof(number));
RAND_RANGE(number, min, max, APR_UINT32_MAX);
}
return APR_SUCCESS;
}
+static apr_status_t core_dirwalk_stat(apr_finfo_t *finfo, request_rec *r,
+ apr_int32_t wanted)
+{
+ return apr_stat(finfo, r->filename, wanted, r->pool);
+}
+
static void core_dump_config(apr_pool_t *p, server_rec *s)
{
core_server_config *sconf = ap_get_core_module_config(s->module_config);
apr_file_printf(out, "ServerRoot: \"%s\"\n", ap_server_root);
tmp = ap_server_root_relative(p, sconf->ap_document_root);
apr_file_printf(out, "Main DocumentRoot: \"%s\"\n", tmp);
- if (s->error_fname[0] != '|' && strcmp(s->error_fname, "syslog") != 0)
+ if (s->error_fname[0] != '|' && s->errorlog_provider == NULL)
tmp = ap_server_root_relative(p, s->error_fname);
else
tmp = s->error_fname;
apr_file_printf(out, "Main ErrorLog: \"%s\"\n", tmp);
if (ap_scoreboard_fname) {
- tmp = ap_server_root_relative(p, ap_scoreboard_fname);
+ tmp = ap_runtime_dir_relative(p, ap_scoreboard_fname);
apr_file_printf(out, "ScoreBoardFile: \"%s\"\n", tmp);
}
ap_dump_mutexes(p, s, out);
ap_hook_child_status(ap_core_child_status, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_insert_network_bucket(core_insert_network_bucket, NULL, NULL,
APR_HOOK_REALLY_LAST);
-
+ ap_hook_dirwalk_stat(core_dirwalk_stat, NULL, NULL, APR_HOOK_REALLY_LAST);
+ ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST);
+
/* register the core's insert_filter hook and register core-provided
* filters
*/