| # vi:filetype= |
| |
| use lib 'lib'; |
| |
| use Test::Nginx::Socket; |
| |
| repeat_each(2); |
| |
| plan tests => repeat_each() * (2 * blocks()); |
| |
| $ENV{TEST_NGINX_HTML_DIR} = html_dir; |
| $ENV{TEST_NGINX_CLIENT_PORT} ||= server_port(); |
| |
| run_tests(); |
| |
| __DATA__ |
| |
| === TEST 1: sanity |
| --- config |
| location /main { |
| echo_subrequest GET /sub; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| GET /main |
| --- response_body |
| hello |
| |
| |
| |
| === TEST 2: trailing echo |
| --- config |
| location /main { |
| echo_subrequest GET /sub; |
| echo after subrequest; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| GET /main |
| --- response_body |
| hello |
| after subrequest |
| |
| |
| |
| === TEST 3: leading echo |
| --- config |
| location /main { |
| echo before subrequest; |
| echo_subrequest GET /sub; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| GET /main |
| --- response_body |
| before subrequest |
| hello |
| |
| |
| |
| === TEST 4: leading & trailing echo |
| --- config |
| location /main { |
| echo before subrequest; |
| echo_subrequest GET /sub; |
| echo after subrequest; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| GET /main |
| --- response_body |
| before subrequest |
| hello |
| after subrequest |
| |
| |
| |
| === TEST 5: multiple subrequests |
| --- config |
| location /main { |
| echo before sr 1; |
| echo_subrequest GET /sub; |
| echo after sr 1; |
| echo before sr 2; |
| echo_subrequest GET /sub; |
| echo after sr 2; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| GET /main |
| --- response_body |
| before sr 1 |
| hello |
| after sr 1 |
| before sr 2 |
| hello |
| after sr 2 |
| |
| |
| |
| === TEST 6: timed multiple subrequests (blocking sleep) |
| --- config |
| location /main { |
| echo_reset_timer; |
| echo_subrequest GET /sub1; |
| echo_subrequest GET /sub2; |
| echo "took $echo_timer_elapsed sec for total."; |
| } |
| location /sub1 { |
| echo_blocking_sleep 0.02; |
| echo hello; |
| } |
| location /sub2 { |
| echo_blocking_sleep 0.01; |
| echo world; |
| } |
| |
| --- request |
| GET /main |
| --- response_body_like |
| ^hello |
| world |
| took 0\.0(?:2[5-9]|3[0-5]) sec for total\.$ |
| |
| |
| |
| === TEST 7: timed multiple subrequests (non-blocking sleep) |
| --- config |
| location /main { |
| echo_reset_timer; |
| echo_subrequest GET /sub1; |
| echo_subrequest GET /sub2; |
| echo "took $echo_timer_elapsed sec for total."; |
| } |
| location /sub1 { |
| echo_sleep 0.02; |
| echo hello; |
| } |
| location /sub2 { |
| echo_sleep 0.01; |
| echo world; |
| } |
| |
| --- request |
| GET /main |
| --- response_body_like |
| ^hello |
| world |
| took 0\.0(?:2[5-9]|3[0-6]) sec for total\.$ |
| |
| |
| |
| === TEST 8: location with args |
| --- config |
| location /main { |
| echo_subrequest GET /sub -q 'foo=Foo&bar=Bar'; |
| } |
| location /sub { |
| echo $arg_foo $arg_bar; |
| } |
| --- request |
| GET /main |
| --- response_body |
| Foo Bar |
| |
| |
| |
| === TEST 9: chained subrequests |
| --- config |
| location /main { |
| echo 'pre main'; |
| echo_subrequest GET /sub; |
| echo 'post main'; |
| } |
| |
| location /sub { |
| echo 'pre sub'; |
| echo_subrequest GET /subsub; |
| echo 'post sub'; |
| } |
| |
| location /subsub { |
| echo 'subsub'; |
| } |
| --- request |
| GET /main |
| --- response_body |
| pre main |
| pre sub |
| subsub |
| post sub |
| post main |
| |
| |
| |
| === TEST 10: chained subrequests using named locations |
| as of 0.8.20, ngx_http_subrequest still does not support |
| named location. sigh. this case is a TODO. |
| --- config |
| location /main { |
| echo 'pre main'; |
| echo_subrequest GET @sub; |
| echo 'post main'; |
| } |
| |
| location @sub { |
| echo 'pre sub'; |
| echo_subrequest GET @subsub; |
| echo 'post sub'; |
| } |
| |
| location @subsub { |
| echo 'subsub'; |
| } |
| --- request |
| GET /main |
| --- response_body |
| pre main |
| pre sub |
| subsub |
| post sub |
| post main |
| --- SKIP |
| |
| |
| |
| === TEST 11: explicit flush in main request |
| --- config |
| location /main { |
| echo 'pre main'; |
| echo_subrequest GET /sub; |
| echo 'post main'; |
| echo_flush; |
| } |
| |
| location /sub { |
| echo_sleep 0.02; |
| echo 'sub'; |
| } |
| --- request |
| GET /main |
| --- response_body |
| pre main |
| sub |
| post main |
| |
| |
| |
| === TEST 12: DELETE subrequest |
| --- config |
| location /main { |
| echo_subrequest DELETE /sub; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| echo "main method: $echo_client_request_method"; |
| } |
| --- request |
| GET /main |
| --- response_body |
| sub method: DELETE |
| main method: GET |
| |
| |
| |
| === TEST 13: DELETE subrequest |
| --- config |
| location /main { |
| echo "main method: $echo_client_request_method"; |
| echo_subrequest GET /proxy; |
| echo_subrequest DELETE /proxy; |
| } |
| location /proxy { |
| proxy_pass $scheme://127.0.0.1:$server_port/sub; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| } |
| --- request |
| GET /main |
| --- response_body |
| main method: GET |
| sub method: GET |
| sub method: DELETE |
| |
| |
| |
| === TEST 14: POST subrequest with body |
| --- config |
| location /main { |
| echo_subrequest POST /sub -b 'hello, world'; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| # we don't need to call echo_read_client_body explicitly here |
| echo "sub body: $echo_request_body"; |
| } |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST |
| sub body: hello, world |
| |
| |
| |
| === TEST 15: POST subrequest with body (explicitly read the body) |
| --- config |
| location /main { |
| echo_subrequest POST /sub -b 'hello, world'; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| # we call echo_read_client_body explicitly here even |
| # though it's not necessary. |
| echo_read_request_body; |
| echo "sub body: $echo_request_body"; |
| } |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST |
| sub body: hello, world |
| |
| |
| |
| === TEST 16: POST subrequest with body (with proxy in the middle) and without read body explicitly |
| --- config |
| location /main { |
| echo_subrequest POST /proxy -b 'hello, world'; |
| } |
| location /proxy { |
| proxy_pass $scheme://127.0.0.1:$server_port/sub; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method."; |
| # we need to read body explicitly here...or $echo_request_body |
| # will evaluate to empty ("") |
| echo "sub body: $echo_request_body."; |
| } |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST. |
| sub body: . |
| |
| |
| |
| === TEST 17: POST subrequest with body (with proxy in the middle) and read body explicitly |
| --- config |
| location /main { |
| echo_subrequest POST /proxy -b 'hello, world'; |
| } |
| location /proxy { |
| proxy_pass $scheme://127.0.0.1:$server_port/sub; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method."; |
| # we need to read body explicitly here...or $echo_request_body |
| # will evaluate to empty ("") |
| echo_read_request_body; |
| echo "sub body: $echo_request_body."; |
| } |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST. |
| sub body: hello, world. |
| |
| |
| |
| === TEST 18: multiple subrequests |
| --- config |
| location /multi { |
| echo_subrequest POST '/sub' -q 'foo=Foo' -b 'hi'; |
| echo_subrequest PUT '/sub' -q 'bar=Bar' -b 'hello'; |
| } |
| location /sub { |
| echo "querystring: $query_string"; |
| echo "method: $echo_request_method"; |
| echo "body: $echo_request_body"; |
| echo "content length: $http_content_length"; |
| echo '///'; |
| } |
| --- request |
| GET /multi |
| --- response_body |
| querystring: foo=Foo |
| method: POST |
| body: hi |
| content length: 2 |
| /// |
| querystring: bar=Bar |
| method: PUT |
| body: hello |
| content length: 5 |
| /// |
| |
| |
| |
| === TEST 19: unsafe uri |
| --- config |
| location /unsafe { |
| echo_subrequest GET '/../foo'; |
| } |
| --- request |
| GET /unsafe |
| --- ignore_response |
| --- error_log |
| echo_subrequest sees unsafe uri: "/../foo" |
| --- no_error_log |
| [error] |
| |
| |
| |
| === TEST 20: querystring in url |
| --- config |
| location /main { |
| echo_subrequest GET /sub?foo=Foo&bar=Bar; |
| } |
| location /sub { |
| echo $arg_foo $arg_bar; |
| } |
| --- request |
| GET /main |
| --- response_body |
| Foo Bar |
| |
| |
| |
| === TEST 21: querystring in url *AND* an explicit querystring |
| --- config |
| location /main { |
| echo_subrequest GET /sub?foo=Foo&bar=Bar -q blah=Blah; |
| } |
| location /sub { |
| echo $arg_foo $arg_bar $arg_blah; |
| } |
| --- request |
| GET /main |
| --- response_body |
| Blah |
| |
| |
| |
| === TEST 22: let subrequest to read the main request's request body |
| --- SKIP |
| --- config |
| location /main { |
| echo_subrequest POST /sub; |
| } |
| location /sub { |
| echo_read_request_body; |
| echo_request_body; |
| } |
| --- request |
| POST /main |
| hello, body! |
| --- response_body chomp |
| hello, body! |
| |
| |
| |
| === TEST 23: deep nested echo_subrequest/echo_subrequest_async |
| --- config |
| location /main { |
| echo_subrequest GET /bar; |
| echo_subrequest_async GET /bar; |
| echo_subrequest_async GET /bar; |
| echo_subrequest GET /group; |
| echo_subrequest_async GET /group; |
| } |
| |
| location /group { |
| echo_subrequest GET /bar; |
| echo_subrequest_async GET /bar; |
| } |
| |
| location /bar { |
| echo $echo_incr; |
| } |
| --- request |
| GET /main |
| --- response_body |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| |
| |
| |
| === TEST 24: deep nested echo_subrequest/echo_subrequest_async |
| --- config |
| location /main { |
| echo_subrequest GET /bar?a; |
| echo_subrequest_async GET /bar?b; |
| echo_subrequest_async GET /bar?c; |
| echo_subrequest GET /group?a=d&b=e; |
| echo_subrequest_async GET /group?a=f&b=g; |
| } |
| |
| location /group { |
| echo_subrequest GET /bar?$arg_a; |
| echo_subrequest_async GET /bar?$arg_b; |
| } |
| |
| location /bar { |
| echo -n $query_string; |
| } |
| --- request |
| GET /main |
| --- response_body: abcdefg |
| --- timeout: 2 |
| |
| |
| |
| === TEST 25: POST subrequest with file body (relative paths) |
| --- config |
| location /main { |
| echo_subrequest POST /sub -f html/blah.txt; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| # we don't need to call echo_read_client_body explicitly here |
| echo_request_body; |
| } |
| --- user_files |
| >>> blah.txt |
| Hello, world |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST |
| Hello, world |
| |
| |
| |
| === TEST 26: POST subrequest with file body (absolute paths) |
| --- config |
| location /main { |
| echo_subrequest POST /sub -f $TEST_NGINX_HTML_DIR/blah.txt; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| # we don't need to call echo_read_client_body explicitly here |
| echo_request_body; |
| } |
| --- user_files |
| >>> blah.txt |
| Hello, world! |
| Haha |
| --- request |
| GET /main |
| --- response_body |
| sub method: POST |
| Hello, world! |
| Haha |
| |
| |
| |
| === TEST 27: POST subrequest with file body (file not found) |
| --- config |
| location /main { |
| echo_subrequest POST /sub -f html/blah/blah.txt; |
| } |
| location /sub { |
| echo "sub method: $echo_request_method"; |
| # we don't need to call echo_read_client_body explicitly here |
| echo_request_body; |
| } |
| --- user_files |
| >>> blah.txt |
| Hello, world |
| --- request |
| GET /main |
| --- ignore_response |
| --- error_log eval |
| qr/open\(\) ".*?" failed/ |
| --- no_error_log |
| [alert] |
| |
| |
| |
| === TEST 28: leading subrequest & echo_before_body |
| --- config |
| location /main { |
| echo_before_body hello; |
| echo_subrequest GET /foo; |
| } |
| location /foo { |
| echo world; |
| } |
| --- request |
| GET /main |
| --- response_body |
| hello |
| world |
| |
| |
| |
| === TEST 29: leading subrequest & xss |
| --- config |
| location /main { |
| default_type 'application/json'; |
| xss_get on; |
| xss_callback_arg c; |
| echo_subrequest GET /foo; |
| } |
| location /foo { |
| echo -n world; |
| } |
| --- request |
| GET /main?c=hi |
| --- response_body chop |
| hi(world); |
| |
| |
| |
| === TEST 30: multiple leading subrequest & xss |
| --- config |
| location /main { |
| default_type 'application/json'; |
| xss_get on; |
| xss_callback_arg c; |
| echo_subrequest GET /foo; |
| echo_subrequest GET /bar; |
| } |
| location /foo { |
| echo -n world; |
| } |
| location /bar { |
| echo -n ' people'; |
| } |
| --- request |
| GET /main?c=hi |
| --- response_body chop |
| hi(world people); |
| |
| |
| |
| === TEST 31: sanity (HEAD) |
| --- config |
| location /main { |
| echo_subrequest GET /sub; |
| echo_subrequest GET /sub; |
| } |
| location /sub { |
| echo hello; |
| } |
| --- request |
| HEAD /main |
| --- response_body |
| |
| |
| |
| === TEST 32: POST subrequest to ngx_proxy |
| --- config |
| location /hello { |
| default_type text/plain; |
| echo_subrequest POST '/proxy' -q 'foo=Foo&bar=baz' -b 'request_body=test&test=3'; |
| } |
| |
| location /proxy { |
| proxy_pass http://127.0.0.1:$TEST_NGINX_CLIENT_PORT/sub; |
| #proxy_pass http://127.0.0.1:1113/sub; |
| } |
| |
| location /sub { |
| echo_read_request_body; |
| echo "sub method: $echo_request_method"; |
| # we don't need to call echo_read_client_body explicitly here |
| echo "sub body: $echo_request_body"; |
| } |
| --- request |
| GET /hello |
| --- response_body |
| sub method: POST |
| sub body: request_body=test&test=3 |
| |