From 473cf0a48fac224e1f2c504c3313dc33ac1125b2 Mon Sep 17 00:00:00 2001 From: Greg Stein Date: Tue, 17 Apr 2001 11:07:09 +0000 Subject: [PATCH] allow non-absolute URIs to occur in some of the requests. RFC 2518 states 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 | 8 ++-- modules/dav/main/mod_dav.h | 3 +- modules/dav/main/util.c | 75 +++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index f1a32bd9c4..8e29f05c7f 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -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. */ diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 466cb6d711..162f7bff66 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -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 { diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 1d523fcb11..cc21a836f9 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -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 ** ### 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); } -- 2.40.0