@@ -37,8 +37,11 @@ ngx_http_modsecurity_body_filter_init(void)
3737ngx_int_t 
3838ngx_http_modsecurity_body_filter (ngx_http_request_t  * r , ngx_chain_t  * in )
3939{
40-     ngx_chain_t  * chain  =  in ;
4140    ngx_http_modsecurity_ctx_t  * ctx  =  NULL ;
41+     ngx_chain_t  * chain  =  in ;
42+     ngx_int_t  ret ;
43+     ngx_pool_t  * old_pool ;
44+     ngx_int_t  is_request_processed  =  0 ;
4245#if  defined(MODSECURITY_SANITY_CHECKS ) &&  (MODSECURITY_SANITY_CHECKS )
4346    ngx_http_modsecurity_conf_t  * mcf ;
4447    ngx_list_part_t  * part  =  & r -> headers_out .headers .part ;
@@ -47,14 +50,19 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
4750#endif 
4851
4952    if  (in  ==  NULL ) {
53+         ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "MDS input chain is null" );
5054        return  ngx_http_next_body_filter (r , in );
5155    }
5256
57+     /* get context for request */ 
5358    ctx  =  ngx_http_get_module_ctx (r , ngx_http_modsecurity_module );
54- 
5559    dd ("body filter, recovering ctx: %p" , ctx );
5660
57-     if  (ctx  ==  NULL ) {
61+ 
62+     if  (ctx  ==  NULL  ||  r -> filter_finalize  ||  ctx -> response_body_filtered ) {
63+         if  (ctx  &&  ctx -> response_body_filtered ) {
64+             r -> filter_finalize  =  1 ;
65+         }
5866        return  ngx_http_next_body_filter (r , in );
5967    }
6068
@@ -140,47 +148,82 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
140148    }
141149#endif 
142150
143-     int  is_request_processed  =  0 ;
144-     for  (; chain  !=  NULL ; chain  =  chain -> next )
145-     {
146-         u_char  * data  =  chain -> buf -> pos ;
147-         int  ret ;
151+     for  (chain  =  in ; chain  !=  NULL ; chain  =  chain -> next ) {
148152
149-         msc_append_response_body (ctx -> modsec_transaction , data , chain -> buf -> last  -  data );
150-         ret  =  ngx_http_modsecurity_process_intervention (ctx -> modsec_transaction , r , 0 );
153+ 
154+         ngx_buf_t  * copy_buf ;
155+         ngx_chain_t *  copy_chain ;
156+         is_request_processed  =  chain -> buf -> last_buf ;
157+         u_char  * data  =  chain -> buf -> pos ;
158+         msc_append_response_body (ctx -> modsec_transaction , data ,
159+                 chain -> buf -> last  -  data );
160+         ret  =  ngx_http_modsecurity_process_intervention (ctx -> modsec_transaction ,
161+                 r , 0 );
151162        if  (ret  >  0 ) {
152163            return  ngx_http_filter_finalize_request (r ,
153164                & ngx_http_modsecurity_module , ret );
154165        }
155- 
156- /* XXX: chain->buf->last_buf || chain->buf->last_in_chain */ 
157-         is_request_processed  =  chain -> buf -> last_buf ;
158- 
159-         if  (is_request_processed ) {
160-             ngx_pool_t  * old_pool ;
161- 
162-             old_pool  =  ngx_http_modsecurity_pcre_malloc_init (r -> pool );
163-             msc_process_response_body (ctx -> modsec_transaction );
164-             ngx_http_modsecurity_pcre_malloc_done (old_pool );
165- 
166- /* XXX: I don't get how body from modsec being transferred to nginx's buffer.  If so - after adjusting of nginx's 
167-    XXX: body we can proceed to adjust body size (content-length).  see xslt_body_filter() for example */ 
168-             ret  =  ngx_http_modsecurity_process_intervention (ctx -> modsec_transaction , r , 0 );
169-             if  (ret  >  0 ) {
170-                 return  ret ;
166+         if  (!chain -> buf -> last_buf ){
167+             copy_chain  =  ngx_alloc_chain_link (r -> pool );
168+             if  (copy_chain  ==  NULL ) {
169+                 return  NGX_ERROR ;
171170            }
172-             else  if  (ret  <  0 ) {
173-                 return  ngx_http_filter_finalize_request (r ,
174-                     & ngx_http_modsecurity_module , NGX_HTTP_INTERNAL_SERVER_ERROR );
175- 
171+             copy_buf  =   ngx_calloc_buf (r -> pool );
172+             if  (copy_buf  ==  NULL ) {
173+                 return  NGX_ERROR ;
176174            }
175+             copy_buf -> pos  =  chain -> buf -> pos  ;
176+             copy_buf -> end  =  chain -> buf -> end ;
177+             copy_buf -> last  =  chain -> buf -> last ;
178+             copy_buf -> temporary  =  (chain -> buf -> temporary  ==  1 ) ? 1  : 0 ;
179+             copy_buf -> memory  =  (chain -> buf -> memory  ==  1 ) ? 1  : 0 ;
180+             copy_chain -> buf  =  copy_buf ;
181+             copy_chain -> buf -> last_buf  =  chain -> buf -> last_buf ;
182+             copy_chain -> next  =  NULL ;
183+             //chain->buf->pos = chain->buf->last; 
184+         }
185+         else  {
186+           copy_chain  =  chain ;
187+         }
188+         if  (ctx -> temp_chain  ==  NULL ) {
189+             ctx -> temp_chain  =  copy_chain ;
190+         } else  {
191+             if  (ctx -> current_chain  ==  NULL ) {
192+                 ctx -> temp_chain -> next  =  copy_chain ;
193+                 ctx -> temp_chain -> buf -> last_buf  =  0 ;
194+             } else  {
195+                 ctx -> current_chain -> next  =  copy_chain ;
196+                 ctx -> current_chain -> buf -> last_buf  =  0 ;
197+             }
198+             ctx -> current_chain  =  copy_chain ;
177199        }
178-     }
179-     if  (!is_request_processed )
180-     {
181-         dd ("buffer was not fully loaded! ctx: %p" , ctx );
182200    }
183201
184- /* XXX: xflt_filter() -- return NGX_OK here */ 
185-     return  ngx_http_next_body_filter (r , in );
202+     if  (is_request_processed ) {
203+         old_pool  =  ngx_http_modsecurity_pcre_malloc_init (r -> pool );
204+         msc_process_response_body (ctx -> modsec_transaction );
205+         ngx_http_modsecurity_pcre_malloc_done (old_pool );
206+         ret  =  ngx_http_modsecurity_process_intervention (ctx -> modsec_transaction , r , 0 );
207+         if  (ret  >  0 ) {
208+             if  (ret  <  NGX_HTTP_BAD_REQUEST  &&  ctx -> header_pt  !=  NULL ){
209+                 ctx -> header_pt (r );
210+                 }
211+             else  {
212+                   ctx -> response_body_filtered  =  1 ;
213+                   return  ngx_http_filter_finalize_request (r ,
214+                       & ngx_http_modsecurity_module 
215+                      , ret );
216+             }
217+         } else  if  (ret  <  0 ) {
218+             ctx -> response_body_filtered  =  1 ;
219+             return  ngx_http_filter_finalize_request (r ,
220+                     & ngx_http_modsecurity_module , NGX_HTTP_INTERNAL_SERVER_ERROR );
221+         }
222+         ctx -> response_body_filtered  =  1 ;
223+         if  (ctx -> header_pt  !=  NULL )
224+             ctx -> header_pt (r );
225+         return  ngx_http_next_body_filter (r , ctx -> temp_chain );
226+     } else  {
227+         return  NGX_AGAIN ;
228+     }
186229}
0 commit comments