blob: 3ba5c58a198177c8717d1f8c26fd03a94e2d3a07 [file] [log] [blame] [raw]
# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib 'lib';
use Test::Nginx::Socket::Lua;
#repeat_each(20000);
repeat_each(2);
#master_on();
#workers(1);
#log_level('debug');
#log_level('warn');
#worker_connections(1024);
plan tests => repeat_each() * (blocks() * 3 + 2);
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;
our $LuaCpath = $ENV{LUA_CPATH} ||
'/usr/local/openresty-debug/lualib/?.so;/usr/local/openresty/lualib/?.so;;';
#$ENV{LUA_PATH} = $ENV{HOME} . '/work/JSON4Lua-0.9.30/json/?.lua';
no_long_string();
run_tests();
__DATA__
=== TEST 1: throw 403
--- config
location /lua {
content_by_lua "ngx.exit(403);ngx.say('hi')";
}
--- request
GET /lua
--- error_code: 403
--- response_body_like: 403 Forbidden
--- no_error_log
[error]
=== TEST 2: throw 404
--- config
location /lua {
content_by_lua "ngx.exit(404);ngx.say('hi');";
}
--- request
GET /lua
--- error_code: 404
--- response_body_like: 404 Not Found
--- no_error_log
[error]
=== TEST 3: throw 404 after sending the header and partial body
--- config
location /lua {
content_by_lua "ngx.say('hi');ngx.exit(404);ngx.say(', you')";
}
--- request
GET /lua
--- error_log
attempt to set status 404 via ngx.exit after sending out the response status 200
--- no_error_log
alert
--- response_body
hi
=== TEST 4: working with ngx_auth_request (succeeded)
--- config
location /auth {
content_by_lua "
if ngx.var.user == 'agentzh' then
ngx.eof();
else
ngx.exit(403)
end";
}
location /api {
set $user $arg_user;
auth_request /auth;
echo "Logged in";
}
--- request
GET /api?user=agentzh
--- error_code: 200
--- response_body
Logged in
--- no_error_log
[error]
=== TEST 5: working with ngx_auth_request (failed)
--- config
location /auth {
content_by_lua "
if ngx.var.user == 'agentzh' then
ngx.eof();
else
ngx.exit(403)
end";
}
location /api {
set $user $arg_user;
auth_request /auth;
echo "Logged in";
}
--- request
GET /api?user=agentz
--- error_code: 403
--- response_body_like: 403 Forbidden
--- no_error_log
[error]
=== TEST 6: working with ngx_auth_request (simplest form, w/o ngx_memc)
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
upstream backend {
drizzle_server 127.0.0.1:\$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test;
drizzle_keepalive max=300 mode=single overflow=ignore;
}
"
--- config
location /memc {
internal;
set $memc_key $arg_key;
set $memc_exptime $arg_exptime;
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
}
location /conv-uid-mysql {
internal;
set $key "conv-uid-$arg_uid";
#srcache_fetch GET /memc key=$key;
#srcache_store PUT /memc key=$key;
default_type 'application/json';
drizzle_query "select new_uid as uid from conv_uid where old_uid=$arg_uid";
drizzle_pass backend;
rds_json on;
}
location /conv-uid {
internal;
content_by_lua_file 'html/foo.lua';
}
location /api {
set $uid $arg_uid;
auth_request /conv-uid;
echo "Logged in $uid";
}
--- user_files
>>> foo.lua
local cjson = require('cjson');
local old_uid = ngx.var.uid
-- print('about to run sr')
local res = ngx.location.capture('/conv-uid-mysql?uid=' .. old_uid)
if (res.status ~= ngx.HTTP_OK) then
ngx.exit(res.status)
end
-- print('just have run sr: ' .. res.body)
res = cjson.decode(res.body)
if (not res or not res[1] or not res[1].uid or
not string.match(res[1].uid, '^%d+$')) then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.uid = res[1].uid;
-- print('done')
--- request
GET /api?uid=32
--- response_body
Logged in 56
--- no_error_log
[error]
=== TEST 7: working with ngx_auth_request (simplest form)
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
upstream backend {
drizzle_server 127.0.0.1:\$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test;
drizzle_keepalive max=300 mode=single overflow=ignore;
}
"
--- config
location /memc {
internal;
set $memc_key $arg_key;
set $memc_exptime $arg_exptime;
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
}
location /conv-uid-mysql {
internal;
set $key "conv-uid-$arg_uid";
#srcache_fetch GET /memc key=$key;
#srcache_store PUT /memc key=$key;
default_type 'application/json';
drizzle_query "select new_uid as uid from conv_uid where old_uid=$arg_uid";
drizzle_pass backend;
rds_json on;
}
location /conv-uid {
internal;
content_by_lua_file 'html/foo.lua';
}
location /api {
set $uid $arg_uid;
auth_request /conv-uid;
echo "Logged in $uid";
}
--- user_files
>>> foo.lua
local cjson = require('cjson');
local old_uid = ngx.var.uid
-- print('about to run sr')
local res = ngx.location.capture('/conv-uid-mysql?uid=' .. old_uid)
-- print('just have run sr' .. res.body)
if (res.status ~= ngx.HTTP_OK) then
ngx.exit(res.status)
end
res = cjson.decode(res.body)
if (not res or not res[1] or not res[1].uid or
not string.match(res[1].uid, '^%d+$')) then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.uid = res[1].uid;
-- print('done')
--- request
GET /api?uid=32
--- response_body
Logged in 56
--- no_error_log
[error]
=== TEST 8: working with ngx_auth_request
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
upstream backend {
drizzle_server 127.0.0.1:\$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test;
drizzle_keepalive max=300 mode=single overflow=ignore;
}
upstream memc_a {
server 127.0.0.1:\$TEST_NGINX_MEMCACHED_PORT;
}
upstream memc_b {
server 127.0.0.1:\$TEST_NGINX_MEMCACHED_PORT;
}
upstream_list memc_cluster memc_a memc_b;
"
--- config
location /memc {
internal;
set $memc_key $arg_key;
set $memc_exptime $arg_exptime;
set_hashed_upstream $backend memc_cluster $arg_key;
memc_pass $backend;
}
location /conv-uid-mysql {
internal;
set $key "conv-uid-$arg_uid";
#srcache_fetch GET /memc key=$key;
#srcache_store PUT /memc key=$key;
default_type 'application/json';
drizzle_query "select new_uid as uid from conv_uid where old_uid=$arg_uid";
drizzle_pass backend;
rds_json on;
}
location /conv-uid {
internal;
content_by_lua_file 'html/foo.lua';
}
location /api {
set $uid $arg_uid;
auth_request /conv-uid;
echo "Logged in $uid";
}
--- user_files
>>> foo.lua
local cjson = require('cjson');
local old_uid = ngx.var.uid
-- print('about to run sr')
local res = ngx.location.capture('/conv-uid-mysql?uid=' .. old_uid)
-- print('just have run sr' .. res.body)
if (res.status ~= ngx.HTTP_OK) then
ngx.exit(res.status)
end
res = cjson.decode(res.body)
if (not res or not res[1] or not res[1].uid or
not string.match(res[1].uid, '^%d+$')) then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.uid = res[1].uid;
-- print('done')
--- request
GET /api?uid=32
--- response_body
Logged in 56
--- no_error_log
[error]
--- timeout: 5
=== TEST 9: working with ngx_auth_request
--- http_config
upstream backend {
drizzle_server 127.0.0.1:$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test;
drizzle_keepalive max=300 mode=single overflow=ignore;
}
upstream memc_a {
server 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
keepalive 300;
}
#upstream_list memc_cluster memc_a memc_b;
--- config
location /memc {
internal;
set $memc_key $arg_key;
set $memc_exptime $arg_exptime;
#set_hashed_upstream $backend memc_cluster $arg_key;
memc_pass memc_a;
}
location /conv-mysql {
internal;
set $key "conv-uri-$query_string";
#srcache_fetch GET /memc key=$key;
#srcache_store PUT /memc key=$key;
default_type 'application/json';
set_quote_sql_str $seo_uri $query_string;
drizzle_query "select url from my_url_map where seo_url=$seo_uri";
drizzle_pass backend;
rds_json on;
}
location /conv-uid {
internal;
content_by_lua_file 'html/foo.lua';
}
location /baz {
set $my_uri $uri;
auth_request /conv-uid;
echo_exec /jump $my_uri;
}
location /jump {
internal;
rewrite ^ $query_string? redirect;
}
--- user_files
>>> foo.lua
local cjson = require('cjson');
local seo_uri = ngx.var.my_uri
-- print('about to run sr')
local res = ngx.location.capture('/conv-mysql?' .. seo_uri)
if (res.status ~= ngx.HTTP_OK) then
ngx.exit(res.status)
end
res = cjson.decode(res.body)
if (not res or not res[1] or not res[1].url) then
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.my_uri = res[1].url;
-- print('done')
--- request
GET /baz
--- response_body_like: 302
--- error_code: 302
--- response_headers
Location: http://localhost:$ServerPort/foo/bar
--- SKIP
=== TEST 10: throw 0
--- config
location /lua {
content_by_lua "ngx.say('Hi'); ngx.eof(); ngx.exit(0);ngx.say('world')";
}
--- request
GET /lua
--- error_code: 200
--- response_body
Hi
--- no_error_log
[error]
=== TEST 11: pcall safe
--- config
location /lua {
content_by_lua '
function f ()
ngx.say("hello")
ngx.exit(200)
end
pcall(f)
ngx.say("world")
';
}
--- request
GET /lua
--- error_code: 200
--- response_body
hello
--- no_error_log
[error]
=== TEST 12: 501 Method Not Implemented
--- config
location /lua {
content_by_lua '
ngx.exit(501)
';
}
--- request
GET /lua
--- error_code: 501
--- response_body_like: 501 (?:Method )?Not Implemented
--- no_error_log
[error]
=== TEST 13: 501 Method Not Implemented
--- config
location /lua {
content_by_lua '
ngx.exit(ngx.HTTP_METHOD_NOT_IMPLEMENTED)
';
}
--- request
GET /lua
--- error_code: 501
--- response_body_like: 501 (?:Method )?Not Implemented
--- no_error_log
[error]
=== TEST 14: throw 403 after sending out headers with 200
--- config
location /lua {
rewrite_by_lua '
ngx.send_headers()
ngx.say("Hello World")
ngx.exit(403)
';
}
--- request
GET /lua
--- response_body
Hello World
--- error_log
attempt to set status 403 via ngx.exit after sending out the response status 200
--- no_error_log
[alert]
=== TEST 15: throw 403 after sending out headers with 403
--- config
location /lua {
rewrite_by_lua '
ngx.status = 403
ngx.send_headers()
ngx.say("Hello World")
ngx.exit(403)
';
}
--- request
GET /lua
--- response_body
Hello World
--- error_code: 403
--- no_error_log
[error]
[alert]
=== TEST 16: throw 403 after sending out headers with 403 (HTTP 1.0 buffering)
--- config
location /t {
rewrite_by_lua '
ngx.status = 403
ngx.say("Hello World")
ngx.exit(403)
';
}
--- request
GET /t HTTP/1.0
--- response_body
Hello World
--- error_code: 403
--- no_error_log
[error]
[alert]
=== TEST 17: throw 444 after sending out responses (HTTP 1.0)
--- config
location /lua {
content_by_lua "
ngx.say('ok');
return ngx.exit(444)
";
}
--- request
GET /lua HTTP/1.0
--- ignore_response
--- log_level: debug
--- no_error_log
lua sending HTTP 1.0 response headers
[error]
=== TEST 18: throw 499 after sending out responses (HTTP 1.0)
--- config
location /lua {
content_by_lua "
ngx.say('ok');
return ngx.exit(499)
";
}
--- request
GET /lua HTTP/1.0
--- ignore_response
--- log_level: debug
--- no_error_log
lua sending HTTP 1.0 response headers
[error]
=== TEST 19: throw 408 after sending out responses (HTTP 1.0)
--- config
location /lua {
content_by_lua "
ngx.say('ok');
return ngx.exit(408)
";
}
--- request
GET /lua HTTP/1.0
--- ignore_response
--- log_level: debug
--- no_error_log
lua sending HTTP 1.0 response headers
[error]
=== TEST 20: exit(201) with custom response body
--- config
location = /t {
content_by_lua "
ngx.status = 201
ngx.say('ok');
return ngx.exit(201)
";
}
--- request
GET /t
--- ignore_response
--- log_level: debug
--- no_error_log
lua sending HTTP 1.0 response headers
[error]
[alert]
=== TEST 21: exit 403 in header filter
--- config
location = /t {
content_by_lua "ngx.say('hi');";
header_filter_by_lua '
return ngx.exit(403)
';
}
--- request
GET /t
--- error_code: 403
--- response_body_like: 403 Forbidden
--- no_error_log
[error]
=== TEST 22: exit 201 in header filter
--- config
lingering_close always;
location = /t {
content_by_lua "ngx.say('hi');";
header_filter_by_lua '
return ngx.exit(201)
';
}
--- request
GET /t
--- error_code: 201
--- response_body
--- no_error_log
[error]
=== TEST 23: exit both in header filter and content handler
--- config
location = /t {
content_by_lua "ngx.status = 201 ngx.say('hi') ngx.exit(201)";
header_filter_by_lua '
return ngx.exit(201)
';
}
--- request
GET /t
--- error_code: 201
--- stap2
/*
F(ngx_http_send_header) {
printf("=== %d\n", $r->headers_out->status)
print_ubacktrace()
}
*/
F(ngx_http_lua_header_filter_inline) {
printf("=== %d\n", $r->headers_out->status)
print_ubacktrace()
}
F(ngx_http_lua_header_filter_by_chunk).return {
if ($return == -1) {
printf("====== header filter by chunk\n")
print_ubacktrace()
}
}
--- stap_out
--- response_body
--- no_error_log
[error]
[alert]
=== TEST 24: exit 444 in header filter
--- config
location = /t {
content_by_lua "ngx.say('hello world');";
header_filter_by_lua '
return ngx.exit(444)
';
}
--- request
GET /t
--- error_code: 444
--- response_body
--- no_error_log
[error]