]> granicus.if.org Git - apache/commitdiff
Filters (and thus ap_pass_brigade()) now return an apr_status_t as their
authorJeff Trawick <trawick@apache.org>
Tue, 29 Aug 2000 20:57:29 +0000 (20:57 +0000)
committerJeff Trawick <trawick@apache.org>
Tue, 29 Aug 2000 20:57:29 +0000 (20:57 +0000)
return value.

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

include/util_filter.h
modules/experimental/mod_charset_lite.c
modules/http/http_core.c
modules/http/http_protocol.c
server/util_filter.c

index ad6e57683609214a2f950179ce3853d6214d04ce..2ce9eeac19dbb5238827b015358d723796a52ec9 100644 (file)
@@ -120,6 +120,8 @@ typedef struct ap_filter_t ap_filter_t;
  * should be considered "const". The filter is allowed to modify the
  * next/prev to insert/remove/replace elements in the bucket list, but
  * the types and values of the individual buckets should not be altered.
+ *
+ * The return value of a filter should be an APR status value.
  */
 typedef apr_status_t (*ap_filter_func)(ap_filter_t *f, ap_bucket_brigade *b);
 
@@ -211,15 +213,14 @@ struct ap_filter_t {
  */
 /**
  * Pass the current bucket brigade down to the next filter on the filter
- * stack.  The filter should return the number of bytes written by the
- * next filter.  If the bottom-most filter doesn't write to the next work,
- * then AP_NOBODY_WROTE is returned.
+ * stack.  The filter should return an apr_status_t value.  If the bottom-most 
+ * filter doesn't write to the network, then AP_NOBODY_WROTE is returned.
  * @param filter The next filter in the chain
  * @param bucket The current bucket brigade
- * @return The number of bytes written
- * @deffunc int ap_pass_brigade(ap_filter_t *filter, ap_bucket_brigade *bucket)
+ * @return apr_status_t value
+ * @deffunc apr_status_t ap_pass_brigade(ap_filter_t *filter, ap_bucket_brigade *bucket)
  */
-API_EXPORT(int) ap_pass_brigade(ap_filter_t *filter, ap_bucket_brigade *bucket);
+API_EXPORT(apr_status_t) ap_pass_brigade(ap_filter_t *filter, ap_bucket_brigade *bucket);
 
 /*
  * ap_register_filter():
index 55eece22010f58086095e41b8f1de21836ce738d..50303df9925ffede0674f040a8e08b9a2c2e2d69 100644 (file)
  * !!!This is an extremely cheap ripoff of mod_charset.c from Russian Apache!!!
  */
 
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
@@ -360,12 +356,15 @@ static void xlate_register_filter(request_rec *r)
  * translation mechanics:
  *   we don't handle characters that straddle more than two buckets; an error
  *   will be generated
+ *
+ *   we don't signal an error if we get EOS but we're in the middle of an input
+ *   character
  */
 
 /* send_downstream() is passed the translated data; it puts it in a single-
  * bucket brigade and passes the brigade to the next filter
  */
-static int send_downstream(ap_filter_t *f, const char *tmp, apr_ssize_t len)
+static apr_status_t send_downstream(ap_filter_t *f, const char *tmp, apr_ssize_t len)
 {
     ap_bucket_brigade *bb;
 
@@ -374,13 +373,13 @@ static int send_downstream(ap_filter_t *f, const char *tmp, apr_ssize_t len)
     return ap_pass_brigade(f->next, bb);
 }
 
-static void send_eos(ap_filter_t *f)
+static apr_status_t send_eos(ap_filter_t *f)
 {
     ap_bucket_brigade *bb;
 
     bb = ap_brigade_create(f->r->pool);
     ap_brigade_append_buckets(bb, ap_bucket_create_eos());
-    ap_pass_brigade(f->next, bb);
+    return ap_pass_brigade(f->next, bb);
 }
 
 static void remove_and_destroy(ap_bucket_brigade *bb, ap_bucket *b)
@@ -440,8 +439,7 @@ static apr_status_t finish_partial_char(ap_filter_t *f,
         ctx->saved = 0;
     }
 
-    /* huh?  we can catch errors here... */
-    return APR_SUCCESS;
+    return rv;
 }
 
 /* xlate_filter() handles arbirary conversions from one charset to another...
@@ -449,7 +447,7 @@ static apr_status_t finish_partial_char(ap_filter_t *f,
  * where the filter's context data is set up... the context data gives us
  * the translation handle
  */
-static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
+static apr_status_t xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
 {
     charset_req_t *reqinfo = ap_get_module_config(f->r->request_config,
                                                   &charset_lite_module);
@@ -462,8 +460,6 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
     char tmp[XLATE_BUF_SIZE];
     apr_ssize_t space_avail;
     int done;
-    int bytes_sent_downstream = 0;
-    int written;
     apr_status_t rv = APR_SUCCESS;
 
     if (debug) {
@@ -522,7 +518,7 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
                  * convert it until we look at the next bucket.
                  */
                 set_aside_partial_char(f, cur_str, cur_len);
-                rv = 0;
+                rv = APR_SUCCESS;
                 cur_len = 0;
             }
         }
@@ -530,21 +526,19 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
         if (rv != APR_SUCCESS) {
             /* bad input byte; we can't continue */
             done = 1;
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, f->r->server,
+                         "xlate_filter() - apr_xlate_conv_buffer() failed"); 
         }
 
         if (space_avail < XLATE_MIN_BUFF_LEFT) {
             /* It is time to flush, as there is not enough space left in the
              * current output buffer to bother with converting more data.
              */
-            /* TODO: handle errors from this operation */
-            written = send_downstream(f, tmp, sizeof(tmp) - space_avail);
+            rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
+            if (rv == APR_SUCCESS) {
+                done = 1;
+            }
             
-            /* The filters (or ap_r* routines) upstream apparently want 
-             * to know how many bytes were written, not how many of their 
-             * bytes were accepted.
-             */
-            bytes_sent_downstream += written;
-
             /* tmp is now empty */
             space_avail = sizeof(tmp);
         }
