25
30
static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r,
27
32
static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr,
28
ngx_uint_t method, ngx_http_request_body_t *body,
29
unsigned share_all_vars);
33
ngx_uint_t method, ngx_http_request_body_t *body, unsigned vars_action,
34
ngx_array_t *extra_vars);
30
35
static int ngx_http_lua_ngx_location_capture(lua_State *L);
31
36
static int ngx_http_lua_ngx_location_capture_multi(lua_State *L);
37
static void ngx_http_lua_process_vars_option(ngx_http_request_t *r,
38
lua_State *L, int table, ngx_array_t **varsp);
39
static ngx_int_t ngx_http_lua_subrequest_add_extra_vars(ngx_http_request_t *r,
40
ngx_array_t *extra_vars);
34
43
/* ngx.location.capture is just a thin wrapper around
175
190
extra_args.data = NULL;
176
191
extra_args.len = 0;
193
if (extra_vars != NULL) {
194
/* flush out existing elements in the array */
195
extra_vars->nelts = 0;
180
202
if (nargs == 2) {
181
203
/* check out the options table */
183
lua_rawgeti(L, 2, 2);
205
lua_rawgeti(L, 2, 2); /* queries query uri opts */
207
dd("queries query uri opts: %d", lua_gettop(L));
185
209
if (lua_type(L, 4) != LUA_TTABLE) {
186
210
return luaL_error(L, "expecting table as the 2nd argument for "
187
"subrequest %d", index);
211
"subrequest %d, but got %s", index,
212
luaL_typename(L, 4));
215
dd("queries query uri opts: %d", lua_gettop(L));
190
217
/* check the args option */
192
219
lua_getfield(L, 4, "args");
245
dd("queries query uri opts: %d", lua_gettop(L));
247
/* check the vars option */
249
lua_getfield(L, 4, "vars");
251
switch (lua_type(L, -1)) {
253
ngx_http_lua_process_vars_option(r, L, -1, &extra_vars);
255
dd("post process vars top: %d", lua_gettop(L));
263
return luaL_error(L, "Bad vars option value");
268
dd("queries query uri opts: %d", lua_gettop(L));
218
270
/* check the share_all_vars option */
220
272
lua_getfield(L, 4, "share_all_vars");
222
type = lua_type(L, -1);
224
if (type == LUA_TNIL) {
228
if (type != LUA_TBOOLEAN) {
229
return luaL_error(L, "Bad share_all_vars option value");
232
share_all_vars = lua_toboolean(L, -1);
237
/* check the method option */
274
switch (lua_type(L, -1)) {
280
if (lua_toboolean(L, -1)) {
281
vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS;
286
return luaL_error(L, "Bad share_all_vars option value");
291
dd("queries query uri opts: %d", lua_gettop(L));
293
/* check the copy_all_vars option */
295
lua_getfield(L, 4, "copy_all_vars");
297
switch (lua_type(L, -1)) {
303
if (lua_toboolean(L, -1)) {
304
vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS;
309
return luaL_error(L, "Bad copy_all_vars option value");
314
dd("queries query uri opts: %d", lua_gettop(L));
316
/* check the "method" option */
239
318
lua_getfield(L, 4, "method");
380
492
ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);
382
rc = ngx_http_lua_adjust_subrequest(sr, method, body, share_all_vars);
494
rc = ngx_http_lua_adjust_subrequest(sr, method, body, vars_action,
384
497
if (rc != NGX_OK) {
385
498
return luaL_error(L, "failed to adjust the subrequest: %d",
389
lua_pop(L, 2); /* pop the subrequest argument and uri */
502
dd("queries query uri opts ctx? %d", lua_gettop(L));
504
/* stack: queries query uri ctx? */
507
ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1);
518
ngx_array_destroy(extra_vars);
392
521
return lua_yield(L, 0);
458
589
sr->headers_in.headers.last = &sr->headers_in.headers.part;
461
if (! share_all_vars) {
592
if (!(vars_action & NGX_HTTP_LUA_SHARE_ALL_VARS)) {
462
593
/* we do not inherit the parent request's variables */
463
594
cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module);
465
sr->variables = ngx_pcalloc(sr->pool, cmcf->variables.nelts
466
* sizeof(ngx_http_variable_value_t));
468
if (sr->variables == NULL) {
469
return NGX_HTTP_INTERNAL_SERVER_ERROR;
596
size = cmcf->variables.nelts * sizeof(ngx_http_variable_value_t);
598
if (vars_action & NGX_HTTP_LUA_COPY_ALL_VARS) {
600
sr->variables = ngx_palloc(sr->pool, size);
601
if (sr->variables == NULL) {
605
ngx_memcpy(sr->variables, r->variables, size);
609
/* we do not inherit the parent request's variables */
611
sr->variables = ngx_pcalloc(sr->pool, size);
612
if (sr->variables == NULL) {
618
return ngx_http_lua_subrequest_add_extra_vars(sr, extra_vars);
623
ngx_http_lua_subrequest_add_extra_vars(ngx_http_request_t *sr,
624
ngx_array_t *extra_vars)
626
ngx_http_core_main_conf_t *cmcf;
627
ngx_http_variable_t *v;
628
ngx_http_variable_value_t *vv;
634
ngx_hash_t *variables_hash;
637
/* set any extra variables that were passed to the subrequest */
639
if (extra_vars == NULL || extra_vars->nelts == 0) {
643
cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module);
645
variables_hash = &cmcf->variables_hash;
647
var = extra_vars->elts;
649
for (i = 0; i < extra_vars->nelts; i++, var++) {
650
/* copy the variable's name and value because they are allocated
653
len = var->key.len + var->value.len;
655
p = ngx_pnalloc(sr->pool, len);
661
name.len = var->key.len;
663
p = ngx_copy(p, var->key.data, var->key.len);
665
hash = ngx_hash_strlow(name.data, name.data, name.len);
668
len = var->value.len;
670
ngx_memcpy(p, var->value.data, len);
672
v = ngx_hash_find(variables_hash, hash, name.data, name.len);
675
if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {
676
ngx_log_error(NGX_LOG_ERR, sr->connection->log, 0,
677
"variable \"%V\" not changeable", &name);
678
return NGX_HTTP_INTERNAL_SERVER_ERROR;
681
if (v->set_handler) {
682
vv = ngx_palloc(sr->pool, sizeof(ngx_http_variable_value_t));
689
vv->no_cacheable = 0;
694
v->set_handler(sr, vv, v->data);
696
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sr->connection->log, 0,
697
"variable \"%V\" set to value \"%v\"", &name, vv);
702
if (v->flags & NGX_HTTP_VAR_INDEXED) {
703
vv = &sr->variables[v->index];
707
vv->no_cacheable = 0;
712
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sr->connection->log, 0,
713
"variable \"%V\" set to value \"%v\"", &name, vv);
719
ngx_log_error(NGX_LOG_ERR, sr->connection->log, 0,
720
"variable \"%V\" cannot be assigned a value (maybe you "
721
"forgot to define it first?) ", &name);
731
ngx_http_lua_process_vars_option(ngx_http_request_t *r, lua_State *L,
732
int table, ngx_array_t **varsp)
738
table = lua_gettop(L) + table + 1;
745
vars = ngx_array_create(r->pool, 4, sizeof(ngx_keyval_t));
748
luaL_error(L, "out of memory");
756
while (lua_next(L, table) != 0) {
758
if (lua_type(L, -2) != LUA_TSTRING) {
759
luaL_error(L, "attempt to use a non-string key in the "
760
"\"vars\" option table");
764
if (!lua_isstring(L, -1)) {
765
luaL_error(L, "attempt to use bad variable value type %s",
766
luaL_typename(L, -1));
769
var = ngx_array_push(vars);
772
luaL_error(L, "out of memory");
776
var->key.data = (u_char *) lua_tolstring(L, -2, &var->key.len);
777
var->value.data = (u_char *) lua_tolstring(L, -1, &var->value.len);
478
785
ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc)
670
977
h->value.len = ngx_sprintf(h->value.data, "%O", len) - h->value.data;
979
h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(
980
ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(
981
ngx_hash('c', 'o'), 'n'), 't'), 'e'), 'n'), 't'), '-'), 'l'), 'e'),
982
'n'), 'g'), 't'), 'h');
985
dd("content length hash: %lu == %lu", (unsigned long) h->hash,
986
ngx_hash_key_lc((u_char *) "Content-Length",
987
sizeof("Content-Length") - 1));
674
990
dd("r content length: %.*s",
675
991
(int)r->headers_in.content_length->value.len,