Mercurial > hg > nginx-quic
comparison src/http/ngx_http_upstream.c @ 5304:d3eab5e2df5f
Upstream: no last buffer on errors.
Previously, after sending a header we always sent a last buffer and
finalized a request with code 0, even in case of errors. In some cases
this resulted in a loss of ability to detect the response wasn't complete
(e.g. if Content-Length was removed from a response by gzip filter).
This change tries to propogate to a client information that a response
isn't complete in such cases. In particular, with this change we no longer
pretend a returned response is complete if we wasn't able to create
a temporary file.
If an error code suggests the error wasn't fatal, we flush buffered data
and disable keepalive, then finalize request normally. This allows to to
propogate information about a problem to a client, while still sending all
the data we've got from an upstream.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 25 Jul 2013 15:00:41 +0400 |
parents | 0fb714d80909 |
children | 12b750d35162 |
comparison
equal
deleted
inserted
replaced
5303:0fb714d80909 | 5304:d3eab5e2df5f |
---|---|
3295 | 3295 |
3296 static void | 3296 static void |
3297 ngx_http_upstream_finalize_request(ngx_http_request_t *r, | 3297 ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
3298 ngx_http_upstream_t *u, ngx_int_t rc) | 3298 ngx_http_upstream_t *u, ngx_int_t rc) |
3299 { | 3299 { |
3300 ngx_uint_t flush; | |
3300 ngx_time_t *tp; | 3301 ngx_time_t *tp; |
3301 | 3302 |
3302 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 3303 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
3303 "finalize http upstream request: %i", rc); | 3304 "finalize http upstream request: %i", rc); |
3304 | 3305 |
3415 { | 3416 { |
3416 ngx_http_finalize_request(r, rc); | 3417 ngx_http_finalize_request(r, rc); |
3417 return; | 3418 return; |
3418 } | 3419 } |
3419 | 3420 |
3420 if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 3421 flush = 0; |
3421 rc = 0; | 3422 |
3423 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
3424 rc = NGX_ERROR; | |
3425 flush = 1; | |
3422 } | 3426 } |
3423 | 3427 |
3424 if (r->header_only) { | 3428 if (r->header_only) { |
3425 ngx_http_finalize_request(r, rc); | 3429 ngx_http_finalize_request(r, rc); |
3426 return; | 3430 return; |
3427 } | 3431 } |
3428 | 3432 |
3429 if (rc == 0) { | 3433 if (rc == 0) { |
3430 rc = ngx_http_send_special(r, NGX_HTTP_LAST); | 3434 rc = ngx_http_send_special(r, NGX_HTTP_LAST); |
3435 | |
3436 } else if (flush) { | |
3437 r->keepalive = 0; | |
3438 rc = ngx_http_send_special(r, NGX_HTTP_FLUSH); | |
3431 } | 3439 } |
3432 | 3440 |
3433 ngx_http_finalize_request(r, rc); | 3441 ngx_http_finalize_request(r, rc); |
3434 } | 3442 } |
3435 | 3443 |