[nginx] Upstream: flushing of event pipe on upstream timeouts.

Maxim Dounin mdounin at mdounin.ru
Fri Aug 28 12:14:08 UTC 2026


details:   http://freenginx.org/hg/nginx/rev/7fa4911c64de
branches:  
changeset: 9586:7fa4911c64de
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Fri Aug 28 15:07:56 2026 +0300
description:
Upstream: flushing of event pipe on upstream timeouts.

Previously, on upstream read timeouts data already read from the
upstream were not flushed.  With this change, similarly to the handling
of upstream read errors (see 6672:0fa883e92895), the data that were
previously read are processed and sent to the client, minimizing the
difference from the response as returned by the upstream server.

diffstat:

 src/event/ngx_event_pipe.c   |  15 +++++++++++++++
 src/http/ngx_http_upstream.c |   5 +++++
 2 files changed, 20 insertions(+), 0 deletions(-)

diffs (40 lines):

diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -565,6 +565,21 @@ ngx_event_pipe_write_to_downstream(ngx_e
 
         if (p->upstream_eof || p->upstream_error || p->upstream_done) {
 
+            /* the first free buf is partially filled */
+
+            if (p->upstream_error
+                && p->free_raw_bufs
+                && p->free_raw_bufs->buf->pos != p->free_raw_bufs->buf->last)
+            {
+                /* STUB */ p->free_raw_bufs->buf->num = p->num++;
+
+                if (p->input_filter(p, p->free_raw_bufs->buf) == NGX_ERROR) {
+                    return NGX_ABORT;
+                }
+
+                p->free_raw_bufs = p->free_raw_bufs->next;
+            }
+
             /* pass the p->out and p->in chains to the output filter */
 
             for (cl = p->busy; cl; cl = cl->next) {
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -4236,6 +4236,11 @@ ngx_http_upstream_process_upstream(ngx_h
         p->upstream_error = 1;
         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
 
+        if (ngx_event_pipe(p, 1) == NGX_ABORT) {
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
+            return;
+        }
+
     } else {
 
         if (rev->delayed) {


More information about the nginx-devel mailing list