]> granicus.if.org Git - apache/blob - server/util_filter.c
Follow up to r1734656: restore c->data_in_input_filters usage to
[apache] / server / util_filter.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define APR_WANT_STRFUNC
18 #include "apr_want.h"
19 #include "apr_lib.h"
20 #include "apr_hash.h"
21 #include "apr_strings.h"
22
23 #include "httpd.h"
24 #include "http_config.h"
25 #include "http_core.h"
26 #include "http_log.h"
27 #include "http_request.h"
28 #include "util_filter.h"
29
30 /* NOTE: Apache's current design doesn't allow a pool to be passed thru,
31    so we depend on a global to hold the correct pool
32 */
33 #define FILTER_POOL     apr_hook_global_pool
34 #include "ap_hooks.h"   /* for apr_hook_global_pool */
35
36 /* XXX: Should these be configurable parameters? */
37 #define THRESHOLD_MAX_BUFFER 65536
38 #define MAX_REQUESTS_IN_PIPELINE 5
39
40 /*
41 ** This macro returns true/false if a given filter should be inserted BEFORE
42 ** another filter. This will happen when one of: 1) there isn't another
43 ** filter; 2) that filter has a higher filter type (class); 3) that filter
44 ** corresponds to a different request.
45 */
46 #define INSERT_BEFORE(f, before_this) ((before_this) == NULL \
47                            || (before_this)->frec->ftype > (f)->frec->ftype \
48                            || (before_this)->r != (f)->r)
49
50 /* Trie structure to hold the mapping from registered
51  * filter names to filters
52  */
53
54 /* we know core's module_index is 0 */
55 #undef APLOG_MODULE_INDEX
56 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
57
58 typedef struct filter_trie_node filter_trie_node;
59
60 typedef struct {
61     int c;
62     filter_trie_node *child;
63 } filter_trie_child_ptr;
64
65 /* Each trie node has an array of pointers to its children.
66  * The array is kept in sorted order so that add_any_filter()
67  * can do a binary search
68  */
69 struct filter_trie_node {
70     ap_filter_rec_t *frec;
71     filter_trie_child_ptr *children;
72     int nchildren;
73     int size;
74 };
75
76 #define TRIE_INITIAL_SIZE 4
77
78 /* Link a trie node to its parent
79  */
80 static void trie_node_link(apr_pool_t *p, filter_trie_node *parent,
81                            filter_trie_node *child, int c)
82 {
83     int i, j;
84
85     if (parent->nchildren == parent->size) {
86         filter_trie_child_ptr *new;
87         parent->size *= 2;
88         new = (filter_trie_child_ptr *)apr_palloc(p, parent->size *
89                                              sizeof(filter_trie_child_ptr));
90         memcpy(new, parent->children, parent->nchildren *
91                sizeof(filter_trie_child_ptr));
92         parent->children = new;
93     }
94
95     for (i = 0; i < parent->nchildren; i++) {
96         if (c == parent->children[i].c) {
97             return;
98         }
99         else if (c < parent->children[i].c) {
100             break;
101         }
102     }
103     for (j = parent->nchildren; j > i; j--) {
104         parent->children[j].c = parent->children[j - 1].c;
105         parent->children[j].child = parent->children[j - 1].child;
106     }
107     parent->children[i].c = c;
108     parent->children[i].child = child;
109
110     parent->nchildren++;
111 }
112
113 /* Allocate a new node for a trie.
114  * If parent is non-NULL, link the new node under the parent node with
115  * key 'c' (or, if an existing child node matches, return that one)
116  */
117 static filter_trie_node *trie_node_alloc(apr_pool_t *p,
118                                          filter_trie_node *parent, char c)
119 {
120     filter_trie_node *new_node;
121     if (parent) {
122         int i;
123         for (i = 0; i < parent->nchildren; i++) {
124             if (c == parent->children[i].c) {
125                 return parent->children[i].child;
126             }
127             else if (c < parent->children[i].c) {
128                 break;
129             }
130         }
131         new_node =
132             (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node));
133         trie_node_link(p, parent, new_node, c);
134     }
135     else { /* No parent node */
136         new_node = (filter_trie_node *)apr_palloc(p,
137                                                   sizeof(filter_trie_node));
138     }
139
140     new_node->frec = NULL;
141     new_node->nchildren = 0;
142     new_node->size = TRIE_INITIAL_SIZE;
143     new_node->children = (filter_trie_child_ptr *)apr_palloc(p,
144                              new_node->size * sizeof(filter_trie_child_ptr));
145     return new_node;
146 }
147
148 static filter_trie_node *registered_output_filters = NULL;
149 static filter_trie_node *registered_input_filters = NULL;
150
151
152 static apr_status_t filter_cleanup(void *ctx)
153 {
154     registered_output_filters = NULL;
155     registered_input_filters = NULL;
156     return APR_SUCCESS;
157 }
158
159 static ap_filter_rec_t *get_filter_handle(const char *name,
160                                           const filter_trie_node *filter_set)
161 {
162     if (filter_set) {
163         const char *n;
164         const filter_trie_node *node;
165
166         node = filter_set;
167         for (n = name; *n; n++) {
168             int start, end;
169             start = 0;
170             end = node->nchildren - 1;
171             while (end >= start) {
172                 int middle = (end + start) / 2;
173                 char ch = node->children[middle].c;
174                 if (*n == ch) {
175                     node = node->children[middle].child;
176                     break;
177                 }
178                 else if (*n < ch) {
179                     end = middle - 1;
180                 }
181                 else {
182                     start = middle + 1;
183                 }
184             }
185             if (end < start) {
186                 node = NULL;
187                 break;
188             }
189         }
190
191         if (node && node->frec) {
192             return node->frec;
193         }
194     }
195     return NULL;
196 }
197
198 AP_DECLARE(ap_filter_rec_t *)ap_get_output_filter_handle(const char *name)
199 {
200     return get_filter_handle(name, registered_output_filters);
201 }
202
203 AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name)
204 {
205     return get_filter_handle(name, registered_input_filters);
206 }
207
208 static ap_filter_rec_t *register_filter(const char *name,
209                             ap_filter_func filter_func,
210                             ap_init_filter_func filter_init,
211                             ap_filter_type ftype,
212                             ap_filter_direction_e direction,
213                             filter_trie_node **reg_filter_set)
214 {
215     ap_filter_rec_t *frec;
216     char *normalized_name;
217     const char *n;
218     filter_trie_node *node;
219
220     if (!*reg_filter_set) {
221         *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0);
222     }
223
224     normalized_name = apr_pstrdup(FILTER_POOL, name);
225     ap_str_tolower(normalized_name);
226
227     node = *reg_filter_set;
228     for (n = normalized_name; *n; n++) {
229         filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n);
230         if (apr_isalpha(*n)) {
231             trie_node_link(FILTER_POOL, node, child, apr_toupper(*n));
232         }
233         node = child;
234     }
235     if (node->frec) {
236         frec = node->frec;
237     }
238     else {
239         frec = apr_pcalloc(FILTER_POOL, sizeof(*frec));
240         node->frec = frec;
241         frec->name = normalized_name;
242     }
243     frec->filter_func = filter_func;
244     frec->filter_init_func = filter_init;
245     frec->ftype = ftype;
246     frec->direction = direction;
247
248     apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,
249                               apr_pool_cleanup_null);
250     return frec;
251 }
252
253 AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
254                                           ap_in_filter_func filter_func,
255                                           ap_init_filter_func filter_init,
256                                           ap_filter_type ftype)
257 {
258     ap_filter_func f;
259     f.in_func = filter_func;
260     return register_filter(name, f, filter_init, ftype, AP_FILTER_INPUT,
261                            &registered_input_filters);
262 }
263
264 AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
265                                            ap_out_filter_func filter_func,
266                                            ap_init_filter_func filter_init,
267                                            ap_filter_type ftype)
268 {
269     return ap_register_output_filter_protocol(name, filter_func,
270                                               filter_init, ftype, 0);
271 }
272
273 AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol(
274                                            const char *name,
275                                            ap_out_filter_func filter_func,
276                                            ap_init_filter_func filter_init,
277                                            ap_filter_type ftype,
278                                            unsigned int proto_flags)
279 {
280     ap_filter_rec_t* ret ;
281     ap_filter_func f;
282     f.out_func = filter_func;
283     ret = register_filter(name, f, filter_init, ftype, AP_FILTER_OUTPUT,
284                           &registered_output_filters);
285     ret->proto_flags = proto_flags ;
286     return ret ;
287 }
288
289 static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
290                                           request_rec *r, conn_rec *c,
291                                           ap_filter_t **r_filters,
292                                           ap_filter_t **p_filters,
293                                           ap_filter_t **c_filters)
294 {
295     apr_pool_t *p = frec->ftype < AP_FTYPE_CONNECTION && r ? r->pool : c->pool;
296     ap_filter_t *f = apr_palloc(p, sizeof(*f));
297     ap_filter_t **outf;
298
299     if (frec->ftype < AP_FTYPE_PROTOCOL) {
300         if (r) {
301             outf = r_filters;
302         }
303         else {
304             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00080)
305                           "a content filter was added without a request: %s", frec->name);
306             return NULL;
307         }
308     }
309     else if (frec->ftype < AP_FTYPE_CONNECTION) {
310         if (r) {
311             outf = p_filters;
312         }
313         else {
314             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00081)
315                           "a protocol filter was added without a request: %s", frec->name);
316             return NULL;
317         }
318     }
319     else {
320         outf = c_filters;
321     }
322
323     f->frec = frec;
324     f->ctx = ctx;
325     /* f->r must always be NULL for connection filters */
326     f->r = frec->ftype < AP_FTYPE_CONNECTION ? r : NULL;
327     f->c = c;
328     f->next = NULL;
329     f->bb = NULL;
330     f->deferred_pool = NULL;
331
332     if (INSERT_BEFORE(f, *outf)) {
333         f->next = *outf;
334
335         if (*outf) {
336             ap_filter_t *first = NULL;
337
338             if (r) {
339                 /* If we are adding our first non-connection filter,
340                  * Then don't try to find the right location, it is
341                  * automatically first.
342                  */
343                 if (*r_filters != *c_filters) {
344                     first = *r_filters;
345                     while (first && (first->next != (*outf))) {
346                         first = first->next;
347                     }
348                 }
349             }
350             if (first && first != (*outf)) {
351                 first->next = f;
352             }
353         }
354         *outf = f;
355     }
356     else {
357         ap_filter_t *fscan = *outf;
358         while (!INSERT_BEFORE(f, fscan->next))
359             fscan = fscan->next;
360
361         f->next = fscan->next;
362         fscan->next = f;
363     }
364
365     if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) {
366         *r_filters = *p_filters;
367     }
368     return f;
369 }
370
371 static ap_filter_t *add_any_filter(const char *name, void *ctx,
372                                    request_rec *r, conn_rec *c,
373                                    const filter_trie_node *reg_filter_set,
374                                    ap_filter_t **r_filters,
375                                    ap_filter_t **p_filters,
376                                    ap_filter_t **c_filters)
377 {
378     if (reg_filter_set) {
379         const char *n;
380         const filter_trie_node *node;
381
382         node = reg_filter_set;
383         for (n = name; *n; n++) {
384             int start, end;
385             start = 0;
386             end = node->nchildren - 1;
387             while (end >= start) {
388                 int middle = (end + start) / 2;
389                 char ch = node->children[middle].c;
390                 if (*n == ch) {
391                     node = node->children[middle].child;
392                     break;
393                 }
394                 else if (*n < ch) {
395                     end = middle - 1;
396                 }
397                 else {
398                     start = middle + 1;
399                 }
400             }
401             if (end < start) {
402                 node = NULL;
403                 break;
404             }
405         }
406
407         if (node && node->frec) {
408             return add_any_filter_handle(node->frec, ctx, r, c, r_filters,
409                                          p_filters, c_filters);
410         }
411     }
412
413     ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, r ? r->connection : c, APLOGNO(00082)
414                   "an unknown filter was not added: %s", name);
415     return NULL;
416 }
417
418 AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
419                                               request_rec *r, conn_rec *c)
420 {
421     return add_any_filter(name, ctx, r, c, registered_input_filters,
422                           r ? &r->input_filters : NULL,
423                           r ? &r->proto_input_filters : NULL, &c->input_filters);
424 }
425
426 AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
427                                                      void *ctx,
428                                                      request_rec *r,
429                                                      conn_rec *c)
430 {
431     return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL,
432                                  r ? &r->proto_input_filters : NULL,
433                                  &c->input_filters);
434 }
435
436 AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
437                                                request_rec *r, conn_rec *c)
438 {
439     return add_any_filter(name, ctx, r, c, registered_output_filters,
440                           r ? &r->output_filters : NULL,
441                           r ? &r->proto_output_filters : NULL, &c->output_filters);
442 }
443
444 AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
445                                                       void *ctx,
446                                                       request_rec *r,
447                                                       conn_rec *c)
448 {
449     return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL,
450                                  r ? &r->proto_output_filters : NULL,
451                                  &c->output_filters);
452 }
453
454 static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt,
455                               ap_filter_t **c_filt)
456 {
457     ap_filter_t **curr = r_filt ? r_filt : c_filt;
458     ap_filter_t *fscan = *curr;
459
460     if (p_filt && *p_filt == f)
461         *p_filt = (*p_filt)->next;
462
463     if (*curr == f) {
464         *curr = (*curr)->next;
465         return;
466     }
467
468     while (fscan->next != f) {
469         if (!(fscan = fscan->next)) {
470             return;
471         }
472     }
473
474     fscan->next = f->next;
475 }
476
477 AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f)
478 {
479     remove_any_filter(f, f->r ? &f->r->input_filters : NULL,
480                       f->r ? &f->r->proto_input_filters : NULL,
481                       &f->c->input_filters);
482 }
483
484 AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
485 {
486
487     if ((f->bb) && !APR_BRIGADE_EMPTY(f->bb)) {
488         apr_brigade_cleanup(f->bb);
489     }
490
491     if (f->deferred_pool) {
492         apr_pool_destroy(f->deferred_pool);
493         f->deferred_pool = NULL;
494     }
495
496     remove_any_filter(f, f->r ? &f->r->output_filters : NULL,
497                       f->r ? &f->r->proto_output_filters : NULL,
498                       &f->c->output_filters);
499 }
500
501 AP_DECLARE(apr_status_t) ap_remove_input_filter_byhandle(ap_filter_t *next,
502                                                          const char *handle)
503 {
504     ap_filter_t *found = NULL;
505     ap_filter_rec_t *filter;
506
507     if (!handle) {
508         return APR_EINVAL;
509     }
510     filter = ap_get_input_filter_handle(handle);
511     if (!filter) {
512         return APR_NOTFOUND;
513     }
514
515     while (next) {
516         if (next->frec == filter) {
517             found = next;
518             break;
519         }
520         next = next->next;
521     }
522     if (found) {
523         ap_remove_input_filter(found);
524         return APR_SUCCESS;
525     }
526     return APR_NOTFOUND;
527 }
528
529 AP_DECLARE(apr_status_t) ap_remove_output_filter_byhandle(ap_filter_t *next,
530                                                           const char *handle)
531 {
532     ap_filter_t *found = NULL;
533     ap_filter_rec_t *filter;
534
535     if (!handle) {
536         return APR_EINVAL;
537     }
538     filter = ap_get_output_filter_handle(handle);
539     if (!filter) {
540         return APR_NOTFOUND;
541     }
542
543     while (next) {
544         if (next->frec == filter) {
545             found = next;
546             break;
547         }
548         next = next->next;
549     }
550     if (found) {
551         ap_remove_output_filter(found);
552         return APR_SUCCESS;
553     }
554     return APR_NOTFOUND;
555 }
556
557
558 /*
559  * Read data from the next filter in the filter stack.  Data should be
560  * modified in the bucket brigade that is passed in.  The core allocates the
561  * bucket brigade, modules that wish to replace large chunks of data or to
562  * save data off to the side should probably create their own temporary
563  * brigade especially for that use.
564  */
565 AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next,
566                                         apr_bucket_brigade *bb,
567                                         ap_input_mode_t mode,
568                                         apr_read_type_e block,
569                                         apr_off_t readbytes)
570 {
571     if (next) {
572         return next->frec->filter_func.in_func(next, bb, mode, block,
573                                                readbytes);
574     }
575     return AP_NOBODY_READ;
576 }
577
578 /* Pass the buckets to the next filter in the filter stack.  If the
579  * current filter is a handler, we should get NULL passed in instead of
580  * the current filter.  At that point, we can just call the first filter in
581  * the stack, or r->output_filters.
582  */
583 AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *next,
584                                          apr_bucket_brigade *bb)
585 {
586     if (next) {
587         apr_bucket *e;
588
589         if ((e = APR_BRIGADE_LAST(bb)) && APR_BUCKET_IS_EOS(e) && next->r) {
590             /* This is only safe because HTTP_HEADER filter is always in
591              * the filter stack.   This ensures that there is ALWAYS a
592              * request-based filter that we can attach this to.  If the
593              * HTTP_FILTER is removed, and another filter is not put in its
594              * place, then handlers like mod_cgi, which attach their own
595              * EOS bucket to the brigade will be broken, because we will
596              * get two EOS buckets on the same request.
597              */
598             next->r->eos_sent = 1;
599
600             /* remember the eos for internal redirects, too */
601             if (next->r->prev) {
602                 request_rec *prev = next->r->prev;
603
604                 while (prev) {
605                     prev->eos_sent = 1;
606                     prev = prev->prev;
607                 }
608             }
609         }
610         return next->frec->filter_func.out_func(next, bb);
611     }
612     return AP_NOBODY_WROTE;
613 }
614
615 /* Pass the buckets to the next filter in the filter stack
616  * checking return status for filter errors.
617  * returns: OK if ap_pass_brigade returns APR_SUCCESS
618  *          AP_FILTER_ERROR if filter error exists
619  *          HTTP_INTERNAL_SERVER_ERROR for all other cases
620  *          logged with optional errmsg
621  */
622 AP_DECLARE(apr_status_t) ap_pass_brigade_fchk(request_rec *r,
623                                               apr_bucket_brigade *bb,
624                                               const char *fmt,
625                                               ...)
626 {
627     apr_status_t rv;
628
629     rv = ap_pass_brigade(r->output_filters, bb);
630     if (rv != APR_SUCCESS) {
631         if (rv != AP_FILTER_ERROR) {
632             if (!fmt)
633                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(00083)
634                               "ap_pass_brigade returned %d", rv);
635             else {
636                 va_list ap;
637                 const char *res;
638                 va_start(ap, fmt);
639                 res = apr_pvsprintf(r->pool, fmt, ap);
640                 va_end(ap);
641                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03158)
642                               "%s", res);
643             }
644             return HTTP_INTERNAL_SERVER_ERROR;
645         }
646         return AP_FILTER_ERROR;
647     }
648     return OK;
649 }
650
651 AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f,
652                                          apr_bucket_brigade **saveto,
653                                          apr_bucket_brigade **b, apr_pool_t *p)
654 {
655     apr_bucket *e;
656     apr_status_t rv, srv = APR_SUCCESS;
657
658     /* If have never stored any data in the filter, then we had better
659      * create an empty bucket brigade so that we can concat. Register
660      * a cleanup to zero out the pointer if the pool is cleared.
661      */
662     if (!(*saveto)) {
663         *saveto = apr_brigade_create(p, f->c->bucket_alloc);
664     }
665
666     for (e = APR_BRIGADE_FIRST(*b);
667          e != APR_BRIGADE_SENTINEL(*b);
668          e = APR_BUCKET_NEXT(e))
669     {
670         rv = apr_bucket_setaside(e, p);
671
672         /* If the bucket type does not implement setaside, then
673          * (hopefully) morph it into a bucket type which does, and set
674          * *that* aside... */
675         if (rv == APR_ENOTIMPL) {
676             const char *s;
677             apr_size_t n;
678
679             rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ);
680             if (rv == APR_SUCCESS) {
681                 rv = apr_bucket_setaside(e, p);
682             }
683         }
684
685         if (rv != APR_SUCCESS) {
686             srv = rv;
687             /* Return an error but still save the brigade if
688              * ->setaside() is really not implemented. */
689             if (rv != APR_ENOTIMPL) {
690                 return rv;
691             }
692         }
693     }
694     APR_BRIGADE_CONCAT(*saveto, *b);
695     return srv;
696 }
697
698 static apr_status_t filters_cleanup(void *data)
699 {
700     ap_filter_t **key = data;
701
702     apr_hash_set((*key)->c->filters, key, sizeof(ap_filter_t **), NULL);
703
704     return APR_SUCCESS;
705 }
706
707 AP_DECLARE(int) ap_filter_prepare_brigade(ap_filter_t *f, apr_pool_t **p)
708 {
709     apr_pool_t *pool;
710     ap_filter_t **key;
711
712     if (!f->bb) {
713
714         pool = f->r ? f->r->pool : f->c->pool;
715
716         key = apr_pmemdup(pool, &f, sizeof f);
717         apr_hash_set(f->c->filters, key, sizeof key, f);
718
719         f->bb = apr_brigade_create(pool, f->c->bucket_alloc);
720
721         apr_pool_pre_cleanup_register(pool, key, filters_cleanup);
722
723         if (p) {
724             *p = pool;
725         }
726
727         return OK;
728     }
729
730     return DECLINED;
731 }
732
733 AP_DECLARE(apr_status_t) ap_filter_setaside_brigade(ap_filter_t *f,
734         apr_bucket_brigade *bb)
735 {
736     int loglevel = ap_get_conn_module_loglevel(f->c, APLOG_MODULE_INDEX);
737
738     if (loglevel >= APLOG_TRACE6) {
739         ap_log_cerror(
740             APLOG_MARK, APLOG_TRACE6, 0, f->c,
741             "setaside %s brigade to %s brigade in '%s' output filter",
742             (APR_BRIGADE_EMPTY(bb) ? "empty" : "full"),
743             (!f->bb || APR_BRIGADE_EMPTY(f->bb) ? "empty" : "full"), f->frec->name);
744     }
745
746     if (!APR_BRIGADE_EMPTY(bb)) {
747         apr_pool_t *pool = NULL;
748         /*
749          * Set aside the brigade bb within f->bb.
750          */
751         ap_filter_prepare_brigade(f, &pool);
752
753         /* decide what pool we setaside to, request pool or deferred pool? */
754         if (f->r) {
755             apr_bucket *e;
756             for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e =
757                     APR_BUCKET_NEXT(e)) {
758                 if (APR_BUCKET_IS_TRANSIENT(e)) {
759                     int rv = apr_bucket_setaside(e, f->r->pool);
760                     if (rv != APR_SUCCESS) {
761                         return rv;
762                     }
763                 }
764             }
765             pool = f->r->pool;
766             APR_BRIGADE_CONCAT(f->bb, bb);
767         }
768         else {
769             if (!f->deferred_pool) {
770                 apr_pool_create(&f->deferred_pool, f->c->pool);
771                 apr_pool_tag(f->deferred_pool, "deferred_pool");
772             }
773             pool = f->deferred_pool;
774             return ap_save_brigade(f, &f->bb, &bb, pool);
775         }
776
777     }
778     else if (f->deferred_pool) {
779         /*
780          * There are no more requests in the pipeline. We can just clear the
781          * pool.
782          */
783         apr_brigade_cleanup(f->bb);
784         apr_pool_clear(f->deferred_pool);
785     }
786     return APR_SUCCESS;
787 }
788
789 AP_DECLARE(apr_status_t) ap_filter_reinstate_brigade(ap_filter_t *f,
790                                                      apr_bucket_brigade *bb,
791                                                      apr_bucket **flush_upto)
792 {
793     apr_bucket *bucket, *next;
794     apr_size_t bytes_in_brigade, non_file_bytes_in_brigade;
795     int eor_buckets_in_brigade, morphing_bucket_in_brigade;
796     int loglevel = ap_get_conn_module_loglevel(f->c, APLOG_MODULE_INDEX);
797
798     if (loglevel >= APLOG_TRACE6) {
799         ap_log_cerror(
800             APLOG_MARK, APLOG_TRACE6, 0, f->c,
801             "reinstate %s brigade to %s brigade in '%s' output filter",
802             (!f->bb || APR_BRIGADE_EMPTY(f->bb) ? "empty" : "full"),
803             (APR_BRIGADE_EMPTY(bb) ? "empty" : "full"), f->frec->name);
804     }
805
806     if (f->bb && !APR_BRIGADE_EMPTY(f->bb)) {
807         APR_BRIGADE_PREPEND(bb, f->bb);
808     }
809
810     /*
811      * Determine if and up to which bucket we need to do a blocking write:
812      *
813      *  a) The brigade contains a flush bucket: Do a blocking write
814      *     of everything up that point.
815      *
816      *  b) The request is in CONN_STATE_HANDLER state, and the brigade
817      *     contains at least THRESHOLD_MAX_BUFFER bytes in non-file
818      *     buckets: Do blocking writes until the amount of data in the
819      *     buffer is less than THRESHOLD_MAX_BUFFER.  (The point of this
820      *     rule is to provide flow control, in case a handler is
821      *     streaming out lots of data faster than the data can be
822      *     sent to the client.)
823      *
824      *  c) The request is in CONN_STATE_HANDLER state, and the brigade
825      *     contains at least MAX_REQUESTS_IN_PIPELINE EOR buckets:
826      *     Do blocking writes until less than MAX_REQUESTS_IN_PIPELINE EOR
827      *     buckets are left. (The point of this rule is to prevent too many
828      *     FDs being kept open by pipelined requests, possibly allowing a
829      *     DoS).
830      *
831      *  d) The request is being served by a connection filter and the
832      *     brigade contains a morphing bucket: If there was no other
833      *     reason to do a blocking write yet, try reading the bucket. If its
834      *     contents fit into memory before THRESHOLD_MAX_BUFFER is reached,
835      *     everything is fine. Otherwise we need to do a blocking write the
836      *     up to and including the morphing bucket, because ap_save_brigade()
837      *     would read the whole bucket into memory later on.
838      */
839
840     *flush_upto = NULL;
841
842     bytes_in_brigade = 0;
843     non_file_bytes_in_brigade = 0;
844     eor_buckets_in_brigade = 0;
845     morphing_bucket_in_brigade = 0;
846
847     for (bucket = APR_BRIGADE_FIRST(bb); bucket != APR_BRIGADE_SENTINEL(bb);
848          bucket = next) {
849         next = APR_BUCKET_NEXT(bucket);
850
851         if (!APR_BUCKET_IS_METADATA(bucket)) {
852             if (bucket->length == (apr_size_t)-1) {
853                 /*
854                  * A setaside of morphing buckets would read everything into
855                  * memory. Instead, we will flush everything up to and
856                  * including this bucket.
857                  */
858                 morphing_bucket_in_brigade = 1;
859             }
860             else {
861                 bytes_in_brigade += bucket->length;
862                 if (!APR_BUCKET_IS_FILE(bucket))
863                     non_file_bytes_in_brigade += bucket->length;
864             }
865         }
866         else if (AP_BUCKET_IS_EOR(bucket)) {
867             eor_buckets_in_brigade++;
868         }
869
870         if (APR_BUCKET_IS_FLUSH(bucket)
871             || non_file_bytes_in_brigade >= THRESHOLD_MAX_BUFFER
872             || (!f->r && morphing_bucket_in_brigade)
873             || eor_buckets_in_brigade > MAX_REQUESTS_IN_PIPELINE) {
874             /* this segment of the brigade MUST be sent before returning. */
875
876             if (loglevel >= APLOG_TRACE6) {
877                 char *reason = APR_BUCKET_IS_FLUSH(bucket) ?
878                                "FLUSH bucket" :
879                                (non_file_bytes_in_brigade >= THRESHOLD_MAX_BUFFER) ?
880                                "THRESHOLD_MAX_BUFFER" :
881                                (!f->r && morphing_bucket_in_brigade) ? "morphing bucket" :
882                                "MAX_REQUESTS_IN_PIPELINE";
883                 ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, f->c,
884                               "will flush because of %s", reason);
885                 ap_log_cerror(APLOG_MARK, APLOG_TRACE8, 0, f->c,
886                               "seen in brigade%s: bytes: %" APR_SIZE_T_FMT
887                               ", non-file bytes: %" APR_SIZE_T_FMT ", eor "
888                               "buckets: %d, morphing buckets: %d",
889                               *flush_upto == NULL ? " so far"
890                                                   : " since last flush point",
891                               bytes_in_brigade,
892                               non_file_bytes_in_brigade,
893                               eor_buckets_in_brigade,
894                               morphing_bucket_in_brigade);
895             }
896             /*
897              * Defer the actual blocking write to avoid doing many writes.
898              */
899             *flush_upto = next;
900
901             bytes_in_brigade = 0;
902             non_file_bytes_in_brigade = 0;
903             eor_buckets_in_brigade = 0;
904             morphing_bucket_in_brigade = 0;
905         }
906     }
907
908     if (loglevel >= APLOG_TRACE8) {
909         ap_log_cerror(APLOG_MARK, APLOG_TRACE8, 0, f->c,
910                       "brigade contains: bytes: %" APR_SIZE_T_FMT
911                       ", non-file bytes: %" APR_SIZE_T_FMT
912                       ", eor buckets: %d, morphing buckets: %d",
913                       bytes_in_brigade, non_file_bytes_in_brigade,
914                       eor_buckets_in_brigade, morphing_bucket_in_brigade);
915     }
916
917     return APR_SUCCESS;
918 }
919
920 AP_DECLARE(int) ap_filter_should_yield(ap_filter_t *f)
921 {
922     /*
923      * Handle the AsyncFilter directive. We limit the filters that are
924      * eligible for asynchronous handling here.
925      */
926     if (f->frec->ftype < f->c->async_filter) {
927         return 0;
928     }
929
930     /*
931      * This function decides whether a filter should yield due to buffered
932      * data in a downstream filter. If a downstream filter buffers we
933      * must back off so we don't overwhelm the server. If this function
934      * returns true, the filter should call ap_filter_setaside_brigade()
935      * to save unprocessed buckets, and then reinstate those buckets on
936      * the next call with ap_filter_reinstate_brigade() and continue
937      * where it left off.
938      *
939      * If this function is forced to return zero, we return back to
940      * synchronous filter behaviour.
941      *
942      * Subrequests present us with a problem - we don't know how much data
943      * they will produce and therefore how much buffering we'll need, and
944      * if a subrequest had to trigger buffering, but next subrequest wouldn't
945      * know when the previous one had finished sending data and buckets
946      * could be sent out of order.
947      *
948      * In the case of subrequests, deny the ability to yield. When the data
949      * reaches the filters from the main request, they will be setaside
950      * there in the right order and the request will be given the
951      * opportunity to yield.
952      */
953     if (f->r && f->r->main) {
954         return 0;
955     }
956
957     /*
958      * This is either a main request or internal redirect, or it is a
959      * connection filter. Yield if there is any buffered data downstream
960      * from us.
961      */
962     while (f) {
963         if (f->bb && !APR_BRIGADE_EMPTY(f->bb)) {
964             return 1;
965         }
966         f = f->next;
967     }
968     return 0;
969 }
970
971 AP_DECLARE(int) ap_filter_output_pending(conn_rec *c)
972 {
973     apr_hash_index_t *rindex;
974     int data_in_output_filters = DECLINED;
975
976     rindex = apr_hash_first(NULL, c->filters);
977     while (rindex) {
978         ap_filter_t *f = apr_hash_this_val(rindex);
979
980         if (f->frec->direction == AP_FILTER_OUTPUT && f->bb
981                 && !APR_BRIGADE_EMPTY(f->bb)) {
982
983             apr_status_t rv;
984
985             rv = ap_pass_brigade(f, c->empty);
986             apr_brigade_cleanup(c->empty);
987             if (APR_SUCCESS != rv) {
988                 ap_log_cerror(
989                         APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(00470)
990                         "write failure in '%s' output filter", f->frec->name);
991                 return rv;
992             }
993
994             if (ap_filter_should_yield(f)) {
995                 data_in_output_filters = OK;
996             }
997         }
998
999         rindex = apr_hash_next(rindex);
1000     }
1001
1002     return data_in_output_filters;
1003 }
1004
1005 AP_DECLARE(int) ap_filter_input_pending(conn_rec *c)
1006 {
1007     apr_hash_index_t *rindex;
1008
1009     rindex = apr_hash_first(NULL, c->filters);
1010     while (rindex) {
1011         ap_filter_t *f = apr_hash_this_val(rindex);
1012
1013         if (f->frec->direction == AP_FILTER_INPUT && f->bb) {
1014             apr_bucket *e = APR_BRIGADE_FIRST(f->bb);
1015
1016             /* if there is at least one non-morphing bucket
1017              * in place, then we have data pending
1018              */
1019             if (e != APR_BRIGADE_SENTINEL(f->bb)
1020                     && e->length != (apr_size_t)(-1)) {
1021                 return OK;
1022             }
1023
1024         }
1025
1026         rindex = apr_hash_next(rindex);
1027     }
1028
1029     return DECLINED;
1030 }
1031
1032 AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,
1033                                                 void *ctx)
1034 {
1035     ap_filter_t *f = ctx;
1036     apr_status_t rv;
1037
1038     rv = ap_pass_brigade(f, bb);
1039
1040     /* Before invocation of the flush callback, apr_brigade_write et
1041      * al may place transient buckets in the brigade, which will fall
1042      * out of scope after returning.  Empty the brigade here, to avoid
1043      * issues with leaving such buckets in the brigade if some filter
1044      * fails and leaves a non-empty brigade. */
1045     apr_brigade_cleanup(bb);
1046
1047     return rv;
1048 }
1049
1050 AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb)
1051 {
1052     apr_bucket *b;
1053
1054     b = apr_bucket_flush_create(f->c->bucket_alloc);
1055     APR_BRIGADE_INSERT_TAIL(bb, b);
1056     return ap_pass_brigade(f, bb);
1057 }
1058
1059 AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f,
1060                                             apr_bucket_brigade *bb, ...)
1061 {
1062     va_list args;
1063     apr_status_t rv;
1064
1065     va_start(args, bb);
1066     rv = apr_brigade_vputstrs(bb, ap_filter_flush, f, args);
1067     va_end(args);
1068     return rv;
1069 }
1070
1071 AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f,
1072                                            apr_bucket_brigade *bb,
1073                                            const char *fmt,
1074                                            ...)
1075 {
1076     va_list args;
1077     apr_status_t rv;
1078
1079     va_start(args, fmt);
1080     rv = apr_brigade_vprintf(bb, ap_filter_flush, f, fmt, args);
1081     va_end(args);
1082     return rv;
1083 }
1084 AP_DECLARE(void) ap_filter_protocol(ap_filter_t *f, unsigned int flags)
1085 {
1086     f->frec->proto_flags = flags ;
1087 }