You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by dr...@apache.org on 2017/03/25 17:24:24 UTC

svn commit: r1788674 - /httpd/httpd/trunk/modules/metadata/mod_remoteip.c

Author: druggeri
Date: Sat Mar 25 17:24:23 2017
New Revision: 1788674

URL: http://svn.apache.org/viewvc?rev=1788674&view=rev
Log:
Finally include feedback from Ruediger Pluem. Add slave "backoff" verified by Sander Hoentjen

Modified:
    httpd/httpd/trunk/modules/metadata/mod_remoteip.c

Modified: httpd/httpd/trunk/modules/metadata/mod_remoteip.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_remoteip.c?rev=1788674&r1=1788673&r2=1788674&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/metadata/mod_remoteip.c (original)
+++ httpd/httpd/trunk/modules/metadata/mod_remoteip.c Sat Mar 25 17:24:23 2017
@@ -862,6 +862,11 @@ static int remoteip_hook_pre_connection(
     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_filte
     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_filte
             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_filte
             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_filte
                        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_filte
                             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_filte
                     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 */