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