implemented the ngx.req.header table interface for retrieving all the request headers for Lua. thanks moodydeath.
This commit is contained in:
Родитель
c230c16f58
Коммит
35b4c8d86d
|
@ -905,13 +905,34 @@ same does assigning an empty table:
|
|||
`ngx.header` is not a normal Lua table so you cannot
|
||||
iterate through it.
|
||||
|
||||
For reading request headers, use `ngx.var.http_HEADER`, that is, nginx's standard $http_HEADER variables:
|
||||
For reading request headers, see the `ngx.req.header` interface instead.
|
||||
|
||||
Reading values from ngx.header.HEADER is not implemented yet,
|
||||
and usually you shouldn't need it.
|
||||
|
||||
ngx.req.header
|
||||
--------------
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
||||
This read-only Lua table holds all of the request headers. Because it is an ordinary Lua table,
|
||||
iterating through it via Lua's `pairs` function is supported, for instance,
|
||||
|
||||
local h = {}
|
||||
for k, v in pairs(ngx.req.header) do
|
||||
h[k] = v
|
||||
end
|
||||
|
||||
For performance reasons, this table
|
||||
is generated on-the-fly at the first time it is accessed.
|
||||
|
||||
This Lua table is read-only, setting values to this table will not automatically modify the request headers on the Nginx land.
|
||||
(TODO: we'll provide `ngx.req.set_header()` and `ngx.req.clear_header()` for
|
||||
request header modification.)
|
||||
|
||||
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
|
||||
|
||||
Reading values from ngx.header.HEADER is not implemented yet, and usually you
|
||||
shouldn't need it.
|
||||
|
||||
ngx.exec(uri, args)
|
||||
-------------------
|
||||
* **Context:** `rewrite_by_lua*`, `access_by_lua*`, `content_by_lua*`
|
||||
|
|
|
@ -42,6 +42,7 @@ static void log_wrapper(ngx_http_request_t *r, const char *ident, int level,
|
|||
lua_State *L);
|
||||
static uintptr_t ngx_http_lua_escape_uri(u_char *dst, u_char *src,
|
||||
size_t size, ngx_uint_t type);
|
||||
static void ngx_http_lua_create_req_header_table(lua_State *L);
|
||||
|
||||
#if defined(NDK) && NDK
|
||||
static ndk_set_var_value_pt ngx_http_lookup_ndk_set_var_directive(u_char *name,
|
||||
|
@ -1933,6 +1934,88 @@ ngx_http_lua_ngx_set(lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
ngx_http_lua_ngx_req_get(lua_State *L) {
|
||||
u_char *p;
|
||||
size_t len;
|
||||
|
||||
p = (u_char *) luaL_checklstring(L, -1, &len);
|
||||
|
||||
if (len == sizeof("header") - 1 &&
|
||||
ngx_strncmp(p, "header", sizeof("header") - 1) == 0)
|
||||
{
|
||||
ngx_http_lua_create_req_header_table(L); /* req "header" header */
|
||||
lua_insert(L, 2); /* req header "header" */
|
||||
lua_pushvalue(L, 2); /* req header "header" header */
|
||||
lua_rawset(L, 1); /* req header */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
dd("key %s not matched", p);
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_lua_create_req_header_table(lua_State *L) {
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_http_request_t *r;
|
||||
ngx_uint_t i;
|
||||
|
||||
lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
|
||||
r = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (r == NULL) {
|
||||
luaL_error(L, "no request object found");
|
||||
return;
|
||||
}
|
||||
|
||||
lua_createtable(L, 0, 8); /* Firefox creates 8 headers in its requests */
|
||||
|
||||
part = &r->headers_in.headers.part;
|
||||
header = part->elts;
|
||||
|
||||
for (i = 0; /* void */; i++) {
|
||||
|
||||
if (i >= part->nelts) {
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
part = part->next;
|
||||
header = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http lua req header: \"%V: %V\"",
|
||||
&header[i].key, &header[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ngx_http_lua_ngx_req_set(lua_State *L) {
|
||||
u_char *p;
|
||||
size_t len;
|
||||
|
||||
/* we skip the first argument that is the table */
|
||||
p = (u_char *) luaL_checklstring(L, 2, &len);
|
||||
|
||||
return luaL_error(L, "Attempt to write to ngx.req. with the key \"%s\"", p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
ngx_http_lua_header_get(lua_State *L)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,9 @@ int ngx_http_lua_ngx_location_capture_multi(lua_State *L);
|
|||
int ngx_http_lua_ngx_get(lua_State *L);
|
||||
int ngx_http_lua_ngx_set(lua_State *L);
|
||||
|
||||
int ngx_http_lua_ngx_req_get(lua_State *L);
|
||||
int ngx_http_lua_ngx_req_set(lua_State *L);
|
||||
|
||||
int ngx_http_lua_header_get(lua_State *L);
|
||||
int ngx_http_lua_header_set(lua_State *L);
|
||||
|
||||
|
|
|
@ -631,6 +631,21 @@ init_ngx_lua_globals(lua_State *L)
|
|||
|
||||
lua_setfield(L, -2, "var");
|
||||
|
||||
/* {{{ ngx.req table */
|
||||
|
||||
lua_newtable(L); /* .req */
|
||||
|
||||
lua_createtable(L, 0, 2); /* metatable for .header */
|
||||
lua_pushcfunction(L, ngx_http_lua_ngx_req_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, ngx_http_lua_ngx_req_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
lua_setfield(L, -2, "req");
|
||||
|
||||
/* }}} */
|
||||
|
||||
#if 1
|
||||
lua_newtable(L); /* .header */
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# vim:set ft= ts=4 sw=4 et fdm=marker:
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx::Socket;
|
||||
|
||||
#worker_connections(1014);
|
||||
#master_process_enabled(1);
|
||||
#log_level('warn');
|
||||
|
||||
repeat_each(2);
|
||||
#repeat_each(1);
|
||||
|
||||
plan tests => blocks() * repeat_each() * 2;
|
||||
|
||||
#no_diff();
|
||||
#no_long_string();
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: random access req headers
|
||||
--- config
|
||||
location /req-header {
|
||||
content_by_lua '
|
||||
ngx.say("Foo: ", ngx.req.header["Foo"] or "nil")
|
||||
ngx.say("Bar: ", ngx.req.header["Bar"] or "nil")
|
||||
';
|
||||
}
|
||||
--- request
|
||||
GET /req-header
|
||||
--- more_headers
|
||||
Foo: bar
|
||||
Bar: baz
|
||||
--- response_body
|
||||
Foo: bar
|
||||
Bar: baz
|
||||
|
||||
|
||||
|
||||
=== TEST 2: iterating through headers
|
||||
--- config
|
||||
location /req-header {
|
||||
content_by_lua '
|
||||
local h = {}
|
||||
for k, v in pairs(ngx.req.header) do
|
||||
h[k] = v
|
||||
end
|
||||
ngx.say("Foo: ", h["Foo"] or "nil")
|
||||
ngx.say("Bar: ", h["Bar"] or "nil")
|
||||
';
|
||||
}
|
||||
--- request
|
||||
GET /req-header
|
||||
--- more_headers
|
||||
Foo: bar
|
||||
Bar: baz
|
||||
--- response_body
|
||||
Foo: bar
|
||||
Bar: baz
|
||||
|
||||
|
||||
|
||||
=== TEST 3: setting req header table
|
||||
--- config
|
||||
location /req-header {
|
||||
content_by_lua '
|
||||
ngx.req.header.foo = 3;
|
||||
ngx.say(ngx.req.header.foo)
|
||||
';
|
||||
}
|
||||
--- request
|
||||
GET /req-header
|
||||
--- more_headers
|
||||
Foo: bar
|
||||
Bar: baz
|
||||
--- response_body
|
||||
3
|
||||
|
Загрузка…
Ссылка в новой задаче