]> git.kaiwu.me - nginx.git/commitdiff
Proxy: detection of data after final chunk.
authorMaxim Dounin <mdounin@mdounin.ru>
Mon, 6 Jul 2020 15:36:20 +0000 (18:36 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Mon, 6 Jul 2020 15:36:20 +0000 (18:36 +0300)
Previously, additional data after final chunk was either ignored
(in the same buffer, or during unbuffered proxying) or sent to the
client (in the next buffer already if it was already read from the
socket).  Now additional data are properly detected and ignored
in all cases.  Additionally, a warning is now logged and keepalive
is disabled in the connection.

src/http/modules/ngx_http_proxy_module.c

index c1c555ee4e9c0f40f5d9b03e970cd46fcd50dade..6cf15759cf9ef69ddebe6bad1514ddd60dabe8c6 100644 (file)
@@ -2104,6 +2104,23 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         return NGX_ERROR;
     }
 
+    if (p->upstream_done) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
+                       "http proxy data after close");
+        return NGX_OK;
+    }
+
+    if (p->length == 0) {
+
+        ngx_log_error(NGX_LOG_WARN, p->log, 0,
+                      "upstream sent data after final chunk");
+
+        r->upstream->keepalive = 0;
+        p->upstream_done = 1;
+
+        return NGX_OK;
+    }
+
     b = NULL;
     prev = &buf->shadow;
 
@@ -2166,9 +2183,15 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
             /* a whole response has been parsed successfully */
 
-            p->upstream_done = 1;
+            p->length = 0;
             r->upstream->keepalive = !r->upstream->headers_in.connection_close;
 
+            if (buf->pos != buf->last) {
+                ngx_log_error(NGX_LOG_WARN, p->log, 0,
+                              "upstream sent data after final chunk");
+                r->upstream->keepalive = 0;
+            }
+
             break;
         }
 
@@ -2347,6 +2370,12 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
             u->keepalive = !u->headers_in.connection_close;
             u->length = 0;
 
+            if (buf->pos != buf->last) {
+                ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+                              "upstream sent data after final chunk");
+                u->keepalive = 0;
+            }
+
             break;
         }