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
This commit is contained in:
William A. Rowe Jr
2002-01-27 07:44:07 +00:00
parent 60919177e8
commit 011c7375e9
5 changed files with 53 additions and 19 deletions

View File

@ -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]

View File

@ -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,10 +134,15 @@ 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;
* <PRE>
* AP_SUBREQ_NO_ARGS ignore r->args and r->path_info
* AP_SUBREQ_MERGE_ARGS merge r->args and r->path_info
* </PRE>
* @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
@ -142,6 +150,7 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file,
*/
AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *finfo,
const request_rec *r,
int subtype,
ap_filter_t *next_filter);
/**
* Create a sub request for the given URI using a specific method. This

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
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;