Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New features for ngx_lua #286

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3f39535
Added an optional parameter for ngx.req.set_header and ngx.req.clear_…
Apr 24, 2013
886e27b
Merged with 0.8.1
May 8, 2013
1c5e5b9
Changed the replace_underscores parameter to a table of parameters (o…
May 8, 2013
f2e849a
Added an options table to clean_header as well.
May 8, 2013
e1281a2
Merge branch 'master' of https://github.com/chaoslawful/lua-nginx-module
Sep 29, 2013
f602d0f
Added ngx.req.set_keepalive and ngx.req.get_keepalive to control the …
Sep 29, 2013
d4d2988
Removed unneeded variable.
Sep 29, 2013
ef2ce04
Added SSL support for TCP cosockets.
Sep 29, 2013
a3f9aa9
Multiple changes:
Sep 29, 2013
d4864a9
Added the option 'bsd_receive' to the receive method, which enables u…
Sep 29, 2013
08dc8b4
Added the lua_correct_location_header directive. If off, when setting…
Sep 29, 2013
7a7b7fc
Added the 'lua_enforce_content_type' directive. When this is off and …
Sep 29, 2013
2a84a4c
Added two killing functions -
Sep 30, 2013
2799aad
Lua subrequests - added support for passing the method optional param…
Sep 30, 2013
c111582
Added ngx.location.capture_stream, which enables a single subrequest …
Sep 30, 2013
2936588
Merge branch 'keepalive' into patches
Sep 30, 2013
61f8f07
Merge branch 'location-header' into patches
Sep 30, 2013
4ed8b96
Merge branch 'socket-changes' into patches
Sep 30, 2013
5e9e3c3
Merge branch 'socket-changes' into patches
Sep 30, 2013
d3c8e40
Merge branch 'subrequest-methods' into patches
Sep 30, 2013
fb225e6
Merge branch 'thread-kill' into patches
Sep 30, 2013
ac49b69
Merge branch 'subrequest-streaming' into patches
Sep 30, 2013
ae9d9f7
Added fake_close to the raw socket as well.
Sep 30, 2013
a5e3322
Merge branch 'socket-changes' into patches
Sep 30, 2013
7cd287a
del_thread doesn't remove the sleeping timer, which may cause segfaul…
Sep 30, 2013
f21cb57
Merge branch 'thread-kill' into patches
Sep 30, 2013
fff19d6
Setting ctx->headers_set to 1 whenever setting a header successfully …
Oct 1, 2013
4714264
Merge branch 'content-type' into patches
Oct 1, 2013
cf77dc3
Now when using the raw request socket, one shouldn't read the entire …
Oct 2, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/src/ngx_http_lua_initby.c \
$ngx_addon_dir/src/ngx_http_lua_socket_udp.c \
$ngx_addon_dir/src/ngx_http_lua_req_method.c \
$ngx_addon_dir/src/ngx_http_lua_req_keepalive.c \
$ngx_addon_dir/src/ngx_http_lua_phase.c \
$ngx_addon_dir/src/ngx_http_lua_uthread.c \
$ngx_addon_dir/src/ngx_http_lua_timer.c \
Expand Down Expand Up @@ -269,6 +270,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ngx_addon_dir/src/ngx_http_lua_initby.h \
$ngx_addon_dir/src/ngx_http_lua_socket_udp.h \
$ngx_addon_dir/src/ngx_http_lua_req_method.h \
$ngx_addon_dir/src/ngx_http_lua_req_keepalive.h \
$ngx_addon_dir/src/ngx_http_lua_phase.h \
$ngx_addon_dir/src/ngx_http_lua_probe.h \
$ngx_addon_dir/src/ngx_http_lua_uthread.h \
Expand Down
45 changes: 44 additions & 1 deletion src/ngx_http_lua_capturefilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "ngx_http_lua_util.h"
#include "ngx_http_lua_exception.h"
#include "ngx_http_lua_subrequest.h"

#include "ngx_http_lua_contentby.h"

ngx_http_output_header_filter_pt ngx_http_lua_next_header_filter;
ngx_http_output_body_filter_pt ngx_http_lua_next_body_filter;
Expand Down Expand Up @@ -104,6 +104,15 @@ ngx_http_lua_capture_header_filter(ngx_http_request_t *r)
}


