Upstream: flush partially filled buffers on upstream timeout

HG changeset patch

User Maxim D. [email protected]

Date 1225109019 -10800

Node ID aa6cd5a06ccc2037064686bcb183c71d8c65f44a

Parent 83ba5ad4985f08c8acbffe694fa365a2dff571bf

Upstream: flush partially filled buffers on upstream timeout.

Fix typo in comment while here.

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
@@ -10,7 +10,8 @@
#include <ngx_event_pipe.h>

-static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
+static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p,

  •                                          ngx_int_t do_flush);
    

static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t
*p);

static ngx_int_t
ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
@@ -40,7 +41,7 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_

     p->log->action = "reading upstream";
  •    if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
    
  •    if (ngx_event_pipe_read_upstream(p, 0) == NGX_ABORT) {
           return NGX_ABORT;
       }
    

@@ -88,8 +89,27 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_
}

+ngx_int_t
+ngx_event_pipe_flush(ngx_event_pipe_t *p)
+{

  • p->log->action = “reading upstream”;
  • if (ngx_event_pipe_read_upstream(p, 1) == NGX_ABORT) {
  •    return NGX_ABORT;
    
  • }
  • p->log->action = “sending to client”;
  • if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) {
  •    return NGX_ABORT;
    
  • }
  • return NGX_OK;
    +}

static ngx_int_t
-ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
+ngx_event_pipe_read_upstream(ngx_event_pipe_t *p, ngx_int_t do_flush)
{
ssize_t n, size;
ngx_int_t rc;
@@ -97,6 +117,9 @@ ngx_event_pipe_read_upstream(ngx_event_p
ngx_chain_t *chain, *cl, *ln;

 if (p->upstream_eof || p->upstream_error || p->upstream_done) {
  •    if (do_flush) {
    
  •        goto flush;
    
  •    }
       return NGX_OK;
    
    }

@@ -330,6 +353,8 @@ ngx_event_pipe_read_upstream(ngx_event_p
p->free_raw_bufs = cl;
}
}
+
+flush:

#if (NGX_DEBUG)

@@ -928,7 +953,7 @@ ngx_event_pipe_add_free_buf(ngx_event_pi
return NGX_OK;
}

  • /* the first free buf is partialy filled, thus add the free buf
    after it */
  • /* the first free buf is partially filled, thus add the free buf
    after it */

    cl->next = p->free_raw_bufs->next;
    p->free_raw_bufs->next = cl;
    diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
    — a/src/event/ngx_event_pipe.h
    +++ b/src/event/ngx_event_pipe.h
    @@ -87,6 +87,7 @@ struct ngx_event_pipe_s {

ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write);
+ngx_int_t ngx_event_pipe_flush(ngx_event_pipe_t *p);
ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p,
ngx_buf_t *buf);
ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t
*b);

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
@@ -2076,6 +2076,16 @@ ngx_http_upstream_process_body(ngx_event
} else {
p->upstream_error = 1;
ngx_connection_error(c, NGX_ETIMEDOUT, “upstream timed
out”);
+

  •        if (ngx_event_pipe_flush(p) == NGX_ABORT) {
    
  •            if (downstream->destroyed) {
    
  •                return;
    
  •            }
    
  •            ngx_http_upstream_finalize_request(r, u, 0);
    
  •            return;
    
  •        }
       }
    

    } else {