Mercurial > hg > nginx-vendor-current
diff src/http/modules/ngx_http_image_filter_module.c @ 488:829f9a66a659 NGINX_0_7_56
nginx 0.7.56
*) Feature: nginx/Windows supports IPv6 in a "listen" directive of the
HTTP module.
*) Bugfix: in ngx_http_image_filter_module.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 11 May 2009 00:00:00 +0400 |
parents | 6484cbba0222 |
children | e66f886a8305 |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_image_filter_module.c +++ b/src/http/modules/ngx_http_image_filter_module.c @@ -7,7 +7,8 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> -#include "gd.h" + +#include <gd.h> #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 @@ typedef struct { } 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); @@ -177,6 +181,13 @@ ngx_http_image_header_filter(ngx_http_re return NGX_ERROR; } + ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module); + + if (ctx) { + ngx_http_set_ctx(r, NULL, ngx_http_image_filter_module); + return ngx_http_next_header_filter(r); + } + ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t)); if (ctx == NULL) { return NGX_ERROR; @@ -247,13 +258,14 @@ ngx_http_image_body_filter(ngx_http_requ if (out.buf) { out.next = NULL; - in = &out; + ctx->phase = NGX_HTTP_IMAGE_DONE; - break; + return ngx_http_image_send(r, ctx, &out); } } return ngx_http_filter_finalize_request(r, + &ngx_http_image_filter_module, NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); } @@ -264,7 +276,9 @@ ngx_http_image_body_filter(ngx_http_requ 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; @@ -281,6 +295,7 @@ ngx_http_image_body_filter(ngx_http_requ if (rc == NGX_ERROR) { return ngx_http_filter_finalize_request(r, + &ngx_http_image_filter_module, NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); } @@ -292,28 +307,49 @@ ngx_http_image_body_filter(ngx_http_requ if (out.buf == NULL) { return ngx_http_filter_finalize_request(r, + &ngx_http_image_filter_module, NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); } 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; }