Commit e367137b authored by William A. Rowe Jr's avatar William A. Rowe Jr
Browse files

  The real slim shady finally stood up.  This patch segregates the fast
  internal redirect logic back into http_request, the next patch will
  actually fix it.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89946 13f79535-47bb-0310-9956-ffa450edef68
parent c8b789b2
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -199,6 +199,16 @@ AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r);
 */
AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r);

/**
 * Redirect the current request to a sub_req, merging the pools
 * @param sub_req A subrequest created from this request
 * @param r The current request
 * @deffunc void ap_internal_fast_redirect(request_rec *sub_req, request_rec *r)
 * @tip the sub_req's pool will be merged into r's pool, be very careful
 * not to destroy this subrequest, it will be destroyed with the main request!
 */
AP_DECLARE(void) ap_internal_fast_redirect(request_rec *sub_req, request_rec *r))

/**
 * Can be used within any handler to determine if any authentication
 * is required for the current request
+27 −0
Original line number Diff line number Diff line
@@ -556,6 +556,33 @@ static request_rec *internal_internal_redirect(const char *new_uri,
    return new;
}

AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r))
{
    /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool
     * will exist as long as r->pool.  Otherwise we run into troubles because
     * some values in this request will be allocated in r->pool, and others in
     * rr->pool.
     */
    apr_pool_join(r->pool, rr->pool);
    r->mtime = 0; /* reset etag info for subrequest */
    r->filename = rr->filename;
    r->handler = rr->handler;
    r->content_type = rr->content_type;
    r->content_encoding = rr->content_encoding;
    r->content_languages = rr->content_languages;
    r->content_language = rr->content_language;
    r->finfo = rr->finfo;
    r->per_dir_config = rr->per_dir_config;
    /* copy output headers from subrequest, but leave negotiation headers */
    r->notes = apr_table_overlay(r->pool, rr->notes, r->notes);
    r->headers_out = apr_table_overlay(r->pool, rr->headers_out,
                                    r->headers_out);
    r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out,
                                        r->err_headers_out);
    r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
                                       r->subprocess_env);
}

AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
{
    request_rec *new = internal_internal_redirect(new_uri, r);
+16 −32
Original line number Diff line number Diff line
@@ -911,6 +911,7 @@ static int read_types_multi(negotiation_state *neg)
    struct var_rec mime_info;
    struct accept_rec accept_info;
    void *new_var;
    int anymatch = 0;

    clean_var_rec(&mime_info);

@@ -947,6 +948,11 @@ static int read_types_multi(negotiation_state *neg)
            continue;
        }

        /* Ok, something's here.  Maybe nothing useful.  Remember that
         * we tried, if we completely fail, so we can reject the request!
         */
        anymatch = 1;

        /* Yep.  See if it's something which we have access to, and 
         * which has a known type and encoding (as opposed to something
         * which we'll be slapping default_type on later).
@@ -954,6 +960,11 @@ static int read_types_multi(negotiation_state *neg)

        sub_req = ap_sub_req_lookup_dirent(&dirent, r, NULL);

        /* BLECH --- don't multi-resolve non-ordinary files */

        if (sub_req->finfo.filetype != APR_REG)
            continue;

        /* If it has a handler, we'll pretend it's a CGI script,
         * since that's a good indication of the sort of thing it
         * might be doing.
@@ -2689,43 +2700,16 @@ static int handle_multi(request_rec *r)
        }
    }

    /* BLECH --- don't multi-resolve non-ordinary files */
    /* now do a "fast redirect" ... promotes the sub_req into the main req */
    ap_internal_fast_redirect(sub_req, r);

    if (sub_req->finfo.filetype != APR_REG) {
        res = HTTP_NOT_FOUND;
        goto return_from_multi;
    }

    /* Otherwise, use it. */

    /* now do a "fast redirect" ... promote the sub_req into the main req */
    /* We need to tell POOL_DEBUG that we're guaranteeing that sub_req->pool
     * will exist as long as r->pool.  Otherwise we run into troubles because
     * some values in this request will be allocated in r->pool, and others in
     * sub_req->pool.
     */
    apr_pool_join(r->pool, sub_req->pool);
    r->mtime = 0; /* reset etag info for subrequest */
    r->filename = sub_req->filename;
    r->handler = sub_req->handler;
    r->content_type = sub_req->content_type;
    r->content_encoding = sub_req->content_encoding;
    r->content_languages = sub_req->content_languages;
    r->content_language = sub_req->content_language;
    r->finfo = sub_req->finfo;
    r->per_dir_config = sub_req->per_dir_config;
    /* copy output headers from subrequest, but leave negotiation headers */
    r->notes = apr_table_overlay(r->pool, sub_req->notes, r->notes);
    r->headers_out = apr_table_overlay(r->pool, sub_req->headers_out,
                                    r->headers_out);
    r->err_headers_out = apr_table_overlay(r->pool, sub_req->err_headers_out,
                                        r->err_headers_out);
    r->subprocess_env = apr_table_overlay(r->pool, sub_req->subprocess_env,
                                       r->subprocess_env);
    /* clean up all but our favorite variant, since that sub_req
     * is now merged into the main request!
     */
    avail_recs = (var_rec *) neg->avail_vars->elts;
    for (j = 0; j < neg->avail_vars->nelts; ++j) {
        var_rec *variant = &avail_recs[j];
        if (variant != best && variant->sub_req) {
        if (variant != best && variant->rr) {
            ap_destroy_sub_req(variant->sub_req);
        }
    }