summaryrefslogtreecommitdiff
path: root/server/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/core.c')
-rw-r--r--server/core.c46
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;
}