Permalink
Browse files

removed input headers physically from the r->headers_in.headers list …

…because ngx_proxy does not honor h->hash.
  • Loading branch information...
1 parent 793158d commit aaf5fce53bad88543edd84195f041e8d58768ff7 @agentzh agentzh committed Jun 5, 2010
Showing with 254 additions and 8 deletions.
  1. +1 −0 .gitignore
  2. +26 −5 src/ngx_http_headers_more_input_headers.c
  3. +126 −2 src/ngx_http_headers_more_util.c
  4. +9 −0 src/ngx_http_headers_more_util.h
  5. +92 −1 test/t/input.t
View
@@ -34,3 +34,4 @@ src/module.c
src/module.h
src/util.c
src/util.h
+go
@@ -145,7 +145,8 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
{
ngx_table_elt_t *h;
ngx_list_part_t *part;
- ngx_uint_t i;
+ ngx_uint_t i;
+ ngx_uint_t rc;
dd_enter();
@@ -173,6 +174,17 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
{
if (value->len == 0) {
h[i].hash = 0;
+
+ rc = ngx_http_headers_more_rm_header_helper(
+ &r->headers_in.headers, part, i);
+
+ if (rc == NGX_OK) {
+ if (output_header) {
+ *output_header = NULL;
+ }
+
+ return NGX_OK;
+ }
}
h[i].value = *value;
@@ -186,7 +198,7 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
}
}
- if (value->len == 0 || hv->replace){
+ if (value->len == 0 || hv->replace) {
return NGX_OK;
}
@@ -230,7 +242,8 @@ static ngx_int_t
ngx_http_set_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_val_t *hv,
ngx_str_t *value)
{
- ngx_table_elt_t *h, **old;
+ ngx_table_elt_t *h, **old;
+ ngx_int_t rc;
dd("entered set_builtin_header (input)");
@@ -256,11 +269,19 @@ ngx_http_set_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_
if (value->len == 0) {
h->hash = 0;
h->value = *value;
- return NGX_OK;
+
+ rc = ngx_http_headers_more_rm_header(&r->headers_in.headers, h);
+
+ dd("rm header: %d", (int) rc);
+
+ if (rc == NGX_OK) {
+ *old = NULL;
+ }
+
+ return rc;
}
h->hash = hv->hash;
- h->key = hv->key;
h->value = *value;
return NGX_OK;
@@ -164,7 +164,7 @@ ngx_http_headers_more_parse_statuses(ngx_log_t *log, ngx_str_t *cmd_name,
}
if (isspace(*p)) {
- dd("Parsed status %d", *s);
+ dd("Parsed status %d", (int) *s);
s = NULL;
continue;
@@ -184,7 +184,7 @@ ngx_http_headers_more_parse_statuses(ngx_log_t *log, ngx_str_t *cmd_name,
}
if (s) {
- dd("Parsed status %d", *s);
+ dd("Parsed status %d", (int) *s);
}
return NGX_OK;
@@ -228,3 +228,127 @@ ngx_http_headers_more_parse_types(ngx_log_t *log, ngx_str_t *cmd_name,
return NGX_OK;
}
+ngx_int_t
+ngx_http_headers_more_rm_header(ngx_list_t *l, ngx_table_elt_t *h)
+{
+ ngx_uint_t i;
+ ngx_list_part_t *part;
+ ngx_table_elt_t *data;
+
+ part = &l->part;
+ data = part->elts;
+
+ for (i = 0; /* void */; i++) {
+ dd("i: %d, part: %p", (int) i, part);
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ h = part->elts;
+ i = 0;
+ }
+
+ if (&data[i] == h) {
+ dd("found header");
+
+ return ngx_http_headers_more_rm_header_helper(l, part, i);
+ }
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_http_headers_more_rm_header_helper(ngx_list_t *l, ngx_list_part_t *cur,
+ ngx_uint_t i)
+{
+ ngx_table_elt_t *data;
+ ngx_list_part_t *new, *part;
+
+ dd("list rm item: part %p, i %d, nalloc %d", cur, (int) i,
+ (int) l->nalloc);
+
+ data = cur->elts;
+
+ dd("cur: nelts %d, nalloc %d", (int) cur->nelts,
+ (int) l->nalloc);
+
+ if (i == 0) {
+ cur->elts = (char *) cur->elts + l->size;
+ cur->nelts--;
+
+ if (cur == l->last) {
+ if (l->nalloc > 1) {
+ l->nalloc--;
+ return NGX_OK;
+ }
+
+ /* l->nalloc == 1 */
+
+ part = &l->part;
+ while (part->next != cur) {
+ if (part->next == NULL) {
+ return NGX_ERROR;
+ }
+ part = part->next;
+ }
+
+ part->next = NULL;
+ l->last = part;
+
+ return NGX_OK;
+ }
+
+ if (cur->nelts == 0) {
+ part = &l->part;
+ while (part->next != cur) {
+ if (part->next == NULL) {
+ return NGX_ERROR;
+ }
+ part = part->next;
+ }
+
+ part->next = cur->next;
+
+ return NGX_OK;
+ }
+
+ return NGX_OK;
+ }
+
+ if (i == cur->nelts - 1) {
+ cur->nelts--;
+
+ if (cur == l->last) {
+ l->nalloc--;
+ }
+
+ return NGX_OK;
+ }
+
+ new = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
+ if (new == NULL) {
+ return NGX_ERROR;
+ }
+
+ new->elts = &data[i + 1];
+ new->nelts = cur->nelts - i - 1;
+ new->next = cur->next;
+
+ l->nalloc = new->nelts;
+
+ cur->nelts = i;
+ cur->next = new;
+ if (cur == l->last) {
+ l->last = new;
+ }
+
+ cur = new;
+
+ return NGX_OK;
+}
+
@@ -1,8 +1,10 @@
#ifndef NGX_HTTP_HEADERS_MORE_UTIL_H
#define NGX_HTTP_HEADERS_MORE_UTIL_H
+
#include "ngx_http_headers_more_filter_module.h"
+
ngx_int_t
ngx_http_headers_more_parse_header(ngx_conf_t *cf, ngx_str_t *cmd_name,
ngx_str_t *raw_header, ngx_array_t *headers,
@@ -15,5 +17,12 @@ ngx_int_t ngx_http_headers_more_parse_statuses(ngx_log_t *log,
ngx_int_t ngx_http_headers_more_parse_types(ngx_log_t *log,
ngx_str_t *cmd_name, ngx_str_t *value, ngx_array_t *types);
+ngx_int_t ngx_http_headers_more_rm_header_helper(ngx_list_t *l,
+ ngx_list_part_t *cur, ngx_uint_t i);
+
+ngx_int_t ngx_http_headers_more_rm_header(ngx_list_t *l,
+ ngx_table_elt_t *h);
+
+
#endif /* NGX_HTTP_HEADERS_MORE_UTIL_H */
View
@@ -3,8 +3,9 @@
use lib 'lib';
use Test::Nginx::Socket; # 'no_plan';
-plan tests => 44;
+plan tests => 50;
+no_long_string();
#no_diff;
run_tests();
@@ -330,3 +331,93 @@ howdy
--- response_body
empty_header:
+
+
+=== TEST 21: clear input headers
+--- config
+ location /foo {
+ set $val 'dog';
+
+ more_clear_input_headers 'User-Agent';
+
+ proxy_pass http://127.0.0.1:$server_port/proxy;
+ }
+ location /proxy {
+ echo -n $echo_client_request_headers;
+ }
+--- request
+ GET /foo
+--- more_headers
+User-Agent: my-sock
+--- response_body eval
+"GET /proxy HTTP/1.0\r
+Host: 127.0.0.1:1984\r
+Connection: close\r
+"
+--- skip_nginx: 3: < 0.7.46
+
+
+
+=== TEST 22: clear input headers
+--- config
+ location /foo {
+ more_clear_input_headers 'User-Agent';
+
+ proxy_pass http://127.0.0.1:$server_port/proxy;
+ }
+ location /proxy {
+ echo -n $echo_client_request_headers;
+ }
+--- request
+ GET /foo
+--- response_body eval
+"GET /proxy HTTP/1.0\r
+Host: 127.0.0.1:1984\r
+Connection: close\r
+"
+--- skip_nginx: 3: < 0.7.46
+
+
+=== TEST 22: clear input headers
+--- config
+ location /foo {
+ more_clear_input_headers 'X-Foo19';
+ more_clear_input_headers 'X-Foo20';
+ more_clear_input_headers 'X-Foo21';
+
+ proxy_pass http://127.0.0.1:$server_port/proxy;
+ }
+ location /proxy {
+ echo -n $echo_client_request_headers;
+ }
+--- request
+ GET /foo
+--- more_headers eval
+my $s;
+for my $i (3..21) {
+ $s .= "X-Foo$i: $i\n";
+}
+$s;
+--- response_body eval
+"GET /proxy HTTP/1.0\r
+Host: 127.0.0.1:1984\r
+Connection: close\r
+X-Foo3: 3\r
+X-Foo4: 4\r
+X-Foo5: 5\r
+X-Foo6: 6\r
+X-Foo7: 7\r
+X-Foo8: 8\r
+X-Foo9: 9\r
+X-Foo10: 10\r
+X-Foo11: 11\r
+X-Foo12: 12\r
+X-Foo13: 13\r
+X-Foo14: 14\r
+X-Foo15: 15\r
+X-Foo16: 16\r
+X-Foo17: 17\r
+X-Foo18: 18\r
+"
+--- skip_nginx: 3: < 0.7.46
+

0 comments on commit aaf5fce

Please sign in to comment.