diff options
Diffstat (limited to 'server/core.c')
-rw-r--r-- | server/core.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/server/core.c b/server/core.c index 37484b66..7ed6d9cc 100644 --- a/server/core.c +++ b/server/core.c @@ -191,6 +191,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->max_reversals = AP_MAXRANGES_UNSET; conf->cgi_pass_auth = AP_CGI_PASS_AUTH_UNSET; + conf->qualify_redirect_url = AP_CORE_CONFIG_UNSET; return (void *)conf; } @@ -405,6 +406,8 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) conf->cgi_pass_auth = new->cgi_pass_auth != AP_CGI_PASS_AUTH_UNSET ? new->cgi_pass_auth : base->cgi_pass_auth; + AP_CORE_MERGE_FLAG(qualify_redirect_url, conf, base, new); + return (void*)conf; } @@ -1707,6 +1710,15 @@ static const char *set_cgi_pass_auth(cmd_parms *cmd, void *d_, int flag) return NULL; } +static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag) +{ + core_dir_config *d = d_; + + d->qualify_redirect_url = flag ? AP_CORE_CONFIG_ON : AP_CORE_CONFIG_OFF; + + return NULL; +} + static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[]) { core_dir_config *d = d_; @@ -1724,7 +1736,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++){ + for (i = 0; i < argc; i++) { if (!strcasecmp(argv[i], "None")) { if (argc != 1) { return "'None' not allowed with other directives in " @@ -1735,6 +1747,7 @@ static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *c else { const command_rec *result = NULL; module *mod = ap_top_module; + result = ap_find_command_in_modules(argv[i], &mod); if (result == NULL) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, @@ -1753,7 +1766,7 @@ static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *c continue; } else { - apr_table_set(d->override_list, argv[i], "1"); + apr_table_setn(d->override_list, argv[i], "1"); } } } @@ -4206,6 +4219,10 @@ AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF, AP_INIT_FLAG("CGIPassAuth", set_cgi_pass_auth, NULL, OR_AUTHCFG, "Controls whether HTTP authorization headers, normally hidden, will " "be passed to scripts"), +AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO, + "Controls whether HTTP authorization headers, normally hidden, will " + "be passed to scripts"), + 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"), @@ -4995,8 +5012,15 @@ static void core_dump_config(apr_pool_t *p, server_rec *s) static int core_upgrade_handler(request_rec *r) { conn_rec *c = r->connection; - const char *upgrade = apr_table_get(r->headers_in, "Upgrade"); + const char *upgrade; + if (c->master) { + /* Not possible to perform an HTTP/1.1 upgrade from a slave + * connection. */ + return DECLINED; + } + + upgrade = apr_table_get(r->headers_in, "Upgrade"); if (upgrade && *upgrade) { const char *conn = apr_table_get(r->headers_in, "Connection"); if (ap_find_token(r->pool, conn, "upgrade")) { @@ -5011,8 +5035,7 @@ static int core_upgrade_handler(request_rec *r) } if (offers && offers->nelts > 0) { - const char *protocol = ap_select_protocol(c, r, r->server, - offers); + const char *protocol = ap_select_protocol(c, r, NULL, offers); if (protocol && strcmp(protocol, ap_get_protocol(c))) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02909) "Upgrade selects '%s'", protocol); @@ -5034,6 +5057,19 @@ static int core_upgrade_handler(request_rec *r) } } } + else if (!c->keepalives) { + /* first request on a master connection, if we have protocols other + * than the current one enabled here, announce them to the + * client. If the client is already talking a protocol with requests + * on slave connections, leave it be. */ + const apr_array_header_t *upgrades; + ap_get_protocol_upgrades(c, r, NULL, 0, &upgrades); + if (upgrades && upgrades->nelts > 0) { + char *protocols = apr_array_pstrcat(r->pool, upgrades, ','); + apr_table_setn(r->headers_out, "Upgrade", protocols); + apr_table_setn(r->headers_out, "Connection", "Upgrade"); + } + } return DECLINED; } |