1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

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
This commit is contained in:
William A. Rowe Jr
2001-08-06 19:03:37 +00:00
parent 7c91bb33c3
commit 68eb2c2c83
3 changed files with 53 additions and 32 deletions

View File

@@ -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); 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 * Can be used within any handler to determine if any authentication
* is required for the current request * is required for the current request

View File

@@ -556,6 +556,33 @@ static request_rec *internal_internal_redirect(const char *new_uri,
return new; 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) AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
{ {
request_rec *new = internal_internal_redirect(new_uri, r); request_rec *new = internal_internal_redirect(new_uri, r);

View File

@@ -911,6 +911,7 @@ static int read_types_multi(negotiation_state *neg)
struct var_rec mime_info; struct var_rec mime_info;
struct accept_rec accept_info; struct accept_rec accept_info;
void *new_var; void *new_var;
int anymatch = 0;
clean_var_rec(&mime_info); clean_var_rec(&mime_info);
@@ -947,6 +948,11 @@ static int read_types_multi(negotiation_state *neg)
continue; 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 /* Yep. See if it's something which we have access to, and
* which has a known type and encoding (as opposed to something * which has a known type and encoding (as opposed to something
* which we'll be slapping default_type on later). * 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); 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, /* 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 * since that's a good indication of the sort of thing it
* might be doing. * 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) { /* clean up all but our favorite variant, since that sub_req
res = HTTP_NOT_FOUND; * is now merged into the main request!
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);
avail_recs = (var_rec *) neg->avail_vars->elts; avail_recs = (var_rec *) neg->avail_vars->elts;
for (j = 0; j < neg->avail_vars->nelts; ++j) { for (j = 0; j < neg->avail_vars->nelts; ++j) {
var_rec *variant = &avail_recs[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); ap_destroy_sub_req(variant->sub_req);
} }
} }