1
# vim:set ft= ts=4 sw=4 et fdm=marker:
3
use Test::Nginx::Socket;
5
#worker_connections(1014);
6
#master_process_enabled(1);
12
plan tests => repeat_each() * (blocks() * 2 + 7);
20
=== TEST 1: basic print
23
# NOTE: the newline escape sequence must be double-escaped, as nginx config
24
# parser will unescape first!
25
rewrite_by_lua 'ngx.print("Hello, Lua!\\n")';
26
content_by_lua return;
38
# NOTE: the newline escape sequence must be double-escaped, as nginx config
39
# parser will unescape first!
41
ngx.say("Hello, Lua!")
42
ngx.say("Yay! ", 123)';
44
content_by_lua 'ngx.exit(ngx.OK)';
54
=== TEST 3: no ngx.echo
57
rewrite_by_lua 'ngx.echo("Hello, Lua!\\n")';
58
content_by_lua 'ngx.exit(ngx.OK)';
62
--- response_body_like: 500 Internal Server Error
70
# NOTE: the newline escape sequence must be double-escaped, as nginx config
71
# parser will unescape first!
72
rewrite_by_lua 'v = ngx.var["request_uri"] ngx.print("request_uri: ", v, "\\n")';
73
content_by_lua 'ngx.exit(ngx.OK)';
78
request_uri: /lua?a=1&b=2
82
=== TEST 5: variable (file)
85
rewrite_by_lua_file html/test.lua;
86
content_by_lua 'ngx.exit(ngx.OK)';
90
v = ngx.var["request_uri"]
91
ngx.print("request_uri: ", v, "\n")
95
request_uri: /lua?a=1&b=2
99
=== TEST 6: calc expression
102
rewrite_by_lua_file html/calc.lua;
103
content_by_lua 'ngx.exit(ngx.OK)';
107
local function uri_unescape(uri)
108
local function convert(hex)
109
return string.char(tonumber("0x"..hex))
111
local s = string.gsub(uri, "%%([0-9a-fA-F][0-9a-fA-F])", convert)
115
local function eval_exp(str)
116
return loadstring("return "..str)()
119
local exp_str = ngx.var["arg_exp"]
120
-- print("exp: '", exp_str, "'\n")
122
status, res = pcall(uri_unescape, exp_str)
124
ngx.print("error: ", res, "\n")
127
status, res = pcall(eval_exp, res)
129
ngx.print("result: ", res, "\n")
131
ngx.print("error: ", res, "\n")
134
GET /lua?exp=1%2B2*math.sin(3)%2Fmath.exp(4)-math.sqrt(2)
136
result: -0.4090441561579
140
=== TEST 7: read $arg_xxx
143
rewrite_by_lua 'who = ngx.var.arg_who
144
ngx.print("Hello, ", who, "!")';
145
content_by_lua 'ngx.exit(ngx.OK)';
149
--- response_body chomp
154
=== TEST 8: capture location
162
res = ngx.location.capture("/other")
163
ngx.print("status=", res.status, " ")
164
ngx.print("body=", res.body)
166
content_by_lua 'ngx.exit(ngx.OK)';
171
status=200 body=hello, world
175
=== TEST 9: capture non-existed location
178
rewrite_by_lua 'res = ngx.location.capture("/other"); ngx.print("status=", res.status)';
179
content_by_lua 'ngx.exit(ngx.OK)';
183
--- response_body: status=404
187
=== TEST 10: invalid capture location (not as expected...)
190
rewrite_by_lua 'res = ngx.location.capture("*(#*"); ngx.say("res=", res.status)';
191
content_by_lua 'ngx.exit(ngx.OK)';
200
=== TEST 11: nil is "nil"
203
rewrite_by_lua 'ngx.print(nil)';
204
content_by_lua 'ngx.exit(ngx.OK)';
208
--- response_body_like: 500 Internal Server Error
213
=== TEST 12: bad argument type to ngx.location.capture
216
rewrite_by_lua 'ngx.location.capture(nil)';
217
content_by_lua 'ngx.exit(ngx.OK)';
221
--- response_body_like: 500 Internal Server Error
226
=== TEST 13: capture location (default 0);
230
local num = tonumber(ngx.var.arg_num) or 0;
231
ngx.print("num is: ", num, "\\n");
234
res = ngx.location.capture("/recur?num="..tostring(num - 1));
235
ngx.print("status=", res.status, " ");
236
ngx.print("body=", res.body, "\\n");
242
content_by_lua 'ngx.exit(ngx.OK)';
252
=== TEST 14: capture location
256
local num = tonumber(ngx.var.arg_num) or 0;
257
ngx.print("num is: ", num, "\\n");
260
res = ngx.location.capture("/recur?num="..tostring(num - 1));
261
ngx.print("status=", res.status, " ");
262
ngx.print("body=", res.body);
268
content_by_lua 'ngx.exit(ngx.OK)';
274
status=200 body=num is: 2
275
status=200 body=num is: 1
276
status=200 body=num is: 0
281
=== TEST 15: setting nginx variables from within Lua
285
rewrite_by_lua 'ngx.var.a = 32; ngx.say(ngx.var.a)';
286
content_by_lua 'ngx.exit(ngx.OK)';
298
=== TEST 16: nginx quote sql string 1
301
set $a 'hello\n\r\'"\\'; # this runs after rewrite_by_lua
302
rewrite_by_lua 'ngx.say(ngx.quote_sql_str(ngx.var.a))';
303
content_by_lua 'ngx.exit(ngx.OK)';
312
=== TEST 17: nginx quote sql string 2
315
#set $a "hello\n\r'\"\\";
316
rewrite_by_lua 'ngx.say(ngx.quote_sql_str("hello\\n\\r\'\\"\\\\"))';
317
content_by_lua 'ngx.exit(ngx.OK)';
326
=== TEST 18: use dollar
330
local s = "hello 112";
331
ngx.say(string.find(s, "%d+$"))';
333
content_by_lua 'ngx.exit(ngx.OK)';
342
=== TEST 19: subrequests do not share variables of main requests by default
349
rewrite_by_lua 'res = ngx.location.capture("/sub"); ngx.print(res.body)';
350
content_by_lua 'ngx.exit(ngx.OK)';
354
--- response_body eval: "\n"
358
=== TEST 20: subrequests can share variables of main requests
367
res = ngx.location.capture(
369
{ share_all_vars = true }
373
content_by_lua 'ngx.exit(ngx.OK)';
382
=== TEST 21: main requests use subrequests' variables
389
res = ngx.location.capture("/sub", { share_all_vars = true });
393
content_by_lua 'ngx.exit(ngx.OK)';
402
=== TEST 22: main requests do NOT use subrequests' variables
406
content_by_lua return;
411
res = ngx.location.capture("/sub", { share_all_vars = false });
414
content_by_lua return;
418
--- response_body_like eval: "\n"
422
=== TEST 23: capture location headers
425
default_type 'foo/bar';
431
res = ngx.location.capture("/other");
432
ngx.say("type: ", res.header["Content-Type"]);
435
content_by_lua 'ngx.exit(ngx.OK)';
444
=== TEST 24: capture location headers
447
default_type 'foo/bar';
449
ngx.header.Bar = "Bah";
451
content_by_lua 'ngx.exit(ngx.OK)';
456
res = ngx.location.capture("/other");
457
ngx.say("type: ", res.header["Content-Type"]);
458
ngx.say("Bar: ", res.header["Bar"]);
461
content_by_lua 'ngx.exit(ngx.OK)';
471
=== TEST 25: capture location headers
474
default_type 'foo/bar';
476
ngx.header.Bar = "Bah";
477
ngx.header.Bar = nil;
479
content_by_lua 'ngx.exit(ngx.OK)';
484
res = ngx.location.capture("/other");
485
ngx.say("type: ", res.header["Content-Type"]);
486
ngx.say("Bar: ", res.header["Bar"] or "nil");
488
content_by_lua 'ngx.exit(ngx.OK)';
498
=== TEST 26: rewrite_by_lua runs before ngx_access
504
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
507
content_by_lua return;
511
--- response_body_like: 500 Internal Server Error
516
=== TEST 27: rewrite_by_lua shouldn't send headers automatically (on simple return)
519
rewrite_by_lua 'return';
521
proxy_pass http://127.0.0.1:$server_port/foo;
525
default_type 'text/css';
533
Content-Type: text/css
539
=== TEST 28: rewrite_by_lua shouldn't send headers automatically (on simple exit)
542
rewrite_by_lua 'ngx.exit(ngx.OK)';
544
proxy_pass http://127.0.0.1:$server_port/foo;
548
default_type 'text/css';
556
Content-Type: text/css
562
=== TEST 29: short circuit
568
ngx.exit(ngx.HTTP_OK)
583
=== TEST 30: nginx vars in script path
585
location ~ /lua/(.+)$ {
586
rewrite_by_lua_file html/$1.lua;
597
ngx.exit(ngx.HTTP_OK)
605
=== TEST 31: phase postponing works for various locations
607
location ~ '^/lua/(.+)' {
609
rewrite_by_lua 'ngx.say(ngx.var.path)';
610
content_by_lua return;
612
location ~ '^/lua2/(.+)' {
614
rewrite_by_lua 'ngx.say(ngx.var.path)';
615
content_by_lua return;
618
echo_location /lua/foo;
619
echo_location /lua/bar;
620
echo_location /lua2/baz;
621
echo_location /lua2/bah;
632
=== TEST 33: server rewrite_by_lua
634
rewrite_by_lua 'ngx.header["X-Foo"] = "bar" ngx.send_headers()';
637
--- response_body chop
638
<html><head><title>It works!</title></head><body>It works!</body></html>
644
=== TEST 34: server rewrite_by_lua_file
646
rewrite_by_lua_file html/foo.lua;
649
ngx.header["X-Foo"] = "bar" ngx.send_headers()
652
--- response_body chop
653
<html><head><title>It works!</title></head><body>It works!</body></html>