From: William A. Rowe Jr Date: Mon, 6 Aug 2001 19:03:37 +0000 (+0000) Subject: The real slim shady finally stood up. This patch segregates the fast X-Git-Tag: 2.0.23~50 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68eb2c2c832a08953db68737d0c315043376a4d6;p=apache 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 --- diff --git a/include/http_request.h b/include/http_request.h index 5e779eccc1..a1f8375a57 100644 --- a/include/http_request.h +++ b/include/http_request.h @@ -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 diff --git a/modules/http/http_request.c b/modules/http/http_request.c index cfb9eeeb25..107436ce25 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -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); diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index 946bac5761..9d162a7e5b 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -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 */ - - if (sub_req->finfo.filetype != APR_REG) { - res = HTTP_NOT_FOUND; - goto return_from_multi; - } - - /* Otherwise, use it. */ + /* now do a "fast redirect" ... promotes the sub_req into the main req */ + ap_internal_fast_redirect(sub_req, r); - /* 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. + /* clean up all but our favorite variant, since that sub_req + * is now merged into the main request! */ - 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); 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); } }