# HG changeset patch # User Igor Sysoev # Date 1241792751 0 # Node ID 43fe53832da792dda75d1143b7ee29fa21abdff9 # Parent 7e02df61252108f61212d591fa4350f974606fae handle big responses for "size" and "test" image_filters diff -r 7e02df612521 -r 43fe53832da7 src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c Fri May 08 09:41:43 2009 +0000 +++ b/src/http/modules/ngx_http_image_filter_module.c Fri May 08 14:25:51 2009 +0000 @@ -7,7 +7,8 @@ #include #include #include -#include "gd.h" + +#include #define NGX_HTTP_IMAGE_OFF 0 @@ -20,7 +21,8 @@ #define NGX_HTTP_IMAGE_START 0 #define NGX_HTTP_IMAGE_READ 1 #define NGX_HTTP_IMAGE_PROCESS 2 -#define NGX_HTTP_IMAGE_DONE 3 +#define NGX_HTTP_IMAGE_PASS 3 +#define NGX_HTTP_IMAGE_DONE 4 #define NGX_HTTP_IMAGE_NONE 0 @@ -55,6 +57,8 @@ } ngx_http_image_filter_ctx_t; +static ngx_int_t ngx_http_image_send(ngx_http_request_t *r, + ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in); static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in); static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in); static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r); @@ -247,9 +251,9 @@ if (out.buf) { out.next = NULL; - in = &out; + ctx->phase = NGX_HTTP_IMAGE_DONE; - break; + return ngx_http_image_send(r, ctx, &out); } } @@ -264,7 +268,9 @@ r->headers_out.content_type = *ct; if (conf->filter == NGX_HTTP_IMAGE_TEST) { - break; + ctx->phase = NGX_HTTP_IMAGE_PASS; + + return ngx_http_image_send(r, ctx, in); } ctx->phase = NGX_HTTP_IMAGE_READ; @@ -296,24 +302,44 @@ } out.next = NULL; - in = &out; + ctx->phase = NGX_HTTP_IMAGE_PASS; + + return ngx_http_image_send(r, ctx, &out); - break; + case NGX_HTTP_IMAGE_PASS: + + return ngx_http_next_body_filter(r, in); default: /* NGX_HTTP_IMAGE_DONE */ - return ngx_http_next_body_filter(r, in); + rc = ngx_http_next_body_filter(r, NULL); + + /* NGX_ERROR resets any pending data */ + return (rc == NGX_OK) ? NGX_ERROR : rc; } +} - ctx->phase = NGX_HTTP_IMAGE_DONE; + +static ngx_int_t +ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx, + ngx_chain_t *in) +{ + ngx_int_t rc; rc = ngx_http_next_header_filter(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { - return rc; + return NGX_ERROR; } - return ngx_http_next_body_filter(r, in); + rc = ngx_http_next_body_filter(r, in); + + if (ctx->phase == NGX_HTTP_IMAGE_DONE) { + /* NGX_ERROR resets any pending data */ + return (rc == NGX_OK) ? NGX_ERROR : rc; + } + + return rc; } diff -r 7e02df612521 -r 43fe53832da7 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Fri May 08 09:41:43 2009 +0000 +++ b/src/http/ngx_http_request.c Fri May 08 14:25:51 2009 +0000 @@ -1815,6 +1815,11 @@ "http finalize request: %d, \"%V?%V\" %d", rc, &r->uri, &r->args, r == c->data); + if (rc == NGX_OK && r->filter_finalize) { + c->error = 1; + return; + } + if (rc == NGX_DECLINED) { r->content_handler = NULL; r->write_event_handler = ngx_http_core_run_phases; diff -r 7e02df612521 -r 43fe53832da7 src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Fri May 08 09:41:43 2009 +0000 +++ b/src/http/ngx_http_request.h Fri May 08 14:25:51 2009 +0000 @@ -478,6 +478,7 @@ unsigned discard_body:1; unsigned internal:1; unsigned error_page:1; + unsigned filter_finalize:1; unsigned post_action:1; unsigned request_complete:1; unsigned request_output:1; diff -r 7e02df612521 -r 43fe53832da7 src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Fri May 08 09:41:43 2009 +0000 +++ b/src/http/ngx_http_special_response.c Fri May 08 14:25:51 2009 +0000 @@ -455,11 +455,21 @@ /* clear the modules contexts */ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module); + r->filter_finalize = 1; + rc = ngx_http_special_response_handler(r, error); /* NGX_ERROR resets any pending data */ - return (rc == NGX_OK) ? NGX_ERROR : rc; + switch (rc) { + + case NGX_OK: + case NGX_DONE: + return NGX_ERROR; + + default: + return rc; + } }