]> granicus.if.org Git - apache/commitdiff
Which PR? I can't count them all. Get QUERY_STRING and PATH_INFO
authorWilliam A. Rowe Jr <wrowe@apache.org>
Sun, 27 Jan 2002 07:44:07 +0000 (07:44 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Sun, 27 Jan 2002 07:44:07 +0000 (07:44 +0000)
  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
include/http_request.h
modules/generators/mod_autoindex.c
modules/mappers/mod_negotiation.c
server/request.c

diff --git a/CHANGES b/CHANGES
index 7757b8e79cba5c21316a5848442d3edd146a1afd..05ef7ebdff7557c3b9cedd98c6f92431823cd642 100644 (file)
--- 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]
index f1963eb20c9c29fc6aa9872b9d4ba5081af6b4b1..6b5cbea4794109a0546f8bfab4d62a36156a0349 100644 (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,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;
+ * <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
  * 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
index 99e65fabc5192ca5a47e4179a1d81b2e2454d71f..bef602ae2463e9681f2184675cdf3d83f118b626 100644 (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);
     }
 
index 12222c08393e82fae36753149c13e2f82b85f9b5..f41d2d4648f87f519e578eabf88646cf173d2a5e 100644 (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;
 
index f58e18caafd108a1abfc47a5f597c4d5a7e75be4..f4cb79ca92145438b6bdccff47a9db57124f2939 100644 (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);
     }
-    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;