Skip to content

Commit 5f0744c

Browse files
committed
now we support multi-value keys in ngx.req.get_query_args().
1 parent 2502bdc commit 5f0744c

File tree

7 files changed

+273
-52
lines changed

7 files changed

+273
-52
lines changed

src/ngx_http_lua_hook.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2975,6 +2975,8 @@ ngx_http_lua_ngx_req_get_query_args(lua_State *L) {
29752975
ngx_http_lua_unescape_uri(&dst, &src, p - q,
29762976
NGX_UNESCAPE_URI_COMPONENT);
29772977

2978+
dd("pushing key %.*s", (int) (dst - q), q);
2979+
29782980
/* push the key */
29792981
lua_pushlstring(L, (char *) q, dst - q);
29802982

@@ -2991,6 +2993,8 @@ ngx_http_lua_ngx_req_get_query_args(lua_State *L) {
29912993
ngx_http_lua_unescape_uri(&dst, &src, p - q,
29922994
NGX_UNESCAPE_URI_COMPONENT);
29932995

2996+
dd("pushing key or value %.*s", (int) (dst - q), q);
2997+
29942998
/* push the value or key */
29952999
lua_pushlstring(L, (char *) q, dst - q);
29963000

@@ -3006,44 +3010,63 @@ ngx_http_lua_ngx_req_get_query_args(lua_State *L) {
30063010
} else {
30073011
/* the current parsing pair takes no value,
30083012
* just push the value "true" */
3013+
dd("pushing boolean true");
3014+
30093015
lua_pushboolean(L, 1);
30103016
}
30113017

30123018
(void) lua_tolstring(L, -2, &len);
30133019

30143020
if (len == 0) {
30153021
/* ignore empty string key pairs */
3022+
dd("popping key and value...");
30163023
lua_pop(L, 2);
30173024

30183025
} else {
3019-
lua_settable(L, 1);
3026+
dd("setting table...");
3027+
ngx_http_lua_set_multi_value_table(L, 1);
30203028
}
30213029

30223030
} else {
30233031
p++;
30243032
}
30253033
}
30263034

3027-
if (p != q) {
3035+
if (p != q || parsing_value) {
30283036
src = q; dst = q;
30293037

30303038
ngx_http_lua_unescape_uri(&dst, &src, p - q,
30313039
NGX_UNESCAPE_URI_COMPONENT);
30323040

3033-
/* push the value or key */
3041+
dd("pushing key or value %.*s", (int) (dst - q), q);
3042+
30343043
lua_pushlstring(L, (char *) q, dst - q);
30353044

30363045
if (! parsing_value) {
3046+
dd("pushing boolean true...");
30373047
lua_pushboolean(L, 1);
30383048
}
30393049

3040-
lua_settable(L, 1);
3050+
(void) lua_tolstring(L, -2, &len);
3051+
3052+
if (len == 0) {
3053+
/* ignore empty string key pairs */
3054+
dd("popping key and value...");
3055+
lua_pop(L, 2);
3056+
3057+
} else {
3058+
dd("setting table...");
3059+
ngx_http_lua_set_multi_value_table(L, 1);
3060+
}
30413061
}
30423062

30433063
ngx_pfree(r->pool, buf);
30443064

30453065
dd("gettop: %d", lua_gettop(L));
30463066
dd("type: %s", lua_typename(L, lua_type(L, 1)));
3067+
if (lua_gettop(L) != 1) {
3068+
return luaL_error(L, "internal error: stack in bad state");
3069+
}
30473070

30483071
return 1;
30493072
}

src/ngx_http_lua_util.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,3 +1701,44 @@ ngx_http_lua_flush_postponed_outputs(ngx_http_request_t *r)
17011701
return NGX_OK;
17021702
}
17031703

