Browse files

now we can completely erase any output headers (both custom and built…

…in ones).
  • Loading branch information...
1 parent 75b1bfa commit c68a095c477426288c242b2718d259138cedf83f @agentzh agentzh committed Jun 5, 2010
View
53 src/ddebug.h
@@ -2,12 +2,14 @@
#define DDEBUG_H
#include <ngx_core.h>
+#include <ngx_http.h>
+#include <nginx.h>
#if defined(DDEBUG) && (DDEBUG)
# if (NGX_HAVE_VARIADIC_MACROS)
-# define dd(...) fprintf(stderr, "headers_more *** "); \
+# define dd(...) fprintf(stderr, "headers-more *** %s: ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, " at %s line %d.\n", __FILE__, __LINE__)
@@ -18,22 +20,67 @@
#include <stdarg.h>
-static void dd(const char* fmt, ...) {
+static void dd(const char * fmt, ...) {
}
# endif
+# if DDEBUG > 1
+
+# define dd_enter() dd_enter_helper(r, __func__)
+
+# if defined(nginx_version) && nginx_version >= 8011
+# define dd_main_req_count r->main->count
+# else
+# define dd_main_req_count 0
+# endif
+
+static void
+dd_enter_helper(ngx_http_request_t *r, const char *func)
+{
+ ngx_http_posted_request_t *pr;
+
+ fprintf(stderr, "headers-more *** enter %s %.*s %.*s?%.*s c:%d m:%p r:%p ar:%p pr:%p",
+ func,
+ (int) r->method_name.len, r->method_name.data,
+ (int) r->uri.len, r->uri.data,
+ (int) r->args.len, r->args.data,
+ (int) dd_main_req_count, r->main,
+ r, r->connection->data, r->parent);
+
+ if (r->posted_requests) {
+ fprintf(stderr, " posted:");
+
+ for (pr = r->posted_requests; pr; pr = pr->next) {
+ fprintf(stderr, "%p,", pr);
+ }
+ }
+
+ fprintf(stderr, "\n");
+}
+
+# else
+
+# define dd_enter()
+
+# endif
+
#else
# if (NGX_HAVE_VARIADIC_MACROS)
# define dd(...)
+# define dd_enter()
+
# else
#include <stdarg.h>
-static void dd(const char* fmt, ...) {
+static void dd(const char * fmt, ...) {
+}
+
+static void dd_enter() {
}
# endif
View
51 src/ngx_http_headers_more_input_headers.c
@@ -147,12 +147,18 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
ngx_list_part_t *part;
ngx_uint_t i;
- dd("entered set_header (input)");
+
+ dd_enter();
part = &r->headers_in.headers.part;
h = part->elts;
+ dd("part %p, part next: %p, last %p", &r->headers_in.headers.part, r->headers_in.headers.part.next, &r->headers_in.headers.last);
+
+ dd("part nelts: %d", (int) part->nelts);
+
for (i = 0; /* void */; i++) {
+ dd("i: %d, part: %p", (int) i, part);
if (i >= part->nelts) {
if (part->next == NULL) {
@@ -177,6 +183,7 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
if (output_header) {
*output_header = &h[i];
+ dd("setting existing builtin input header");
}
return NGX_OK;
@@ -193,12 +200,31 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- h->hash = hv->hash;
+ dd("created new header for %.*s", (int) hv->key.len, hv->key.data);
+
+ if (value->len == 0) {
+ h->hash = 0;
+ } else {
+ h->hash = hv->hash;
+ }
+
h->key = hv->key;
h->value = *value;
+ h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
+ if (h->lowcase_key == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
+
if (output_header) {
*output_header = h;
+
+ while (r != r->main) {
+ r->parent->headers_in = r->headers_in;
+ r = r->parent;
+ }
}
return NGX_OK;
@@ -219,7 +245,13 @@ ngx_http_set_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_
old = NULL;
}
+ dd("old builtin ptr ptr: %p", old);
+ if (old) {
+ dd("old builtin ptr: %p", *old);
+ }
+
if (old == NULL || *old == NULL) {
+ dd("set normal header");
return ngx_http_set_header_helper(r, hv, value, old);
}
@@ -242,7 +274,7 @@ static ngx_int_t
ngx_http_set_host_header(ngx_http_request_t *r, ngx_http_headers_more_header_val_t *hv,
ngx_str_t *value)
{
- dd("server new value len: %d", value->len);
+ dd("server new value len: %d", (int) value->len);
r->headers_in.server = *value;
@@ -320,13 +352,14 @@ ngx_http_headers_more_check_type(ngx_http_request_t *r, ngx_array_t *types)
return 0;
}
- dd("headers_in->content_type: %s (len %d)",
- actual_type.data,
- actual_type.len);
+ dd("headers_in->content_type: %.*s",
+ (int) actual_type.len,
+ actual_type.data);
t = types->elts;
for (i = 0; i < types->nelts; i++) {
- dd("...comparing with type [%s] (len %d)", t[i].data, t[i].len);
+ dd("...comparing with type [%.*s]", (int) t[i].len, t[i].data);
+
if (actual_type.len == t[i].len
&& ngx_strncmp(actual_type.data,
t[i].data, t[i].len) == 0)
@@ -443,8 +476,8 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
}
dd("Found %d types, and %d headers",
- cmd->types->nelts,
- cmd->headers->nelts);
+ (int) cmd->types->nelts,
+ (int) cmd->headers->nelts);
if (cmd->headers->nelts == 0) {
ngx_pfree(cf->pool, cmd->headers);
View
53 src/ngx_http_headers_more_output_headers.c
@@ -163,7 +163,8 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
ngx_uint_t i;
ngx_flag_t matched = 0;
- dd("entered set_header");
+
+ dd_enter();
part = &r->headers_out.headers.part;
h = part->elts;
@@ -177,6 +178,7 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
h = part->elts;
i = 0;
}
+
if (
(!hv->wildcard && (h[i].key.len == hv->key.len
&& ngx_strncasecmp(h[i].key.data,
@@ -190,6 +192,9 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
)
{
if (value->len == 0) {
+ dd("clearing normal header for %.*s", (int) hv->key.len,
+ hv->key.data);
+
h[i].hash = 0;
}
@@ -199,12 +204,13 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
*output_header = &h[i];
}
if (!hv->wildcard){
- return NGX_OK;
+ return NGX_OK;
} else {
- matched = 1;
+ matched = 1;
}
}
}
+
if (matched){
return NGX_OK;
}
@@ -219,10 +225,23 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_headers_more_header_v
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- h->hash = hv->hash;
+ if (value->len == 0) {
+ h->hash = 0;
+ } else {
+ h->hash = hv->hash;
+ }
+
h->key = hv->key;
h->value = *value;
+ h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
+ if (h->lowcase_key == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
+
+
if (output_header) {
*output_header = h;
}
@@ -237,7 +256,8 @@ ngx_http_set_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_
{
ngx_table_elt_t *h, **old;
- dd("entered set_builtin_header");
+
+ dd_enter();
if (hv->offset) {
old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
@@ -253,8 +273,11 @@ ngx_http_set_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_
h = *old;
if (value->len == 0) {
+ dd("clearing the builtin header");
+
h->hash = 0;
h->value = *value;
+
return NGX_OK;
}
@@ -315,7 +338,10 @@ static ngx_int_t
ngx_http_clear_builtin_header(ngx_http_request_t *r, ngx_http_headers_more_header_val_t *hv,
ngx_str_t *value)
{
+ dd_enter();
+
value->len = 0;
+
return ngx_http_set_builtin_header(r, hv, value);
}
@@ -344,13 +370,16 @@ ngx_http_headers_more_check_type(ngx_http_request_t *r, ngx_array_t *types)
ngx_uint_t i;
ngx_str_t *t;
- dd("headers_out->content_type: %s (len %d)",
+ dd("headers_out->content_type: %.*s (len %d)",
+ (int) r->headers_out.content_type.len,
r->headers_out.content_type.data,
- r->headers_out.content_type.len);
+ (int) r->headers_out.content_type.len);
t = types->elts;
+
for (i = 0; i < types->nelts; i++) {
- dd("...comparing with type [%s] (len %d)", t[i].data, t[i].len);
+ dd("...comparing with type [%.*s]", (int) t[i].len, t[i].data);
+
if (r->headers_out.content_type.len == t[i].len
&& ngx_strncmp(r->headers_out.content_type.data,
t[i].data, t[i].len) == 0)
@@ -369,11 +398,11 @@ ngx_http_headers_more_check_status(ngx_http_request_t *r, ngx_array_t *statuses)
ngx_uint_t i;
ngx_uint_t *status;
- dd("headers_out.status = %d", r->headers_out.status);
+ dd("headers_out.status = %d", (int) r->headers_out.status);
status = statuses->elts;
for (i = 0; i < statuses->nelts; i++) {
- dd("...comparing with specified status %d", status[i]);
+ dd("...comparing with specified status %d", (int) status[i]);
if (r->headers_out.status == status[i]) {
return 1;
@@ -506,8 +535,8 @@ ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
}
dd("Found %d statuses, %d types, and %d headers",
- cmd->statuses->nelts, cmd->types->nelts,
- cmd->headers->nelts);
+ (int) cmd->statuses->nelts, (int) cmd->types->nelts,
+ (int) cmd->headers->nelts);
if (cmd->headers->nelts == 0) {
cmd->headers = NULL;
View
22 test/lib/Test/Nginx/Socket.pm
@@ -218,6 +218,13 @@ $parsed_req->{content}";
#warn "raw resonse: [$raw_resp]\n";
+ my $raw_headers = '';
+ if ($raw_resp =~ /(.*?)\r\n\r\n/s) {
+ #warn "\$1: $1";
+ $raw_headers = $1;
+ }
+ #warn "raw headers: $raw_headers\n";
+
my $res = HTTP::Response->parse($raw_resp);
my $enc = $res->header('Transfer-Encoding');
@@ -275,11 +282,18 @@ $parsed_req->{content}";
if (defined $block->response_headers) {
my $headers = parse_headers($block->response_headers);
while (my ($key, $val) = each %$headers) {
- my $expected_val = $res->header($key);
- if (!defined $expected_val) {
- $expected_val = '';
+ if (!defined $val) {
+ #warn "HIT";
+ unlike $raw_headers, qr/^\s*\Q$key\E\s*:/ms, "$name - header $key not present in the raw headers";
+ next;
+ }
+
+ my $actual_val = $res->header($key);
+ if (!defined $actual_val) {
+ $actual_val = '';
}
- is $expected_val, $val,
+
+ is $actual_val, $val,
"$name - header $key ok";
}
} elsif (defined $block->response_headers_like) {
View
10 test/lib/Test/Nginx/Util.pm
@@ -317,8 +317,14 @@ sub parse_headers ($) {
open my $in, '<', \$s;
while (<$in>) {
s/^\s+|\s+$//g;
- my ($key, $val) = split /\s*:\s*/, $_, 2;
- $headers{$key} = $val;
+ my $neg = ($_ =~ s/^!\s*//);
+ #warn "neg: $neg ($_)";
+ if ($neg) {
+ $headers{$_} = undef;
+ } else {
+ my ($key, $val) = split /\s*:\s*/, $_, 2;
+ $headers{$key} = $val;
+ }
}
close $in;
return \%headers;
View
4 test/t/bug.t
@@ -1,7 +1,7 @@
# vi:filetype=perl
use lib 'lib';
-use Test::Nginx::LWP; # 'no_plan';
+use Test::Nginx::Socket; # 'no_plan';
plan tests => 3;
@@ -18,6 +18,6 @@ __DATA__
--- request
GET /index.html
--- response_headers
-Last-Modified:
+! Last-Modified
--- response_body_like: It works!
View
36 test/t/builtin.t
@@ -1,7 +1,7 @@
# vi:filetype=perl
use lib 'lib';
-use Test::Nginx::LWP; # 'no_plan';
+use Test::Nginx::Socket; # 'no_plan';
plan tests => 57;
@@ -35,7 +35,7 @@ hi
--- request
GET /foo
--- response_headers
-Server:
+! Server
--- response_body
hi
@@ -83,7 +83,7 @@ Content-Type: text/css
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -100,7 +100,7 @@ Content-Type:
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -117,7 +117,7 @@ Content-Type:
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -134,7 +134,7 @@ Content-Type:
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -151,7 +151,7 @@ Content-Type:
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -168,7 +168,7 @@ Content-Type:
--- request
GET /foo
--- response_headers
-Content-Type:
+! Content-Type
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -184,8 +184,8 @@ Content-Type:
GET /len
--- response_headers
Content-Length: 2
---- response_body chomp
-he
+--- response_body
+hello
@@ -200,8 +200,8 @@ he
GET /len
--- response_headers
Content-Length: 4
---- response_body chomp
-hell
+--- response_body
+hello
@@ -215,7 +215,7 @@ hell
--- request
GET /len
--- response_headers
-Content-Length:
+! Content-Length
--- response_body
hello
@@ -231,7 +231,7 @@ hello
--- request
GET /len
--- response_headers
-Content-Length:
+! Content-Length
--- response_body
hello
@@ -247,7 +247,7 @@ hello
--- request
GET /len
--- response_headers
-Content-Type:
+! Content-Type
--- response_body
hello
@@ -263,7 +263,7 @@ hello
--- request
GET /len
--- response_headers
-Content-Type:
+! Content-Type
--- response_body
hello
@@ -296,7 +296,7 @@ hello
--- request
GET /len
--- response_headers
-Charset:
+! Charset
--- response_body
hello
@@ -313,7 +313,7 @@ hello
--- request
GET /len
--- response_headers
-Charset:
+! Charset
--- response_body
hello
View
39 test/t/input.t
@@ -1,7 +1,7 @@
# vi:filetype=perl
use lib 'lib';
-use Test::Nginx::LWP; # 'no_plan';
+use Test::Nginx::Socket; # 'no_plan';
plan tests => 44;
@@ -19,10 +19,10 @@ __DATA__
}
--- request
GET /foo
---- request_headers
+--- more_headers
X-Foo: blah
--- response_headers
-X-Foo:
+! X-Foo
--- response_body
blah
@@ -36,10 +36,10 @@ blah
}
--- request
GET /foo
---- request_headers
+--- more_headers
X-Foo: blah
--- response_headers
-X-Foo:
+! X-Foo
--- response_body
howdy
@@ -119,7 +119,7 @@ User-Agent:
}
--- request
GET /bar
---- request_headers
+--- more_headers
X-Foo: bar
--- response_body
Host: localhost
@@ -137,7 +137,7 @@ X-Foo:
--- request
POST /bar
hello
---- request_headers
+--- more_headers
--- response_body
Content-Length:
@@ -152,7 +152,7 @@ Content-Length:
--- request
POST /bar
hello
---- request_headers
+--- more_headers
--- response_body
Content-Length:
@@ -167,7 +167,7 @@ Content-Length:
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/plain
--- response_body
Content-Type: text/css
@@ -183,7 +183,7 @@ Content-Type: text/css
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/plain
--- response_body
Content-Type:
@@ -199,7 +199,7 @@ Content-Type:
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/plain
--- response_body
Content-Type:
@@ -215,7 +215,7 @@ Content-Type:
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/plain
--- response_body
yay
@@ -231,7 +231,7 @@ yay
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/css
--- response_body eval: "\n"
@@ -246,7 +246,7 @@ Content-Type: text/css
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/css
--- response_body
yay
@@ -262,7 +262,7 @@ yay
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/plain
--- response_body
yay
@@ -278,7 +278,7 @@ yay
--- request
POST /bar
hello
---- request_headers
+--- more_headers
Content-Type: text/html
--- response_body eval: "\n"
@@ -308,10 +308,10 @@ yay
}
--- request
GET /foo
---- request_headers
+--- more_headers
X-Foo: blah
--- response_headers
-X-Foo:
+! X-Foo
--- response_body
howdy
@@ -326,6 +326,7 @@ howdy
--- request
GET /foo
--- response_headers
-X-Foo:
+! X-Foo
--- response_body
empty_header:
+
View
38 test/t/sanity.t
@@ -1,7 +1,7 @@
# vi:filetype=perl
use lib 'lib';
-use Test::Nginx::LWP;
+use Test::Nginx::Socket;
plan tests => 107;
@@ -79,15 +79,15 @@ X-Bar: hi
=== TEST 5: set a header then clears it (500)
--- config
location /two {
- more_set_headers 'X-Foo: Blah'
+ more_set_headers 'X-Foo: Blah';
more_set_headers 'X-Foo:';
return 500;
}
--- request
GET /two
--- response_headers
-X-Foo:
-X-Bar:
+! X-Foo
+! X-Bar
--- response_body_like: 500 Internal Server Error
--- error_code: 500
@@ -104,7 +104,7 @@ X-Bar:
GET /bad
--- response_headers
X-Mine: Hiya
-X-Yours:
+! X-Yours
--- response_body_like: 500 Internal Server Error
--- error_code: 500
@@ -120,8 +120,8 @@ X-Yours:
--- request
GET /bad
--- response_headers
-X-Mine:
-X-Yours:
+! X-Mine
+! X-Yours
--- response_body
hello
--- error_code: 200
@@ -138,7 +138,7 @@ hello
--- request
GET /bad
--- response_headers
-X-Mine:
+! X-Mine
X-Yours: Blah
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -156,7 +156,7 @@ X-Yours: Blah
GET /bad
--- response_headers
X-Mine: Hiya
-X-Yours:
+! X-Yours
--- response_body_like: 503 Service
--- error_code: 503
@@ -189,7 +189,7 @@ X-Yours: Blah
--- request
GET /bad
--- response_headers
-X-Mine:
+! X-Mine
X-Yours: Blah
--- response_body_like: 413 Request Entity Too Large
--- error_code: 413
@@ -222,7 +222,7 @@ hi
--- request
GET /bad
--- response_headers
-X-CSS:
+! X-CSS
--- response_body
hi
@@ -238,7 +238,7 @@ hi
--- request
GET /bad
--- response_headers
-X-CSS:
+! X-CSS
--- response_body
hi
@@ -333,7 +333,7 @@ hi
--- request
GET /bad
--- response_headers
-X-status:
+! X-status
--- response_body
hi
@@ -395,7 +395,7 @@ X-status: howdy2
--- request
GET /bad
--- response_headers
-X-status:
+! X-status
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -428,7 +428,7 @@ hi
--- request
GET /bad
--- response_headers
-X-status:
+! X-status
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -446,7 +446,7 @@ X-status:
GET /bad
--- response_headers
X-status2: howdy3
-X-status:
+! X-status
--- response_body_like: 404 Not Found
--- error_code: 404
@@ -463,7 +463,7 @@ X-status:
--- request
GET /bad
--- response_headers
-X-status2:
+! X-status2
X-status: howdy2
--- response_body
yeah
@@ -520,8 +520,8 @@ X-status2: nope
--- request
GET /hello
--- response_headers
-X-Hidden-One:
-X-Hidden-Two:
+! X-Hidden-One
+! X-Hidden-Two
--- response_body
hi
View
37 test/t/subrequest.t
@@ -1,9 +1,9 @@
# vi:filetype=perl
use lib 'lib';
-use Test::Nginx::LWP; # 'no_plan';
+use Test::Nginx::Socket; # 'no_plan';
-plan tests => 3;
+plan tests => blocks() * 3;
no_diff;
@@ -29,10 +29,41 @@ __DATA__
}
--- request
GET /main
+--- more_headers
+User-Agent: my-sock
--- response_body
sub: dog
main: dog
--- response_headers
-Host:
+! Host
+--- skip_nginx: 3: < 0.7.46
+
+
+
+=== TEST 2: vars in input header directives
+--- config
+ location /main {
+ #more_set_input_headers 'User-Agent: cat';
+ echo_location /foo;
+ echo "main: $http_user_agent";
+ }
+ location /foo {
+ set $val 'dog';
+
+ more_set_input_headers 'User-Agent: $val';
+
+ proxy_pass http://127.0.0.1:$server_port/proxy;
+ #echo $http_user_agent;
+ }
+ location /proxy {
+ echo "sub: $http_user_agent";
+ }
+--- request
+ GET /main
+--- response_body
+sub: dog
+main: dog
+--- response_headers
+! Host
--- skip_nginx: 3: < 0.7.46

0 comments on commit c68a095

Please sign in to comment.