blob: 9c5da23e8c6b801f83d69a2548d40cc4661b85cb [file] [log] [blame] [raw]
# vi:filetype=
use lib 'lib';
use Test::Nginx::Socket; # 'no_plan';
repeat_each(2);
plan tests => repeat_each() * 105;
no_long_string();
#no_diff;
run_tests();
__DATA__
=== TEST 1: set request header at client side
--- config
location /foo {
#more_set_input_headers 'X-Foo: howdy';
echo $http_x_foo;
}
--- request
GET /foo
--- more_headers
X-Foo: blah
--- response_headers
! X-Foo
--- response_body
blah
=== TEST 2: set request header at client side and rewrite it
--- config
location /foo {
more_set_input_headers 'X-Foo: howdy';
echo $http_x_foo;
}
--- request
GET /foo
--- more_headers
X-Foo: blah
--- response_headers
! X-Foo
--- response_body
howdy
=== TEST 3: rewrite content length
--- config
location /bar {
more_set_input_headers 'Content-Length: 2048';
echo_read_request_body;
echo_request_body;
}
--- request eval
"POST /bar\n" .
"a" x 4096
--- response_body eval
"a" x 2048
--- timeout: 15
=== TEST 4: try to rewrite content length using the rewrite module
Thisshould not take effect ;)
--- config
location /bar {
set $http_content_length 2048;
echo_read_request_body;
echo_request_body;
}
--- request eval
"POST /bar\n" .
"a" x 4096
--- response_body eval
"a" x 4096
=== TEST 5: rewrite host and user-agent
--- config
location /bar {
more_set_input_headers 'Host: foo' 'User-Agent: blah';
echo "Host: $host";
echo "User-Agent: $http_user_agent";
}
--- request
GET /bar
--- response_body
Host: foo
User-Agent: blah
=== TEST 6: clear host and user-agent
$host always has a default value and cannot be really cleared.
--- config
location /bar {
more_clear_input_headers 'Host: foo' 'User-Agent: blah';
echo "Host: $host";
echo "Host (2): $http_host";
echo "User-Agent: $http_user_agent";
}
--- request
GET /bar
--- response_body
Host: localhost
Host (2):
User-Agent:
=== TEST 7: clear host and user-agent (the other way)
--- config
location /bar {
more_set_input_headers 'Host:' 'User-Agent:' 'X-Foo:';
echo "Host: $host";
echo "User-Agent: $http_user_agent";
echo "X-Foo: $http_x_foo";
}
--- request
GET /bar
--- more_headers
X-Foo: bar
--- response_body
Host: localhost
User-Agent:
X-Foo:
=== TEST 8: clear content-length
--- config
location /bar {
more_set_input_headers 'Content-Length: ';
echo "Content-Length: $http_content_length";
}
--- request
POST /bar
hello
--- more_headers
--- response_body
Content-Length:
=== TEST 9: clear content-length (the other way)
--- config
location /bar {
more_clear_input_headers 'Content-Length: ';
echo "Content-Length: $http_content_length";
}
--- request
POST /bar
hello
--- more_headers
--- response_body
Content-Length:
=== TEST 10: rewrite type
--- config
location /bar {
more_set_input_headers 'Content-Type: text/css';
echo "Content-Type: $content_type";
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/plain
--- response_body
Content-Type: text/css
=== TEST 11: clear type
--- config
location /bar {
more_set_input_headers 'Content-Type:';
echo "Content-Type: $content_type";
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/plain
--- response_body
Content-Type:
=== TEST 12: clear type (the other way)
--- config
location /bar {
more_clear_input_headers 'Content-Type:foo';
echo "Content-Type: $content_type";
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/plain
--- response_body
Content-Type:
=== TEST 13: add type constraints
--- config
location /bar {
more_set_input_headers -t 'text/plain' 'X-Blah:yay';
echo $http_x_blah;
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/plain
--- response_body
yay
=== TEST 14: add type constraints (not matched)
--- config
location /bar {
more_set_input_headers -t 'text/plain' 'X-Blah:yay';
echo $http_x_blah;
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/css
--- response_body eval: "\n"
=== TEST 15: add type constraints (OR'd)
--- config
location /bar {
more_set_input_headers -t 'text/plain text/css' 'X-Blah:yay';
echo $http_x_blah;
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/css
--- response_body
yay
=== TEST 16: add type constraints (OR'd)
--- config
location /bar {
more_set_input_headers -t 'text/plain text/css' 'X-Blah:yay';
echo $http_x_blah;
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/plain
--- response_body
yay
=== TEST 17: add type constraints (OR'd) (not matched)
--- config
location /bar {
more_set_input_headers -t 'text/plain text/css' 'X-Blah:yay';
echo $http_x_blah;
}
--- request
POST /bar
hello
--- more_headers
Content-Type: text/html
--- response_body eval: "\n"
=== TEST 18: mix input and output cmds
--- config
location /bar {
more_set_input_headers 'X-Blah:yay';
more_set_headers 'X-Blah:hiya';
echo $http_x_blah;
}
--- request
GET /bar
--- response_headers
X-Blah: hiya
--- response
yay
=== TEST 19: set request header at client side and replace
--- config
location /foo {
more_set_input_headers -r 'X-Foo: howdy';
echo $http_x_foo;
}
--- request
GET /foo
--- more_headers
X-Foo: blah
--- response_headers
! X-Foo
--- response_body
howdy
=== TEST 20: do no set request header at client, so no replace with -r option
--- config
location /foo {
more_set_input_headers -r 'X-Foo: howdy';
echo "empty_header:" $http_x_foo;
}
--- request
GET /foo
--- response_headers
! X-Foo
--- 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:\$ServerPort\r
Connection: close\r
\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:\$ServerPort\r
Connection: close\r
\r
"
--- skip_nginx: 3: < 0.7.46
=== TEST 23: 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:\$ServerPort\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
\r
"
--- skip_nginx: 3: < 0.7.46
=== TEST 24: Accept-Encoding
--- config
location /bar {
default_type 'text/plain';
more_set_input_headers 'Accept-Encoding: gzip';
gzip on;
gzip_min_length 1;
gzip_buffers 4 8k;
gzip_types text/plain;
}
--- user_files
">>> bar
" . ("hello" x 512)
--- request
GET /bar
--- response_headers
Content-Encoding: gzip
--- response_body_like: .
=== TEST 25: rewrite + set request header
--- config
location /t {
rewrite ^ /foo last;
}
location /foo {
more_set_input_headers 'X-Foo: howdy';
proxy_pass http://127.0.0.1:$server_port/echo;
}
location /echo {
echo "X-Foo: $http_x_foo";
}
--- request
GET /foo
--- response_headers
! X-Foo
--- response_body
X-Foo: howdy
=== TEST 26: clear_header should clear all the instances of the user custom header
--- config
location = /t {
more_clear_input_headers Foo;
proxy_pass http://127.0.0.1:$server_port/echo;
}
location = /echo {
echo "Foo: [$http_foo]";
echo "Test-Header: [$http_test_header]";
}
--- request
GET /t
--- more_headers
Foo: foo
Foo: bah
Test-Header: 1
--- response_body
Foo: []
Test-Header: [1]
=== TEST 27: clear_header should clear all the instances of the builtin header
--- config
location = /t {
more_clear_input_headers Content-Type;
proxy_pass http://127.0.0.1:$server_port/echo;
}
location = /echo {
echo "Content-Type: [$http_content_type]";
echo "Test-Header: [$http_test_header]";
#echo $echo_client_request_headers;
}
--- request
GET /t
--- more_headers
Content-Type: foo
Content-Type: bah
Test-Header: 1
--- response_body
Content-Type: []
Test-Header: [1]
=== TEST 28: Converting POST to GET - clearing headers (bug found by Matthieu Tourne, 411 error page)
--- config
location /t {
more_clear_input_headers Content-Type;
more_clear_input_headers Content-Length;
#proxy_pass http://127.0.0.1:8888;
proxy_pass http://127.0.0.1:$server_port/back;
}
location /back {
echo $echo_client_request_headers;
}
--- request
POST /t
hello world
--- more_headers
Content-Type: application/ocsp-request
Test-Header: 1
--- response_body_like eval
qr/Connection: close\r
Test-Header: 1\r
\r
$/
--- no_error_log
[error]
=== TEST 29: clear_header() does not duplicate subsequent headers (old bug)
--- config
location = /t {
more_clear_input_headers Foo;
proxy_pass http://127.0.0.1:$server_port/echo;
}
location = /echo {
echo $echo_client_request_headers;
}
--- request
GET /t
--- more_headers
Bah: bah
Foo: foo
Test-Header: 1
Foo1: foo1
Foo2: foo2
Foo3: foo3
Foo4: foo4
Foo5: foo5
Foo6: foo6
Foo7: foo7
Foo8: foo8
Foo9: foo9
Foo10: foo10
Foo11: foo11
Foo12: foo12
Foo13: foo13
Foo14: foo14
Foo15: foo15
Foo16: foo16
Foo17: foo17
Foo18: foo18
Foo19: foo19
Foo20: foo20
Foo21: foo21
Foo22: foo22
--- response_body_like eval
qr/Bah: bah\r
Test-Header: 1\r
Foo1: foo1\r
Foo2: foo2\r
Foo3: foo3\r
Foo4: foo4\r
Foo5: foo5\r
Foo6: foo6\r
Foo7: foo7\r
Foo8: foo8\r
Foo9: foo9\r
Foo10: foo10\r
Foo11: foo11\r
Foo12: foo12\r
Foo13: foo13\r
Foo14: foo14\r
Foo15: foo15\r
Foo16: foo16\r
Foo17: foo17\r
Foo18: foo18\r
Foo19: foo19\r
Foo20: foo20\r
Foo21: foo21\r
Foo22: foo22\r
/
=== TEST 30: clear input header (just more than 20 headers)
--- config
location = /t {
more_clear_input_headers "R";
proxy_pass http://127.0.0.1:$server_port/back;
proxy_set_header Host foo;
#proxy_pass http://127.0.0.1:1234/back;
}
location = /back {
echo -n $echo_client_request_headers;
}
--- request
GET /t
--- more_headers eval
my $s = "User-Agent: curl\n";
for my $i ('a' .. 'r') {
$s .= uc($i) . ": " . "$i\n"
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
A: a\r
B: b\r
C: c\r
D: d\r
E: e\r
F: f\r
G: g\r
H: h\r
I: i\r
J: j\r
K: k\r
L: l\r
M: m\r
N: n\r
O: o\r
P: p\r
Q: q\r
\r
"
=== TEST 31: clear input header (just more than 20 headers, and add more)
--- config
location = /t {
more_clear_input_headers R;
more_set_input_headers "foo-1: 1" "foo-2: 2" "foo-3: 3" "foo-4: 4"
"foo-5: 5" "foo-6: 6" "foo-7: 7" "foo-8: 8" "foo-9: 9"
"foo-10: 10" "foo-11: 11" "foo-12: 12" "foo-13: 13"
"foo-14: 14" "foo-15: 15" "foo-16: 16" "foo-17: 17" "foo-18: 18"
"foo-19: 19" "foo-20: 20" "foo-21: 21";
proxy_pass http://127.0.0.1:$server_port/back;
proxy_set_header Host foo;
#proxy_pass http://127.0.0.1:1234/back;
}
location = /back {
echo -n $echo_client_request_headers;
}
--- request
GET /t
--- more_headers eval
my $s = "User-Agent: curl\n";
for my $i ('a' .. 'r') {
$s .= uc($i) . ": " . "$i\n"
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
A: a\r
B: b\r
C: c\r
D: d\r
E: e\r
F: f\r
G: g\r
H: h\r
I: i\r
J: j\r
K: k\r
L: l\r
M: m\r
N: n\r
O: o\r
P: p\r
Q: q\r
foo-1: 1\r
foo-2: 2\r
foo-3: 3\r
foo-4: 4\r
foo-5: 5\r
foo-6: 6\r
foo-7: 7\r
foo-8: 8\r
foo-9: 9\r
foo-10: 10\r
foo-11: 11\r
foo-12: 12\r
foo-13: 13\r
foo-14: 14\r
foo-15: 15\r
foo-16: 16\r
foo-17: 17\r
foo-18: 18\r
foo-19: 19\r
foo-20: 20\r
foo-21: 21\r
\r
"
=== TEST 32: clear input header (just more than 21 headers)
--- config
location = /t {
more_clear_input_headers R Q;
proxy_pass http://127.0.0.1:$server_port/back;
proxy_set_header Host foo;
#proxy_pass http://127.0.0.1:1234/back;
}
location = /back {
echo -n $echo_client_request_headers;
}
--- request
GET /t
--- more_headers eval
my $s = "User-Agent: curl\nBah: bah\n";
for my $i ('a' .. 'r') {
$s .= uc($i) . ": " . "$i\n"
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
Bah: bah\r
A: a\r
B: b\r
C: c\r
D: d\r
E: e\r
F: f\r
G: g\r
H: h\r
I: i\r
J: j\r
K: k\r
L: l\r
M: m\r
N: n\r
O: o\r
P: p\r
\r
"
=== TEST 33: clear input header (just more than 21 headers)
--- config
location = /t {
more_clear_input_headers R Q;
more_set_input_headers "foo-1: 1" "foo-2: 2" "foo-3: 3" "foo-4: 4"
"foo-5: 5" "foo-6: 6" "foo-7: 7" "foo-8: 8" "foo-9: 9"
"foo-10: 10" "foo-11: 11" "foo-12: 12" "foo-13: 13"
"foo-14: 14" "foo-15: 15" "foo-16: 16" "foo-17: 17" "foo-18: 18"
"foo-19: 19" "foo-20: 20" "foo-21: 21";
proxy_pass http://127.0.0.1:$server_port/back;
proxy_set_header Host foo;
#proxy_pass http://127.0.0.1:1234/back;
}
location = /back {
echo -n $echo_client_request_headers;
}
--- request
GET /t
--- more_headers eval
my $s = "User-Agent: curl\nBah: bah\n";
for my $i ('a' .. 'r') {
$s .= uc($i) . ": " . "$i\n"
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
Bah: bah\r
A: a\r
B: b\r
C: c\r
D: d\r
E: e\r
F: f\r
G: g\r
H: h\r
I: i\r
J: j\r
K: k\r
L: l\r
M: m\r
N: n\r
O: o\r
P: p\r
foo-1: 1\r
foo-2: 2\r
foo-3: 3\r
foo-4: 4\r
foo-5: 5\r
foo-6: 6\r
foo-7: 7\r
foo-8: 8\r
foo-9: 9\r
foo-10: 10\r
foo-11: 11\r
foo-12: 12\r
foo-13: 13\r
foo-14: 14\r
foo-15: 15\r
foo-16: 16\r
foo-17: 17\r
foo-18: 18\r
foo-19: 19\r
foo-20: 20\r
foo-21: 21\r
\r
"
=== TEST 34: clear X-Real-IP
--- config
location /t {
more_clear_input_headers X-Real-IP;
echo "X-Real-IP: $http_x_real_ip";
}
--- request
GET /t
--- more_headers
X-Real-IP: 8.8.8.8
--- stap
F(ngx_http_headers_more_exec_input_cmd) {
if (@defined($r->headers_in->x_real_ip) && $r->headers_in->x_real_ip) {
printf("rewrite: x-real-ip: %s\n",
user_string_n($r->headers_in->x_real_ip->value->data,
$r->headers_in->x_real_ip->value->len))
} else {
println("rewrite: no x-real-ip")
}
}
F(ngx_http_core_content_phase) {
if (@defined($r->headers_in->x_real_ip) && $r->headers_in->x_real_ip) {
printf("content: x-real-ip: %s\n",
user_string_n($r->headers_in->x_real_ip->value->data,
$r->headers_in->x_real_ip->value->len))
} else {
println("content: no x-real-ip")
}
}
--- stap_out
rewrite: x-real-ip: 8.8.8.8
content: no x-real-ip
--- response_body
X-Real-IP:
--- no_error_log
[error]
=== TEST 35: set custom X-Real-IP
--- config
location /t {
more_set_input_headers "X-Real-IP: 8.8.4.4";
echo "X-Real-IP: $http_x_real_ip";
}
--- request
GET /t
--- stap
F(ngx_http_headers_more_exec_input_cmd) {
if (@defined($r->headers_in->x_real_ip) && $r->headers_in->x_real_ip) {
printf("rewrite: x-real-ip: %s\n",
user_string_n($r->headers_in->x_real_ip->value->data,
$r->headers_in->x_real_ip->value->len))
} else {
println("rewrite: no x-real-ip")
}
}
F(ngx_http_core_content_phase) {
if (@defined($r->headers_in->x_real_ip) && $r->headers_in->x_real_ip) {
printf("content: x-real-ip: %s\n",
user_string_n($r->headers_in->x_real_ip->value->data,
$r->headers_in->x_real_ip->value->len))
} else {
println("content: no x-real-ip")
}
}
--- stap_out
rewrite: no x-real-ip
content: x-real-ip: 8.8.4.4
--- response_body
X-Real-IP: 8.8.4.4
--- no_error_log
[error]
=== TEST 36: clear Via
--- config
location /t {
more_clear_input_headers Via;
echo "Via: $http_via";
}
--- request
GET /t
--- more_headers
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
--- stap
F(ngx_http_headers_more_exec_input_cmd) {
if (@defined($r->headers_in->via) && $r->headers_in->via) {
printf("rewrite: via: %s\n",
user_string_n($r->headers_in->via->value->data,
$r->headers_in->via->value->len))
} else {
println("rewrite: no via")
}
}
F(ngx_http_core_content_phase) {
if (@defined($r->headers_in->via) && $r->headers_in->via) {
printf("content: via: %s\n",
user_string_n($r->headers_in->via->value->data,
$r->headers_in->via->value->len))
} else {
println("content: no via")
}
}
--- stap_out
rewrite: via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
content: no via
--- response_body
Via:
--- no_error_log
[error]
=== TEST 37: set custom Via
--- config
location /t {
more_set_input_headers "Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)";
echo "Via: $http_via";
}
--- request
GET /t
--- stap
F(ngx_http_headers_more_exec_input_cmd) {
if (@defined($r->headers_in->via) && $r->headers_in->via) {
printf("rewrite: via: %s\n",
user_string_n($r->headers_in->via->value->data,
$r->headers_in->via->value->len))
} else {
println("rewrite: no via")
}
}
F(ngx_http_core_content_phase) {
if (@defined($r->headers_in->via) && $r->headers_in->via) {
printf("content: via: %s\n",
user_string_n($r->headers_in->via->value->data,
$r->headers_in->via->value->len))
} else {
println("content: no via")
}
}
--- stap_out
rewrite: no via
content: via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
--- response_body
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
--- no_error_log
[error]
=== TEST 38: HTTP 0.9 (set)
--- config
location /foo {
more_set_input_headers 'X-Foo: howdy';
echo "x-foo: $http_x_foo";
}
--- raw_request eval
"GET /foo\r\n"
--- response_headers
! X-Foo
--- response_body
x-foo:
--- http09
=== TEST 39: HTTP 0.9 (clear)
--- config
location /foo {
more_clear_input_headers 'X-Foo';
echo "x-foo: $http_x_foo";
}
--- raw_request eval
"GET /foo\r\n"
--- response_headers
! X-Foo
--- response_body
x-foo:
--- http09
=== TEST 40: Host header with port and $host
--- config
location /bar {
more_set_input_headers 'Host: agentzh.org:1984';
echo "host var: $host";
echo "http_host var: $http_host";
}
--- request
GET /bar
--- response_body
host var: agentzh.org
http_host var: agentzh.org:1984
=== TEST 41: Host header with upper case letters and $host
--- config
location /bar {
more_set_input_headers 'Host: agentZH.org:1984';
echo "host var: $host";
echo "http_host var: $http_host";
}
--- request
GET /bar
--- response_body
host var: agentzh.org
http_host var: agentZH.org:1984
=== TEST 42: clear all and re-insert
--- config
location = /t {
more_clear_input_headers Host Connection Cache-Control Accept
User-Agent Accept-Encoding Accept-Language
Cookie;
more_set_input_headers "Host: a" "Connection: b" "Cache-Control: c"
"Accept: d" "User-Agent: e" "Accept-Encoding: f"
"Accept-Language: g" "Cookie: h";
more_clear_input_headers Host Connection Cache-Control Accept
User-Agent Accept-Encoding Accept-Language
Cookie;
more_set_input_headers "Host: a" "Connection: b" "Cache-Control: c"
"Accept: d" "User-Agent: e" "Accept-Encoding: f"
"Accept-Language: g" "Cookie: h";
echo ok;
}
--- raw_request eval
"GET /t HTTP/1.1\r
Host: localhost\r
Connection: close\r
Cache-Control: max-age=0\r
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\r
Accept-Encoding: gzip,deflate,sdch\r
Accept-Language: en-US,en;q=0.8\r
Cookie: test=cookie;\r
\r
"
--- response_body
ok
--- no_error_log
[error]
=== TEST 43: more_set_input_header does not override request headers with multiple values
--- config
#lua_code_cache off;
location = /t {
more_set_input_headers "AAA: 111";
content_by_lua '
local headers = ngx.req.get_headers()
ngx.say(headers["AAA"])
';
}
--- request
GET /t
--- more_headers
AAA: 123
AAA: 456
AAA: 678
--- response_body
111
--- no_error_log
[error]