@@ -6,6 +6,10 @@ static void ngx_http_redirectionio_response_headers_cleanup(void *response_heade
66
77static ngx_int_t ngx_http_redirectionio_create_filter_body (ngx_http_request_t * r );
88
9+ static ngx_int_t ngx_http_redirectionio_header_read (ngx_http_request_t * r , ngx_table_elt_t * header , struct REDIRECTIONIO_HeaderMap * * first );
10+
11+ static ngx_int_t ngx_http_redirectionio_header_content_type_read (ngx_http_request_t * r , struct REDIRECTIONIO_HeaderMap * * first );
12+
913ngx_int_t ngx_http_redirectionio_match_on_response_status_header_filter (ngx_http_request_t * r ) {
1014 ngx_http_redirectionio_ctx_t * ctx ;
1115 ngx_http_redirectionio_conf_t * conf ;
@@ -48,7 +52,7 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
4852 ngx_uint_t i ;
4953 ngx_table_elt_t * h ;
5054 ngx_list_part_t * part ;
51- struct REDIRECTIONIO_HeaderMap * first_header = NULL , * current_header = NULL ;
55+ struct REDIRECTIONIO_HeaderMap * header_map = NULL ;
5256 ngx_pool_cleanup_t * cln ;
5357
5458 conf = ngx_http_get_module_loc_conf (r , ngx_http_redirectionio_module );
@@ -73,14 +77,6 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
7377
7478 ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio start header filter" );
7579
76- // @TODO Handle specific headers
77- // - Server
78- // - Content Type / Charset
79- // - Content Length (too touchy ?)
80- // - Last modified
81- // - Location
82- // -
83-
8480 for (i = 0 ; /* void */ ; i ++ ) {
8581 if (i >= part -> nelts ) {
8682 if (part -> next == NULL ) {
@@ -97,26 +93,18 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
9793 continue ;
9894 }
9995
100- current_header = (struct REDIRECTIONIO_HeaderMap * )ngx_pcalloc (r -> pool , sizeof (struct REDIRECTIONIO_HeaderMap ));
101- current_header -> name = ngx_pcalloc (r -> pool , h [i ].key .len + 1 );
102- current_header -> value = ngx_pcalloc (r -> pool , h [i ].value .len + 1 );
103- current_header -> next = first_header ;
104-
105- ngx_memcpy ((char * )current_header -> name , h [i ].key .data , h [i ].key .len );
106- * ((char * )current_header -> name + h [i ].key .len ) = '\0' ;
107-
108- ngx_memcpy ((char * )current_header -> value , h [i ].value .data , h [i ].value .len );
109- * ((char * )current_header -> value + h [i ].value .len ) = '\0' ;
96+ ngx_http_redirectionio_header_read (r , & h [i ], & header_map );
11097
111- ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio add filter to send \"%s: %s\"" , current_header -> name , current_header -> value );
112-
113- first_header = current_header ;
98+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio add filter to send \"%s: %s\"" , header_map -> name , header_map -> value );
11499 }
115100
101+ // Copy specific headers
102+ ngx_http_redirectionio_header_content_type_read (r , & header_map );
103+
116104 ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio filtering on response status code %d" , r -> headers_out .status );
117- first_header = (struct REDIRECTIONIO_HeaderMap * )redirectionio_action_header_filter_filter (ctx -> action , first_header , r -> headers_out .status , conf -> show_rule_ids == NGX_HTTP_REDIRECTIONIO_ON );
105+ header_map = (struct REDIRECTIONIO_HeaderMap * )redirectionio_action_header_filter_filter (ctx -> action , header_map , r -> headers_out .status , conf -> show_rule_ids == NGX_HTTP_REDIRECTIONIO_ON );
118106
119- if (first_header == NULL ) {
107+ if (header_map == NULL ) {
120108 ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio no filter to add" );
121109
122110 return ngx_http_redirectionio_create_filter_body (r );
@@ -125,11 +113,11 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
125113 cln = ngx_pool_cleanup_add (r -> pool , 0 );
126114
127115 if (cln != NULL ) {
128- cln -> data = first_header ;
116+ cln -> data = header_map ;
129117 cln -> handler = ngx_http_redirectionio_response_headers_cleanup ;
130118 }
131119
132- ctx -> response_headers = first_header ;
120+ ctx -> response_headers = header_map ;
133121
134122 // Deactivate all old headers
135123 part = & r -> headers_out .headers .part ;
@@ -157,34 +145,41 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
157145 h [i ].value .len = 0 ;
158146 }
159147
160- current_header = first_header ;
148+ while (header_map != NULL ) {
149+ if (header_map -> name == NULL || header_map -> value == NULL ) {
150+ header_map = header_map -> next ;
151+
152+ continue ;
153+ }
154+
155+ // Handle specific headers
156+ if (ngx_strcasecmp ((u_char * )header_map -> name , (u_char * )"Content-Type" ) == 0 ) {
157+ header_map = header_map -> next ;
161158
162- while (first_header != NULL ) {
163- if (first_header -> name == NULL || first_header -> value == NULL ) {
164159 continue ;
165160 }
166161
167162 h = ngx_list_push (& r -> headers_out .headers );
168163
169164 if (h == NULL ) {
170- first_header = first_header -> next ;
165+ header_map = header_map -> next ;
171166
172167 continue ;
173168 }
174169
175170 h -> hash = 1 ;
176171
177- h -> key .len = strlen (first_header -> name );
172+ h -> key .len = strlen (header_map -> name );
178173 h -> key .data = ngx_pcalloc (r -> pool , h -> key .len );
179- ngx_memcpy (h -> key .data , first_header -> name , h -> key .len );
174+ ngx_memcpy (h -> key .data , header_map -> name , h -> key .len );
180175
181- h -> value .len = strlen (first_header -> value );
176+ h -> value .len = strlen (header_map -> value );
182177 h -> value .data = ngx_pcalloc (r -> pool , h -> value .len );
183- ngx_memcpy (h -> value .data , first_header -> value , h -> value .len );
178+ ngx_memcpy (h -> value .data , header_map -> value , h -> value .len );
184179
185- ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio add header to response \"%s: %s\"" , first_header -> name , first_header -> value );
180+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio add header to response \"%s: %s\"" , header_map -> name , header_map -> value );
186181
187- first_header = first_header -> next ;
182+ header_map = header_map -> next ;
188183 }
189184
190185 ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio header filter done" );
@@ -409,3 +404,56 @@ static void ngx_http_redirectionio_response_headers_cleanup(void *response_heade
409404 first_header = tmp_header ;
410405 }
411406}
407+
408+ static ngx_int_t ngx_http_redirectionio_header_read (ngx_http_request_t * r , ngx_table_elt_t * header , struct REDIRECTIONIO_HeaderMap * * first ) {
409+ struct REDIRECTIONIO_HeaderMap * new_header ;
410+
411+ new_header = (struct REDIRECTIONIO_HeaderMap * )ngx_pcalloc (r -> pool , sizeof (struct REDIRECTIONIO_HeaderMap ));
412+ new_header -> name = ngx_pcalloc (r -> pool , header -> key .len + 1 );
413+ new_header -> value = ngx_pcalloc (r -> pool , header -> value .len + 1 );
414+ new_header -> next = * first ;
415+
416+ ngx_memcpy ((char * )new_header -> name , header -> key .data , header -> key .len );
417+ * ((char * )new_header -> name + header -> key .len ) = '\0' ;
418+
419+ ngx_memcpy ((char * )new_header -> value , header -> value .data , header -> value .len );
420+ * ((char * )new_header -> value + header -> value .len ) = '\0' ;
421+
422+ * first = new_header ;
423+
424+ return NGX_OK ;
425+ }
426+
427+ static ngx_int_t ngx_http_redirectionio_header_content_type_read (ngx_http_request_t * r , struct REDIRECTIONIO_HeaderMap * * first ) {
428+ struct REDIRECTIONIO_HeaderMap * new_header ;
429+ ngx_uint_t len = 0 ;
430+
431+ if (r -> headers_out .content_type .len ) {
432+ len += r -> headers_out .content_type .len + 1 ;
433+
434+ if (r -> headers_out .content_type_len == r -> headers_out .content_type .len && r -> headers_out .charset .len ) {
435+ len += sizeof ("; charset=" ) - 1 + r -> headers_out .charset .len ;
436+ }
437+ }
438+
439+ if (len == 0 ) {
440+ return NGX_OK ;
441+ }
442+
443+ new_header = (struct REDIRECTIONIO_HeaderMap * )ngx_pcalloc (r -> pool , sizeof (struct REDIRECTIONIO_HeaderMap ));
444+ new_header -> name = "Content-Type" ;
445+ new_header -> value = ngx_pcalloc (r -> pool , len );
446+ new_header -> next = * first ;
447+
448+ ngx_memcpy ((char * )new_header -> value , r -> headers_out .content_type .data , r -> headers_out .content_type .len );
449+
450+ if (r -> headers_out .content_type_len == r -> headers_out .content_type .len && r -> headers_out .charset .len ) {
451+ ngx_memcpy ((char * )new_header -> value , "; charset=" , sizeof ("; charset=" ) - 1 );
452+ ngx_memcpy ((char * )new_header -> value , r -> headers_out .charset .data , r -> headers_out .charset .len );
453+ }
454+
455+ * ((char * )new_header -> value + len ) = '\0' ;
456+ * first = new_header ;
457+
458+ return NGX_OK ;
459+ }
0 commit comments