From f357ceef76f584d9194e967cad5bbd883922f6ec Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Tue, 29 Aug 2000 20:57:29 +0000 Subject: [PATCH] Filters (and thus ap_pass_brigade()) now return an apr_status_t as their return value. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@86160 13f79535-47bb-0310-9956-ffa450edef68 --- include/util_filter.h | 13 +++---- modules/experimental/mod_charset_lite.c | 48 +++++++++++-------------- modules/http/http_core.c | 20 +++++++---- modules/http/http_protocol.c | 5 ++- server/util_filter.c | 2 +- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/include/util_filter.h b/include/util_filter.h index ad6e576836..2ce9eeac19 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -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(): diff --git a/modules/experimental/mod_charset_lite.c b/modules/experimental/mod_charset_lite.c index 55eece2201..50303df992 100644 --- a/modules/experimental/mod_charset_lite.c +++ b/modules/experimental/mod_charset_lite.c @@ -66,10 +66,6 @@ * !!!This is an extremely cheap ripoff of mod_charset.c from Russian Apache!!! */ -#ifdef HAVE_STDIO_H -#include -#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, }; diff --git a/modules/http/http_core.c b/modules/http/http_core.c index dbd9fdb4f9..041f5f8633 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -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 diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 615744ba43..d74516814c 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -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 */ diff --git a/server/util_filter.c b/server/util_filter.c index 328fe036ef..491a52b379 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -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);