419
442
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
420
if (ctx != NULL && ctx->eof == 0) {
421
ctx->eof = 1; /* set eof flag to prevent further output */
422
ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/);
444
rc = ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/);
446
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
447
return luaL_error(L, "failed to send eof buf");
454
/* ngx.location.capture is just a thin wrapper around
455
* ngx.location.capture_multi */
430
457
ngx_http_lua_ngx_location_capture(lua_State *L)
463
if (n != 1 && n != 2) {
464
return luaL_error(L, "expecting one or two arguments");
467
lua_createtable(L, n, 0); /* uri opts? table */
468
lua_insert(L, 1); /* table uri opts? */
469
if (n == 1) { /* table uri */
470
lua_rawseti(L, 1, 1); /* table */
472
} else { /* table uri opts */
473
lua_rawseti(L, 1, 2); /* table uri */
474
lua_rawseti(L, 1, 1); /* table */
477
lua_createtable(L, 1, 0); /* table table' */
478
lua_insert(L, 1); /* table' table */
479
lua_rawseti(L, 1, 1); /* table' */
481
return ngx_http_lua_ngx_location_capture_multi(L);
486
ngx_http_lua_ngx_location_capture_multi(lua_State *L)
432
488
ngx_http_request_t *r;
433
489
ngx_http_request_t *sr; /* subrequest object */
434
490
ngx_http_post_subrequest_t *psr;
435
491
ngx_http_lua_ctx_t *sr_ctx;
492
ngx_http_lua_ctx_t *ctx;
438
ngx_str_t extra_args = ngx_null_string;
439
ngx_uint_t flags = 0;
495
ngx_str_t extra_args;
445
503
ngx_uint_t method;
446
ngx_http_request_body_t *body = NULL;
504
ngx_http_request_body_t *body;
449
ngx_flag_t share_all_vars = 0;
507
ngx_flag_t share_all_vars;
510
size_t sr_statuses_len;
511
size_t sr_headers_len;
512
size_t sr_bodies_len;
516
return luaL_error(L, "only one argument is expected, but got %d", n);
519
luaL_checktype(L, 1, LUA_TTABLE);
521
nsubreqs = lua_objlen(L, 1);
523
return luaL_error(L, "at least one subrequest should be specified");
451
526
lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
452
527
r = lua_touserdata(L, -1);
456
531
return luaL_error(L, "no request object found");
534
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
536
return luaL_error(L, "no ctx found");
539
sr_statuses_len = nsubreqs * sizeof(ngx_int_t);
540
sr_headers_len = nsubreqs * sizeof(ngx_http_headers_out_t *);
541
sr_bodies_len = nsubreqs * sizeof(ngx_str_t);
543
p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len +
547
return luaL_error(L, "out of memory");
550
ctx->sr_statuses = (void *) p;
551
p += sr_statuses_len;
553
ctx->sr_headers = (void *) p;
556
ctx->sr_bodies = (void *) p;
558
ctx->nsubreqs = nsubreqs;
459
560
n = lua_gettop(L);
461
if (n != 1 && n != 2) {
462
return luaL_error(L, "expecting one or two arguments");
466
/* check out the options table */
468
if (lua_type(L, 2) != LUA_TTABLE) {
469
return luaL_error(L, "expecting table as the 2nd argument");
472
/* check the args option */
474
lua_getfield(L, 2, "args");
476
type = lua_type(L, -1);
480
ngx_http_lua_process_args_option(r, L, -1, &extra_args);
489
extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
490
extra_args.len = len;
495
return luaL_error(L, "Bad args option value");
500
/* check the share_all_vars option */
502
lua_getfield(L, 2, "share_all_vars");
504
type = lua_type(L, -1);
505
if (type == LUA_TNIL) {
561
dd("top before loop: %d", n);
566
for (index = 0; index < nsubreqs; index++) {
569
lua_rawgeti(L, 1, index + 1);
570
if (lua_isnil(L, -1)) {
571
return luaL_error(L, "only array-like tables are allowed");
574
if (lua_type(L, -1) != LUA_TTABLE) {
575
return luaL_error(L, "the query argument %d is not a table, "
577
index, lua_typename(L, lua_type(L, -1)));
580
dd("lua top so far: %d", lua_gettop(L));
582
nargs = lua_objlen(L, -1);
584
if (nargs != 1 && nargs != 2) {
585
return luaL_error(L, "query argument %d expecting one or "
586
"two arguments", index);
589
lua_rawgeti(L, 2, 1); /* queries query uri */
591
dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1)));
595
extra_args.data = NULL;
601
/* check out the options table */
603
lua_rawgeti(L, 2, 2);
605
if (lua_type(L, 4) != LUA_TTABLE) {
606
return luaL_error(L, "expecting table as the 2nd argument for "
607
"subrequest %d", index);
610
/* check the args option */
612
lua_getfield(L, 4, "args");
614
type = lua_type(L, -1);
618
ngx_http_lua_process_args_option(r, L, -1, &extra_args);
627
extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
628
extra_args.len = len;
633
return luaL_error(L, "Bad args option value");
638
/* check the share_all_vars option */
640
lua_getfield(L, 4, "share_all_vars");
642
type = lua_type(L, -1);
643
if (type == LUA_TNIL) {
646
if (type != LUA_TBOOLEAN) {
647
return luaL_error(L, "Bad share_all_vars option value");
650
share_all_vars = lua_toboolean(L, -1);
655
/* check the method option */
657
lua_getfield(L, 4, "method");
659
type = lua_type(L, -1);
660
if (type == LUA_TNIL) {
661
method = NGX_HTTP_GET;
663
if (type != LUA_TNUMBER) {
664
return luaL_error(L, "Bad http request method");
667
method = (ngx_uint_t) lua_tonumber(L, -1);
672
/* check the body option */
674
lua_getfield(L, 4, "body");
676
if (type != LUA_TNIL) {
677
if (type != LUA_TSTRING && type != LUA_TNUMBER) {
678
return luaL_error(L, "Bad http request body");
681
body = ngx_pcalloc(r->pool,
682
sizeof(ngx_http_request_body_t));
685
return luaL_error(L, "out of memory");
688
q = (u_char *) lua_tolstring(L, -1, &len);
690
dd("request body: [%.*s]", (int) len, q);
693
b = ngx_create_temp_buf(r->pool, len);
695
return luaL_error(L, "out of memory");
698
b->last = ngx_copy(b->last, q, len);
700
body->bufs = ngx_alloc_chain_link(r->pool);
701
if (body->bufs == NULL) {
702
return luaL_error(L, "out of memory");
706
body->bufs->next = NULL;
712
lua_pop(L, 2); /* pop body and opts table */
508
if (type != LUA_TBOOLEAN) {
509
return luaL_error(L, "Bad share_all_vars option value");
512
share_all_vars = lua_toboolean(L, -1);
517
/* check the method option */
519
lua_getfield(L, 2, "method");
521
type = lua_type(L, -1);
522
if (type == LUA_TNIL) {
523
714
method = NGX_HTTP_GET;
525
if (type != LUA_TNUMBER) {
526
return luaL_error(L, "Bad http request method");
529
method = (ngx_uint_t) lua_tonumber(L, -1);
534
/* check the body option */
536
lua_getfield(L, 2, "body");
538
if (type != LUA_TNIL) {
539
if (type != LUA_TSTRING && type != LUA_TNUMBER) {
540
return luaL_error(L, "Bad http request body");
543
q = (u_char *) lua_tolstring(L, -1, &len);
545
body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
547
b = ngx_create_temp_buf(r->pool, len);
549
return luaL_error(L, "out of memory");
552
b->last = ngx_copy(b->last, q, len);
554
body->bufs = ngx_alloc_chain_link(r->pool);
555
if (body->bufs == NULL) {
556
return luaL_error(L, "out of memory");
560
body->bufs->next = NULL;
569
method = NGX_HTTP_GET;
572
p = (u_char *) luaL_checklstring(L, 1, &len);
574
uri.data = ngx_palloc(r->pool, len);
575
if (uri.data == NULL) {
576
return luaL_error(L, "memory allocation error");
579
ngx_memcpy(uri.data, p, len);
586
rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
588
dd("rc = %d", (int) rc);
590
return luaL_error(L, "unsafe uri in argument #1: %s", p);
595
} else if (extra_args.len) {
596
/* concatenate the two parts of args together */
597
len = args.len + (sizeof("&") - 1) + extra_args.len;
599
p = ngx_palloc(r->pool, len);
718
dd("top size so far: %d", n);
720
p = (u_char *) luaL_checklstring(L, 3, &len);
722
uri.data = ngx_palloc(r->pool, len);
723
if (uri.data == NULL) {
724
return luaL_error(L, "memory allocation error");
727
ngx_memcpy(uri.data, p, len);
736
rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
738
dd("rc = %d", (int) rc);
740
return luaL_error(L, "unsafe uri in argument #1: %s", p);
746
} else if (extra_args.len) {
747
/* concatenate the two parts of args together */
748
len = args.len + (sizeof("&") - 1) + extra_args.len;
750
p = ngx_palloc(r->pool, len);
752
return luaL_error(L, "out of memory");
755
q = ngx_copy(p, args.data, args.len);
757
q = ngx_copy(q, extra_args.data, extra_args.len);
763
psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
765
return luaL_error(L, "memory allocation error");
768
sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
769
if (sr_ctx == NULL) {
601
770
return luaL_error(L, "out of memory");
604
q = ngx_copy(p, args.data, args.len);
606
q = ngx_copy(q, extra_args.data, extra_args.len);
612
psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
614
return luaL_error(L, "memory allocation error");
617
sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
618
if (sr_ctx == NULL) {
619
return luaL_error(L, "memory allocation error");
624
psr->handler = ngx_http_lua_post_subrequest;
627
rc = ngx_http_subrequest(r, &uri, &args, &sr, psr, 0);
630
return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
633
ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);
635
rc = ngx_http_lua_adjust_subrequest(sr, method, body, share_all_vars);
638
return luaL_error(L, "failed to adjust the subrequest: %d", (int) rc);
773
/* set by ngx_pcalloc:
774
* sr_ctx->run_post_subrequest = 0
775
* sr_ctx->free = NULL
778
sr_ctx->cc_ref = LUA_NOREF;
782
sr_ctx->index = index;
784
psr->handler = ngx_http_lua_post_subrequest;
787
rc = ngx_http_subrequest(r, &uri, &args, &sr, psr, 0);
790
return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
793
ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);
795
rc = ngx_http_lua_adjust_subrequest(sr, method, body, share_all_vars);
798
return luaL_error(L, "failed to adjust the subrequest: %d",
802
lua_pop(L, 2); /* pop the subrequest argument and uri */
641
805
lua_pushinteger(L, location_capture);
739
920
return NGX_ERROR;
745
pr->write_event_handler = ngx_http_lua_wev_handler;
925
if (pr_ctx->waiting == 0) {
929
if (pr_ctx->entered_content_phase) {
930
dd("setting wev handler");
931
pr->write_event_handler = ngx_http_lua_content_wev_handler;
934
dd("status rc = %d", (int) rc);
935
dd("status headers_out.status = %d", (int) r->headers_out.status);
936
dd("uri: %.*s", (int) r->uri.len, r->uri.data);
747
938
/* capture subrequest response status */
748
939
if (rc == NGX_ERROR) {
749
pr_ctx->sr_status = NGX_HTTP_INTERNAL_SERVER_ERROR;
940
pr_ctx->sr_statuses[ctx->index] = NGX_HTTP_INTERNAL_SERVER_ERROR;
750
942
} else if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
751
pr_ctx->sr_status = rc;
944
pr_ctx->sr_statuses[ctx->index] = rc;
753
pr_ctx->sr_status = r->headers_out.status;
756
/* copy subrequest response body */
757
pr_ctx->sr_body = ctx->body;
948
pr_ctx->sr_statuses[ctx->index] = r->headers_out.status;
951
if (pr_ctx->sr_statuses[ctx->index] == 0) {
952
pr_ctx->sr_statuses[ctx->index] = NGX_HTTP_OK;
955
dd("pr_ctx status: %d", (int) pr_ctx->sr_statuses[ctx->index]);
759
957
/* copy subrequest response headers */
760
pr_ctx->sr_headers = &r->headers_out;
762
/* ensure that the parent request is (or will be)
763
* posted out the head of the r->posted_requests chain */
765
if (r->main->posted_requests
766
&& r->main->posted_requests->request != pr)
959
pr_ctx->sr_headers[ctx->index] = &r->headers_out;
961
/* copy subrequest response body */
963
body_str = &pr_ctx->sr_bodies[ctx->index];
965
if (ctx->body && ctx->body->next == NULL) {
966
/* optimize for the single buf body */
970
len = cl->buf->last - cl->buf->pos;
975
body_str->data = NULL;
978
body_str->data = cl->buf->pos;
983
for (cl = ctx->body; cl; cl = cl->next) {
984
/* ignore all non-memory buffers */
985
len += cl->buf->last - cl->buf->pos;
991
body_str->data = NULL;
994
p = ngx_palloc(r->pool, len);
1001
/* copy from and then free the data buffers */
1003
for (cl = ctx->body; cl; cl = cl->next) {
1004
p = ngx_copy(p, cl->buf->pos,
1005
cl->buf->last - cl->buf->pos);
1007
dd("free bod chain link buf ASAP");
1008
ngx_pfree(r->pool, cl->buf->start);
1014
/* free the ctx->body chain such that it can be reused by
1015
* other subrequests */
1017
if (pr_ctx->free == NULL) {
1018
pr_ctx->free = ctx->body;
1021
for (cl = pr_ctx->free; cl->next; cl = cl->next) { /* void */ }
1023
cl->next = ctx->body;
1027
/* work-around issues in nginx's event module */
1029
if (r != r->connection->data && r->postponed &&
1030
(r->main->posted_requests == NULL ||
1031
r->main->posted_requests->request != pr))
768
rc = ngx_http_lua_post_request_at_head(pr, NULL);
1033
#if defined(nginx_version) && nginx_version >= 8012
1034
ngx_http_post_request(pr, NULL);
1036
ngx_http_post_request(pr);