extern "C" {
#endif
+#define AP_SUBREQ_NO_ARGS 0
+#define AP_SUBREQ_MERGE_ARGS 1
+
/**
* @file http_request.h
* @brief Apache Request library
* 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
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;
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;
*/
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) {
}
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;