Skip to content

Commit

Permalink
feature: shared ngx.ctx among SSL_* phases and the following phases.
Browse files Browse the repository at this point in the history
  • Loading branch information
spacewander committed Aug 21, 2020
1 parent 21cfd8a commit 489ae10
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3769,6 +3769,14 @@ Then `GET /orig` will give

rather than the original `"hello"` value.

Because HTTP request is created after SSL handshake, the `ngx.ctx` created
in [ssl_certificate_by_lua*](#ssl_certificate_by_lua), [ssl_session_store_by_lua*](#ssl_session_store_by_lua) and [ssl_session_fetch_by_lua*](#ssl_session_fetch_by_lua)
is not available in the following phases like [rewrite_by_lua*](#rewrite_by_lua).

Since `dev`, the `ngx.ctx` created during a SSL handshake
will be inherited by the requests which share the same TCP connection established by the handshake.
Note that overwrite values in `ngx.ctx` in the http request phases (like `rewrite_by_lua*`) will only take affect in the current http request.

Arbitrary data values, including Lua closures and nested tables, can be inserted into this "magic" table. It also allows the registration of custom meta methods.

Overriding `ngx.ctx` with a new Lua table is also supported, for example,
Expand Down
8 changes: 8 additions & 0 deletions doc/HttpLuaModule.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -3082,6 +3082,14 @@ Then <code>GET /orig</code> will give
rather than the original <code>"hello"</code> value.
Because HTTP request is created after SSL handshake, the <code>ngx.ctx</code> created
in [[#ssl_certificate_by_lua|ssl_certificate_by_lua*]], [[#ssl_session_store_by_lua|ssl_session_store_by_lua*]] and [[#ssl_session_fetch_by_lua|ssl_session_fetch_by_lua*]]
is not available in the following phases like [[#rewrite_by_lua|rewrite_by_lua*]].
Since <code>dev</code>, the <code>ngx.ctx</code> created during a SSL handshake
will be inherited by the requests which share the same TCP connection established by the handshake.
Note that overwrite values in <code>ngx.ctx</code> in the http request phases (like `rewrite_by_lua*`) will only take affect in the current http request.
Arbitrary data values, including Lua closures and nested tables, can be inserted into this "magic" table. It also allows the registration of custom meta methods.
Overriding <code>ngx.ctx</code> with a new Lua table is also supported, for example,
Expand Down
62 changes: 53 additions & 9 deletions src/ngx_http_lua_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


#include "ngx_http_lua_util.h"
#include "ngx_http_lua_ssl.h"
#include "ngx_http_lua_ctx.h"


Expand All @@ -21,14 +22,16 @@ typedef struct {


static ngx_int_t ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r,
int ref);
ngx_pool_t *pool, int ref);
static void ngx_http_lua_ngx_ctx_cleanup(void *data);


int
ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,
ngx_http_lua_ctx_t *ctx, int index)
{
ngx_pool_t *pool;

if (index < 0) {
index = lua_gettop(L) + index + 1;
}
Expand All @@ -43,7 +46,8 @@ ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,
ctx->ctx_ref = luaL_ref(L, -2);
lua_pop(L, 1);

if (ngx_http_lua_ngx_ctx_add_cleanup(r, ctx->ctx_ref) != NGX_OK) {
pool = r->pool;
if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ctx->ctx_ref) != NGX_OK) {
return luaL_error(L, "no memory");
}

Expand All @@ -66,32 +70,71 @@ ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,


int
ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t *r)
ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t *r, int *in_ssl_phase,
int *ssl_ctx_ref)
{
ngx_http_lua_ctx_t *ctx;
ngx_http_lua_ctx_t *ctx;
ngx_http_lua_ssl_ctx_t *ssl_ctx;

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

return ctx->ctx_ref;
if (ctx->ctx_ref >= 0 || in_ssl_phase == NULL) {
return ctx->ctx_ref;
}

*in_ssl_phase = ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE);
*ssl_ctx_ref = LUA_NOREF;

if (r->connection->ssl != NULL) {
ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);

if (ssl_ctx != NULL) {
*ssl_ctx_ref = ssl_ctx->ctx_ref;
}
}

return LUA_NOREF;
}


int
ngx_http_lua_ffi_set_ctx_ref(ngx_http_request_t *r, int ref)
{
ngx_http_lua_ctx_t *ctx;
ngx_pool_t *pool;
ngx_connection_t *c;
ngx_http_lua_ctx_t *ctx;
ngx_http_lua_ssl_ctx_t *ssl_ctx;

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

if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE))
{
ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);
if (ssl_ctx == NULL) {
return NGX_ERROR;
}

ssl_ctx->ctx_ref = ref;
c = ngx_ssl_get_connection(r->connection->ssl->connection);
pool = c->pool;

} else {
pool = r->pool;
}

ctx->ctx_ref = ref;

if (ngx_http_lua_ngx_ctx_add_cleanup(r, ref) != NGX_OK) {
if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ref) != NGX_OK) {
return NGX_ERROR;
}

Expand All @@ -100,7 +143,8 @@ ngx_http_lua_ffi_set_ctx_ref(ngx_http_request_t *r, int ref)


static ngx_int_t
ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, int ref)
ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, ngx_pool_t *pool,
int ref)
{
lua_State *L;
ngx_pool_cleanup_t *cln;
Expand All @@ -111,7 +155,7 @@ ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, int ref)
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
L = ngx_http_lua_get_lua_vm(r, ctx);

cln = ngx_pool_cleanup_add(r->pool,
cln = ngx_pool_cleanup_add(pool,
sizeof(ngx_http_lua_ngx_ctx_cleanup_data_t));
if (cln == NULL) {
return NGX_ERROR;
Expand Down
4 changes: 4 additions & 0 deletions src/ngx_http_lua_ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ typedef struct {
int exit_code; /* exit code for openssl's
set_cert_cb callback */

int ctx_ref; /* reference to anchor
request ctx data in lua
registry */

unsigned done:1;
unsigned aborted:1;

Expand Down
2 changes: 2 additions & 0 deletions src/ngx_http_lua_ssl_certby.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ ngx_http_lua_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data)
if (cctx == NULL) {
goto failed; /* error */
}

cctx->ctx_ref = LUA_NOREF;
}

cctx->exit_code = 1; /* successful by default */
Expand Down
2 changes: 2 additions & 0 deletions src/ngx_http_lua_ssl_session_fetchby.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ ngx_http_lua_ssl_sess_fetch_handler(ngx_ssl_conn_t *ssl_conn,
if (cctx == NULL) {
goto failed; /* error */
}

cctx->ctx_ref = LUA_NOREF;
}

cctx->exit_code = 1; /* successful by default */
Expand Down
2 changes: 2 additions & 0 deletions src/ngx_http_lua_ssl_session_storeby.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ ngx_http_lua_ssl_sess_store_handler(ngx_ssl_conn_t *ssl_conn,
if (cctx == NULL) {
goto failed; /* error */
}

cctx->ctx_ref = LUA_NOREF;
}

#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
Expand Down
1 change: 1 addition & 0 deletions src/ngx_http_lua_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


#include "ngx_http_lua_common.h"
#include "ngx_http_lua_ssl.h"
#include "ngx_http_lua_api.h"


Expand Down

0 comments on commit 489ae10

Please sign in to comment.