summaryrefslogtreecommitdiff
path: root/server/request.c
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2015-10-04 10:10:51 +0000
committerGraham Leggett <minfrin@apache.org>2015-10-04 10:10:51 +0000
commit615f97f93364fd7189ce973478266ce3d229d76b (patch)
tree84b9f0601b3a3ba6ecb0caf794378d7019f850e5 /server/request.c
parentcd6aa9bc3bc2391839c64c8778ed5d7ec0d220d7 (diff)
downloadhttpd-615f97f93364fd7189ce973478266ce3d229d76b.tar.gz
core: Extend support for asynchronous write completion from the
network filter to any connection or request filter. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1706669 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/request.c')
-rw-r--r--server/request.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/server/request.c b/server/request.c
index 67e535d14c..9c9ad9f93b 100644
--- a/server/request.c
+++ b/server/request.c
@@ -2036,6 +2036,64 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f,
return APR_SUCCESS;
}
+AP_CORE_DECLARE_NONSTD(apr_status_t) ap_request_core_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb)
+{
+ apr_bucket *flush_upto = NULL;
+ apr_status_t status = APR_SUCCESS;
+ apr_bucket_brigade *tmp_bb = f->ctx;
+
+ if (!tmp_bb) {
+ tmp_bb = f->ctx = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+ }
+
+ /* Reinstate any buffered content */
+ ap_filter_reinstate_brigade(f, bb, &flush_upto);
+
+ while (!APR_BRIGADE_EMPTY(bb)) {
+ apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
+
+ /* if the core has set aside data, back off and try later */
+ if (!flush_upto) {
+ if (ap_filter_should_yield(f)) {
+ break;
+ }
+ }
+ else if (flush_upto == bucket) {
+ flush_upto = NULL;
+ }
+
+ /* have we found a morphing bucket? if so, force it to morph into something
+ * safe to pass down to the connection filters without needing to be set
+ * aside.
+ */
+ if (!APR_BUCKET_IS_METADATA(bucket)) {
+ if (bucket->length == (apr_size_t) - 1) {
+ const char *data;
+ apr_size_t size;
+ if (APR_SUCCESS
+ != (status = apr_bucket_read(bucket, &data, &size,
+ APR_BLOCK_READ))) {
+ return status;
+ }
+ }
+ }
+
+ /* pass each bucket down the chain */
+ APR_BUCKET_REMOVE(bucket);
+ APR_BRIGADE_INSERT_TAIL(tmp_bb, bucket);
+
+ status = ap_pass_brigade(f->next, tmp_bb);
+ if (!APR_STATUS_IS_EOF(status) && (status != APR_SUCCESS)) {
+ return status;
+ }
+
+ }
+
+ ap_filter_setaside_brigade(f, bb);
+ return status;
+}
+
extern APR_OPTIONAL_FN_TYPE(authz_some_auth_required) *ap__authz_ap_some_auth_required;
AP_DECLARE(int) ap_some_auth_required(request_rec *r)