1704+
1705+
void
1706+
ngx_http_lua_set_multi_value_table(lua_State *L, int index)
1707+
{
1708+
if (index < 0) {
1709+
index = lua_gettop(L) + index + 1;
1710+
}
1711+
1712+
lua_pushvalue(L, -2); /* stack: table key value key */
1713+
lua_rawget(L, index);
1714+
if (lua_isnil(L, -1)) {
1715+
lua_pop(L, 1); /* stack: table key value */
1716+
lua_rawset(L, index); /* stack: table */
1717+
1718+
} else {
1719+
if (! lua_istable(L, -1)) {
1720+
/* just inserted one value */
1721+
lua_createtable(L, 4, 0);
1722+
/* stack: table key value value table */
1723+
lua_insert(L, -2);
1724+
/* stack: table key value table value */
1725+
lua_rawseti(L, -2, 1);
1726+
/* stack: table key value table */
1727+
lua_insert(L, -2);
1728+
/* stack: table key table value */
1729+
1730+
lua_rawseti(L, -2, 2); /* stack: table key table */
1731+
1732+
lua_rawset(L, index); /* stack: table */
1733+
1734+
} else {
1735+
/* stack: table key value table */
1736+
lua_insert(L, -2); /* stack: table key table value */
1737+
1738+
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
1739+
/* stack: table key table */
1740+
lua_pop(L, 2); /* stack: table */
1741+
}
1742+
}
1743+
}
1744+

src/ngx_http_lua_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ u_char * ngx_http_lua_digest_hex(u_char *dest, const u_char *buf,
4343
int buf_len);
4444
void ngx_http_lua_dump_postponed(ngx_http_request_t *r);
4545
ngx_int_t ngx_http_lua_flush_postponed_outputs(ngx_http_request_t *r);
46+
void ngx_http_lua_set_multi_value_table(lua_State *L, int index);
4647

4748

4849
#endif /* NGX_HTTP_LUA_UTIL_H */
50+

t/002-content.t

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ GET /lua
171171

172172

173173

