5
6
#include "ngx_http_lua_hook.h"
6
7
#include "ngx_http_lua_util.h"
7
8
#include "ngx_http_lua_contentby.h"
8
#include "ngx_http_lua_headers.h"
9
#include "ngx_http_lua_headers_out.h"
10
#include "ngx_http_lua_headers_in.h"
10
12
#define NGX_UNESCAPE_URI_COMPONENT 0
13
#define ngx_str_set(str, text) \
14
(str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
18
14
#define ngx_http_lua_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
16
jmp_buf ngx_http_lua_exception;
20
18
static ngx_str_t ngx_http_lua_get_method = ngx_http_lua_method_name("GET");
21
19
static ngx_str_t ngx_http_lua_put_method = ngx_http_lua_method_name("PUT");
22
20
static ngx_str_t ngx_http_lua_post_method = ngx_http_lua_method_name("POST");
32
30
static void ngx_http_lua_process_args_option(ngx_http_request_t *r,
33
31
lua_State *L, int table, ngx_str_t *args);
34
32
static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r,
36
34
static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr,
37
35
ngx_uint_t method, ngx_http_request_body_t *body,
38
36
ngx_flag_t share_all_vars);
39
static ngx_int_t ngx_http_lua_post_subrequest(ngx_http_request_t *r,
40
void *data, ngx_int_t rc);
41
37
static int ngx_http_lua_ngx_echo(lua_State *L, ngx_flag_t newline);
42
38
static void ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size,
1936
ngx_http_lua_header_get(lua_State *L)
1946
ngx_http_lua_ngx_req_get_headers(lua_State *L) {
1947
ngx_list_part_t *part;
1948
ngx_table_elt_t *header;
1949
ngx_http_request_t *r;
1952
if (lua_gettop(L) != 0) {
1953
return luaL_error(L, "expecting 0 arguments but seen %d",
1957
lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
1958
r = lua_touserdata(L, -1);
1962
return luaL_error(L, "no request object found");
1965
lua_createtable(L, 0, 4);
1967
part = &r->headers_in.headers.part;
1968
header = part->elts;
1970
for (i = 0; /* void */; i++) {
1972
if (i >= part->nelts) {
1973
if (part->next == NULL) {
1978
header = part->elts;
1982
lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len);
1983
/* stack: table key */
1985
lua_pushvalue(L, -1); /* stack: table key key */
1987
/* check if header already exists */
1988
lua_rawget(L, -3); /* stack: table key value */
1990
if (lua_isnil(L, -1)) {
1991
dd("req.header key %.*s not exist", (int) header[i].key.len,
1992
header[i].key.data);
1994
lua_pop(L, 1); /* stack: table key */
1996
lua_pushlstring(L, (char *) header[i].value.data,
1997
header[i].value.len); /* stack: table key value */
1999
lua_rawset(L, -3); /* stack: table */
2002
dd("req.header key %.*s exists", (int) header[i].key.len,
2003
header[i].key.data);
2005
if (! lua_istable(L, -1)) { /* already inserted one value */
2006
dd("req.header key %.*s already has one value",
2007
(int) header[i].key.len, header[i].key.data);
2008
lua_createtable(L, 4, 0);
2009
/* stack: table key value table */
2011
lua_insert(L, -2); /* stack: table key table value */
2012
lua_rawseti(L, -2, 1); /* stack: table key table */
2014
lua_pushlstring(L, (char *) header[i].value.data,
2015
header[i].value.len);
2016
/* stack: table key table value */
2018
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
2019
/* stack: table key table */
2021
lua_rawset(L, -3); /* stack: table */
2024
dd("req.header key %.*s already has multi values",
2025
(int) header[i].key.len, header[i].key.data);
2027
lua_pushlstring(L, (char *) header[i].value.data,
2028
header[i].value.len);
2029
/* stack: table key table value */
2031
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
2032
/* stack: table key table */
2034
lua_pop(L, 2); /* stack: table */
2038
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2039
"http lua req header: \"%V: %V\"",
2040
&header[i].key, &header[i].value);
2048
ngx_http_lua_ngx_header_get(lua_State *L)
1938
2050
return luaL_error(L, "header get not implemented yet");
1943
ngx_http_lua_header_set(lua_State *L)
2055
ngx_http_lua_ngx_header_set(lua_State *L)
1945
2057
ngx_http_request_t *r;
2048
2160
dd("key: %.*s, value: %.*s",
2049
2161
(int) key.len, key.data, (int) value.len, value.data);
2051
rc = ngx_http_lua_set_header(r, key, value, 1 /* override */);
2163
rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */);
2166
return luaL_error(L, "failed to set header %s (error: %d)",
2167
key.data, (int) rc);
2175
ngx_http_lua_ngx_req_header_clear(lua_State *L)
2177
if (lua_gettop(L) != 1) {
2178
return luaL_error(L, "expecting one arguments, but seen %d",
2184
return ngx_http_lua_ngx_req_header_set_helper(L);
2189
ngx_http_lua_ngx_req_header_set(lua_State *L)
2191
if (lua_gettop(L) != 2) {
2192
return luaL_error(L, "expecting two arguments, but seen %d",
2196
return ngx_http_lua_ngx_req_header_set_helper(L);
2201
ngx_http_lua_ngx_req_header_set_helper(lua_State *L)
2203
ngx_http_request_t *r;
2212
lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
2213
r = lua_touserdata(L, -1);
2217
return luaL_error(L, "no request object found");
2220
p = (u_char *) luaL_checklstring(L, 1, &len);
2222
dd("key: %.*s, len %d", (int) len, p, (int) len);
2224
/* replace "_" with "-" */
2225
for (i = 0; i < len; i++) {
2231
key.data = ngx_palloc(r->pool, len + 1);
2232
if (key.data == NULL) {
2233
return luaL_error(L, "out of memory");
2236
ngx_memcpy(key.data, p, len);
2238
key.data[len] = '\0';
2242
if (lua_type(L, 2) == LUA_TNIL) {
2246
} else if (lua_type(L, 2) == LUA_TTABLE) {
2247
n = luaL_getn(L, 2);
2253
for (i = 1; i <= n; i++) {
2254
dd("header value table index %d", (int) i);
2256
lua_rawgeti(L, 2, i);
2257
p = (u_char *) luaL_checklstring(L, -1, &len);
2259
value.data = ngx_palloc(r->pool, len);
2260
if (value.data == NULL) {
2261
return luaL_error(L, "out of memory");
2264
ngx_memcpy(value.data, p, len);
2267
rc = ngx_http_lua_set_input_header(r, key, value,
2268
i == 1 /* override */);
2271
return luaL_error(L,
2272
"failed to set header %s (error: %d)",
2273
key.data, (int) rc);
2281
p = (u_char *) luaL_checklstring(L, 2, &len);
2282
value.data = ngx_palloc(r->pool, len);
2283
if (value.data == NULL) {
2284
return luaL_error(L, "out of memory");
2287
ngx_memcpy(value.data, p, len);
2291
dd("key: %.*s, value: %.*s",
2292
(int) key.len, key.data, (int) value.len, value.data);
2294
rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */);
2053
2296
if (rc != NGX_OK) {
2054
2297
return luaL_error(L, "failed to set header %s (error: %d)",
2532
#endif /* defined(NDK) && NDK */
2290
2535
static ngx_int_t
2291
ngx_http_lua_set_content_length_header(ngx_http_request_t *r, size_t len)
2536
ngx_http_lua_set_content_length_header(ngx_http_request_t *r, off_t len)
2538
ngx_table_elt_t *h, *header;
2540
ngx_list_part_t *part;
2541
ngx_http_request_t *pr;
2295
2544
r->headers_in.content_length_n = len;
2296
r->headers_in.content_length = ngx_pcalloc(r->pool,
2297
sizeof(ngx_table_elt_t));
2299
r->headers_in.content_length->value.data =
2300
ngx_palloc(r->pool, NGX_OFF_T_LEN);
2302
if (r->headers_in.content_length->value.data == NULL) {
2306
r->headers_in.content_length->value.len = ngx_sprintf(
2307
r->headers_in.content_length->value.data, "%O",
2308
r->headers_in.content_length_n) -
2309
r->headers_in.content_length->value.data;
2311
2546
if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
2312
2547
sizeof(ngx_table_elt_t)) != NGX_OK) {
2331
2562
ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
2564
r->headers_in.content_length = h;
2566
p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
2573
h->value.len = ngx_sprintf(h->value.data, "%O", len) - h->value.data;
2333
2577
dd("r content length: %.*s",
2334
2578
(int)r->headers_in.content_length->value.len,
2335
2579
r->headers_in.content_length->value.data);
2587
/* forward the parent request's all other request headers */
2589
part = &pr->headers_in.headers.part;
2590
header = part->elts;
2592
for (i = 0; /* void */; i++) {
2594
if (i >= part->nelts) {
2595
if (part->next == NULL) {
2600
header = part->elts;
2604
h = ngx_list_push(&r->headers_in.headers);
2612
/* XXX maybe we should set those built-in header slot in
2613
* ngx_http_headers_in_t too? */
2643
ngx_http_lua_ngx_http_time(lua_State *L)
2648
u_char buf[sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1];
2650
if (lua_gettop(L) != 1) {
2651
return luaL_error(L, "expecting one argument");
2654
t = (time_t) luaL_checknumber(L, 1);
2657
p = ngx_http_time(p, t);
2659
lua_pushlstring(L, (char *) buf, p - buf);
2666
ngx_http_lua_ngx_parse_http_time(lua_State *L)
2672
if (lua_gettop(L) != 1) {
2673
return luaL_error(L, "expecting one argument");
2676
p = (u_char *) luaL_checklstring(L, 1, &len);
2678
time = ngx_http_parse_time(p, len);
2679
if (time == NGX_ERROR) {
2684
lua_pushnumber(L, (lua_Number) time);
2374
2691
ngx_http_lua_ngx_redirect(lua_State *L)
2376
2693
ngx_http_lua_ctx_t *ctx;