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;
 }