]> granicus.if.org Git - apache/commitdiff
allow non-absolute URIs to occur in some of the requests. RFC 2518 states
authorGreg Stein <gstein@apache.org>
Tue, 17 Apr 2001 11:07:09 +0000 (11:07 +0000)
committerGreg Stein <gstein@apache.org>
Tue, 17 Apr 2001 11:07:09 +0000 (11:07 +0000)
that the Destination: header (used in MOVE/COPY) must be an absolute URI, so
it keeps that constraint.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88876 13f79535-47bb-0310-9956-ffa450edef68

modules/dav/main/mod_dav.c
modules/dav/main/mod_dav.h
modules/dav/main/util.c

index f1a32bd9c437906c4f96c508601877b4bdda12de..8e29f05c7f70b1cee2207d6e5f15b5ce0f0799ec 100644 (file)
@@ -2522,7 +2522,7 @@ static int dav_method_copymove(request_rec *r, int is_move)
        return HTTP_BAD_REQUEST;
     }
 
-    lookup = dav_lookup_uri(dest, r);
+    lookup = dav_lookup_uri(dest, r, 1 /* must_be_absolute */);
     if (lookup.rnew == NULL) {
        if (lookup.err.status == HTTP_BAD_REQUEST) {
            /* This supplies additional information for the default message. */
@@ -3686,7 +3686,7 @@ static int dav_method_update(request_rec *r)
     /* if target is a version, resolve the version resource */
     /* ### dav_lookup_uri only allows absolute URIs; is that OK? */
     if (!is_label) {
-        lookup = dav_lookup_uri(target, r);
+        lookup = dav_lookup_uri(target, r, 0 /* must_be_absolute */);
         if (lookup.rnew == NULL) {
            if (lookup.err.status == HTTP_BAD_REQUEST) {
                /* This supplies additional information for the default message. */
@@ -4156,7 +4156,7 @@ static int dav_method_merge(request_rec *r)
 
     /* get a subrequest for the source, so that we can get a dav_resource
        for that source. */
-    lookup = dav_lookup_uri(source, r);
+    lookup = dav_lookup_uri(source, r, 0 /* must_be_absolute */);
     if (lookup.rnew == NULL) {
         if (lookup.err.status == HTTP_BAD_REQUEST) {
            /* This supplies additional information for the default message. */
@@ -4278,7 +4278,7 @@ static int dav_method_bind(request_rec *r)
        return HTTP_BAD_REQUEST;
     }
 
-    lookup = dav_lookup_uri(dest, r);
+    lookup = dav_lookup_uri(dest, r, 0 /* must_be_absolute */);
     if (lookup.rnew == NULL) {
        if (lookup.err.status == HTTP_BAD_REQUEST) {
            /* This supplies additional information for the default message. */
index 466cb6d711cccea6755f5d060222d616e983635a..162f7bff66b12ed642c2e34bc4530b29bce20caa 100644 (file)
@@ -491,7 +491,8 @@ typedef struct
 } dav_lookup_result;
 
 
-dav_lookup_result dav_lookup_uri(const char *uri, request_rec *r);
+dav_lookup_result dav_lookup_uri(const char *uri, request_rec *r,
+                                 int must_be_absolute);
 
 /* defines type of property info a provider is to return */
 typedef enum {
index 1d523fcb1106172fd3481ab735844720b7c8409b..cc21a836f9da7ac83ca5cf86fc381ae4db33d411 100644 (file)
@@ -183,7 +183,8 @@ DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf,
 ** If NULL is returned, then an error occurred with parsing the URI or
 ** the URI does not match the current server.
 */
-dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r)
+dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r,
+                                 int must_be_absolute)
 {
     dav_lookup_result result = { 0 };
     const char *scheme;
@@ -200,38 +201,13 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r)
     }
 
     /* the URI must be an absoluteURI (WEBDAV S9.3) */
-    if (comp.scheme == NULL) {
+    if (comp.scheme == NULL && must_be_absolute) {
        result.err.status = HTTP_BAD_REQUEST;
        result.err.desc = "Destination URI must be an absolute URI.";
        return result;
     }
 
-    /* ### not sure this works if the current request came in via https: */
-    scheme = r->parsed_uri.scheme;
-    if (scheme == NULL)
-       scheme = ap_http_method(r);
-
-    /* insert a port if the URI did not contain one */
-    if (comp.port == 0)
-        comp.port = ap_default_port_for_scheme(comp.scheme);
-
-    /* now, verify that the URI uses the same scheme as the current request.
-       the port, must match our port.
-       the URI must not have a query (args) or a fragment
-     */
-    apr_sockaddr_port_get(&port, r->connection->local_addr);
-    if (strcasecmp(comp.scheme, scheme) != 0 ||
-       comp.port != port) {
-       result.err.status = HTTP_BAD_GATEWAY;
-       result.err.desc = apr_psprintf(r->pool,
-                                     "Destination URI refers to different "
-                                     "scheme or port (%s://hostname:%d)" 
-                                      APR_EOL_STR "(want: %s://hostname:%d)",
-                                     comp.scheme ? comp.scheme : scheme,
-                                     comp.port ? comp.port : port,
-                                     scheme, port);
-       return result;
-    }
+    /* the URI must not have a query (args) or a fragment */
     if (comp.query != NULL || comp.fragment != NULL) {
        result.err.status = HTTP_BAD_REQUEST;
        result.err.desc =
@@ -240,6 +216,44 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r)
        return result;
     }
 
+    /* If the scheme or port was provided, then make sure that it matches
+       the scheme/port of this request. If the request must be absolute,
+       then require the (explicit/implicit) scheme/port be matching.
+
+       ### hmm. if a port wasn't provided (does the parse return port==0?),
+       ### but we're on a non-standard port, then we won't detect that the
+       ### URI's port implies the wrong one.
+    */
+    if (comp.scheme != NULL || comp.port != 0 || must_be_absolute)
+    {
+        /* ### not sure this works if the current request came in via https: */
+        scheme = r->parsed_uri.scheme;
+        if (scheme == NULL)
+            scheme = ap_http_method(r);
+
+        /* insert a port if the URI did not contain one */
+        if (comp.port == 0)
+            comp.port = ap_default_port_for_scheme(comp.scheme);
+
+        /* now, verify that the URI uses the same scheme as the current.
+           request. the port must match our port.
+        */
+        apr_sockaddr_port_get(&port, r->connection->local_addr);
+        if (strcasecmp(comp.scheme, scheme) != 0 ||
+            comp.port != port) {
+            result.err.status = HTTP_BAD_GATEWAY;
+            result.err.desc = apr_psprintf(r->pool,
+                                           "Destination URI refers to "
+                                           "different scheme or port "
+                                           "(%s://hostname:%d)" APR_EOL_STR
+                                           "(want: %s://hostname:%d)",
+                                           comp.scheme ? comp.scheme : scheme,
+                                           comp.port ? comp.port : port,
+                                           scheme, port);
+            return result;
+        }
+    }
+
     /* we have verified the scheme, port, and general structure */
 
     /*
@@ -254,8 +268,9 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r)
     ** ### maybe the admin should list the unqualified hosts in a
     ** ### <ServerAlias> block?
     */
-    if (strrchr(comp.hostname, '.') == NULL &&
-       (domain = strchr(r->server->server_hostname, '.')) != NULL) {
+    if (comp.hostname != NULL
+        && strrchr(comp.hostname, '.') == NULL
+       && (domain = strchr(r->server->server_hostname, '.')) != NULL) {
        comp.hostname = apr_pstrcat(r->pool, comp.hostname, domain, NULL);
     }