Mercurial > hg > nginx-vendor-current
diff src/http/ngx_http_upstream.c @ 76:da9a3b14312d NGINX_0_1_38
nginx 0.1.38
*) Feature: the "limit_rate" directive is supported in in proxy and
FastCGI mode.
*) Feature: the "X-Accel-Limit-Rate" response header line is supported
in proxy and FastCGI mode.
*) Feature: the "break" directive.
*) Feature: the "log_not_found" directive.
*) Bugfix: the response status code was not changed when request was
redirected by the ""X-Accel-Redirect" header line.
*) Bugfix: the variables set by the "set" directive could not be used
in SSI.
*) Bugfix: the segmentation fault may occurred if the SSI page has more
than one remote subrequest.
*) Bugfix: nginx treated the backend response as invalid if the status
line in the header was transferred in two packets; bug appeared in
0.1.29.
*) Feature: the "ssi_types" directive.
*) Feature: the "autoindex_exact_size" directive.
*) Bugfix: the ngx_http_autoindex_module did not support the long file
names in UTF-8.
*) Feature: the IMAP/POP3 proxy.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 08 Jul 2005 00:00:00 +0400 |
parents | 77969b24f355 |
children | 9db7e0b5b27f |
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -39,6 +39,8 @@ static ngx_int_t ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t @@ -143,6 +145,10 @@ ngx_http_upstream_header_t ngx_http_ups offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), ngx_http_upstream_ignore_header_line, 0, 0 }, + { ngx_string("X-Accel-Limit-Rate"), + ngx_http_upstream_process_limit_rate, 0, + ngx_http_upstream_ignore_header_line, 0, 0 }, + #if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), ngx_http_upstream_process_header_line, @@ -299,12 +305,19 @@ ngx_http_upstream_check_broken_connectio ngx_connection_t *c; ngx_http_upstream_t *u; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "http upstream check client, write event:%d", ev->write); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0, + "http upstream check client, write event:%d, \"%V\"", + ev->write, &r->uri); c = r->connection; u = r->upstream; + if (c->closed) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_CLIENT_CLOSED_REQUEST); + return; + } + if (u->peer.connection == NULL) { return; } @@ -318,6 +331,7 @@ ngx_http_upstream_check_broken_connectio } ev->eof = 1; + c->closed = 1; if (ev->kq_errno) { ev->error = 1; @@ -325,9 +339,8 @@ ngx_http_upstream_check_broken_connectio if (!u->cachable && u->peer.connection) { ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, - "kevent() reported that client closed " - "prematurely connection, " - "so upstream connection is closed too"); + "kevent() reported that client closed prematurely " + "connection, so upstream connection is closed too"); ngx_http_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; @@ -374,6 +387,7 @@ ngx_http_upstream_check_broken_connectio } ev->eof = 1; + c->closed = 1; if (n == -1) { if (err == NGX_EAGAIN) { @@ -924,6 +938,8 @@ ngx_http_upstream_process_header(ngx_eve } } + r->headers_out.status_line.len = 0; + ngx_http_internal_redirect(r, &r->upstream->headers_in.x_accel_redirect->value, NULL); @@ -1155,9 +1171,33 @@ ngx_http_upstream_process_body(ngx_event if (ev->timedout) { if (ev->write) { - p->downstream_error = 1; - ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, - "client timed out"); + if (ev->delayed) { + + ev->timedout = 0; + ev->delayed = 0; + + if (!ev->ready) { + ngx_add_timer(ev, p->send_timeout); + + if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR) + { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + return; + } + + if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + } else { + p->downstream_error = 1; + ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, + "client timed out"); + } } else { p->upstream_error = 1; @@ -1166,6 +1206,17 @@ ngx_http_upstream_process_body(ngx_event } } else { + if (ev->write && ev->delayed) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http downstream delayed"); + + if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR) { + return; + } + + return; + } + if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { ngx_http_upstream_finalize_request(r, u, 0); return; @@ -1281,6 +1332,7 @@ ngx_http_upstream_next(ngx_http_request_ } if (r->connection->write->eof) { + r->connection->closed = 1; ngx_http_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; @@ -1432,6 +1484,24 @@ ngx_http_upstream_ignore_header_line(ngx static ngx_int_t +ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, + ngx_uint_t offset) +{ + ngx_int_t n; + + r->upstream->headers_in.x_accel_limit_rate = h; + + n = ngx_atoi(h->value.data, h->value.len); + + if (n != NGX_ERROR) { + r->limit_rate = (size_t) n; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) {