proxy input filter chain?

Maxim Dounin mdounin at mdounin.ru
Fri Mar 15 17:46:22 UTC 2013


Hello!

On Fri, Mar 15, 2013 at 09:59:57AM -0700, Dave Bailey wrote:

> Hi,
> 
> I would like to apply a filter to the request body as it is read from the
> client, but before it is sent upstream.  So in the various proxy module
> input filters, when the input ngx_buf_t are initialized and pushed onto the
> input buffer chain, I would like to pass them through my filter at that
> time, so that the input buffer chain contains the buffers that my filter
> generates from the original input buffers.  My filter might also (based on
> its input) choose to finalize the request with a status code 403 or similar
> (e.g. if the input is deemed to be malicious, etc) before the upstream
> connection is made.
> 
> My questions:
> 
> 1) Is anything like this currently being developed?
> 2) If not, could I try to provide a patch?

There is an experimental patch which introduces request body 
filters (attached).  It was written with chunked input support, 
but wasn't committed as there is no clear understanding it should 
work this way.

-- 
Maxim Dounin
http://nginx.org/en/donation.html
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1358156187 -14400
# Node ID 26a111efb3ba16b45a9688dbaf5823f9235e221f
# Parent  13c4c155f26f772b0bc1074a05298088d6499218
Request body: filters support (experimental).

diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -69,8 +69,9 @@ static ngx_int_t ngx_http_add_addrs6(ngx
 ngx_uint_t   ngx_http_max_module;
 
 
-ngx_int_t  (*ngx_http_top_header_filter) (ngx_http_request_t *r);
-ngx_int_t  (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
+ngx_http_output_body_filter_pt    ngx_http_top_body_filter;
+ngx_http_request_body_filter_pt   ngx_http_top_request_body_filter;
 
 
 ngx_str_t  ngx_http_html_default_types[] = {
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -166,6 +166,7 @@ extern ngx_str_t  ngx_http_html_default_
 
 extern ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
 extern ngx_http_output_body_filter_pt    ngx_http_top_body_filter;
+extern ngx_http_request_body_filter_pt   ngx_http_top_request_body_filter;
 
 
 #endif /* _NGX_HTTP_H_INCLUDED_ */
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -26,6 +26,7 @@ static ngx_int_t ngx_http_core_find_stat
     ngx_http_location_tree_node_t *node);
 
 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
+static ngx_int_t ngx_http_core_postconfiguration(ngx_conf_t *cf);
 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
@@ -792,7 +793,7 @@ static ngx_command_t  ngx_http_core_comm
 
 static ngx_http_module_t  ngx_http_core_module_ctx = {
     ngx_http_core_preconfiguration,        /* preconfiguration */
-    NULL,                                  /* postconfiguration */
+    ngx_http_core_postconfiguration,       /* postconfiguration */
 
     ngx_http_core_create_main_conf,        /* create main configuration */
     ngx_http_core_init_main_conf,          /* init main configuration */
@@ -3314,6 +3315,15 @@ ngx_http_core_preconfiguration(ngx_conf_
 }
 
 
+static ngx_int_t
+ngx_http_core_postconfiguration(ngx_conf_t *cf)
+{
+    ngx_http_top_request_body_filter = ngx_http_request_body_save_filter;
+
+    return NGX_OK;
+}
+
+
 static void *
 ngx_http_core_create_main_conf(ngx_conf_t *cf)
 {
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -506,10 +506,14 @@ ngx_http_cleanup_t *ngx_http_cleanup_add
 typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);
 typedef ngx_int_t (*ngx_http_output_body_filter_pt)
     (ngx_http_request_t *r, ngx_chain_t *chain);
+typedef ngx_int_t (*ngx_http_request_body_filter_pt)
+    (ngx_http_request_t *r, ngx_chain_t *chain);
 
 
 ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
 ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
+ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
+   ngx_chain_t *chain);
 
 
 ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -24,8 +24,6 @@ static ngx_int_t ngx_http_request_body_l
     ngx_chain_t *in);
 static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r,
     ngx_chain_t *in);
-static ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
-    ngx_chain_t *in);
 
 
 ngx_int_t
@@ -832,7 +830,7 @@ ngx_http_request_body_length_filter(ngx_
         ll = &tl->next;
     }
 
-    rc = ngx_http_request_body_save_filter(r, out);
+    rc = ngx_http_top_request_body_filter(r, out);
 
     ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
                             (ngx_buf_tag_t) &ngx_http_read_client_request_body);
@@ -984,7 +982,7 @@ ngx_http_request_body_chunked_filter(ngx
         }
     }
 
-    rc = ngx_http_request_body_save_filter(r, out);
+    rc = ngx_http_top_request_body_filter(r, out);
 
     ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
                             (ngx_buf_tag_t) &ngx_http_read_client_request_body);
@@ -993,7 +991,7 @@ ngx_http_request_body_chunked_filter(ngx
 }
 
 
-static ngx_int_t
+ngx_int_t
 ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
 {
 #if (NGX_DEBUG)


More information about the nginx-devel mailing list