Hello! Here attaches V2 of my patch to make ngx_http_upstream detect truncated responses. Changes since V1 are as follows:
1. No longer change r->headers_out.status. 2. Just skip sending the last buf (i.e., setting the last_buf or last_in_chain flags) for errors. 3. Use u->length and u->pipe->length to test good "eof" instead of testing u->headers_in.content_length_n. Things that I'm not sure are 1. Whether to emit an error message when truncation happens. (This is not implemented in my patch.) 2. Whether to use NGX_HTTP_BAD_GATEWAY to finalize the upstream instead of NGX_ERROR. Comments are highly appreciated as always :) Thanks! -agentzh --- nginx-1.2.7/src/http/ngx_http_upstream.c 2013-02-11 06:39:49.000000000 -0800 +++ nginx-1.2.7-patched/src/http/ngx_http_upstream.c 2013-04-05 12:24:34.108742922 -0700 @@ -2399,7 +2399,7 @@ ngx_http_upstream_process_non_buffered_u if (c->read->timedout) { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT); return; } @@ -2446,13 +2446,20 @@ ngx_http_upstream_process_non_buffered_r if (u->busy_bufs == NULL) { if (u->length == 0 - || upstream->read->eof - || upstream->read->error) + || (upstream->read->eof + && u->length == -1 + && u->pipe + && u->pipe->length == -1)) { ngx_http_upstream_finalize_request(r, u, 0); return; } + if (upstream->read->eof || upstream->read->error) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + b->pos = b->start; b->last = b->start; } @@ -2720,7 +2727,9 @@ ngx_http_upstream_process_request(ngx_ht #endif - if (p->upstream_done || p->upstream_eof || p->upstream_error) { + if (p->upstream_done + || (p->upstream_eof && u->length == -1 && p->length == -1)) + { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http upstream exit: %p", p->out); #if 0 @@ -2729,6 +2738,14 @@ ngx_http_upstream_process_request(ngx_ht ngx_http_upstream_finalize_request(r, u, 0); return; } + + if (p->upstream_eof || p->upstream_error) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http upstream exit: %p", p->out); + + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } } if (p->downstream_error) { @@ -3087,7 +3104,8 @@ ngx_http_upstream_finalize_request(ngx_h if (u->header_sent && rc != NGX_HTTP_REQUEST_TIME_OUT - && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) + && rc != NGX_HTTP_GATEWAY_TIME_OUT + && rc >= NGX_HTTP_SPECIAL_RESPONSE) { rc = 0; }
nginx-1.2.7-upstream_truncation.patch
Description: Binary data
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel