@@ -6,6 +6,10 @@ static void ngx_http_redirectionio_response_headers_cleanup(void *response_heade
6
6
7
7
static ngx_int_t ngx_http_redirectionio_create_filter_body (ngx_http_request_t * r );
8
8
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
+
9
13
ngx_int_t ngx_http_redirectionio_match_on_response_status_header_filter (ngx_http_request_t * r ) {
10
14
ngx_http_redirectionio_ctx_t * ctx ;
11
15
ngx_http_redirectionio_conf_t * conf ;
@@ -48,7 +52,7 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
48
52
ngx_uint_t i ;
49
53
ngx_table_elt_t * h ;
50
54
ngx_list_part_t * part ;
51
- struct REDIRECTIONIO_HeaderMap * first_header = NULL , * current_header = NULL ;
55
+ struct REDIRECTIONIO_HeaderMap * header_map = NULL ;
52
56
ngx_pool_cleanup_t * cln ;
53
57
54
58
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) {
73
77
74
78
ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio start header filter" );
75
79
76
- // @TODO Handle specific headers
77
- // - Server
78
- // - Content Type / Charset
79
- // - Content Length (too touchy ?)
80
- // - Last modified
81
- // - Location
82
- // -
83
-
84
80
for (i = 0 ; /* void */ ; i ++ ) {
85
81
if (i >= part -> nelts ) {
86
82
if (part -> next == NULL ) {
@@ -97,26 +93,18 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
97
93
continue ;
98
94
}
99
95
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 );
110
97
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 );
114
99
}
115
100
101
+ // Copy specific headers
102
+ ngx_http_redirectionio_header_content_type_read (r , & header_map );
103
+
116
104
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 );
118
106
119
- if (first_header == NULL ) {
107
+ if (header_map == NULL ) {
120
108
ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "http redirectionio no filter to add" );
121
109
122
110
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) {
125
113
cln = ngx_pool_cleanup_add (r -> pool , 0 );
126
114
127
115
if (cln != NULL ) {
128
- cln -> data = first_header ;
116
+ cln -> data = header_map ;
129
117
cln -> handler = ngx_http_redirectionio_response_headers_cleanup ;
130
118
}
131
119
132
- ctx -> response_headers = first_header ;
120
+ ctx -> response_headers = header_map ;
133
121
134
122
// Deactivate all old headers
135
123
part = & r -> headers_out .headers .part ;
@@ -157,34 +145,41 @@ ngx_int_t ngx_http_redirectionio_headers_filter(ngx_http_request_t *r) {
157
145
h [i ].value .len = 0 ;
158
146
}
159
147
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 ;
161
158
162
- while (first_header != NULL ) {
163
- if (first_header -> name == NULL || first_header -> value == NULL ) {
164
159
continue ;
165
160
}
166
161
167
162
h = ngx_list_push (& r -> headers_out .headers );
168
163
169
164
if (h == NULL ) {
170
- first_header = first_header -> next ;
165
+ header_map = header_map -> next ;
171
166
172
167
continue ;
173
168
}
174
169
175
170
h -> hash = 1 ;
176
171
177
- h -> key .len = strlen (first_header -> name );
172
+ h -> key .len = strlen (header_map -> name );
178
173
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 );
180
175
181
- h -> value .len = strlen (first_header -> value );
176
+ h -> value .len = strlen (header_map -> value );
182
177
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 );
184
179
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 );
186
181
187
- first_header = first_header -> next ;
182
+ header_map = header_map -> next ;
188
183
}
189
184
190
185
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
409
404
first_header = tmp_header ;
410
405
}
411
406
}
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