#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
static ngx_int_t
_should_store_chain_link(ngx_chain_t *in)
{
return ((in != NULL) && ((in->buf->pos != in->buf->last)));
}
#endif


static ngx_int_t
ngx_http_lua_capture_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
Expand Down Expand Up @@ -162,6 +171,40 @@ ngx_http_lua_capture_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->seen_last_for_subreq = 1;
}

#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
if (pr_ctx->async_capture) {
/* In order to wake the parent up, we should call post and not discard
the buffer */
pr_ctx->current_subrequest = r; /* Required for wake up (?) */
pr_ctx->current_subrequest_ctx = ctx; /* Required for the buffer */

/* XXX: In some cases, pr_ctx->current_subrequest_buffer is being
cleaned by Nginx and buf gets the value 0x1... */
if (((pr_ctx->current_subrequest_buffer == NULL)
|| (pr_ctx->current_subrequest_buffer->buf == (void *) 1))
&& (_should_store_chain_link(in))) {
pr_ctx->current_subrequest_buffer = in;
}

/* TODO: Is this line needed? */
r->parent->write_event_handler = ngx_http_lua_content_wev_handler;

if (!eof) {
pr_ctx->wakeup_subrequest = 1;
/* On EOF, the post subrequest callback is called, and it handles
the setting of the resume handler. The parent request would be
woken up anyway by Nginx.
*/
if (ngx_http_post_request(r->parent, NULL) != NGX_OK) {
return NGX_ERROR;
}
return NGX_OK;
} else {
pr_ctx->wakeup_subrequest = 0;
}
}
#endif

ngx_http_lua_discard_bufs(r->pool, in);

return NGX_OK;
Expand Down
28 changes: 28 additions & 0 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,16 @@ typedef struct {
ngx_flag_t transform_underscores_in_resp_headers;
ngx_flag_t log_socket_errors;
ngx_flag_t check_client_abort;

ngx_flag_t enforce_content_type;
ngx_flag_t correct_location_header;

#if (NGX_HTTP_SSL)
ngx_ssl_t *ssl;
ngx_flag_t ssl_verify;
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
#endif
} ngx_http_lua_loc_conf_t;


Expand Down Expand Up @@ -330,6 +340,19 @@ typedef struct ngx_http_lua_ctx_s {

ngx_int_t exit_code;

#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
ngx_int_t async_capture;
ngx_http_request_t *current_subrequest;
struct ngx_http_lua_ctx_s *current_subrequest_ctx;
ngx_chain_t *current_subrequest_buffer;
ngx_int_t returned_headers;
#endif

ngx_http_lua_co_ctx_t *calling_coctx; /* co ctx for the caller to location.capture */

ngx_http_lua_co_ctx_t *req_body_reader_co_ctx; /* co ctx for the coroutine
reading the request
body */
ngx_http_lua_co_ctx_t *downstream_co_ctx; /* co ctx for the coroutine
reading the request body */

Expand Down Expand Up @@ -371,6 +394,11 @@ typedef struct ngx_http_lua_ctx_s {
unsigned headers_set:1; /* whether the user has set custom
response headers */

#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
unsigned wakeup_subrequest:1;
unsigned subrequest_yield:1;
#endif

unsigned entered_rewrite_phase:1;
unsigned entered_access_phase:1;
unsigned entered_content_phase:1;
Expand Down
58 changes: 57 additions & 1 deletion src/ngx_http_lua_contentby.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@

static void ngx_http_lua_content_phase_post_read(ngx_http_request_t *r);

#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
static ngx_int_t _is_chain_valid(ngx_chain_t * cl);
static ngx_int_t _is_last_chain_link(ngx_chain_t * cl);
static ngx_int_t _post_request_if_not_posted(ngx_http_request_t *r,
ngx_http_posted_request_t *pr);
#endif

ngx_int_t
ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
Expand Down Expand Up @@ -115,17 +121,67 @@ ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
}


#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
static ngx_int_t
_post_request_if_not_posted(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
{
ngx_http_posted_request_t *p;

/* Search request in the posted requests list, so that it would not be posted twice. */
for (p = r->main->posted_requests; p; p = p->next) {
if (p->request == r) {
return NGX_OK;
}
}

return ngx_http_post_request(r, pr);
}

static ngx_int_t
_is_chain_valid(ngx_chain_t * cl)
{
/* For some reason, sometimes when cl->buf is cleaned, 1 is assigned to it. */
return ((cl != NULL) && (cl->buf != NULL) && (cl->buf != (void *) 1));
}
static ngx_int_t
_is_last_chain_link(ngx_chain_t * cl)
{
/* last_in_chain is for subrequests. */
return cl->buf->last_in_chain || cl->buf->last_buf;
}
#endif

void
ngx_http_lua_content_wev_handler(ngx_http_request_t *r)
{
ngx_http_lua_ctx_t *ctx;
ngx_int_t rc;

ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
if (ctx == NULL) {
return;
}

(void) ctx->resume_handler(r);
rc = ctx->resume_handler(r);

if (rc == NGX_DONE) {
return;
}

#ifdef NGX_LUA_CAPTURE_DOWN_STREAMING
if (ctx->current_subrequest && ctx->wakeup_subrequest) {
/* Make sure that the subrequest continues */
if (_post_request_if_not_posted(ctx->current_subrequest, NULL) != NGX_OK) {
ngx_http_lua_finalize_request(r, NGX_ERROR);
}
/* Don't try to discard the last buffer, as it will cause a NULL dereference... */
if (_is_chain_valid(ctx->current_subrequest_buffer) && (!_is_last_chain_link(ctx->current_subrequest_buffer))) {
ngx_http_lua_discard_bufs(ctx->current_subrequest->pool, ctx->current_subrequest_buffer);
}
ctx->current_subrequest_buffer = NULL;
ctx->wakeup_subrequest = 0;
}
#endif
}


Expand Down
27 changes: 19 additions & 8 deletions src/ngx_http_lua_headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
}
}

