Commit d5c35f81 authored by Joe Orton's avatar Joe Orton
Browse files

Backport some mod_dav fixes:

* modules/dav/fs/repos.c (MAP_IO2HTTP): New macro.
(dav_fs_copymove_file): Use it to give a 507 if open() returns ENOSPC,
and use it to handle apr_file_write_full() return code.
(dav_fs_open_stream): Use MAP_IO2HTTP.
(dav_fs_create_collection): Use APR_STATUS_IS_ENOSPC.

* modules/dav/fs/repos.c (dav_fs_copymove_file): Update for the fact
that apr_file_read() has guaranteed len == 0 at EOF for a looong time;
and avoid a redundant call to write(,,0) when EOF is reached.

* modules/dav/main/util.c (dav_validate_resource_state): Fix a 2617
violation: if the lock user validation fails, rather than giving a 401
without a WWW-Authenticate header, give a 403.

Reviewed by: Andr�� Malo, Jeff Trawick


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@103685 13f79535-47bb-0310-9956-ffa450edef68
parent e1fc7cf0
Loading
Loading
Loading
Loading
+1 −9
Changes for STATUS: 1 added line, 9 removed lines.
Original line number Diff line number Diff line
APACHE 2.0 STATUS:                                              -*-text-*-
Last modified at [$Date: 2004/05/14 11:30:42 $]
Last modified at [$Date: 2004/05/17 14:13:49 $]

Release:

@@ -227,19 +227,11 @@ PATCHES TO BACKPORT FROM 2.1
       http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_auth_digest.c?r1=1.86&r2=1.87
       +1: geoff, nd

    *) mod_dav: Fix a 2617 compliance issue
       http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/dav/main/util.c?r1=1.53&r2=1.54
       +1: jorton, nd, trawick

    *) mod_dav: Send an EOS at the end of the multistatus brigade.
       http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/dav/main/mod_dav.c?r1=1.105&r2=1.106
       +1: jorton
         nd asks: Sure, you want to drop the return code of ap_pass_brigade?

    *) mod_dav_fs: Better ENOSPC handling and a remove a write(,,0) call:
       http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/dav/fs/repos.c?r1=1.77&r2=1.79
       +1: jorton, nd, trawick

    *) Allow Satisfy directives to be influenced by <Limit>.
       PR: 14726
         include/http_core.h: r1.81
+21 −24
Changes for modules/dav/fs/repos.c: 21 added lines, 24 removed lines.
Original line number Diff line number Diff line
@@ -182,6 +182,11 @@ struct dav_stream {
    const char *pathname;       /* we may need to remove it at close time */
};

/* returns an appropriate HTTP status code given an APR status code for a 
 * failed I/O operation.  ### use something besides 500? */
#define MAP_IO2HTTP(e) (APR_STATUS_IS_ENOSPC(e) ? HTTP_INSUFFICIENT_STORAGE : \
                        HTTP_INTERNAL_SERVER_ERROR)

/* forward declaration for internal treewalkers */
static dav_error * dav_fs_walk(const dav_walk_params *params, int depth,
                               dav_response **response);
@@ -301,6 +306,7 @@ static dav_error * dav_fs_copymove_file(
    dav_buffer work_buf = { 0 };
    apr_file_t *inf = NULL;
    apr_file_t *outf = NULL;
    apr_status_t status;

    if (pbuf == NULL)
        pbuf = &work_buf;
@@ -315,18 +321,17 @@ static dav_error * dav_fs_copymove_file(
    }

    /* ### do we need to deal with the umask? */
    if ((apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY,
                 APR_OS_DEFAULT, p)) != APR_SUCCESS) {
    status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE 
                           | APR_BINARY, APR_OS_DEFAULT, p);
    if (status != APR_SUCCESS) {
        apr_file_close(inf);

        /* ### use something besides 500? */
        return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
        return dav_new_error(p, MAP_IO2HTTP(status), 0,
                             "Could not open file for writing");
    }

    while (1) {
        apr_size_t len = DAV_FS_COPY_BLOCKSIZE;
        apr_status_t status;

        status = apr_file_read(inf, pbuf->buf, &len);
        if (status != APR_SUCCESS && status != APR_EOF) {
@@ -348,10 +353,12 @@ static dav_error * dav_fs_copymove_file(
                                 "Could not read input file");
        }

        /* write any bytes that were read (applies to APR_EOF, too) */
        if (apr_file_write_full(outf, pbuf->buf, len, NULL) != APR_SUCCESS) {
            int save_errno = errno;
        if (status == APR_EOF)
            break;

        /* write any bytes that were read */
        status = apr_file_write_full(outf, pbuf->buf, len, NULL);
        if (status != APR_SUCCESS) {
            apr_file_close(inf);
            apr_file_close(outf);

@@ -365,19 +372,9 @@ static dav_error * dav_fs_copymove_file(
                                     "inconsistent state.");
            }

            if (save_errno == ENOSPC) {
                return dav_new_error(p, HTTP_INSUFFICIENT_STORAGE, 0,
                                     "There is not enough storage to write to "
                                     "this resource.");
            }

            /* ### use something besides 500? */
            return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
            return dav_new_error(p, MAP_IO2HTTP(status), 0,
                                 "Could not write output file");
        }

        if (status == APR_EOF)
            break;
    }

    apr_file_close(inf);
@@ -817,6 +814,7 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource,
    apr_pool_t *p = resource->info->pool;
    dav_stream *ds = apr_pcalloc(p, sizeof(*ds));
    apr_int32_t flags;
    apr_status_t rv;

    switch (mode) {
    default:
@@ -833,10 +831,9 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource,

    ds->p = p;
    ds->pathname = resource->info->pathname;
    if (apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, 
                ds->p) != APR_SUCCESS) {
        /* ### use something besides 500? */
        return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
    rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
    if (rv != APR_SUCCESS) {
        return dav_new_error(p, MAP_IO2HTTP(rv), 0,
                             "An error occurred while opening a resource.");
    }

@@ -985,7 +982,7 @@ static dav_error * dav_fs_create_collection(dav_resource *resource)
    apr_status_t status;

    status = apr_dir_make(ctx->pathname, APR_OS_DEFAULT, ctx->pool);
    if (status == ENOSPC) {
    if (APR_STATUS_IS_ENOSPC(status)) {
        return dav_new_error(ctx->pool, HTTP_INSUFFICIENT_STORAGE, 0,
                             "There is not enough storage to create "
                             "this collection.");
+1 −1
Changes for modules/dav/main/util.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -1145,7 +1145,7 @@ static dav_error * dav_validate_resource_state(apr_pool_t *p,
                                            "\" submitted a locktoken created "
                                            "by user \"",
                                            lock->auth_user, "\".", NULL);
                        return dav_new_error(p, HTTP_UNAUTHORIZED, 0, errmsg);
                        return dav_new_error(p, HTTP_FORBIDDEN, 0, errmsg);
                    }

                    /*