diff options
Diffstat (limited to 'server/core.c')
-rw-r--r-- | server/core.c | 487 |
1 files changed, 363 insertions, 124 deletions
diff --git a/server/core.c b/server/core.c index e2a91c7..e5e059e 100644 --- a/server/core.c +++ b/server/core.c @@ -22,6 +22,11 @@ #include "apr_thread_proc.h" /* for RLIMIT stuff */ #include "apr_random.h" +#include "apr_version.h" +#if APR_MAJOR_VERSION < 2 +#include "apu_version.h" +#endif + #define APR_WANT_IOVEC #define APR_WANT_STRFUNC #define APR_WANT_MEMFUNC @@ -33,6 +38,7 @@ #include "http_core.h" #include "http_protocol.h" /* For index_of_response(). Grump. */ #include "http_request.h" +#include "http_ssl.h" #include "http_vhost.h" #include "http_main.h" /* For the default_handler below... */ #include "http_log.h" @@ -61,11 +67,13 @@ /* LimitRequestBody handling */ #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) -#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) +#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */ /* LimitXMLRequestBody handling */ #define AP_LIMIT_UNSET ((long) -1) #define AP_DEFAULT_LIMIT_XML_BODY ((apr_size_t)1000000) +/* Hard limit for ap_escape_html2() */ +#define AP_MAX_LIMIT_XML_BODY ((apr_size_t)(APR_SIZE_MAX / 6 - 1)) #define AP_MIN_SENDFILE_BYTES (256) @@ -81,9 +89,13 @@ #define AP_CONTENT_MD5_ON 1 #define AP_CONTENT_MD5_UNSET 2 +#define AP_FLUSH_MAX_THRESHOLD 65535 +#define AP_FLUSH_MAX_PIPELINED 4 + APR_HOOK_STRUCT( APR_HOOK_LINK(get_mgmt_items) APR_HOOK_LINK(insert_network_bucket) + APR_HOOK_LINK(get_pollfd_from_conn) ) AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, @@ -95,6 +107,11 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, insert_network_bucket, apr_socket_t *socket), (c, bb, socket), AP_DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, get_pollfd_from_conn, + (conn_rec *c, struct apr_pollfd_t *pfd, + apr_interval_time_t *ptimeout), + (c, pfd, ptimeout), APR_ENOTIMPL) + /* Server core module... This module provides support for really basic * server operations, including options and commands which control the * operation of other modules. Consider this the bureaucracy module. @@ -122,8 +139,12 @@ AP_DECLARE_DATA int ap_document_root_check = 1; /* magic pointer for ErrorDocument xxx "default" */ static char errordocument_default; +/* Global state allocated out of pconf: variables here MUST be + * cleared/reset in reset_config(), a pconf cleanup, to avoid the + * variable getting reused after the pool is cleared. */ static apr_array_header_t *saved_server_config_defines = NULL; static apr_table_t *server_config_defined_vars = NULL; +AP_DECLARE_DATA const char *ap_runtime_dir = NULL; AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP; AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN; @@ -390,6 +411,13 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) if (new->enable_sendfile != ENABLE_SENDFILE_UNSET) { conf->enable_sendfile = new->enable_sendfile; } + + if (new->read_buf_size) { + conf->read_buf_size = new->read_buf_size; + } + else { + conf->read_buf_size = base->read_buf_size; + } conf->allow_encoded_slashes = new->allow_encoded_slashes; conf->decode_encoded_slashes = new->decode_encoded_slashes; @@ -462,14 +490,18 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) apr_table_setn(conf->accf_map, "http", "data"); apr_table_setn(conf->accf_map, "https", "data"); #endif + + conf->flush_max_threshold = AP_FLUSH_MAX_THRESHOLD; + conf->flush_max_pipelined = AP_FLUSH_MAX_PIPELINED; } - /* pcalloc'ed - we have NULL's/0's - else ** is_virtual ** { - conf->ap_document_root = NULL; - conf->access_name = NULL; - conf->accf_map = NULL; + else { + /* Use main ErrorLogFormat while the vhost is loading */ + core_server_config *main_conf = + ap_get_core_module_config(ap_server_conf->module_config); + conf->error_log_format = main_conf->error_log_format; + + conf->flush_max_pipelined = -1; } - */ /* initialization, no special case for global context */ @@ -490,7 +522,10 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) conf->protocols = apr_array_make(a, 5, sizeof(const char *)); conf->protocols_honor_order = -1; + conf->merge_slashes = AP_CORE_CONFIG_UNSET; + conf->strict_host_check= AP_CORE_CONFIG_UNSET; + return (void *)conf; } @@ -555,7 +590,22 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) conf->protocols_honor_order = ((virt->protocols_honor_order < 0)? base->protocols_honor_order : virt->protocols_honor_order); + AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt); + + conf->flush_max_threshold = (virt->flush_max_threshold) + ? virt->flush_max_threshold + : base->flush_max_threshold; + conf->flush_max_pipelined = (virt->flush_max_pipelined >= 0) + ? virt->flush_max_pipelined + : base->flush_max_pipelined; + + conf->strict_host_check = (virt->strict_host_check != AP_CORE_CONFIG_UNSET) + ? virt->strict_host_check + : base->strict_host_check; + + AP_CORE_MERGE_FLAG(strict_host_check, conf, base, virt); + return conf; } @@ -693,6 +743,7 @@ void ap_core_reorder_directories(apr_pool_t *p, server_rec *s) /* we have to allocate tmp space to do a stable sort */ apr_pool_create(&tmp, p); + apr_pool_tag(tmp, "core_reorder_directories"); sortbin = apr_palloc(tmp, sec_dir->nelts * sizeof(*sortbin)); for (i = 0; i < nelts; ++i) { sortbin[i].orig_index = i; @@ -735,7 +786,7 @@ AP_DECLARE(int) ap_allow_overrides(request_rec *r) /* * Optional function coming from mod_authn_core, used for - * retrieving the type of autorization + * retrieving the type of authorization */ static APR_OPTIONAL_FN_TYPE(authn_ap_auth_type) *authn_ap_auth_type; @@ -1217,6 +1268,13 @@ AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r) return d->limit_req_body; } +AP_DECLARE(apr_size_t) ap_get_read_buf_size(const request_rec *r) +{ + core_dir_config *d = ap_get_core_module_config(r->per_dir_config); + + return d->read_buf_size ? d->read_buf_size : AP_IOBUFSIZE; +} + /***************************************************************** * @@ -1233,7 +1291,7 @@ static const ap_directive_t * find_parent(const ap_directive_t *dirp, dirp = dirp->parent; /* ### it would be nice to have atom-ized directives */ - if (strcasecmp(dirp->directive, what) == 0) + if (ap_cstr_casecmp(dirp->directive, what) == 0) return dirp; } @@ -1412,6 +1470,7 @@ static int reset_config_defines(void *dummy) ap_server_config_defines = saved_server_config_defines; saved_server_config_defines = NULL; server_config_defined_vars = NULL; + ap_runtime_dir = NULL; return OK; } @@ -1518,7 +1577,7 @@ static const char *set_gprof_dir(cmd_parms *cmd, void *dummy, const char *arg) return err; } - conf->gprof_dir = arg; + conf->gprof_dir = apr_pstrdup(cmd->pool, arg); return NULL; } #endif /*GPROF*/ @@ -1528,10 +1587,10 @@ static const char *set_add_default_charset(cmd_parms *cmd, { core_dir_config *d = d_; - if (!strcasecmp(arg, "Off")) { + if (!ap_cstr_casecmp(arg, "Off")) { d->add_default_charset = ADD_DEFAULT_CHARSET_OFF; } - else if (!strcasecmp(arg, "On")) { + else if (!ap_cstr_casecmp(arg, "On")) { d->add_default_charset = ADD_DEFAULT_CHARSET_ON; d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; } @@ -1648,7 +1707,7 @@ static const char *set_error_document(cmd_parms *cmd, void *conf_, conf->response_code_exprs = apr_hash_make(cmd->pool); } - if (strcasecmp(msg, "default") == 0) { + if (ap_cstr_casecmp(msg, "default") == 0) { /* special case: ErrorDocument 404 default restores the * canned server error response */ @@ -1704,36 +1763,36 @@ static const char *set_allow_opts(cmd_parms *cmd, allow_options_t *opts, first = 0; } - if (!strcasecmp(w, "Indexes")) { + if (!ap_cstr_casecmp(w, "Indexes")) { opt = OPT_INDEXES; } - else if (!strcasecmp(w, "Includes")) { + else if (!ap_cstr_casecmp(w, "Includes")) { /* If Includes is permitted, both Includes and * IncludesNOEXEC may be changed. */ opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); } - else if (!strcasecmp(w, "IncludesNOEXEC")) { + else if (!ap_cstr_casecmp(w, "IncludesNOEXEC")) { opt = OPT_INCLUDES; } - else if (!strcasecmp(w, "FollowSymLinks")) { + else if (!ap_cstr_casecmp(w, "FollowSymLinks")) { opt = OPT_SYM_LINKS; } - else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) { + else if (!ap_cstr_casecmp(w, "SymLinksIfOwnerMatch")) { opt = OPT_SYM_OWNER; } - else if (!strcasecmp(w, "ExecCGI")) { + else if (!ap_cstr_casecmp(w, "ExecCGI")) { opt = OPT_EXECCGI; } - else if (!strcasecmp(w, "MultiViews")) { + else if (!ap_cstr_casecmp(w, "MultiViews")) { opt = OPT_MULTI; } - else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ + else if (!ap_cstr_casecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ opt = OPT_MULTI|OPT_EXECCGI; } - else if (!strcasecmp(w, "None")) { + else if (!ap_cstr_casecmp(w, "None")) { opt = OPT_NONE; } - else if (!strcasecmp(w, "All")) { + else if (!ap_cstr_casecmp(w, "All")) { opt = OPT_ALL; } else { @@ -1774,40 +1833,43 @@ static const char *set_override(cmd_parms *cmd, void *d_, const char *l) *v++ = '\0'; } - if (!strcasecmp(w, "Limit")) { + if (!ap_cstr_casecmp(w, "Limit")) { d->override |= OR_LIMIT; } - else if (!strcasecmp(k, "Options")) { + else if (!ap_cstr_casecmp(k, "Options")) { d->override |= OR_OPTIONS; if (v) set_allow_opts(cmd, &(d->override_opts), v); else d->override_opts = OPT_ALL; } - else if (!strcasecmp(w, "FileInfo")) { + else if (!ap_cstr_casecmp(w, "FileInfo")) { d->override |= OR_FILEINFO; } - else if (!strcasecmp(w, "AuthConfig")) { + else if (!ap_cstr_casecmp(w, "AuthConfig")) { d->override |= OR_AUTHCFG; } - else if (!strcasecmp(w, "Indexes")) { + else if (!ap_cstr_casecmp(w, "Indexes")) { d->override |= OR_INDEXES; } - else if (!strcasecmp(w, "Nonfatal")) { - if (!strcasecmp(v, "Override")) { + else if (!ap_cstr_casecmp(w, "Nonfatal")) { + if (!v) { + return apr_pstrcat(cmd->pool, "=Override, =Unknown or =All expected after ", w, NULL); + } + else if (!ap_cstr_casecmp(v, "Override")) { d->override |= NONFATAL_OVERRIDE; } - else if (!strcasecmp(v, "Unknown")) { + else if (!ap_cstr_casecmp(v, "Unknown")) { d->override |= NONFATAL_UNKNOWN; } - else if (!strcasecmp(v, "All")) { + else if (!ap_cstr_casecmp(v, "All")) { d->override |= NONFATAL_ALL; } } - else if (!strcasecmp(w, "None")) { + else if (!ap_cstr_casecmp(w, "None")) { d->override = OR_NONE; } - else if (!strcasecmp(w, "All")) { + else if (!ap_cstr_casecmp(w, "All")) { d->override = OR_ALL; } else { @@ -1863,6 +1925,13 @@ static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag) return NULL; } +static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag) +{ + core_server_config *conf = + ap_get_core_module_config(cmd->server->module_config); + return ap_set_flag_slot(cmd, conf, flag); +} + static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[]) { core_dir_config *d = d_; @@ -1881,7 +1950,7 @@ static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *c d->override_list = apr_table_make(cmd->pool, argc); for (i = 0; i < argc; i++) { - if (!strcasecmp(argv[i], "None")) { + if (!ap_cstr_casecmp(argv[i], "None")) { if (argc != 1) { return "'None' not allowed with other directives in " "AllowOverrideList"; @@ -1945,31 +2014,31 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l) return "Either all Options must start with + or -, or no Option may."; } - if (!strcasecmp(w, "Indexes")) { + if (!ap_cstr_casecmp(w, "Indexes")) { opt = OPT_INDEXES; } - else if (!strcasecmp(w, "Includes")) { + else if (!ap_cstr_casecmp(w, "Includes")) { opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); } - else if (!strcasecmp(w, "IncludesNOEXEC")) { + else if (!ap_cstr_casecmp(w, "IncludesNOEXEC")) { opt = OPT_INCLUDES; } - else if (!strcasecmp(w, "FollowSymLinks")) { + else if (!ap_cstr_casecmp(w, "FollowSymLinks")) { opt = OPT_SYM_LINKS; } - else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) { + else if (!ap_cstr_casecmp(w, "SymLinksIfOwnerMatch")) { opt = OPT_SYM_OWNER; } - else if (!strcasecmp(w, "ExecCGI")) { + else if (!ap_cstr_casecmp(w, "ExecCGI")) { opt = OPT_EXECCGI; } - else if (!strcasecmp(w, "MultiViews")) { + else if (!ap_cstr_casecmp(w, "MultiViews")) { opt = OPT_MULTI; } - else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ + else if (!ap_cstr_casecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ opt = OPT_MULTI|OPT_EXECCGI; } - else if (!strcasecmp(w, "None")) { + else if (!ap_cstr_casecmp(w, "None")) { if (!first) { return "'Options None' must be the first Option given."; } @@ -1979,7 +2048,7 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l) opt = OPT_NONE; all_none = 1; } - else if (!strcasecmp(w, "All")) { + else if (!ap_cstr_casecmp(w, "All")) { if (!first) { return "'Options All' must be the first option given."; } @@ -2020,7 +2089,7 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l) static const char *set_default_type(cmd_parms *cmd, void *d_, const char *arg) { - if ((strcasecmp(arg, "off") != 0) && (strcasecmp(arg, "none") != 0)) { + if ((ap_cstr_casecmp(arg, "off") != 0) && (ap_cstr_casecmp(arg, "none") != 0)) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00117) "Ignoring deprecated use of DefaultType in line %d of %s.", cmd->directive->line_num, cmd->directive->filename); @@ -2090,7 +2159,7 @@ static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, } } - if (strcasecmp(token, "None") == 0) { + if (ap_cstr_casecmp(token, "None") == 0) { if (action != '*') { valid = 0; } @@ -2099,7 +2168,7 @@ static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, explicit = 1; } } - else if (strcasecmp(token, "All") == 0) { + else if (ap_cstr_casecmp(token, "All") == 0) { if (action != '*') { valid = 0; } @@ -2108,17 +2177,20 @@ static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, cfg->etag_bits = bit = ETAG_ALL; } } - else if (strcasecmp(token, "Size") == 0) { + else if (ap_cstr_casecmp(token, "Size") == 0) { bit = ETAG_SIZE; } - else if ((strcasecmp(token, "LMTime") == 0) - || (strcasecmp(token, "MTime") == 0) - || (strcasecmp(token, "LastModified") == 0)) { + else if ((ap_cstr_casecmp(token, "LMTime") == 0) + || (ap_cstr_casecmp(token, "MTime") == 0) + || (ap_cstr_casecmp(token, "LastModified") == 0)) { bit = ETAG_MTIME; } - else if (strcasecmp(token, "INode") == 0) { + else if (ap_cstr_casecmp(token, "INode") == 0) { bit = ETAG_INODE; } + else if (ap_cstr_casecmp(token, "Digest") == 0) { + bit = ETAG_DIGEST; + } else { return apr_pstrcat(cmd->pool, "Unknown keyword '", token, "' for ", cmd->cmd->name, @@ -2183,10 +2255,10 @@ static const char *set_enable_mmap(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { d->enable_mmap = ENABLE_MMAP_ON; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { d->enable_mmap = ENABLE_MMAP_OFF; } else { @@ -2201,10 +2273,10 @@ static const char *set_enable_sendfile(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { d->enable_sendfile = ENABLE_SENDFILE_ON; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { d->enable_sendfile = ENABLE_SENDFILE_OFF; } else { @@ -2214,6 +2286,64 @@ static const char *set_enable_sendfile(cmd_parms *cmd, void *d_, return NULL; } +static const char *set_read_buf_size(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + apr_off_t size; + char *end; + + if (apr_strtoff(&size, arg, &end, 10) + || *end || size < 0 || size > APR_UINT32_MAX) + return apr_pstrcat(cmd->pool, + "parameter must be a number between 0 and " + APR_STRINGIFY(APR_UINT32_MAX) "): ", + arg, NULL); + + d->read_buf_size = (apr_size_t)size; + + return NULL; +} + +static const char *set_flush_max_threshold(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_server_config *conf = + ap_get_core_module_config(cmd->server->module_config); + apr_off_t size; + char *end; + + if (apr_strtoff(&size, arg, &end, 10) + || *end || size < 0 || size > APR_UINT32_MAX) + return apr_pstrcat(cmd->pool, + "parameter must be a number between 0 and " + APR_STRINGIFY(APR_UINT32_MAX) "): ", + arg, NULL); + + conf->flush_max_threshold = (apr_size_t)size; + + return NULL; +} + +static const char *set_flush_max_pipelined(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_server_config *conf = + ap_get_core_module_config(cmd->server->module_config); + apr_off_t num; + char *end; + + if (apr_strtoff(&num, arg, &end, 10) + || *end || num < -1 || num > APR_INT32_MAX) + return apr_pstrcat(cmd->pool, + "parameter must be a number between -1 and " + APR_STRINGIFY(APR_INT32_MAX) ": ", + arg, NULL); + + conf->flush_max_pipelined = (apr_int32_t)num; + + return NULL; +} /* * Report a missing-'>' syntax error. @@ -2778,8 +2908,15 @@ static int test_iffile_section(cmd_parms *cmd, const char *arg) const char *relative; apr_finfo_t sb; + /* + * At least on Windows, if the path we are testing is not valid (for example + * a path on a USB key that is not plugged), 'ap_server_root_relative()' will + * return NULL. In such a case, consider that the file is not there and that + * the section should be skipped. + */ relative = ap_server_root_relative(cmd->temp_pool, arg); - return (apr_stat(&sb, relative, 0, cmd->pool) == APR_SUCCESS); + return (relative && + (apr_stat(&sb, relative, APR_FINFO_TYPE, cmd->temp_pool) == APR_SUCCESS)); } static int test_ifdirective_section(cmd_parms *cmd, const char *arg) @@ -3052,13 +3189,13 @@ static const char *set_signature_flag(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (strcasecmp(arg, "On") == 0) { + if (ap_cstr_casecmp(arg, "On") == 0) { d->server_signature = srv_sig_on; } - else if (strcasecmp(arg, "Off") == 0) { + else if (ap_cstr_casecmp(arg, "Off") == 0) { d->server_signature = srv_sig_off; } - else if (strcasecmp(arg, "EMail") == 0) { + else if (ap_cstr_casecmp(arg, "EMail") == 0) { d->server_signature = srv_sig_withmail; } else { @@ -3120,13 +3257,13 @@ static const char *set_allow2f(cmd_parms *cmd, void *d_, const char *arg) { core_dir_config *d = d_; - if (0 == strcasecmp(arg, "on")) { + if (0 == ap_cstr_casecmp(arg, "on")) { d->allow_encoded_slashes = 1; d->decode_encoded_slashes = 1; /* for compatibility with 2.0 & 2.2 */ - } else if (0 == strcasecmp(arg, "off")) { + } else if (0 == ap_cstr_casecmp(arg, "off")) { d->allow_encoded_slashes = 0; d->decode_encoded_slashes = 0; - } else if (0 == strcasecmp(arg, "nodecode")) { + } else if (0 == ap_cstr_casecmp(arg, "nodecode")) { d->allow_encoded_slashes = 1; d->decode_encoded_slashes = 0; } else { @@ -3142,13 +3279,13 @@ static const char *set_hostname_lookups(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (!strcasecmp(arg, "on")) { + if (!ap_cstr_casecmp(arg, "on")) { d->hostname_lookups = HOSTNAME_LOOKUP_ON; } - else if (!strcasecmp(arg, "off")) { + else if (!ap_cstr_casecmp(arg, "off")) { d->hostname_lookups = HOSTNAME_LOOKUP_OFF; } - else if (!strcasecmp(arg, "double")) { + else if (!ap_cstr_casecmp(arg, "double")) { d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE; } else { @@ -3184,13 +3321,13 @@ static const char *set_accept_path_info(cmd_parms *cmd, void *d_, const char *ar { core_dir_config *d = d_; - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { d->accept_path_info = AP_REQ_ACCEPT_PATH_INFO; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { d->accept_path_info = AP_REQ_REJECT_PATH_INFO; } - else if (strcasecmp(arg, "default") == 0) { + else if (ap_cstr_casecmp(arg, "default") == 0) { d->accept_path_info = AP_REQ_DEFAULT_PATH_INFO; } else { @@ -3205,13 +3342,13 @@ static const char *set_use_canonical_name(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { d->use_canonical_name = USE_CANONICAL_NAME_ON; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { d->use_canonical_name = USE_CANONICAL_NAME_OFF; } - else if (strcasecmp(arg, "dns") == 0) { + else if (ap_cstr_casecmp(arg, "dns") == 0) { d->use_canonical_name = USE_CANONICAL_NAME_DNS; } else { @@ -3226,10 +3363,10 @@ static const char *set_use_canonical_phys_port(cmd_parms *cmd, void *d_, { core_dir_config *d = d_; - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { d->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_ON; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { d->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_OFF; } else { @@ -3525,22 +3662,22 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, return err; } - if (!strcasecmp(arg, "OS")) { + if (!ap_cstr_casecmp(arg, "OS")) { ap_server_tokens = SrvTk_OS; } - else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) { + else if (!ap_cstr_casecmp(arg, "Min") || !ap_cstr_casecmp(arg, "Minimal")) { ap_server_tokens = SrvTk_MINIMAL; } - else if (!strcasecmp(arg, "Major")) { + else if (!ap_cstr_casecmp(arg, "Major")) { ap_server_tokens = SrvTk_MAJOR; } - else if (!strcasecmp(arg, "Minor") ) { + else if (!ap_cstr_casecmp(arg, "Minor") ) { ap_server_tokens = SrvTk_MINOR; } - else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) { + else if (!ap_cstr_casecmp(arg, "Prod") || !ap_cstr_casecmp(arg, "ProductOnly")) { ap_server_tokens = SrvTk_PRODUCT_ONLY; } - else if (!strcasecmp(arg, "Full")) { + else if (!ap_cstr_casecmp(arg, "Full")) { ap_server_tokens = SrvTk_FULL; } else { @@ -3637,6 +3774,11 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, if (conf->limit_xml_body < 0) return "LimitXMLRequestBody requires a non-negative integer."; + /* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */ + if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY) + return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed " + "%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY); + return NULL; } @@ -3645,13 +3787,13 @@ static const char *set_max_ranges(cmd_parms *cmd, void *conf_, const char *arg) core_dir_config *conf = conf_; int val = 0; - if (!strcasecmp(arg, "none")) { + if (!ap_cstr_casecmp(arg, "none")) { val = AP_MAXRANGES_NORANGES; } - else if (!strcasecmp(arg, "default")) { + else if (!ap_cstr_casecmp(arg, "default")) { val = AP_MAXRANGES_DEFAULT; } - else if (!strcasecmp(arg, "unlimited")) { + else if (!ap_cstr_casecmp(arg, "unlimited")) { val = AP_MAXRANGES_UNLIMITED; } else { @@ -3671,13 +3813,13 @@ static const char *set_max_overlaps(cmd_parms *cmd, void *conf_, const char *arg core_dir_config *conf = conf_; int val = 0; - if (!strcasecmp(arg, "none")) { + if (!ap_cstr_casecmp(arg, "none")) { val = AP_MAXRANGES_NORANGES; } - else if (!strcasecmp(arg, "default")) { + else if (!ap_cstr_casecmp(arg, "default")) { val = AP_MAXRANGES_DEFAULT; } - else if (!strcasecmp(arg, "unlimited")) { + else if (!ap_cstr_casecmp(arg, "unlimited")) { val = AP_MAXRANGES_UNLIMITED; } else { @@ -3697,13 +3839,13 @@ static const char *set_max_reversals(cmd_parms *cmd, void *conf_, const char *ar core_dir_config *conf = conf_; int val = 0; - if (!strcasecmp(arg, "none")) { + if (!ap_cstr_casecmp(arg, "none")) { val = AP_MAXRANGES_NORANGES; } - else if (!strcasecmp(arg, "default")) { + else if (!ap_cstr_casecmp(arg, "default")) { val = AP_MAXRANGES_DEFAULT; } - else if (!strcasecmp(arg, "unlimited")) { + else if (!ap_cstr_casecmp(arg, "unlimited")) { val = AP_MAXRANGES_UNLIMITED; } else { @@ -3725,6 +3867,8 @@ AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r) conf = ap_get_core_module_config(r->per_dir_config); if (conf->limit_xml_body == AP_LIMIT_UNSET) return AP_DEFAULT_LIMIT_XML_BODY; + if (conf->limit_xml_body == 0) + return AP_MAX_LIMIT_XML_BODY; return (apr_size_t)conf->limit_xml_body; } @@ -3818,24 +3962,26 @@ static const char *set_recursion_limit(cmd_parms *cmd, void *dummy, static void log_backtrace(const request_rec *r) { - const request_rec *top = r; + if (APLOGrdebug(r)) { + const request_rec *top = r; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00121) - "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00121) + "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)"); - while (top && (top->prev || top->main)) { - if (top->prev) { - top = top->prev; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00122) - "redirected from r->uri = %s", - top->uri ? top->uri : "(unexpectedly NULL)"); - } + while (top && (top->prev || top->main)) { + if (top->prev) { + top = top->prev; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00122) + "redirected from r->uri = %s", + top->uri ? top->uri : "(unexpectedly NULL)"); + } - if (!top->prev && top->main) { - top = top->main; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00123) - "subrequested from r->uri = %s", - top->uri ? top->uri : "(unexpectedly NULL)"); + if (!top->prev && top->main) { + top = top->main; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00123) + "subrequested from r->uri = %s", + top->uri ? top->uri : "(unexpectedly NULL)"); + } } } } @@ -3909,13 +4055,13 @@ static const char *set_trace_enable(cmd_parms *cmd, void *dummy, core_server_config *conf = ap_get_core_module_config(cmd->server->module_config); - if (strcasecmp(arg1, "on") == 0) { + if (ap_cstr_casecmp(arg1, "on") == 0) { conf->trace_enable = AP_TRACE_ENABLE; } - else if (strcasecmp(arg1, "off") == 0) { + else if (ap_cstr_casecmp(arg1, "off") == 0) { conf->trace_enable = AP_TRACE_DISABLE; } - else if (strcasecmp(arg1, "extended") == 0) { + else if (ap_cstr_casecmp(arg1, "extended") == 0) { conf->trace_enable = AP_TRACE_EXTENDED; } else { @@ -3954,10 +4100,10 @@ static const char *set_protocols_honor_order(cmd_parms *cmd, void *dummy, return err; } - if (strcasecmp(arg, "on") == 0) { + if (ap_cstr_casecmp(arg, "on") == 0) { conf->protocols_honor_order = 1; } - else if (strcasecmp(arg, "off") == 0) { + else if (ap_cstr_casecmp(arg, "off") == 0) { conf->protocols_honor_order = 0; } else { @@ -4227,7 +4373,7 @@ static const char *set_errorlog_format(cmd_parms *cmd, void *dummy, conf->error_log_format = parse_errorlog_string(cmd->pool, arg1, &err_string, 1); } - else if (!strcasecmp(arg1, "connection")) { + else if (!ap_cstr_casecmp(arg1, "connection")) { if (!conf->error_log_conn) { conf->error_log_conn = apr_array_make(cmd->pool, 5, sizeof(apr_array_header_t *)); @@ -4239,7 +4385,7 @@ static const char *set_errorlog_format(cmd_parms *cmd, void *dummy, *e = parse_errorlog_string(cmd->pool, arg2, &err_string, 0); } } - else if (!strcasecmp(arg1, "request")) { + else if (!ap_cstr_casecmp(arg1, "request")) { if (!conf->error_log_req) { conf->error_log_req = apr_array_make(cmd->pool, 5, sizeof(apr_array_header_t *)); @@ -4374,6 +4520,13 @@ AP_INIT_TAKE1("EnableMMAP", set_enable_mmap, NULL, OR_FILEINFO, "Controls whether memory-mapping may be used to read files"), AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO, "Controls whether sendfile may be used to transmit files"), +AP_INIT_TAKE1("ReadBufferSize", set_read_buf_size, NULL, ACCESS_CONF|RSRC_CONF, + "Size (in bytes) of the memory buffers used to read data"), +AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF, + "Maximum threshold above which pending data are flushed to the network"), +AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF, + "Maximum number of pipelined responses (pending) above which they are " + "flushed to the network"), /* Old server config file commands */ @@ -4498,9 +4651,12 @@ AP_INIT_FLAG("CGIPassAuth", set_cgi_pass_auth, NULL, OR_AUTHCFG, AP_INIT_TAKE2("CGIVar", set_cgi_var, NULL, OR_FILEINFO, "Controls how some CGI variables are set"), AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO, - "Controls whether HTTP authorization headers, normally hidden, will " - "be passed to scripts"), - + "Controls whether the REDIRECT_URL environment variable is fully " + "qualified"), +AP_INIT_FLAG("StrictHostCheck", set_core_server_flag, + (void *)APR_OFFSETOF(core_server_config, strict_host_check), + RSRC_CONF, + "Controls whether a hostname match is required"), AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower, (void *)APR_OFFSETOF(core_dir_config, mime_type), OR_FILEINFO, "a mime type that overrides other configured type"), @@ -4562,6 +4718,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CON "'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"), AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF, "Registers non-standard HTTP methods"), +AP_INIT_FLAG("MergeSlashes", set_core_server_flag, + (void *)APR_OFFSETOF(core_server_config, merge_slashes), + RSRC_CONF, + "Controls whether consecutive slashes in the URI path are merged"), { NULL } }; @@ -4583,7 +4743,7 @@ AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r) } if (!r->uri || ((r->uri[0] != '/') && strcmp(r->uri, "*"))) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00126) - "Invalid URI in request %s", r->the_request); + "Invalid URI in request '%s' '%s'", r->uri, r->the_request); return HTTP_BAD_REQUEST; } @@ -4793,7 +4953,7 @@ static int default_handler(request_rec *r) ap_update_mtime(r, r->finfo.mtime); ap_set_last_modified(r); - ap_set_etag(r); + ap_set_etag_fd(r, fd); ap_set_accept_ranges(r); ap_set_content_length(r, r->finfo.size); if (bld_content_md5) { @@ -4815,12 +4975,19 @@ static int default_handler(request_rec *r) (void)apr_bucket_file_enable_mmap(e, 0); } #endif +#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6) + if (d->read_buf_size) { + apr_bucket_file_set_buf_size(e, d->read_buf_size); + } +#endif } e = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, e); status = ap_pass_brigade(r->output_filters, bb); + apr_brigade_cleanup(bb); + if (status == APR_SUCCESS || r->status != HTTP_OK || c->aborted) { @@ -4924,7 +5091,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem apr_pool_cleanup_register(pconf, NULL, reset_config_defines, apr_pool_cleanup_null); - ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY); + ap_regcomp_set_default_cflags(AP_REG_DEFAULT); mpm_common_pre_config(pconf); @@ -4943,6 +5110,7 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte set_banner(pconf); ap_setup_make_content_type(pconf); ap_setup_auth_internal(ptemp); + ap_setup_ssl_optional_fns(pconf); if (!sys_privileges) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(00136) "Server MUST relinquish startup privileges before " @@ -5059,10 +5227,10 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, /* Got a connection structure, so initialize what fields we can * (the rest are zeroed out by pcalloc). */ + c->pool = ptrans; c->conn_config = ap_create_conn_config(ptrans); c->notes = apr_table_make(ptrans, 5); - 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) @@ -5070,8 +5238,17 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, apr_socket_close(csd); return NULL; } + if (apr_sockaddr_ip_get(&c->local_ip, c->local_addr)) { +#if APR_HAVE_SOCKADDR_UN + if (c->local_addr->family == APR_UNIX) { + c->local_ip = apr_pstrndup(c->pool, c->local_addr->ipaddr_ptr, + c->local_addr->ipaddr_len); + } + else +#endif + c->local_ip = apr_pstrdup(c->pool, "unknown"); + } - 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) @@ -5079,8 +5256,17 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, apr_socket_close(csd); return NULL; } + if (apr_sockaddr_ip_get(&c->client_ip, c->client_addr)) { +#if APR_HAVE_SOCKADDR_UN + if (c->client_addr->family == APR_UNIX) { + c->client_ip = apr_pstrndup(c->pool, c->client_addr->ipaddr_ptr, + c->client_addr->ipaddr_len); + } + else +#endif + c->client_ip = apr_pstrdup(c->pool, "unknown"); + } - apr_sockaddr_ip_get(&c->client_ip, c->client_addr); c->base_server = server; c->id = id; @@ -5093,9 +5279,14 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, static int core_pre_connection(conn_rec *c, void *csd) { - core_net_rec *net = apr_palloc(c->pool, sizeof(*net)); + core_net_rec *net; apr_status_t rv; + if (c->master) { + return DONE; + } + + net = apr_palloc(c->pool, sizeof(*net)); /* The Nagle algorithm says that we should delay sending partial * packets in hopes of getting more data. We don't want to do * this; we are not telnet. There are bad interactions between @@ -5136,6 +5327,31 @@ static int core_pre_connection(conn_rec *c, void *csd) return DONE; } +AP_DECLARE(int) ap_pre_connection(conn_rec *c, void *csd) +{ + int rc = OK; + + rc = ap_run_pre_connection(c, csd); + if (rc != OK && rc != DONE) { + c->aborted = 1; + /* + * In case we errored, the pre_connection hook of the core + * module maybe did not run (it is APR_HOOK_REALLY_LAST) and + * hence we missed to + * + * - Put the socket in c->conn_config + * - Setup core output and input filters + * - Set socket options and timeouts + * + * Hence call it in this case. + */ + if (!ap_get_conn_socket(c)) { + core_pre_connection(c, csd); + } + } + return rc; +} + AP_DECLARE(int) ap_state_query(int query) { switch (query) { @@ -5394,6 +5610,28 @@ static int core_upgrade_storage(request_rec *r) return DECLINED; } +static apr_status_t core_get_pollfd_from_conn(conn_rec *c, + struct apr_pollfd_t *pfd, + apr_interval_time_t *ptimeout) +{ + if (c && !c->master) { + pfd->desc_type = APR_POLL_SOCKET; + pfd->desc.s = ap_get_conn_socket(c); + if (ptimeout) { + apr_socket_timeout_get(pfd->desc.s, ptimeout); + } + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c, + struct apr_pollfd_t *pfd, + apr_interval_time_t *ptimeout) +{ + return ap_run_get_pollfd_from_conn(c, pfd, ptimeout); +} + static void register_hooks(apr_pool_t *p) { errorlog_hash = apr_hash_make(p); @@ -5437,7 +5675,9 @@ static void register_hooks(apr_pool_t *p) ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST); ap_hook_optional_fn_retrieve(core_optional_fn_retrieve, NULL, NULL, APR_HOOK_MIDDLE); - + ap_hook_get_pollfd_from_conn(core_get_pollfd_from_conn, NULL, NULL, + APR_HOOK_REALLY_LAST); + /* register the core's insert_filter hook and register core-provided * filters */ @@ -5470,4 +5710,3 @@ AP_DECLARE_MODULE(core) = { core_cmds, /* command apr_table_t */ register_hooks /* register hooks */ }; - |