AP_DECLARE(apr_status_t) ap_filter_setaside_brigade(ap_filter_t *f,
apr_bucket_brigade *bb);
-/*
- * Adopt a bucket brigade as is (no setaside nor copy).
- * @param f The current filter
- * @param bb The bucket brigade adopted. This brigade is always empty
- * on return
- * @remark httpd internal, not exported, needed by
- * ap_core_input_filter
- */
-void ap_filter_adopt_brigade(ap_filter_t *f, apr_bucket_brigade *bb);
-
/**
* Reinstate a brigade setaside earlier, and calculate the amount of data we
* should write based on the presence of flush buckets, size limits on in
*/
AP_DECLARE_NONSTD(int) ap_filter_input_pending(conn_rec *c);
-/*
- * Recycle removed request filters so that they can be reused for filters
- * added later on the same connection. This typically should happen after
- * each request handling.
- *
- * @param c The connection.
- * @remark httpd internal, not exported, needed by
- * ap_process_request_after_handler
- *
- */
-void ap_filter_recycle(conn_rec *c);
-
/**
* Flush function for apr_brigade_* calls. This calls ap_pass_brigade
* to flush the brigade if the brigade buffer overflows.
#include "http_log.h"
#include "http_request.h"
#include "util_filter.h"
+#include "core.h"
/* NOTE: Apache's current design doesn't allow a pool to be passed thru,
so we depend on a global to hold the correct pool
* while it is handling/passing the EOR, and we want each filter or
* ap_filter_output_pending() to be able to dereference f until they
* return. So request filters are recycled in dead_filters and will only
- * be moved to spare_filters when ap_filter_recycle() is called explicitly.
- * Set f->r to NULL still for any use after free to crash quite reliably.
+ * be moved to spare_filters when recycle_dead_filters() is called, i.e.
+ * in ap_filter_{in,out}put_pending(). Set f->r to NULL still for any use
+ * after free to crash quite reliably.
*/
f->r = NULL;
put_spare(c, f, &x->dead_filters);
return APR_SUCCESS;
}
-void ap_filter_recycle(conn_rec *c)
+static void recycle_dead_filters(conn_rec *c)
{
struct ap_filter_conn_ctx *x = c->filter_conn_ctx;
ap_release_brigade(c, bb);
cleanup:
- /* No more flushing, all filters have returned, recycle/unleak dead request
- * filters before leaving (i.e. make them reusable).
+ /* All filters have returned, time to recycle/unleak ap_filter_t-s
+ * before leaving (i.e. make them reusable).
*/
- ap_filter_recycle(c);
+ recycle_dead_filters(c);
return rc;
}
{
struct ap_filter_conn_ctx *x = c->filter_conn_ctx;
struct ap_filter_private *fp;
+ int rc = DECLINED;
if (!x || !x->pending_input_filters) {
- return DECLINED;
+ goto cleanup;
}
for (fp = APR_RING_LAST(x->pending_input_filters);
e = APR_BRIGADE_FIRST(fp->bb);
if (e != APR_BRIGADE_SENTINEL(fp->bb)
&& e->length != (apr_size_t)(-1)) {
- return OK;
+ rc = OK;
+ break;
}
}
- return DECLINED;
+cleanup:
+ /* All filters have returned, time to recycle/unleak ap_filter_t-s
+ * before leaving (i.e. make them reusable).
+ */
+ recycle_dead_filters(c);
+
+ return rc;
}
AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,