Commit 1b8552f8 authored by Greg Stein's avatar Greg Stein
Browse files

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
parent d276850e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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. */
+2 −1
Original line number Diff line number Diff line
@@ -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 {
+45 −30
Original line number Diff line number Diff line
@@ -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,12 +201,31 @@ 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;
    }

    /* 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 =
	    "Destination URI contains invalid components "
	    "(a query or a fragment).";
	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)
@@ -215,29 +235,23 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r)
        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
        /* 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)",
                                           "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;
        }
    if (comp.query != NULL || comp.fragment != NULL) {
	result.err.status = HTTP_BAD_REQUEST;
	result.err.desc =
	    "Destination URI contains invalid components "
	    "(a query or a fragment).";
	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);
    }