mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
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
This commit is contained in:
@@ -120,6 +120,8 @@ typedef struct ap_filter_t ap_filter_t;
|
|||||||
* should be considered "const". The filter is allowed to modify the
|
* should be considered "const". The filter is allowed to modify the
|
||||||
* next/prev to insert/remove/replace elements in the bucket list, but
|
* 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 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);
|
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
|
* 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
|
* stack. The filter should return an apr_status_t value. If the bottom-most
|
||||||
* next filter. If the bottom-most filter doesn't write to the next work,
|
* filter doesn't write to the network, then AP_NOBODY_WROTE is returned.
|
||||||
* then AP_NOBODY_WROTE is returned.
|
|
||||||
* @param filter The next filter in the chain
|
* @param filter The next filter in the chain
|
||||||
* @param bucket The current bucket brigade
|
* @param bucket The current bucket brigade
|
||||||
* @return The number of bytes written
|
* @return apr_status_t value
|
||||||
* @deffunc int ap_pass_brigade(ap_filter_t *filter, ap_bucket_brigade *bucket)
|
* @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():
|
* ap_register_filter():
|
||||||
|
@@ -66,10 +66,6 @@
|
|||||||
* !!!This is an extremely cheap ripoff of mod_charset.c from Russian Apache!!!
|
* !!!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 "httpd.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_core.h"
|
#include "http_core.h"
|
||||||
@@ -360,12 +356,15 @@ static void xlate_register_filter(request_rec *r)
|
|||||||
* translation mechanics:
|
* translation mechanics:
|
||||||
* we don't handle characters that straddle more than two buckets; an error
|
* we don't handle characters that straddle more than two buckets; an error
|
||||||
* will be generated
|
* 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-
|
/* send_downstream() is passed the translated data; it puts it in a single-
|
||||||
* bucket brigade and passes the brigade to the next filter
|
* 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;
|
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);
|
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;
|
ap_bucket_brigade *bb;
|
||||||
|
|
||||||
bb = ap_brigade_create(f->r->pool);
|
bb = ap_brigade_create(f->r->pool);
|
||||||
ap_brigade_append_buckets(bb, ap_bucket_create_eos());
|
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)
|
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;
|
ctx->saved = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* huh? we can catch errors here... */
|
return rv;
|
||||||
return APR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xlate_filter() handles arbirary conversions from one charset to another...
|
/* 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
|
* where the filter's context data is set up... the context data gives us
|
||||||
* the translation handle
|
* 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_req_t *reqinfo = ap_get_module_config(f->r->request_config,
|
||||||
&charset_lite_module);
|
&charset_lite_module);
|
||||||
@@ -462,8 +460,6 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
|
|||||||
char tmp[XLATE_BUF_SIZE];
|
char tmp[XLATE_BUF_SIZE];
|
||||||
apr_ssize_t space_avail;
|
apr_ssize_t space_avail;
|
||||||
int done;
|
int done;
|
||||||
int bytes_sent_downstream = 0;
|
|
||||||
int written;
|
|
||||||
apr_status_t rv = APR_SUCCESS;
|
apr_status_t rv = APR_SUCCESS;
|
||||||
|
|
||||||
if (debug) {
|
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.
|
* convert it until we look at the next bucket.
|
||||||
*/
|
*/
|
||||||
set_aside_partial_char(f, cur_str, cur_len);
|
set_aside_partial_char(f, cur_str, cur_len);
|
||||||
rv = 0;
|
rv = APR_SUCCESS;
|
||||||
cur_len = 0;
|
cur_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,20 +526,18 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
|
|||||||
if (rv != APR_SUCCESS) {
|
if (rv != APR_SUCCESS) {
|
||||||
/* bad input byte; we can't continue */
|
/* bad input byte; we can't continue */
|
||||||
done = 1;
|
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) {
|
if (space_avail < XLATE_MIN_BUFF_LEFT) {
|
||||||
/* It is time to flush, as there is not enough space left in the
|
/* It is time to flush, as there is not enough space left in the
|
||||||
* current output buffer to bother with converting more data.
|
* current output buffer to bother with converting more data.
|
||||||
*/
|
*/
|
||||||
/* TODO: handle errors from this operation */
|
rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
|
||||||
written = 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 */
|
/* tmp is now empty */
|
||||||
space_avail = sizeof(tmp);
|
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 (rv == APR_SUCCESS) {
|
||||||
if (space_avail < sizeof(tmp)) { /* gotta write out what we converted */
|
if (space_avail < sizeof(tmp)) { /* gotta write out what we converted */
|
||||||
written = send_downstream(f, tmp, sizeof(tmp) - space_avail);
|
rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
|
||||||
bytes_sent_downstream += written;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (rv == APR_SUCCESS) {
|
||||||
if (cur_len == AP_END_OF_BRIGADE) {
|
if (cur_len == AP_END_OF_BRIGADE) {
|
||||||
send_eos(f);
|
rv = send_eos(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -565,7 +559,7 @@ static int xlate_filter(ap_filter_t *f, ap_bucket_brigade *bb)
|
|||||||
"xlate_filter() - returning error");
|
"xlate_filter() - returning error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes_sent_downstream;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const command_rec cmds[] =
|
static const command_rec cmds[] =
|
||||||
|
@@ -2919,14 +2919,14 @@ static int default_handler(request_rec *r)
|
|||||||
* smart about when it actually sends the data, but this implements some sort
|
* smart about when it actually sends the data, but this implements some sort
|
||||||
* of chunking for right now.
|
* 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;
|
ap_bucket *dptr = b->head, *lb, *next, *tail;
|
||||||
int len = 0, cur_len;
|
int len = 0, cur_len;
|
||||||
char lenstr[sizeof("ffffffff\r\n")];
|
char lenstr[sizeof("ffffffff\r\n")];
|
||||||
const char *cur_str;
|
const char *cur_str;
|
||||||
int hit_eos = 0;
|
int hit_eos = 0;
|
||||||
apr_status_t rv = 0; /* currently bytes written, will be APR_* */
|
apr_status_t rv = APR_SUCCESS;
|
||||||
|
|
||||||
while (dptr) {
|
while (dptr) {
|
||||||
if (dptr->type == AP_BUCKET_EOS) {
|
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);
|
b->tail = ap_bucket_create_transient("\r\n", 2);
|
||||||
dptr->next = b->tail;
|
dptr->next = b->tail;
|
||||||
b->tail->prev = dptr;
|
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 */
|
/* start a new brigade */
|
||||||
len = 0;
|
len = 0;
|
||||||
b = ap_brigade_create(f->r->pool);
|
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;
|
b->head = lb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv += ap_pass_brigade(f->next, b);
|
return ap_pass_brigade(f->next, b);
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default filter. This filter should almost always be used. Its only job
|
/* 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
|
#if 0
|
||||||
request_rec *r = f->r;
|
request_rec *r = f->r;
|
||||||
#endif
|
#endif
|
||||||
|
apr_status_t rv;
|
||||||
apr_ssize_t bytes_sent = 0;
|
apr_ssize_t bytes_sent = 0;
|
||||||
ap_bucket *dptr = b->head;
|
ap_bucket *dptr = b->head;
|
||||||
int len = 0, written;
|
int len = 0, written;
|
||||||
@@ -3041,7 +3044,10 @@ static int core_filter(ap_filter_t *f, ap_bucket_brigade *b)
|
|||||||
else {
|
else {
|
||||||
#endif
|
#endif
|
||||||
while (dptr->read(dptr, &str, &len, 0) != AP_END_OF_BRIGADE) {
|
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;
|
dptr = dptr->next;
|
||||||
bytes_sent += written;
|
bytes_sent += written;
|
||||||
if (!dptr) {
|
if (!dptr) {
|
||||||
@@ -3053,7 +3059,7 @@ static int core_filter(ap_filter_t *f, ap_bucket_brigade *b)
|
|||||||
if (len == AP_END_OF_BRIGADE) {
|
if (len == AP_END_OF_BRIGADE) {
|
||||||
ap_bflush(f->r->connection->client);
|
ap_bflush(f->r->connection->client);
|
||||||
}
|
}
|
||||||
return bytes_sent;
|
return APR_SUCCESS;
|
||||||
#if 0
|
#if 0
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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,
|
API_EXPORT(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
|
||||||
size_t length)
|
size_t length)
|
||||||
{
|
{
|
||||||
apr_ssize_t bytes_sent = 0;
|
|
||||||
ap_bucket_brigade *bb = NULL;
|
ap_bucket_brigade *bb = NULL;
|
||||||
|
|
||||||
/* WE probably need to do something to make sure we are respecting the
|
/* 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);
|
bb = ap_brigade_create(r->pool);
|
||||||
ap_brigade_append_buckets(bb, ap_bucket_create_mmap(mm, 0, mm->size));
|
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 */
|
#endif /* USE_MMAP_FILES */
|
||||||
|
|
||||||
|
@@ -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 current filter. At that point, we can just call the first filter in
|
||||||
* the stack, or r->filters.
|
* 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) {
|
if (next) {
|
||||||
return next->filter_func(next, bb);
|
return next->filter_func(next, bb);
|
||||||
|
Reference in New Issue
Block a user