Skip to content

Commit 48e80d6

Browse files
committed
Handle content type header
1 parent eed01fc commit 48e80d6

File tree

1 file changed

+84
-36
lines changed

1 file changed

+84
-36
lines changed

src/ngx_http_redirectionio_module_filter.c

Lines changed: 84 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ static void ngx_http_redirectionio_response_headers_cleanup(void *response_heade
66

77
static 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+
913
ngx_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

Comments
 (0)