comparison src/http/modules/ngx_http_image_filter_module.c @ 2819:43fe53832da7

handle big responses for "size" and "test" image_filters
author Igor Sysoev <igor@sysoev.ru>
date Fri, 08 May 2009 14:25:51 +0000
parents d82d08314f78
children 26e06e009ced
comparison
equal deleted inserted replaced
2818:7e02df612521 2819:43fe53832da7
5 5
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 #include "gd.h" 10
11 #include <gd.h>
11 12
12 13
13 #define NGX_HTTP_IMAGE_OFF 0 14 #define NGX_HTTP_IMAGE_OFF 0
14 #define NGX_HTTP_IMAGE_TEST 1 15 #define NGX_HTTP_IMAGE_TEST 1
15 #define NGX_HTTP_IMAGE_SIZE 2 16 #define NGX_HTTP_IMAGE_SIZE 2
18 19
19 20
20 #define NGX_HTTP_IMAGE_START 0 21 #define NGX_HTTP_IMAGE_START 0
21 #define NGX_HTTP_IMAGE_READ 1 22 #define NGX_HTTP_IMAGE_READ 1
22 #define NGX_HTTP_IMAGE_PROCESS 2 23 #define NGX_HTTP_IMAGE_PROCESS 2
23 #define NGX_HTTP_IMAGE_DONE 3 24 #define NGX_HTTP_IMAGE_PASS 3
25 #define NGX_HTTP_IMAGE_DONE 4
24 26
25 27
26 #define NGX_HTTP_IMAGE_NONE 0 28 #define NGX_HTTP_IMAGE_NONE 0
27 #define NGX_HTTP_IMAGE_JPEG 1 29 #define NGX_HTTP_IMAGE_JPEG 1
28 #define NGX_HTTP_IMAGE_GIF 2 30 #define NGX_HTTP_IMAGE_GIF 2
53 ngx_uint_t phase; 55 ngx_uint_t phase;
54 ngx_uint_t type; 56 ngx_uint_t type;
55 } ngx_http_image_filter_ctx_t; 57 } ngx_http_image_filter_ctx_t;
56 58
57 59
60 static ngx_int_t ngx_http_image_send(ngx_http_request_t *r,
61 ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in);
58 static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in); 62 static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in);
59 static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in); 63 static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in);
60 static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r); 64 static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r);
61 static ngx_buf_t *ngx_http_image_json(ngx_http_request_t *r, 65 static ngx_buf_t *ngx_http_image_json(ngx_http_request_t *r,
62 ngx_http_image_filter_ctx_t *ctx); 66 ngx_http_image_filter_ctx_t *ctx);
245 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { 249 if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
246 out.buf = ngx_http_image_json(r, NULL); 250 out.buf = ngx_http_image_json(r, NULL);
247 251
248 if (out.buf) { 252 if (out.buf) {
249 out.next = NULL; 253 out.next = NULL;
250 in = &out; 254 ctx->phase = NGX_HTTP_IMAGE_DONE;
251 255
252 break; 256 return ngx_http_image_send(r, ctx, &out);
253 } 257 }
254 } 258 }
255 259
256 return ngx_http_filter_finalize_request(r, 260 return ngx_http_filter_finalize_request(r,
257 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); 261 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
262 ct = &ngx_http_image_types[ctx->type - 1]; 266 ct = &ngx_http_image_types[ctx->type - 1];
263 r->headers_out.content_type_len = ct->len; 267 r->headers_out.content_type_len = ct->len;
264 r->headers_out.content_type = *ct; 268 r->headers_out.content_type = *ct;
265 269
266 if (conf->filter == NGX_HTTP_IMAGE_TEST) { 270 if (conf->filter == NGX_HTTP_IMAGE_TEST) {
267 break; 271 ctx->phase = NGX_HTTP_IMAGE_PASS;
272
273 return ngx_http_image_send(r, ctx, in);
268 } 274 }
269 275
270 ctx->phase = NGX_HTTP_IMAGE_READ; 276 ctx->phase = NGX_HTTP_IMAGE_READ;
271 277
272 /* fall through */ 278 /* fall through */
294 return ngx_http_filter_finalize_request(r, 300 return ngx_http_filter_finalize_request(r,
295 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); 301 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
296 } 302 }
297 303
298 out.next = NULL; 304 out.next = NULL;
299 in = &out; 305 ctx->phase = NGX_HTTP_IMAGE_PASS;
300 306
301 break; 307 return ngx_http_image_send(r, ctx, &out);
308
309 case NGX_HTTP_IMAGE_PASS:
310
311 return ngx_http_next_body_filter(r, in);
302 312
303 default: /* NGX_HTTP_IMAGE_DONE */ 313 default: /* NGX_HTTP_IMAGE_DONE */
304 314
305 return ngx_http_next_body_filter(r, in); 315 rc = ngx_http_next_body_filter(r, NULL);
306 } 316
307 317 /* NGX_ERROR resets any pending data */
308 ctx->phase = NGX_HTTP_IMAGE_DONE; 318 return (rc == NGX_OK) ? NGX_ERROR : rc;
319 }
320 }
321
322
323 static ngx_int_t
324 ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx,
325 ngx_chain_t *in)
326 {
327 ngx_int_t rc;
309 328
310 rc = ngx_http_next_header_filter(r); 329 rc = ngx_http_next_header_filter(r);
311 330
312 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { 331 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
313 return rc; 332 return NGX_ERROR;
314 } 333 }
315 334
316 return ngx_http_next_body_filter(r, in); 335 rc = ngx_http_next_body_filter(r, in);
336
337 if (ctx->phase == NGX_HTTP_IMAGE_DONE) {
338 /* NGX_ERROR resets any pending data */
339 return (rc == NGX_OK) ? NGX_ERROR : rc;
340 }
341
342 return rc;
317 } 343 }
318 344
319 345
320 static ngx_uint_t 346 static ngx_uint_t
321 ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in) 347 ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)