Mercurial > hg > nginx-vendor-0-8
diff src/http/ngx_http_upstream.c @ 248:acd2ec3541cb NGINX_0_4_9
nginx 0.4.9
*) Feature: the "set" parameter in the "include" SSI command.
*) Feature: the ngx_http_perl_module now tests the nginx.pm module
version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 13 Oct 2006 00:00:00 +0400 |
parents | 500a3242dff6 |
children | fbf2b2f66c9f |
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -21,6 +21,7 @@ static void ngx_http_upstream_send_reque ngx_http_upstream_t *u); static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); static void ngx_http_upstream_process_header(ngx_event_t *rev); +static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u); static void @@ -1061,6 +1062,12 @@ ngx_http_upstream_process_header(ngx_eve /* rc == NGX_OK */ + if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST + && r->subrequest_in_memory) + { + u->buffer.last = u->buffer.pos; + } + if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) { if (u->peer.tries > 1 @@ -1248,7 +1255,109 @@ ngx_http_upstream_process_header(ngx_eve u->length = NGX_MAX_SIZE_T_VALUE; } - ngx_http_upstream_send_response(r, u); + if (!r->subrequest_in_memory) { + ngx_http_upstream_send_response(r, u); + return; + } + + /* subrequest content in memory */ + + if (u->input_filter == NULL) { + u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; + u->input_filter = ngx_http_upstream_non_buffered_filter; + u->input_filter_ctx = r; + } + + if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + if (u->buffer.last - u->buffer.pos >= (ssize_t) u->length) { + if (u->input_filter(u->input_filter_ctx, 0) == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + rev->handler = ngx_http_upstream_process_body_in_memory; + + ngx_http_upstream_process_body_in_memory(rev); +} + + +static void +ngx_http_upstream_process_body_in_memory(ngx_event_t *rev) +{ + size_t size; + ssize_t n; + ngx_buf_t *b; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_upstream_t *u; + + c = rev->data; + r = c->data; + u = r->upstream; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream process body on memory"); + + if (rev->timedout) { + ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); + ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT); + return; + } + + b = &u->buffer; + + for ( ;; ) { + + size = b->end - b->last; + + if (size == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "upstream buffer is too small to read repsonse"); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + + n = c->recv(c, b->last, size); + + if (n == NGX_AGAIN) { + break; + } + + if (n == 0 || n == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, n); + return; + } + + if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + + if (!rev->ready) { + break; + } + } + + if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + + if (rev->active) { + ngx_add_timer(rev, u->conf->read_timeout); + + } else if (rev->timer_set) { + ngx_del_timer(rev); + } }