BBlack has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/71623


Change subject: Dynamic HTTP receive buffer size in case of large error mssages
......................................................................

Dynamic HTTP receive buffer size in case of large error mssages

Change-Id: I8967342e07d9216886832f51ac6895a4e8a2b6a8
---
M src/purger.c
1 file changed, 16 insertions(+), 10 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/software/varnish/vhtcpd 
refs/changes/23/71623/1

diff --git a/src/purger.c b/src/purger.c
index 38df8d3..e36cc4d 100644
--- a/src/purger.c
+++ b/src/purger.c
@@ -44,8 +44,8 @@
 // this buffer holds a fully-formed HTTP request to purge a single URL.
 #define OUTBUF_SIZE 4096U
 
-// this buffer holds the complete HTTP response we get
-#define INBUF_SIZE 4096U
+// this buffer holds the complete HTTP response we get, and can grow at runtime
+#define INBUF_INITSIZE 4096U
 
 // initial and maximum wait betwen connect() attempts when connects are failing
 //  and/or timing out.  The wait doubles after every failure (but limited to 
the
@@ -136,7 +136,8 @@
     int fd;
     unsigned outbuf_bytes;   // total size of current buffered message
     unsigned outbuf_written; // bytes of the message sent so far...
-    unsigned inbuf_parsed;
+    unsigned inbuf_size;     // dynamic resize of inbuf
+    unsigned inbuf_parsed;   // consumed by parser so far
     unsigned io_timeout;     // these two are fixed via config
     unsigned idle_timeout;   // these two are fixed via config
     unsigned conn_wait_timeout; // dynamic, rises until success...
@@ -189,6 +190,8 @@
 static void purger_assert_sanity(purger_t* s) {
     dmn_assert(s);
     dmn_assert(s->outbuf);
+    dmn_assert(s->inbuf);
+    dmn_assert(s->inbuf_size);
     dmn_assert(s->queue);
     dmn_assert(s->loop);
     dmn_assert(s->write_watcher);
@@ -514,7 +517,7 @@
     purger_assert_sanity(s);
     dmn_log_debug("purger: %s/%s -> hit purger_read_cb()", 
dmn_logf_anysin(&s->daddr), state_strs[s->state]);
 
-    const unsigned to_recv = INBUF_SIZE - s->inbuf_parsed;
+    const unsigned to_recv = s->inbuf_size - s->inbuf_parsed;
     int recvrv = recv(s->fd, &s->inbuf[s->inbuf_parsed], to_recv, 0);
     if(recvrv < 1) {
         if(recvrv == -1) {
@@ -553,11 +556,14 @@
     }
 
     if(recvrv == (int)to_recv) {
-        dmn_log_err("TCP conn to %s: response too large, dropping request", 
dmn_logf_anysin(&s->daddr));
-        close_from_read_cb(s, true);
-        return;
+        // TCP might want to give us more data than the buffer can hold, 
expand it the buffer
+        //  and feed what we have to the parser.  It's exceedingly likely the 
parse won't yet
+        //  complete and we'll get another recv callback to finish up.
+        s->inbuf_size <<= 1;
+        s->inbuf = realloc(s->inbuf, s->inbuf_size);
+        dmn_log_err("TCP recv buffer for %s grew to %u", 
dmn_logf_anysin(&s->daddr), s->inbuf_size);
     }
-    else { // reasonably-sized data, attempt parse
+
         if(!s->inbuf_parsed) // first read
             http_parser_init(s->parser, HTTP_RESPONSE);
 
@@ -610,7 +616,6 @@
             //  so just return to the loop and maintain this state to get more 
data.
             dmn_log_debug("purger: %s/%s -> purger_read_cb silent result: 
apparent partial parse, still waiting for data...", dmn_logf_anysin(&s->daddr), 
state_strs[s->state]);
         }
-    }
 }
 
 static void purger_timeout_cb(struct ev_loop* loop, ev_timer* w, int revents) {
@@ -673,8 +678,9 @@
     purger_t* s = calloc(1, sizeof(purger_t));
     s->fd = -1;
     s->purge_full_url = purge_full_url;
+    s->inbuf_size = INBUF_INITSIZE;
     s->outbuf = malloc(OUTBUF_SIZE);
-    s->inbuf = malloc(INBUF_SIZE);
+    s->inbuf = malloc(s->inbuf_size);
     s->parser = malloc(sizeof(http_parser));
     s->queue = queue;
     s->vhead = vhead;

-- 
To view, visit https://gerrit.wikimedia.org/r/71623
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8967342e07d9216886832f51ac6895a4e8a2b6a8
Gerrit-PatchSet: 1
Gerrit-Project: operations/software/varnish/vhtcpd
Gerrit-Branch: master
Gerrit-Owner: BBlack <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to