Skip to content

Commit 218af5e

Browse files
authored
feature: shared ngx.ctx among SSL_* phases and the following phases. (openresty#1514)
1 parent d6a29d2 commit 218af5e

8 files changed

+80
-9
lines changed

README.markdown

+8
Original file line numberDiff line numberDiff line change
@@ -3769,6 +3769,14 @@ Then `GET /orig` will give
37693769

37703770
rather than the original `"hello"` value.
37713771

3772+
Because HTTP request is created after SSL handshake, the `ngx.ctx` created
3773+
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)
3774+
is not available in the following phases like [rewrite_by_lua*](#rewrite_by_lua).
3775+
3776+
Since `dev`, the `ngx.ctx` created during a SSL handshake
3777+
will be inherited by the requests which share the same TCP connection established by the handshake.
3778+
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.
3779+
37723780
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.
37733781

37743782
Overriding `ngx.ctx` with a new Lua table is also supported, for example,

doc/HttpLuaModule.wiki

+8
Original file line numberDiff line numberDiff line change
@@ -3082,6 +3082,14 @@ Then <code>GET /orig</code> will give
30823082
30833083
rather than the original <code>"hello"</code> value.
30843084
3085+
Because HTTP request is created after SSL handshake, the <code>ngx.ctx</code> created
3086+
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*]]
3087+
is not available in the following phases like [[#rewrite_by_lua|rewrite_by_lua*]].
3088+
3089+
Since <code>dev</code>, the <code>ngx.ctx</code> created during a SSL handshake
3090+
will be inherited by the requests which share the same TCP connection established by the handshake.
3091+
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.
3092+
30853093
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.
30863094
30873095
Overriding <code>ngx.ctx</code> with a new Lua table is also supported, for example,

src/ngx_http_lua_ctx.c

+53-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313
#include "ngx_http_lua_util.h"
14+
#include "ngx_http_lua_ssl.h"
1415
#include "ngx_http_lua_ctx.h"
1516

1617

@@ -21,14 +22,16 @@ typedef struct {
2122

2223

2324
static ngx_int_t ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r,
24-
int ref);
25+
ngx_pool_t *pool, int ref);
2526
static void ngx_http_lua_ngx_ctx_cleanup(void *data);
2627

2728

2829
int
2930
ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,
3031
ngx_http_lua_ctx_t *ctx, int index)
3132
{
33+
ngx_pool_t *pool;
34+
3235
if (index < 0) {
3336
index = lua_gettop(L) + index + 1;
3437
}
@@ -43,7 +46,8 @@ ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,
4346
ctx->ctx_ref = luaL_ref(L, -2);
4447
lua_pop(L, 1);
4548

46-
if (ngx_http_lua_ngx_ctx_add_cleanup(r, ctx->ctx_ref) != NGX_OK) {
49+
pool = r->pool;
50+
if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ctx->ctx_ref) != NGX_OK) {
4751
return luaL_error(L, "no memory");
4852
}
4953

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

6771

6872
int
69-
ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t *r)
73+
ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t *r, int *in_ssl_phase,
74+
int *ssl_ctx_ref)
7075
{
71-
ngx_http_lua_ctx_t *ctx;
76+
ngx_http_lua_ctx_t *ctx;
77+
ngx_http_lua_ssl_ctx_t *ssl_ctx;
7278

7379
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
7480
if (ctx == NULL) {
7581
return NGX_HTTP_LUA_FFI_NO_REQ_CTX;
7682
}
7783

78-
return ctx->ctx_ref;
84+
if (ctx->ctx_ref >= 0 || in_ssl_phase == NULL) {
85+
return ctx->ctx_ref;
86+
}
87+
88+
*in_ssl_phase = ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
89+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
90+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE);
91+
*ssl_ctx_ref = LUA_NOREF;
92+
93+
if (r->connection->ssl != NULL) {
94+
ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);
95+
96+
if (ssl_ctx != NULL) {
97+
*ssl_ctx_ref = ssl_ctx->ctx_ref;
98+
}
99+
}
100+
101+
return LUA_NOREF;
79102
}
80103