if (!ctx->headers_set) {
if (!ctx->headers_set && llcf->enforce_content_type) {
rc = ngx_http_set_content_type(r);
if (rc != NGX_OK) {
return luaL_error(L,
Expand Down Expand Up @@ -531,6 +531,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
}
}

ctx->headers_set = 1;
return 0;
}

Expand All @@ -555,19 +556,28 @@ ngx_http_lua_ngx_header_set(lua_State *L)
key.data, (int) rc);
}

ctx->headers_set = 1;
return 0;
}


static int
ngx_http_lua_ngx_req_header_clear(lua_State *L)
{
if (lua_gettop(L) != 1) {
return luaL_error(L, "expecting one arguments, but seen %d",
ngx_uint_t n;
n = lua_gettop(L);
if ((n != 1) && (n != 2)) {
return luaL_error(L, "expecting one or two arguments, but seen %d",
lua_gettop(L));
}

lua_pushnil(L);
if (n == 2) {
lua_pushnil(L);
/* Top element is now 3, replace it with element 3 */
lua_insert(L, 2);
} else {
lua_pushnil(L);
}

return ngx_http_lua_ngx_req_header_set_helper(L);
}
Expand All @@ -576,7 +586,7 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L)
static int
ngx_http_lua_ngx_req_header_set(lua_State *L)
{
if (lua_gettop(L) != 2) {
if ((lua_gettop(L) != 2) && (lua_gettop(L) != 3)) {
return luaL_error(L, "expecting two arguments, but seen %d",
lua_gettop(L));
}
Expand Down Expand Up @@ -614,9 +624,10 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L)

#if 0
/* replace "_" with "-" */
for (i = 0; i < len; i++) {
if (p[i] == '_') {
p[i] = '-';
for (i = 0; i < len; i++) {
if (p[i] == '_') {
p[i] = '-';
}
}
}
#endif
Expand Down
14 changes: 14 additions & 0 deletions src/ngx_http_lua_headers_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
ngx_http_lua_header_val_t hv;
ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers;
ngx_uint_t i;
ngx_http_lua_loc_conf_t *llcf;

llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);

dd("set header value: %.*s", (int) value.len, value.data);

Expand All @@ -455,6 +458,17 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
continue;
}

if (!llcf->correct_location_header
&& ngx_strncasecmp(hv.key.data,
(u_char *) "Location",
sizeof("Location"))
== 0) {
/* XXX The best way to get the index of the last of the structure */
i = (sizeof(ngx_http_lua_set_handlers) /
sizeof(ngx_http_lua_set_handlers[0])) - 1;
break;
}

dd("Matched handler: %s %s", handlers[i].name.data, hv.key.data);

hv.offset = handlers[i].offset;
Expand Down
Loading