]> granicus.if.org Git - apache/commitdiff
* Move code for broken backend detection out of core filter into a new http
authorRuediger Pluem <rpluem@apache.org>
Sun, 18 Dec 2005 22:09:05 +0000 (22:09 +0000)
committerRuediger Pluem <rpluem@apache.org>
Sun, 18 Dec 2005 22:09:05 +0000 (22:09 +0000)
  protocol filter (ap_http_broken_backend_filter) that is only run in the
  proxy case.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@357519 13f79535-47bb-0310-9956-ffa450edef68

modules/http/http_core.c
modules/http/http_filters.c
modules/http/mod_core.h
server/core_filters.c

index 14d8a1b598b8b1198d33ffa3b8682ea2b015a99b..b939967e6e9f82f33c0c7ce94c9b43d5ee25ed39 100644 (file)
@@ -39,6 +39,7 @@
 AP_DECLARE_DATA ap_filter_rec_t *ap_http_input_filter_handle;
 AP_DECLARE_DATA ap_filter_rec_t *ap_http_header_filter_handle;
 AP_DECLARE_DATA ap_filter_rec_t *ap_chunk_filter_handle;
+AP_DECLARE_DATA ap_filter_rec_t *ap_broken_backend_filter_handle;
 AP_DECLARE_DATA ap_filter_rec_t *ap_byterange_filter_handle;
 
 static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
@@ -242,6 +243,10 @@ static void register_hooks(apr_pool_t *p)
     ap_chunk_filter_handle =
         ap_register_output_filter("CHUNK", ap_http_chunk_filter,
                                   NULL, AP_FTYPE_TRANSCODE);
+    ap_broken_backend_filter_handle =
+        ap_register_output_filter("BROKEN_BACKEND",
+                                  ap_http_broken_backend_filter,
+                                  NULL, AP_FTYPE_PROTOCOL);
     ap_byterange_filter_handle =
         ap_register_output_filter("BYTERANGE", ap_byterange_filter,
                                   NULL, AP_FTYPE_PROTOCOL);
index 750fdbda46117872bdecd05e32622c20baa31a4e..9434ac1668e9191a9195737b8a9b80f7e0ffb77f 100644 (file)
@@ -1055,6 +1055,9 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
          */
         ap_add_output_filter("CHUNK", NULL, r, r->connection);
     }
+    /* If we have a Proxy request, add the BROKEN_BACKEND filter now */
+    if (r->proxyreq != PROXYREQ_NONE)
+        ap_add_output_filter("BROKEN_BACKEND", NULL, r, r->connection);
 
     /* Don't remove this filter until after we have added the CHUNK filter.
      * Otherwise, f->next won't be the CHUNK filter and thus the first
@@ -1330,3 +1333,23 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
     return bufsiz;
 }
 
+apr_status_t ap_http_broken_backend_filter(ap_filter_t *f,
+                                           apr_bucket_brigade *b)
+{
+    request_rec *r = f->r;
+    apr_bucket *e;
+
+    for (e = APR_BRIGADE_FIRST(b);
+         e != APR_BRIGADE_SENTINEL(b);
+         e = APR_BUCKET_NEXT(e))
+    {
+        if (AP_BUCKET_IS_ERROR(e)
+            && (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY)) {
+            /* stream aborted and we have not ended it yet */
+            r->connection->keepalive = AP_CONN_CLOSE;
+        }
+    }
+
+    return ap_pass_brigade(f->next,  b);
+}
+
index 1f5c1d8c9a9c8ea22366795b04bf75e573d858ec..c084a755ec7de05562295b9cfd0b077ca91aeb9a 100644 (file)
@@ -42,6 +42,7 @@ extern "C" {
 extern AP_DECLARE_DATA ap_filter_rec_t *ap_http_input_filter_handle;
 extern AP_DECLARE_DATA ap_filter_rec_t *ap_http_header_filter_handle;
 extern AP_DECLARE_DATA ap_filter_rec_t *ap_chunk_filter_handle;
+extern AP_DECLARE_DATA ap_filter_rec_t *ap_broken_backend_filter_handle;
 extern AP_DECLARE_DATA ap_filter_rec_t *ap_byterange_filter_handle;
 
 /*
@@ -54,6 +55,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
 /* HTTP/1.1 chunked transfer encoding filter. */
 apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b);
 
+/* Filter to close the connection to the client if backend broke */
+apr_status_t ap_http_broken_backend_filter(ap_filter_t *f,
+                                           apr_bucket_brigade *b);
+
 char *ap_response_code_string(request_rec *r, int error_index);
 
 /**
index 90f5d4bf7ba0cdc6c69f5e4af0c43486aa8e3fc9..5f6ff31ec48bdbfcecb83b066a8811e1d1ff82bb 100644 (file)
@@ -315,9 +315,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
                                              apr_size_t *bytes_written,
                                              conn_rec *c);
 
-static void detect_error_bucket(apr_bucket *bucket, conn_rec *c);
-
-static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c);
+static void remove_empty_buckets(apr_bucket_brigade *bb);
 
 static apr_status_t send_brigade_blocking(apr_socket_t *s,
                                           apr_bucket_brigade *bb,
@@ -489,7 +487,7 @@ static void setaside_remaining_output(ap_filter_t *f,
     if (bb == NULL) {
         return;
     }
-    remove_empty_buckets(bb, c);
+    remove_empty_buckets(bb);
     if (!APR_BRIGADE_EMPTY(bb)) {
         c->data_in_output_filters = 1;
         if (make_a_copy) {
@@ -528,7 +526,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
     struct iovec vec[MAX_IOVEC_TO_WRITE];
     apr_size_t nvec = 0;
 
-    remove_empty_buckets(bb, c);
+    remove_empty_buckets(bb);
 
     for (bucket = APR_BRIGADE_FIRST(bb);
          bucket != APR_BRIGADE_SENTINEL(bb);
@@ -598,26 +596,16 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
         }
     }
 
-    remove_empty_buckets(bb, c);
+    remove_empty_buckets(bb);
 
     return APR_SUCCESS;
 }
 
-static void detect_error_bucket(apr_bucket *bucket, conn_rec *c)
-{
-    if (AP_BUCKET_IS_ERROR(bucket)
-        && (((ap_bucket_error *)(bucket->data))->status == HTTP_BAD_GATEWAY)) {
-        /* stream aborted and we have not ended it yet */
-        c->keepalive = AP_CONN_CLOSE;
-    }
-}
-
-static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c)
+static void remove_empty_buckets(apr_bucket_brigade *bb)
 {
     apr_bucket *bucket;
     while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) &&
            (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) {
-        detect_error_bucket(bucket, c);
         APR_BUCKET_REMOVE(bucket);
         apr_bucket_destroy(bucket);
     }
@@ -690,7 +678,6 @@ static apr_status_t writev_nonblocking(apr_socket_t *s,
             for (i = offset; i < nvec; ) {
                 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
                 if (APR_BUCKET_IS_METADATA(bucket)) {
-                    detect_error_bucket(bucket, c);
                     APR_BUCKET_REMOVE(bucket);
                     apr_bucket_destroy(bucket);
                 }