httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Justin Erenkrantz <jerenkra...@apache.org>
Subject [PATCH] Switch DAV PUT to use brigades
Date Sun, 02 Jun 2002 23:15:11 GMT
This patch switches mod_dav to use brigades for input when
handling PUT.

My one caveat with this is what to do when the filters return
an error (spec. AP_FILTER_ERROR which means that they already
took care of it).  In this case, the handler should NOT generate
an error of its own and just return the AP_FILTER_ERROR value
back.  mod_dav has its own error handling, so its not as
straightforward as the other modules.

Greg?  Anyone else?  -- justin

Index: modules/dav/main/mod_dav.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.c,v
retrieving revision 1.79
diff -u -r1.79 mod_dav.c
--- modules/dav/main/mod_dav.c	17 May 2002 11:33:08 -0000	1.79
+++ modules/dav/main/mod_dav.c	2 Jun 2002 23:12:53 -0000
@@ -868,10 +868,6 @@
     apr_off_t range_start;
     apr_off_t range_end;
 
-    if ((result = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) {
-        return result;
-    }
-
     /* Ask repository module to resolve the resource */
     err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
                            &resource);
@@ -946,40 +942,73 @@
     }
 
     if (err == NULL) {
-        if (ap_should_client_block(r)) {
-            char *buffer = apr_palloc(r->pool, DAV_READ_BLOCKSIZE);
-            long len;
+        apr_bucket_brigade *brigade;
+        apr_bucket *bucket;
+        apr_status_t rv;
+        int seen_eos;
+
+        brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+        seen_eos = 0;
+
+        /*
+         * ### what happens if we read more/less than the amount
+         * ### specified in the Content-Range? eek...
+         */
+        do {
+            rv = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES,
+                                APR_BLOCK_READ, DAV_READ_BLOCKSIZE);
 
             /*
-             * Once we start reading the request, then we must read the
-             * whole darn thing. ap_discard_request_body() won't do anything
-             * for a partially-read request.
+             * Error reading request body. This has precedence over
+             * prior errors.  
              */
-
-            while ((len = ap_get_client_block(r, buffer,
-                                              DAV_READ_BLOCKSIZE)) > 0) {
-                   if (err == NULL) {
-                       /* write whatever we read, until we see an error */
-                       err = (*resource->hooks->write_stream)(stream,
-                                                              buffer, len);
-                   }
+            if (rv != APR_SUCCESS) {
+                /* If the filter didn't handle this error. */
+                if (rv != AP_FILTER_ERROR) {
+                    rv = HTTP_BAD_REQUEST;
+                }
+
+                err = dav_new_error(r->pool, rv, 0,
+                                   "An error occurred while reading the "
+                                   "request body.");
+                break;
             }
 
-            /*
-             * ### what happens if we read more/less than the amount
-             * ### specified in the Content-Range? eek...
-             */
-
-            if (len == -1) {
-                /*
-                 * Error reading request body. This has precedence over
-                 * prior errors.
-                 */
-                err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
-                                    "An error occurred while reading the "
-                                    "request body.");
+            APR_BRIGADE_FOREACH(bucket, brigade) {
+                const char *data;
+                apr_size_t len;
+
+                if (APR_BUCKET_IS_EOS(bucket)) {
+                    seen_eos = 1;
+                    break;
+                }
+
+                /* Ahem, what to do? */
+                if (APR_BUCKET_IS_METADATA(bucket)) {
+                    continue;
+                }
+
+                rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+                if (rv != APR_SUCCESS) {
+                    err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
+                                        "An error occurred while reading the "
+                                        "request body.");
+                    /* This is a error which preempts us from reading to
+                     * EOS. */
+                    seen_eos = 1;
+                    break;
+                }
+
+                if (err == NULL) {
+                    /* write whatever we read, until we see an error */
+                    err = (*resource->hooks->write_stream)(stream,
+                                                           data, len);
+                }
             }
+
+            apr_brigade_cleanup(brigade); 
         }
+        while (!seen_eos);
 
         err2 = (*resource->hooks->close_stream)(stream,
                                                 err == NULL /* commit */);

Mime
View raw message