]> granicus.if.org Git - apache/commitdiff
Finally include feedback from Ruediger Pluem. Add slave "backoff" verified by Sander...
authorDaniel Ruggeri <druggeri@apache.org>
Sat, 25 Mar 2017 17:24:23 +0000 (17:24 +0000)
committerDaniel Ruggeri <druggeri@apache.org>
Sat, 25 Mar 2017 17:24:23 +0000 (17:24 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1788674 13f79535-47bb-0310-9956-ffa450edef68

modules/metadata/mod_remoteip.c

index 796976600b382e85e350420f65defd844890e3c8..ca985913fa45dd3a7a22dff6132ad138210c16a1 100644 (file)
@@ -862,6 +862,11 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
     remoteip_conn_config_t *conn_conf;
     int optional;
 
+    /* Do not attempt to manipulate slave connections */
+    if (c->master != NULL) {
+        return DECLINED;
+    }
+
     conf = ap_get_module_config(ap_server_conf->module_config,
                                 &remoteip_module);
 
@@ -1031,6 +1036,8 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
     remoteip_parse_status_t psts = HDR_NEED_MORE;
     const char *ptr;
     apr_size_t len;
+    apr_size_t this_read = 0; /* Track bytes read in each brigade */
+    apr_size_t prev_read = 0;
 
     if (f->c->aborted) {
         return APR_ECONNABORTED;
@@ -1077,9 +1084,23 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
             return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF;
         }
 
+        if (ctx->peeking) {
+            ctx->rcvd = 0;
+            ctx->need = MIN_HDR_LEN;
+        }
+
         while (!ctx->done && !APR_BRIGADE_EMPTY(ctx->bb)) {
             b = APR_BRIGADE_FIRST(ctx->bb);
 
+            if (ctx->peeking && APR_BUCKET_IS_EOS(b)) {
+                /* Shortcut - we know no header was found yet and an
+                   EOS indicates we never will */
+                apr_brigade_destroy(ctx->bb);
+                ctx->bb = NULL;
+                ctx->done = 1;
+                return APR_SUCCESS;
+            }
+
             ret = apr_bucket_read(b, &ptr, &len, block);
             if (APR_STATUS_IS_EAGAIN(ret) && block == APR_NONBLOCK_READ) {
                 return APR_SUCCESS;
@@ -1091,6 +1112,10 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
             memcpy(ctx->header + ctx->rcvd, ptr, len);
             ctx->rcvd += len;
 
+            if (ctx->peeking && block == APR_NONBLOCK_READ) {
+                this_read += len;
+            }
+
             apr_bucket_delete(b);
             psts = HDR_NEED_MORE;
 
@@ -1103,12 +1128,11 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
                        we purge the bb and can decide to step aside or switch to
                        non-speculative read to consume the data */
                     if (ctx->peeking) {
-                        apr_brigade_destroy(ctx->bb);
-
                         if (ctx->version < 0) {
                             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03512)
                                           "RemoteIPProxyProtocol: PROXY header is missing from "
                                           "request. Stepping aside.");
+                            apr_brigade_destroy(ctx->bb);
                             ctx->bb = NULL;
                             ctx->done = 1;
                             return ap_get_brigade(f->next, bb_out, mode, block, readbytes);
@@ -1118,10 +1142,10 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
                             ctx->rcvd = 0;
                             ctx->need = MIN_HDR_LEN;
                             ctx->version = 0;
-                            ctx->bb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
                             ctx->done = 0;
                             ctx->mode = AP_MODE_READBYTES;
                             ctx->peeking = 0;
+                            apr_brigade_cleanup(ctx->bb);
 
                             ap_get_brigade(f->next, ctx->bb, ctx->mode, block,
                                            ctx->need - ctx->rcvd);
@@ -1184,6 +1208,18 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
                     break;
             }
         }
+
+        /* In SPECULATIVE mode, upstream will return all data on each brigade get - even data
+           we've seen.  For non blocking read, make sure we got new data or return early when
+           we haven't */
+        if (ctx->peeking && block == APR_NONBLOCK_READ) {
+            if (this_read == prev_read) {
+                return APR_SUCCESS;
+            }
+            else {
+                prev_read = this_read;
+            }
+        }
     }
 
     /* we only get here when done == 1 */