1
2 /*
3 * Copyright (C) Yichun Zhang (agentzh)
4 */
5
6
7 #ifndef DDEBUG
8 #define DDEBUG 0
9 #endif
10 #include "ddebug.h"
11
12
13 #include "ngx_http_lua_util.h"
14 #include "ngx_http_lua_ssl.h"
15 #include "ngx_http_lua_ctx.h"
16
17
18 typedef struct {
19 int ref;
20 lua_State *vm;
21 } ngx_http_lua_ngx_ctx_cleanup_data_t;
22
23
24 static ngx_int_t ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r,
25 ngx_pool_t *pool, int ref);
26 static void ngx_http_lua_ngx_ctx_cleanup(void *data);
27
28
29 int
ngx_http_lua_ngx_set_ctx_helper(lua_State * L,ngx_http_request_t * r,ngx_http_lua_ctx_t * ctx,int index)30 ngx_http_lua_ngx_set_ctx_helper(lua_State *L, ngx_http_request_t *r,
31 ngx_http_lua_ctx_t *ctx, int index)
32 {
33 ngx_pool_t *pool;
34
35 if (index < 0) {
36 index = lua_gettop(L) + index + 1;
37 }
38
39 if (ctx->ctx_ref == LUA_NOREF) {
40 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
41 "lua create ngx.ctx table for the current request");
42
43 lua_pushliteral(L, ngx_http_lua_ctx_tables_key);
44 lua_rawget(L, LUA_REGISTRYINDEX);
45 lua_pushvalue(L, index);
46 ctx->ctx_ref = luaL_ref(L, -2);
47 lua_pop(L, 1);
48
49 pool = r->pool;
50 if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ctx->ctx_ref) != NGX_OK) {
51 return luaL_error(L, "no memory");
52 }
53
54 return 0;
55 }
56
57 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
58 "lua fetching existing ngx.ctx table for the current "
59 "request");
60
61 lua_pushliteral(L, ngx_http_lua_ctx_tables_key);
62 lua_rawget(L, LUA_REGISTRYINDEX);
63 luaL_unref(L, -1, ctx->ctx_ref);
64 lua_pushvalue(L, index);
65 ctx->ctx_ref = luaL_ref(L, -2);
66 lua_pop(L, 1);
67
68 return 0;
69 }
70
71
72 int
ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t * r,int * in_ssl_phase,int * ssl_ctx_ref)73 ngx_http_lua_ffi_get_ctx_ref(ngx_http_request_t *r, int *in_ssl_phase,
74 int *ssl_ctx_ref)
75 {
76 ngx_http_lua_ctx_t *ctx;
77 #if (NGX_HTTP_SSL)
78 ngx_http_lua_ssl_ctx_t *ssl_ctx;
79 #endif
80
81 ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
82 if (ctx == NULL) {
83 return NGX_HTTP_LUA_FFI_NO_REQ_CTX;
84 }
85
86 if (ctx->ctx_ref >= 0 || in_ssl_phase == NULL) {
87 return ctx->ctx_ref;
88 }
89
90 *in_ssl_phase = ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
91 | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
92 | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE);
93 *ssl_ctx_ref = LUA_NOREF;
94
95 #if (NGX_HTTP_SSL)
96 if (r->connection->ssl != NULL) {
97 ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);
98
99 if (ssl_ctx != NULL) {
100 *ssl_ctx_ref = ssl_ctx->ctx_ref;
101 }
102 }
103 #endif
104
105 return LUA_NOREF;
106 }
107
108
109 int
ngx_http_lua_ffi_set_ctx_ref(ngx_http_request_t * r,int ref)110 ngx_http_lua_ffi_set_ctx_ref(ngx_http_request_t *r, int ref)
111 {
112 ngx_pool_t *pool;
113 ngx_http_lua_ctx_t *ctx;
114 #if (NGX_HTTP_SSL)
115 ngx_connection_t *c;
116 ngx_http_lua_ssl_ctx_t *ssl_ctx;
117 #endif
118
119 ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
120 if (ctx == NULL) {
121 return NGX_HTTP_LUA_FFI_NO_REQ_CTX;
122 }
123
124 #if (NGX_HTTP_SSL)
125 if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
126 | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
127 | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE))
128 {
129 ssl_ctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection);
130 if (ssl_ctx == NULL) {
131 return NGX_ERROR;
132 }
133
134 ssl_ctx->ctx_ref = ref;
135 c = ngx_ssl_get_connection(r->connection->ssl->connection);
136 pool = c->pool;
137
138 } else {
139 pool = r->pool;
140 }
141
142 #else
143 pool = r->pool;
144 #endif
145
146 ctx->ctx_ref = ref;
147
148 if (ngx_http_lua_ngx_ctx_add_cleanup(r, pool, ref) != NGX_OK) {
149 return NGX_ERROR;
150 }
151
152 return NGX_OK;
153 }
154
155
156 static ngx_int_t
ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t * r,ngx_pool_t * pool,int ref)157 ngx_http_lua_ngx_ctx_add_cleanup(ngx_http_request_t *r, ngx_pool_t *pool,
158 int ref)
159 {
160 lua_State *L;
161 ngx_pool_cleanup_t *cln;
162 ngx_http_lua_ctx_t *ctx;
163
164 ngx_http_lua_ngx_ctx_cleanup_data_t *data;
165
166 ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
167 L = ngx_http_lua_get_lua_vm(r, ctx);
168
169 cln = ngx_pool_cleanup_add(pool,
170 sizeof(ngx_http_lua_ngx_ctx_cleanup_data_t));
171 if (cln == NULL) {
172 return NGX_ERROR;
173 }
174
175 cln->handler = ngx_http_lua_ngx_ctx_cleanup;
176
177 data = cln->data;
178 data->vm = L;
179 data->ref = ref;
180
181 return NGX_OK;
182 }
183
184
185 static void
ngx_http_lua_ngx_ctx_cleanup(void * data)186 ngx_http_lua_ngx_ctx_cleanup(void *data)
187 {
188 lua_State *L;
189
190 ngx_http_lua_ngx_ctx_cleanup_data_t *clndata = data;
191
192 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
193 "lua release ngx.ctx at ref %d", clndata->ref);
194
195 L = clndata->vm;
196
197 lua_pushliteral(L, ngx_http_lua_ctx_tables_key);
198 lua_rawget(L, LUA_REGISTRYINDEX);
199 luaL_unref(L, -1, clndata->ref);
200 lua_pop(L, 1);
201 }
202
203
204 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
205