comparison 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
comparison
equal deleted inserted replaced
487:e98b980b4fe7 488:829f9a66a659
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);
175 "image filter: multipart/x-mixed-replace response"); 179 "image filter: multipart/x-mixed-replace response");
176 180
177 return NGX_ERROR; 181 return NGX_ERROR;
178 } 182 }
179 183
184 ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
185
186 if (ctx) {
187 ngx_http_set_ctx(r, NULL, ngx_http_image_filter_module);
188 return ngx_http_next_header_filter(r);
189 }
190
180 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t)); 191 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t));
181 if (ctx == NULL) { 192 if (ctx == NULL) {
182 return NGX_ERROR; 193 return NGX_ERROR;
183 } 194 }
184 195
245 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { 256 if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
246 out.buf = ngx_http_image_json(r, NULL); 257 out.buf = ngx_http_image_json(r, NULL);
247 258
248 if (out.buf) { 259 if (out.buf) {
249 out.next = NULL; 260 out.next = NULL;
250 in = &out; 261 ctx->phase = NGX_HTTP_IMAGE_DONE;
251 262
252 break; 263 return ngx_http_image_send(r, ctx, &out);
253 } 264 }
254 } 265 }
255 266
256 return ngx_http_filter_finalize_request(r, 267 return ngx_http_filter_finalize_request(r,
268 &ngx_http_image_filter_module,
257 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); 269 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
258 } 270 }
259 271
260 /* override content type */ 272 /* override content type */
261 273
262 ct = &ngx_http_image_types[ctx->type - 1]; 274 ct = &ngx_http_image_types[ctx->type - 1];
263 r->headers_out.content_type_len = ct->len; 275 r->headers_out.content_type_len = ct->len;
264 r->headers_out.content_type = *ct; 276 r->headers_out.content_type = *ct;
265 277
266 if (conf->filter == NGX_HTTP_IMAGE_TEST) { 278 if (conf->filter == NGX_HTTP_IMAGE_TEST) {
267 break; 279 ctx->phase = NGX_HTTP_IMAGE_PASS;
280
281 return ngx_http_image_send(r, ctx, in);
268 } 282 }
269 283
270 ctx->phase = NGX_HTTP_IMAGE_READ; 284 ctx->phase = NGX_HTTP_IMAGE_READ;
271 285
272 /* fall through */ 286 /* fall through */
279 return NGX_OK; 293 return NGX_OK;
280 } 294 }
281 295
282 if (rc == NGX_ERROR) { 296 if (rc == NGX_ERROR) {
283 return ngx_http_filter_finalize_request(r, 297 return ngx_http_filter_finalize_request(r,
298 &ngx_http_image_filter_module,
284 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); 299 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
285 } 300 }
286 301
287 /* fall through */ 302 /* fall through */
288 303
290 305
291 out.buf = ngx_http_image_process(r); 306 out.buf = ngx_http_image_process(r);
292 307
293 if (out.buf == NULL) { 308 if (out.buf == NULL) {
294 return ngx_http_filter_finalize_request(r, 309 return ngx_http_filter_finalize_request(r,
310 &ngx_http_image_filter_module,
295 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); 311 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
296 } 312 }
297 313
298 out.next = NULL; 314 out.next = NULL;
299 in = &out; 315 ctx->phase = NGX_HTTP_IMAGE_PASS;
300 316
301 break; 317 return ngx_http_image_send(r, ctx, &out);
318
319 case NGX_HTTP_IMAGE_PASS:
320
321 return ngx_http_next_body_filter(r, in);
302 322
303 default: /* NGX_HTTP_IMAGE_DONE */ 323 default: /* NGX_HTTP_IMAGE_DONE */
304 324
305 return ngx_http_next_body_filter(r, in); 325 rc = ngx_http_next_body_filter(r, NULL);
306 } 326
307 327 /* NGX_ERROR resets any pending data */
308 ctx->phase = NGX_HTTP_IMAGE_DONE; 328 return (rc == NGX_OK) ? NGX_ERROR : rc;
329 }
330 }
331
332
333 static ngx_int_t
334 ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx,
335 ngx_chain_t *in)
336 {
337 ngx_int_t rc;
309 338
310 rc = ngx_http_next_header_filter(r); 339 rc = ngx_http_next_header_filter(r);
311 340
312 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { 341 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
313 return rc; 342 return NGX_ERROR;
314 } 343 }
315 344
316 return ngx_http_next_body_filter(r, in); 345 rc = ngx_http_next_body_filter(r, in);
346
347 if (ctx->phase == NGX_HTTP_IMAGE_DONE) {
348 /* NGX_ERROR resets any pending data */
349 return (rc == NGX_OK) ? NGX_ERROR : rc;
350 }
351
352 return rc;
317 } 353 }
318 354
319 355
320 static ngx_uint_t 356 static ngx_uint_t
321 ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in) 357 ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)