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