added support for multi-value request headers in ngx.req.get_headers().

This commit is contained in:
agentzh (章亦春) 2011-05-10 09:39:28 +08:00
Родитель 23cad91f06
Коммит 9739fccaa5
4 изменённых файлов: 92 добавлений и 5 удалений

Просмотреть файл

@ -927,6 +927,16 @@ To read an individual header:
ngx.say("Host: ", ngx.req.get_headers()["Host"])
For multiple instances of request headers like
Foo: foo
Foo: bar
Foo: baz
the value of `ngx.req.get_headers()["Foo"]` will be a Lua (array) table like this:
{"foo", "bar", "baz"}
Another way to read individual request headers is to use `ngx.var.http_HEADER`, that is, nginx's standard $http_HEADER variables:
http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER

Просмотреть файл

@ -1956,7 +1956,7 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) {
return luaL_error(L, "no request object found");
}
lua_createtable(L, 0, 8); /* Firefox creates 8 headers in its requests */
lua_createtable(L, 0, 4);
part = &r->headers_in.headers.part;
header = part->elts;
@ -1974,8 +1974,60 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) {
}
lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len);
lua_pushlstring(L, (char *) header[i].value.data, header[i].value.len);
lua_rawset(L, -3);
/* stack: table key */
lua_pushvalue(L, -1); /* stack: table key key */
/* check if header already exists */
lua_rawget(L, -3); /* stack: table key value */
if (lua_isnil(L, -1)) {
dd("req.header key %.*s not exist", (int) header[i].key.len,
header[i].key.data);
lua_pop(L, 1); /* stack: table key */
lua_pushlstring(L, (char *) header[i].value.data,
header[i].value.len); /* stack: table key value */
lua_rawset(L, -3); /* stack: table */
} else {
dd("req.header key %.*s exists", (int) header[i].key.len,
header[i].key.data);
if (! lua_istable(L, -1)) { /* already inserted one value */
dd("req.header key %.*s already has one value",
(int) header[i].key.len, header[i].key.data);
lua_createtable(L, 4, 0);
/* stack: table key value table */
lua_insert(L, -2); /* stack: table key table value */
lua_rawseti(L, -2, 1); /* stack: table key table */
lua_pushlstring(L, (char *) header[i].value.data,
header[i].value.len);
/* stack: table key table value */
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
/* stack: table key table */
lua_rawset(L, -3); /* stack: table */
} else {
dd("req.header key %.*s already has multi values",
(int) header[i].key.len, header[i].key.data);
lua_pushlstring(L, (char *) header[i].value.data,
header[i].value.len);
/* stack: table key table value */
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
/* stack: table key table */
lua_pop(L, 2); /* stack: table */
}
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http lua req header: \"%V: %V\"",

Просмотреть файл

@ -525,7 +525,7 @@ init_ngx_lua_globals(lua_State *L)
lua_setglobal(L, "ndk");
#endif /* defined(NDK) && NDK */
lua_createtable(L, 0, 20); /* ngx.* */
lua_createtable(L, 0, 22); /* ngx.* */
/* {{{ register nginx hook functions */
lua_pushcfunction(L, ngx_http_lua_ngx_exec);

Просмотреть файл

@ -284,7 +284,7 @@ GET /bar
=== TEST 15: set_header and clear_header should refresh ngx.req.header automatically
=== TEST 15: set_header and clear_header should refresh ngx.req.get_headers() automatically
--- config
location /foo {
content_by_lua '
@ -310,3 +310,28 @@ Foo 1: 32
Foo 2: abc
Foo 3: nil
=== TEST 16: duplicate req headers
--- config
location /foo {
content_by_lua '
local vals = ngx.req.get_headers()["Foo"]
ngx.say("value is of type ", type(vals), ".")
if type(vals) == "table" then
ngx.say("Foo takes ", #vals or "nil", " values.")
ngx.say("They are ", table.concat(vals, ", "), ".")
end
';
}
--- more_headers
Foo: foo
Foo: bar
Foo: baz
--- request
GET /foo
--- response_body
value is of type table.
Foo takes 3 values.
They are foo, bar, baz.