@@ -552,12 +546,12 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
 
     if (rv == APR_SUCCESS) {
         if (space_avail < sizeof(tmp)) { /* gotta write out what we converted */
-            written = send_downstream(f, tmp, sizeof(tmp) - space_avail);
-            bytes_sent_downstream += written;
+            rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
         }
-        
+    }
+    if (rv == APR_SUCCESS) {
         if (cur_len == AP_END_OF_BRIGADE) {
-            send_eos(f);
+            rv = send_eos(f);
         }
     }
     else {
@@ -565,7 +559,7 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
                       "xlate_filter() - returning error");
     }
 
-    return bytes_sent_downstream;
+    return rv;
 }
 
 static const command_rec cmds[] =
@@ -608,6 +602,6 @@ module charset_lite_module =
     NULL,
     cmds,
     NULL,
-   charset_register_hooks,
+    charset_register_hooks,
 };
 
index dbd9fdb4f97cbf2172566e1157a2f3c956dcea88..041f5f863316b453da022f05f904f71a5762a166 100644 (file)
@@ -2919,14 +2919,14 @@ static int default_handler(request_rec *r)
  * smart about when it actually sends the data, but this implements some sort
  * of chunking for right now.
  */
-static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
+static apr_status_t chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
 {
     ap_bucket *dptr = b->head, *lb, *next, *tail;
     int len = 0, cur_len;
     char lenstr[sizeof("ffffffff\r\n")];
     const char *cur_str;
     int hit_eos = 0;
-    apr_status_t rv = 0; /* currently bytes written, will be APR_* */
+    apr_status_t rv = APR_SUCCESS;
 
     while (dptr) {
         if (dptr->type == AP_BUCKET_EOS) {
@@ -2948,7 +2948,10 @@ static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
                 b->tail = ap_bucket_create_transient("\r\n", 2);
                 dptr->next = b->tail;
                 b->tail->prev = dptr;
-                rv += ap_pass_brigade(f->next, b);
+                rv = ap_pass_brigade(f->next, b);
+                if (rv != APR_SUCCESS) {
+                    return rv;
+                }
                 /* start a new brigade */
                 len = 0;
                 b = ap_brigade_create(f->r->pool);
@@ -2994,8 +2997,7 @@ static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
             b->head = lb;
         }
     }
-    rv += ap_pass_brigade(f->next, b);
-    return rv;
+    return ap_pass_brigade(f->next, b);
 }
 
 /* Default filter.  This filter should almost always be used.  Its only job
@@ -3014,6 +3016,7 @@ static int core_filter(ap_filter_t *f, ap_bucket_brigade *b)
 #if 0
     request_rec *r = f->r;
 #endif
+    apr_status_t rv;
     apr_ssize_t bytes_sent = 0;
     ap_bucket *dptr = b->head;
     int len = 0, written;
@@ -3041,7 +3044,10 @@ static int core_filter(ap_filter_t *f, ap_bucket_brigade *b)
     else {
 #endif
     while (dptr->read(dptr, &str, &len, 0) != AP_END_OF_BRIGADE) {
-        ap_bwrite(f->r->connection->client, str, len, &written);
+        if ((rv = ap_bwrite(f->r->connection->client, str, len, &written))
+            != APR_SUCCESS) {
+            return rv;
+        }
         dptr = dptr->next;
         bytes_sent += written;
         if (!dptr) {
@@ -3053,7 +3059,7 @@ static int core_filter(ap_filter_t *f, ap_bucket_brigade *b)
     if (len == AP_END_OF_BRIGADE) {
         ap_bflush(f->r->connection->client);
     }
-    return bytes_sent;
+    return APR_SUCCESS;
 #if 0
     }
 #endif
index 615744ba4324e95d6b64dfae321513f3b680e12a..d74516814c0de4a27ee1df4186c9ddf67529b177 100644 (file)
@@ -2512,7 +2512,6 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length)
 API_EXPORT(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
                              size_t length)
 {
-    apr_ssize_t bytes_sent = 0;
     ap_bucket_brigade *bb = NULL;
     
     /* WE probably need to do something to make sure we are respecting the
@@ -2521,9 +2520,9 @@ API_EXPORT(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
      */
     bb = ap_brigade_create(r->pool);
     ap_brigade_append_buckets(bb, ap_bucket_create_mmap(mm, 0, mm->size));
-    bytes_sent = ap_pass_brigade(r->filters, bb);
+    ap_pass_brigade(r->filters, bb);
 
-    return bytes_sent;
+    return mm->size; /* XXX - change API to report apr_status_t? */
 }
 #endif /* USE_MMAP_FILES */
 
index 328fe036efbec38c6740b494c8828079b382345c..491a52b379429fa23b18016bb02706d6b09f7837 100644 (file)
@@ -152,7 +152,7 @@ API_EXPORT(void) ap_add_filter(const char *name, void *ctx, request_rec *r)
  * the current filter.  At that point, we can just call the first filter in
  * the stack, or r->filters.
  */
-API_EXPORT(int) ap_pass_brigade(ap_filter_t *next, ap_bucket_brigade *bb)
+API_EXPORT(apr_status_t) ap_pass_brigade(ap_filter_t *next, ap_bucket_brigade *bb)
 {
     if (next) {
         return next->filter_func(next, bb);