From 07d0f00ac0ad168859ccb81dadb4a6e5037697c6 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Sun, 27 Jan 2002 07:44:07 +0000 Subject: [PATCH] Which PR? I can't count them all. Get QUERY_STRING and PATH_INFO working again. Also rounds out our fix to work around negotiated directories which Greg Ames fixed; this addition in request.c simply shortcuts all further processing. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93045 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ include/http_request.h | 15 ++++++++++--- modules/generators/mod_autoindex.c | 2 +- modules/mappers/mod_negotiation.c | 16 +++++++++----- server/request.c | 35 ++++++++++++++++++++++-------- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 7757b8e79c..05ef7ebdff 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 2.0.31-dev + *) Fixed PATH_INFO and QUERY_STRING from mod_negotiation results. + Resolves the common case of using negotation to resolve the request + /script/foo for /script.cgi/foo. [William Rowe] + *) Added new functions ap_add_(input|output)_filter_handle to allow modules to bypass the usual filter name lookup when adding hard-coded filters to a request [Brian Pane] diff --git a/include/http_request.h b/include/http_request.h index f1963eb20c..6b5cbea479 100644 --- a/include/http_request.h +++ b/include/http_request.h @@ -66,6 +66,9 @@ extern "C" { #endif +#define AP_SUBREQ_NO_ARGS 0 +#define AP_SUBREQ_MERGE_ARGS 1 + /** * @file http_request.h * @brief Apache Request library @@ -131,18 +134,24 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, * can be inspected to find information about the requested file * @param finfo The apr_dir_read result to lookup * @param r The current request + * @param subtype What type of subrequest to perform, one of; + *
+ *      AP_SUBREQ_NO_ARGS     ignore r->args and r->path_info
+ *      AP_SUBREQ_MERGE_ARGS  merge r->args and r->path_info
+ * 
* @param next_filter The first filter the sub_request should use. If this is * NULL, it defaults to the first filter for the main request * @return The new request record - * @deffunc request_rec * ap_sub_req_lookup_dirent(apr_finfo_t *finfo, const request_rec *r) + * @deffunc request_rec * ap_sub_req_lookup_dirent(apr_finfo_t *finfo, int subtype, const request_rec *r) * @tip The apr_dir_read flags value APR_FINFO_MIN|APR_FINFO_NAME flag is the * minimum recommended query if the results will be passed to apr_dir_read. * The file info passed must include the name, and must have the same relative * directory as the current request. */ AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *finfo, - const request_rec *r, - ap_filter_t *next_filter); + const request_rec *r, + int subtype, + ap_filter_t *next_filter); /** * Create a sub request for the given URI using a specific method. This * sub request can be inspected to find information about the requested URI diff --git a/modules/generators/mod_autoindex.c b/modules/generators/mod_autoindex.c index 99e65fabc5..bef602ae24 100644 --- a/modules/generators/mod_autoindex.c +++ b/modules/generators/mod_autoindex.c @@ -1286,7 +1286,7 @@ static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, return (NULL); } - if (!(rr = ap_sub_req_lookup_dirent(dirent, r, NULL))) { + if (!(rr = ap_sub_req_lookup_dirent(dirent, r, AP_SUBREQ_NO_ARGS, NULL))) { return (NULL); } diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index 12222c0839..f41d2d4648 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -1072,20 +1072,24 @@ static int read_types_multi(negotiation_state *neg) continue; } + /* Don't negotiate directories and other unusual files + */ + if (dirent.filetype != APR_REG) + 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 + /* 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). */ + sub_req = ap_sub_req_lookup_dirent(&dirent, r, AP_SUBREQ_MERGE_ARGS, NULL); - sub_req = ap_sub_req_lookup_dirent(&dirent, r, NULL); - - /* BLECH --- don't multi-resolve non-ordinary files */ - + /* Double check, we still don't multi-resolve non-ordinary files + */ if (sub_req->finfo.filetype != APR_REG) continue; diff --git a/server/request.c b/server/request.c index f58e18caaf..f4cb79ca92 100644 --- a/server/request.c +++ b/server/request.c @@ -1579,6 +1579,7 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_uri(const char *new_file, AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, const request_rec *r, + int subtype, ap_filter_t *next_filter) { request_rec *rnew; @@ -1593,16 +1594,26 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, */ if (r->path_info && *r->path_info) { /* strip path_info off the end of the uri to keep it in sync - * with r->filename, which has already been stripped by directory_walk + * with r->filename, which has already been stripped by directory_walk, + * merge the dirent->name, and then, if the caller wants us to remerge + * the original path info, do so. Note we never fix the path_info back + * to r->filename, since dir_walk would do so (but we don't expect it + * to happen in the usual cases) */ udir = apr_pstrdup(rnew->pool, r->uri); udir[ap_find_path_info(udir, r->path_info)] = '\0'; udir = ap_make_dirstr_parent(rnew->pool, udir); + + rnew->uri = ap_make_full_path(rnew->pool, udir, dirent->name); + if (subtype == AP_SUBREQ_MERGE_ARGS) { + rnew->uri = ap_make_full_path(rnew->pool, rnew->uri, r->path_info + 1); + rnew->path_info = apr_pstrdup(rnew->pool, r->path_info); + } } else { udir = ap_make_dirstr_parent(rnew->pool, r->uri); + rnew->uri = ap_make_full_path(rnew->pool, udir, dirent->name); } - rnew->uri = ap_make_full_path(rnew->pool, udir, dirent->name); fdir = ap_make_dirstr_parent(rnew->pool, r->filename); rnew->filename = ap_make_full_path(rnew->pool, fdir, dirent->name); if (r->canonical_filename == r->filename) { @@ -1657,17 +1668,23 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, } if (rnew->finfo.filetype == APR_DIR) { - /* ### Would be real nice if apr_make_full_path overallocated - * the buffer by one character instead of a complete copy. + /* ap_make_full_path overallocated the buffers + * by one character to help us out here. */ - rnew->filename = apr_pstrcat(rnew->pool, rnew->filename, "/", NULL); - rnew->uri = apr_pstrcat(rnew->pool, rnew->uri, "/", NULL); - if (r->canonical_filename == r->filename) { - rnew->canonical_filename = rnew->filename; + strcpy(rnew->filename + strlen(rnew->filename), "/"); + if (!rnew->path_info || !*rnew->path_info) { + strcpy(rnew->uri + strlen(rnew->uri ), "/"); } } - ap_parse_uri(rnew, rnew->uri); /* fill in parsed_uri values */ + /* fill in parsed_uri values + */ + if (r->args && *r->args && (subtype == AP_SUBREQ_MERGE_ARGS)) { + ap_parse_uri(rnew, apr_pstrcat(r->pool, rnew->uri, "?", r->args, NULL)); + } + else { + ap_parse_uri(rnew, rnew->uri); + } if ((res = ap_process_request_internal(rnew))) { rnew->status = res; -- 2.40.0