Commit d4b92389 authored by Stefan Fritsch's avatar Stefan Fritsch
Browse files

- Introduce concept of context prefix (which is an URL prefix)

  and context document root (which is the file system directory that
  this URL prefix is mapped to). This generalization of the document
  root makes it easier for scripts to create self-referential URLs and
  to find their files.
- Expose CONTEXT_DOCUMENT_ROOT and CONTEXT_PREFIX as envvars, in mod_rewrite,
  and in ap_expr.
- Make mod_alias and mod_userdir set the context information.
- Allow to override the document root on a per-request basis. This allows
  mass vhosting modules to set DOCUMENT_ROOT correctly.
- Make mod_vhost_alias set the per-request document root

PR: 26052, 46198, 49705

Remaining tasks:
- Use the context document root & prefix in mod_rewrite to make RewriteBase
  unneccessary in many cases. Do this without breaking compatibility.
- Write docs.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1132494 13f79535-47bb-0310-9956-ffa450edef68
parent dc8e3c08
Loading
Loading
Loading
Loading
+9 −0
Changes for CHANGES: 9 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -2,6 +2,15 @@

Changes with Apache 2.3.13

  *) mod_userdir/mod_alias/mod_vhost_alias: Correctly set DOCUMENT_ROOT,
     CONTEXT_DOCUMENT_ROOT, CONTEXT_PREFIX. PR 26052. PR 46198.
     [Stefan Fritsch]

  *) core: Allow to override document_root on a per-request basis. Introduce
     new context_document_root and context_prefix which provide information
     about non-global URI-to-directory mappings (from e.g. mod_userdir or
     mod_alias) to scripts. PR 49705. [Stefan Fritsch]

  *) core: Add <ElseIf> and <Else> to complement <If> sections.
     [Stefan Fritsch]

+4 −1
Changes for include/ap_mmn.h: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -327,7 +327,10 @@
 *                         ap_expr_exec_ctx()
 * 20110604.0 (2.3.13-dev) Make ap_rputs() inline
 * 20110605.0 (2.3.13-dev) add core_dir_config->condition_ifelse, change return
 *                         type of ap_add_if_conf()
 *                         type of ap_add_if_conf().
 *                         Add members of core_request_config: document_root,
 *                         context_document_root, context_prefix.
 *                         Add ap_context_*(), ap_set_context_info(), ap_set_document_root()
 */

#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
+18 −0
Changes for include/http_core.h: 18 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -340,6 +340,24 @@ typedef struct {
                                   * ErrorDocument
                                   */

    /** per-request document root of the server. This allows mass vhosting
     * modules better compatibility with some scripts. Normally the
     * context_* info should be used instead */
    const char *document_root;

    /*
     * more fine-grained context information which is set by modules like
     * mod_alias and mod_userdir
     */
    /** the context root directory on disk for the current resource,
     *  without trailing slash
     */
    const char *context_document_root;
    /** the URI prefix that corresponds to the context_document_root directory,
     *  without trailing slash
     */
    const char *context_prefix;

    /** There is a script processor installed on the output filter chain,
     * so it needs the default_handler to deliver a (script) file into
     * the chain so it can process it. Normally, default_handler only
+36 −0
Changes for include/httpd.h: 36 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1295,6 +1295,42 @@ typedef struct core_net_rec {
    core_ctx_t *in_ctx;
} core_net_rec;

/**
 * Get the context_document_root for a request. This is a generalization of
 * the document root, which is too limited in the presence of mappers like
 * mod_userdir and mod_alias. The context_document_root is the directory
 * on disk that maps to the context_prefix URI prefix.
 * @param r The request
 * @note For resources that do not map to the file system or for very complex
 * mappings, this information may still be wrong.
 */
AP_DECLARE(const char *) ap_context_document_root(request_rec *r);

/**
 * Get the context_prefix for a request. The context_prefix URI prefix
 * maps to the context_document_root on disk.
 * @param r The request
 */
AP_DECLARE(const char *) ap_context_prefix(request_rec *r);

/** Set context_prefix and context_document_root for a request.
 * @param r The request
 * @param prefix the URI prefix, without trailing slash
 * @param document_root the corresponding directory on disk, without trailing
 * slash
 * @note If one of prefix of document_root is NULL, the corrsponding
 * property will not be changed.
 */
AP_DECLARE(void) ap_set_context_info(request_rec *r, const char *prefix,
                                     const char *document_root);

/** Set per-request document root. This is for mass virtual hosting modules
 * that want to provide the correct DOCUMENT_ROOT value to scripts.
 * @param r The request
 * @param document_root the document root for the request.
 */
AP_DECLARE(void) ap_set_document_root(request_rec *r, const char *document_root);

/**
 * Examine a field value (such as a media-/content-type) string and return
 * it sans any parameters; e.g., strip off any ';charset=foo' and the like.
+18 −4
Changes for modules/mappers/mod_alias.c: 18 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ static int alias_matches(const char *uri, const char *alias_fakename)
}

static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
                            int doesc, int *status)
                            int is_redir, int *status)
{
    alias_entry *entries = (alias_entry *) aliases->elts;
    ap_regmatch_t regm[AP_MAX_REG_MATCH];
@@ -350,7 +350,8 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
                if (alias->real) {
                    found = ap_pregsub(r->pool, alias->real, r->uri,
                                       AP_MAX_REG_MATCH, regm);
                    if (found && doesc) {
                    if (found) {
                       if (is_redir) {
                            apr_uri_t uri;
                            apr_uri_parse(r->pool, found, &uri);
                            /* Do not escape the query string or fragment. */
@@ -366,6 +367,18 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
                                                    uri.fragment, NULL);
                            }
                       }
                       else {
                           int pathlen = strlen(found) -
                                         (strlen(r->uri + regm[0].rm_eo));
                           AP_DEBUG_ASSERT(pathlen >= 0);
                           AP_DEBUG_ASSERT(pathlen <= strlen(found));
                           ap_set_context_info(r,
                                               apr_pstrmemdup(r->pool, r->uri,
                                                              regm[0].rm_eo),
                                               apr_pstrmemdup(r->pool, found,
                                                              pathlen));
                       }
                    }
                }
                else {
                    /* need something non-null */
@@ -377,7 +390,8 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
            l = alias_matches(r->uri, alias->fake);

            if (l > 0) {
                if (doesc) {
                ap_set_context_info(r, alias->fake, alias->real);
                if (is_redir) {
                    char *escurl;
                    escurl = ap_os_escape_path(r->pool, r->uri + l, 1);

@@ -398,7 +412,7 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
             * canonicalized.  After I finish eliminating os canonical.
             * Better fail test for ap_server_root_relative needed here.
             */
            if (!doesc) {
            if (!is_redir) {
                found = ap_server_root_relative(r->pool, found);
            }
            if (found) {
Loading