#! /bin/sh /usr/share/dpatch/dpatch-run ## 056_mod_dir_content_location by Jose Kahan ## ## All lines beginning with `## DP:' are a description of the patch. ### DP: mod_neg wasn't handling the query arguments to files ### DP: chosen thru a typemap @DPATCH@ apache2-2.2.9~/support/ab.c apache2-2.2.9/support/ab.c diff -urNad apache2-2.2.16~/modules/mappers/mod_dir.c apache2-2.2.16/trunk/modules/mappers/mod_dir.c --- apache2-2.2.16~/modules/mappers/mod_dir.c 2008-05-12 11:16:00.000000000 +0000 +++ apache2-2.2.16/modules/mappers/mod_dir.c 2008-05-12 11:19:16.000000000 +0000 @@ -32,14 +32,16 @@ module AP_MODULE_DECLARE_DATA dir_module; typedef enum { - SLASH_OFF = 0, - SLASH_ON, - SLASH_UNSET -} slash_cfg; + OPTION_OFF = 0, + OPTION_ON, + OPTION_UNSET +} option_cfg; typedef struct dir_config_struct { apr_array_header_t *index_names; - slash_cfg do_slash; + option_cfg do_slash; + option_cfg cl_enable; + char *cl_condition_var; const char *dflt; } dir_config_rec; @@ -60,10 +62,29 @@ { dir_config_rec *d = d_; - d->do_slash = arg ? SLASH_ON : SLASH_OFF; + d->do_slash = arg ? OPTION_ON : OPTION_OFF; return NULL; } +static const char *enable_content_location(cmd_parms *cmd, void *dconf, const char *enable, const char *envclause) +{ + dir_config_rec *d = dconf; + + d->cl_enable = enable ? OPTION_ON : OPTION_OFF; + + if (d->cl_enable && envclause != NULL) { + if (strncasecmp(envclause, "env=", 4) != 0) { + return "error in condition clause"; + } + if ((envclause[4] == '\0') + || ((envclause[4] == '!') && (envclause[5] == '\0'))) { + return "missing environment variable name"; + } + d->cl_condition_var = apr_pstrdup(cmd->pool, &envclause[4]); + } + return NULL; +} + static const command_rec dir_cmds[] = { AP_INIT_TAKE1("FallbackResource", ap_set_string_slot, @@ -73,6 +94,9 @@ "a list of file names"), AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS, "On or Off"), + AP_INIT_TAKE12("DirectoryRevealContentLocation", + enable_content_location, NULL, DIR_CMD_PERMS, + "On or Off, and an optional \"env=\" clause (see docs)"), {NULL} }; @@ -81,7 +105,9 @@ dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec)); new->index_names = NULL; - new->do_slash = SLASH_UNSET; + new->do_slash = OPTION_UNSET; + new->cl_enable = OPTION_UNSET; + new->cl_condition_var = NULL; return (void *) new; } @@ -93,7 +119,11 @@ new->index_names = add->index_names ? add->index_names : base->index_names; new->do_slash = - (add->do_slash == SLASH_UNSET) ? base->do_slash : add->do_slash; + (add->do_slash == OPTION_UNSET) ? base->do_slash : add->do_slash; + new->cl_enable = + (add->cl_enable == OPTION_UNSET) ? base->cl_enable : add->cl_enable; + new->cl_condition_var = + add->cl_condition_var ? add->cl_condition_var : base->cl_condition_var; new->dflt = add->dflt ? add->dflt : base->dflt; return new; } @@ -127,6 +157,33 @@ && ( (rr->handler && !strcmp(rr->handler, "proxy-server")) || rr->finfo.filetype == APR_REG)) { ap_internal_fast_redirect(rr, r); + + /* return Content-Location for this location? */ + if (d->cl_enable == OPTION_ON) { + /* + * See if we've got any conditional envariable-controlled decisions + * to make. + */ + if (d->cl_condition_var != NULL) { + char *envar = d->cl_condition_var; + if (*envar != '!') { + if (apr_table_get(r->subprocess_env, envar) == NULL) { + return OK; + } + } + else { + if (apr_table_get(r->subprocess_env, &envar[1]) != NULL) { + return OK; + } + } + } + apr_table_unset(r->err_headers_out, "Content-Location"); + if (r->uri && r->parsed_uri.path) { + apr_table_setn(r->err_headers_out, "Content-Location", + apr_pstrdup(r->pool, + (char *) &r->uri[strlen(r->parsed_uri.path)])); + } + } return OK; } else if (ap_is_HTTP_REDIRECT(rr->status)) { @@ -255,6 +312,33 @@ && ( (rr->handler && !strcmp(rr->handler, "proxy-server")) || rr->finfo.filetype == APR_REG)) { ap_internal_fast_redirect(rr, r); + + /* return Content-Location for this location? */ + if (d->cl_enable == OPTION_ON) { + /* + * See if we've got any conditional envariable-controlled decisions + * to make. + */ + if (d->cl_condition_var != NULL) { + char *envar = d->cl_condition_var; + if (*envar != '!') { + if (apr_table_get(r->subprocess_env, envar) == NULL) { + return OK; + } + } + else { + if (apr_table_get(r->subprocess_env, &envar[1]) != NULL) { + return OK; + } + } + } + apr_table_unset(r->err_headers_out, "Content-Location"); + if (r->uri && r->parsed_uri.path) { + apr_table_setn(r->err_headers_out, "Content-Location", + apr_pstrdup(r->pool, + (char *) &r->uri[strlen(r->parsed_uri.path)])); + } + } return OK; }