81104

82105
int
83106
ngx_http_lua_ffi_set_ctx_ref(ngx_http_request_t *r, int ref)
84107
{
85-
ngx_http_lua_ctx_t *ctx;
108+
ngx_pool_t *pool;
109+
ngx_connection_t *c;
110+
ngx_http_lua_ctx_t *ctx;
111+
ngx_http_lua_ssl_ctx_t *ssl_ctx;
86112

87113
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
88114
if (ctx == NULL) {
89115
return NGX_HTTP_LUA_FFI_NO_REQ_CTX;
90116
}
91117

118+
if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
119+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
120+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE))
121+
{
122+
ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);
123+
if (ssl_ctx == NULL) {
124+
return NGX_ERROR;
125+
}
126+
127+
ssl_ctx->ctx_ref = ref;
128+
c = ngx_ssl_get_connection(r->connection->ssl->connection);
129+
pool = c->pool;
130+
131+
} else {
132+
pool = r->pool;
133+
}
134+
92135
ctx->ctx_ref = ref;
93136

94-
if (ngx_http_lua_ngx_ctx_add_cleanup(r, ref) != NGX_OK) {
137+
if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ref) != NGX_OK) {
95138
return NGX_ERROR;
96139
}
97140

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

101144

102145
static ngx_int_t
103-
ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, int ref)
146+
ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, ngx_pool_t *pool,
147+
int ref)
104148
{
105149
lua_State *L;
106150
ngx_pool_cleanup_t *cln;
@@ -111,7 +155,7 @@ ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, int ref)
111155
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
112156
L = ngx_http_lua_get_lua_vm(r, ctx);
113157

114-
cln = ngx_pool_cleanup_add(r->pool,
158+
cln = ngx_pool_cleanup_add(pool,
115159
sizeof(ngx_http_lua_ngx_ctx_cleanup_data_t));
116160
if (cln == NULL) {
117161
return NGX_ERROR;

src/ngx_http_lua_ssl.h

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ typedef struct {
2727
int exit_code; /* exit code for openssl's
2828
set_cert_cb callback */
2929

30+
int ctx_ref; /* reference to anchor
31+
request ctx data in lua
32+
registry */
33+
3034
unsigned done:1;
3135
unsigned aborted:1;
3236

src/ngx_http_lua_ssl_certby.c

+2
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ ngx_http_lua_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data)
257257
if (cctx == NULL) {
258258
goto failed; /* error */
259259
}
260+
261+
cctx->ctx_ref = LUA_NOREF;
260262
}
261263

262264
cctx->exit_code = 1; /* successful by default */

src/ngx_http_lua_ssl_session_fetchby.c

+2
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ ngx_http_lua_ssl_sess_fetch_handler(ngx_ssl_conn_t *ssl_conn,
279279
if (cctx == NULL) {
280280
goto failed; /* error */
281281
}
282+
283+
cctx->ctx_ref = LUA_NOREF;
282284
}
283285

284286
cctx->exit_code = 1; /* successful by default */

src/ngx_http_lua_ssl_session_storeby.c

+2
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ ngx_http_lua_ssl_sess_store_handler(ngx_ssl_conn_t *ssl_conn,
241241
if (cctx == NULL) {
242242
goto failed; /* error */
243243
}
244+
245+
cctx->ctx_ref = LUA_NOREF;
244246
}
245247

246248
#if OPENSSL_VERSION_NUMBER >= 0x1000200fL

src/ngx_http_lua_util.h

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616

1717
#include "ngx_http_lua_common.h"
18+
#include "ngx_http_lua_ssl.h"
1819
#include "ngx_http_lua_api.h"
1920

2021

0 commit comments

Comments
 (0)