174-
=== TEST 10: invalid capture location (not as expected...)
174+
=== TEST 9: invalid capture location (not as expected...)
175175
--- config
176176
location /lua {
177177
content_by_lua 'res = ngx.location.capture("*(#*"); ngx.say("res=", res.status)';
@@ -183,7 +183,7 @@ res=404
183183

184184

185185

186-
=== TEST 11: nil is "nil"
186+
=== TEST 10: nil is "nil"
187187
--- config
188188
location /lua {
189189
content_by_lua 'ngx.say(nil)';
@@ -195,6 +195,18 @@ nil
195195

196196

197197

198+
=== TEST 11: write boolean
199+
--- config
200+
location /lua {
201+
content_by_lua 'ngx.say(true, " ", false)';
202+
}
203+
--- request
204+
GET /lua
205+
--- response_body
206+
true false
207+
208+
209+
198210
=== TEST 12: bad argument type to ngx.location.capture
199211
--- config
200212
location /lua {

t/023-rewrite/sanity.t

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,20 @@ nil
210210

211211

212212

213-
=== TEST 12: bad argument type to ngx.location.capture
213+
=== TEST 12: write boolean
214+
--- config
215+
location /lua {
216+
rewrite_by_lua 'ngx.say(true, " ", false)';
217+
content_by_lua return;
218+
}
219+
--- request
220+
GET /lua
221+
--- response_body
222+
true false
223+
224+
225+
226+
=== TEST 13: bad argument type to ngx.location.capture
214227
--- config
215228
location /lua {
216229
rewrite_by_lua 'ngx.location.capture(nil)';
@@ -223,7 +236,7 @@ GET /lua
223236

224237

225238

226-
=== TEST 13: capture location (default 0);
239+
=== TEST 14: capture location (default 0);
227240
--- config
228241
location /recur {
229242
rewrite_by_lua '
@@ -249,7 +262,7 @@ end
249262

250263

251264

252-
=== TEST 14: capture location
265+
=== TEST 15: capture location
253266
--- config
254267
location /recur {
255268
rewrite_by_lua '
@@ -278,7 +291,7 @@ end
278291

279292

280293

281-
=== TEST 15: setting nginx variables from within Lua
294+
=== TEST 16: setting nginx variables from within Lua
282295
--- config
283296
location /set {
284297
set $a "";
@@ -295,7 +308,7 @@ Foo: 32
295308

296309

297310

298-
=== TEST 16: nginx quote sql string 1
311+
=== TEST 17: nginx quote sql string 1
299312
--- config
300313
location /set {
301314
set $a 'hello\n\r\'"\\'; # this runs after rewrite_by_lua
@@ -309,7 +322,7 @@ GET /set
309322

310323

311324

312-
=== TEST 17: nginx quote sql string 2
325+
=== TEST 18: nginx quote sql string 2
313326
--- config
314327
location /set {
315328
#set $a "hello\n\r'\"\\";
@@ -323,7 +336,7 @@ GET /set
323336

324337

325338

326-
=== TEST 18: use dollar
339+
=== TEST 19: use dollar
327340
--- config
328341
location /set {
329342
rewrite_by_lua '
@@ -339,7 +352,7 @@ GET /set
339352

340353

341354

342-
=== TEST 19: subrequests do not share variables of main requests by default
355+
=== TEST 20: subrequests do not share variables of main requests by default
343356
--- config
344357
location /sub {
345358
echo $a;
@@ -355,7 +368,7 @@ GET /parent
355368

356369

357370

358-
=== TEST 20: subrequests can share variables of main requests
371+
=== TEST 21: subrequests can share variables of main requests
359372
--- config
360373
location /sub {
361374
echo $a;
@@ -379,7 +392,7 @@ GET /parent
379392

380393

381394

382-
=== TEST 21: main requests use subrequests' variables
395+
=== TEST 22: main requests use subrequests' variables
383396
--- config
384397
location /sub {
385398
set $a 12;
@@ -399,7 +412,7 @@ GET /parent
399412

400413

401414

402-
=== TEST 22: main requests do NOT use subrequests' variables
415+
=== TEST 23: main requests do NOT use subrequests' variables
403416
--- config
404417
location /sub {
405418
set $a 12;
@@ -419,7 +432,7 @@ GET /parent
419432

420433

421434

422-
=== TEST 23: capture location headers
435+
=== TEST 24: capture location headers
423436
--- config
424437
location /other {
425438
default_type 'foo/bar';
@@ -441,7 +454,7 @@ type: foo/bar
441454

442455

443456

444-
=== TEST 24: capture location headers
457+
=== TEST 25: capture location headers
445458
--- config
446459
location /other {
447460
default_type 'foo/bar';
@@ -468,7 +481,7 @@ Bar: Bah
468481

469482

470483

471-
=== TEST 25: capture location headers
484+
=== TEST 26: capture location headers
472485
--- config
473486
location /other {
474487
default_type 'foo/bar';
@@ -495,7 +508,7 @@ Bar: nil
495508

496509

497510

498-
=== TEST 26: rewrite_by_lua runs before ngx_access
511+
=== TEST 27: rewrite_by_lua runs before ngx_access
499512
--- config
500513
location /lua {
501514
deny all;
@@ -513,7 +526,7 @@ GET /lua
513526

514527

515528

516-
=== TEST 27: rewrite_by_lua shouldn't send headers automatically (on simple return)
529+
=== TEST 28: rewrite_by_lua shouldn't send headers automatically (on simple return)
517530
--- config
518531
location /lua {
519532
rewrite_by_lua 'return';
@@ -536,7 +549,7 @@ foo
536549

537550

538551

539-
=== TEST 28: rewrite_by_lua shouldn't send headers automatically (on simple exit)
552+
=== TEST 29: rewrite_by_lua shouldn't send headers automatically (on simple exit)
540553
--- config
541554
location /lua {
542555
rewrite_by_lua 'ngx.exit(ngx.OK)';
@@ -559,7 +572,7 @@ foo
559572

560573

561574

562-
=== TEST 29: short circuit
575+
=== TEST 30: short circuit
563576
--- config
564577
location /lua {
565578
rewrite_by_lua '
@@ -580,7 +593,7 @@ Hi
580593

581594

582595

583-
=== TEST 30: nginx vars in script path
596+
=== TEST 31: nginx vars in script path
584597
--- config
585598
location ~ /lua/(.+)$ {
586599
rewrite_by_lua_file html/$1.lua;
@@ -602,7 +615,7 @@ Hi
602615

603616

604617

605-
=== TEST 31: phase postponing works for various locations
618+
=== TEST 32: phase postponing works for various locations
606619
--- config
607620
location ~ '^/lua/(.+)' {
608621
set $path $1;
@@ -630,7 +643,7 @@ bah
630643

631644

632645

633-
=== TEST 32: server rewrite_by_lua
646+
=== TEST 33: server rewrite_by_lua
634647
--- config
635648
rewrite_by_lua 'ngx.header["X-Foo"] = "bar" ngx.send_headers()';
636649
--- request
@@ -642,7 +655,7 @@ X-Foo: bar
642655

643656

644657

645-
=== TEST 33: server rewrite_by_lua_file
658+
=== TEST 34: server rewrite_by_lua_file
646659
--- config
647660
rewrite_by_lua_file html/foo.lua;
648661
--- user_files

0 commit comments

Comments
 (0)