aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-05-08 14:25:51 +0000
committerIgor Sysoev <igor@sysoev.ru>2009-05-08 14:25:51 +0000
commitfd4191845b62a9bc7ad0cf23d6e64866dbc5e0f6 (patch)
treec7ff251d2c11da5aea16f3780cdb39fed1c1efc1
parent4318688cce5dc30a2db7bfe1a734e1ff6782e7f9 (diff)
downloadnginx-fd4191845b62a9bc7ad0cf23d6e64866dbc5e0f6.tar.gz
nginx-fd4191845b62a9bc7ad0cf23d6e64866dbc5e0f6.zip
handle big responses for "size" and "test" image_filters
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c48
-rw-r--r--src/http/ngx_http_request.c5
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_special_response.c12
4 files changed, 54 insertions, 12 deletions
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 10fefc549..c68ecb510 100644
--- 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);
@@ -247,9 +251,9 @@ ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
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 @@ ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
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 @@ ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
out.next = NULL;
- in = &out;
+ ctx->phase = NGX_HTTP_IMAGE_PASS;
- break;
+ return ngx_http_image_send(r, ctx, &out);
- default: /* NGX_HTTP_IMAGE_DONE */
+ case NGX_HTTP_IMAGE_PASS:
return ngx_http_next_body_filter(r, in);
+
+ default: /* NGX_HTTP_IMAGE_DONE */
+
+ 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;
+ }
+
+ 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 ngx_http_next_body_filter(r, in);
+ return rc;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 9cdd92ddd..32f120c8e 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1815,6 +1815,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
"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 --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 23a884630..4fef7c36c 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -478,6 +478,7 @@ struct ngx_http_request_s {
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 --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 7d3fd43e9..8f0a2078d 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -455,11 +455,21 @@ ngx_http_filter_finalize_request(ngx_http_request_t *r, ngx_int_t error)
/* 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;
+ }
}