42
70
lua_setglobal(cc, GLOBALS_SYMBOL_REQUEST);
45
/* {{{ initialize request context */
46
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
48
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
50
return NGX_HTTP_INTERNAL_SERVER_ERROR;
53
ngx_http_set_ctx(r, ctx, ngx_http_lua_module);
57
74
ctx->cc_ref = cc_ref;
61
76
/* {{{ register request cleanup hooks */
62
cln = ngx_http_cleanup_add(r, 0);
64
return NGX_HTTP_INTERNAL_SERVER_ERROR;
77
if (ctx->cleanup == NULL) {
78
cln = ngx_http_cleanup_add(r, 0);
80
return NGX_HTTP_INTERNAL_SERVER_ERROR;
83
cln->handler = ngx_http_lua_request_cleanup;
85
ctx->cleanup = &cln->handler;
67
cln->handler = ngx_http_lua_request_cleanup;
69
ctx->cleanup = &cln->handler;
72
89
return ngx_http_lua_run_thread(L, r, ctx, 0);
77
ngx_http_lua_run_thread(lua_State *L, ngx_http_request_t *r,
78
ngx_http_lua_ctx_t *ctx, int nret)
83
const char *err, *msg;
85
/* set Lua VM panic handler */
86
lua_atpanic(L, ngx_http_lua_atpanic);
88
NGX_LUA_EXCEPTION_TRY {
93
rc = lua_resume(cc, nret);
95
dd("lua resume returns %d", (int) rc);
99
/* yielded, let event handler do the rest job */
100
/* FIXME: add io cmd dispatcher here */
107
ngx_http_lua_del_thread(r, L, cc_ref, 0);
110
dd("cleaning up cleanup");
111
*ctx->cleanup = NULL;
115
ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */);
120
err = "runtime error";
124
err = "syntax error";
128
err = "memory allocation error";
132
err = "error handler error";
136
err = "unknown error";
140
if (lua_isstring(cc, -1)) {
141
dd("user custom error msg");
142
msg = lua_tostring(cc, -1);
145
if (lua_isnil(cc, -1)) {
147
dd("run here...exiting...");
149
ngx_http_lua_del_thread(r, L, cc_ref, 0);
152
*ctx->cleanup = NULL;
156
return ctx->exit_code;
159
if (ctx->exec_uri.len) {
160
ngx_http_lua_del_thread(r, L, cc_ref, 0);
163
*ctx->cleanup = NULL;
167
if (ctx->exec_uri.data[0] == '@') {
168
if (ctx->exec_args.len > 0) {
169
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
170
"query strings %V ignored when exec'ing named location %V",
171
&ctx->exec_args, &ctx->exec_uri);
174
return ngx_http_named_location(r, &ctx->exec_uri);
177
return ngx_http_internal_redirect(r, &ctx->exec_uri,
182
msg = "unknown reason";
185
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
186
"content_by_lua aborted: %s: %s",
189
ngx_http_lua_del_thread(r, L, cc_ref, 0);
192
*ctx->cleanup = NULL;
196
dd("headers sent? %d", ctx->headers_sent ? 1 : 0);
198
return ctx->headers_sent ? NGX_ERROR : NGX_HTTP_INTERNAL_SERVER_ERROR;
199
} NGX_LUA_EXCEPTION_CATCH {
200
dd("NginX execution restored");
94
ngx_http_lua_content_wev_handler(ngx_http_request_t *r)
96
(void) ngx_http_lua_wev_handler(r);
101
ngx_http_lua_content_handler(ngx_http_request_t *r)
103
ngx_http_lua_loc_conf_t *llcf;
104
ngx_http_lua_ctx_t *ctx;
107
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
109
if (llcf->content_handler == NULL) {
110
dd("no content handler found");
114
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
119
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
121
return NGX_HTTP_INTERNAL_SERVER_ERROR;
124
dd("setting new ctx: ctx = %p", ctx);
126
ctx->cc_ref = LUA_NOREF;
128
ngx_http_set_ctx(r, ctx, ngx_http_lua_module);
131
dd("entered? %d", (int) ctx->entered_content_phase);
133
if (ctx->waiting_more_body) {
137
if (ctx->entered_content_phase) {
138
dd("calling wev handler");
139
rc = ngx_http_lua_wev_handler(r);
140
dd("wev handler returns %d", (int) rc);
144
if (llcf->force_read_body &&
145
! ctx->read_body_done &&
146
((r->method & NGX_HTTP_POST) || (r->method & NGX_HTTP_PUT)))
148
rc = ngx_http_read_client_request_body(r,
149
ngx_http_lua_content_phase_post_read);
151
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
155
if (rc == NGX_AGAIN) {
156
ctx->waiting_more_body = 1;
162
dd("setting entered");
164
ctx->entered_content_phase = 1;
166
dd("calling content handler");
167
return llcf->content_handler(r);
171
/* post read callback for the content phase */
208
ngx_http_lua_request_cleanup(void *data)
210
ngx_http_request_t *r = data;
211
ngx_http_lua_main_conf_t *lmcf;
212
ngx_http_lua_ctx_t *ctx;
173
ngx_http_lua_content_phase_post_read(ngx_http_request_t *r)
175
ngx_http_lua_ctx_t *ctx;
177
r->read_event_handler = ngx_http_request_empty_handler;
179
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
181
ctx->read_body_done = 1;
183
if (ctx->waiting_more_body) {
184
ctx->waiting_more_body = 0;
185
ngx_http_finalize_request(r, ngx_http_lua_content_handler(r));
188
#if defined(nginx_version) && nginx_version >= 8011
196
ngx_http_lua_content_handler_file(ngx_http_request_t *r)
201
ngx_http_lua_main_conf_t *lmcf;
202
ngx_http_lua_loc_conf_t *llcf;
206
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
208
if (ngx_http_complex_value(r, &llcf->content_src, &eval_src) != NGX_OK) {
212
script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data,
215
if (script_path == NULL) {
219
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
222
/* load Lua script file (w/ cache) sp = 1 */
223
rc = ngx_http_lua_cache_loadfile(L, script_path, llcf->content_src_key,
224
&err, llcf->enable_code_cache);
228
err = "unknown error";
231
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
232
"Failed to load Lua inlined code: %s", err);
234
return NGX_HTTP_INTERNAL_SERVER_ERROR;
237
/* make sure we have a valid code chunk */
238
assert(lua_isfunction(L, -1));
240
rc = ngx_http_lua_content_by_chunk(L, r);
242
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
246
if (rc == NGX_DONE) {
250
if (rc == NGX_AGAIN) {
251
#if defined(nginx_version) && nginx_version >= 8011
262
ngx_http_lua_content_handler_inline(ngx_http_request_t *r)
215
dd("(lua-request-cleanup) force request coroutine quit");
217
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
219
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
221
/* force coroutine handling the request quit */
227
*ctx->cleanup = NULL;
231
lua_getfield(L, LUA_REGISTRYINDEX, NGX_LUA_CORT_REF);
232
lua_rawgeti(L, -1, ctx->cc_ref);
234
if (lua_isthread(L, -1)) {
235
/* coroutine not finished yet, force quit */
236
ngx_http_lua_del_thread(r, L, ctx->cc_ref, 1);
239
ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */);
248
ngx_http_lua_wev_handler(ngx_http_request_t *r)
251
ngx_http_lua_ctx_t *ctx;
252
266
ngx_http_lua_main_conf_t *lmcf;
257
ngx_http_headers_out_t *sr_headers;
258
ngx_list_part_t *part;
259
ngx_table_elt_t *header;
262
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
267
dd("request done: %d", (int) r->done);
268
dd("cleanup done: %p", ctx->cleanup);
271
if (ctx->cleanup == NULL) {
276
if (ctx->waiting && ! ctx->done) {
277
if (r->main->posted_requests
278
&& r->main->posted_requests->request != r)
280
dd("postpone our wev handler");
282
#if defined(nginx_version) && nginx_version >= 8012
283
ngx_http_post_request(r, NULL);
285
ngx_http_post_request(r);
295
for (cl = ctx->sr_body; cl; cl = cl->next) {
296
/* ignore all non-memory buffers */
297
len += cl->buf->last - cl->buf->pos;
304
last = pos = ngx_palloc(r->pool, len);
309
for (cl = ctx->sr_body; cl; cl = cl->next) {
310
/* ignore all non-memory buffers */
311
last = ngx_copy(last, cl->buf->pos, cl->buf->last - cl->buf->pos);
317
/* {{{ construct ret value */
320
/* copy captured status */
321
lua_pushinteger(cc, ctx->sr_status);
322
lua_setfield(cc, -2, "status");
324
/* copy captured body */
325
lua_pushlstring(cc, (const char *) pos, len);
326
lua_setfield(cc, -2, "body");
328
/* copy captured headers */
330
lua_newtable(cc); /* res.header */
332
sr_headers = ctx->sr_headers;
334
if (sr_headers->content_length == NULL
335
&& sr_headers->content_length_n >= 0)
337
lua_pushliteral(cc, "Content-Length"); /* header key */
338
lua_pushnumber(cc, sr_headers->content_length_n); /* head key value */
339
lua_rawset(cc, -3); /* head */
342
if (sr_headers->content_type.len) {
343
lua_pushliteral(cc, "Content-Type"); /* header key */
344
lua_pushlstring(cc, (char *) sr_headers->content_type.data,
345
sr_headers->content_type.len); /* head key value */
346
lua_rawset(cc, -3); /* head */
349
part = &sr_headers->headers.part;
352
for (i = 0; /* void */; i++) {
354
if (i >= part->nelts) {
355
if (part->next == NULL) {
365
if (header[i].hash == 0) {
370
lua_pushlstring(cc, (char *) header[i].key.data,
371
header[i].key.len); /* header key */
373
lua_pushlstring(cc, (char *) header[i].value.data,
374
header[i].value.len); /* header key value */
376
lua_rawset(cc, -3); /* head */
379
lua_setfield(cc, -2, "header");
267
ngx_http_lua_loc_conf_t *llcf;
270
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
383
271
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
385
dd("about to run thread...");
387
rc = ngx_http_lua_run_thread(lmcf->lua, r, ctx, 1);
389
dd("already run thread...");
391
if (rc == NGX_AGAIN || rc == NGX_DONE) {
399
ngx_http_finalize_request(r, rc);
405
ngx_http_finalize_request(r,
406
ctx->headers_sent ? NGX_ERROR: NGX_HTTP_INTERNAL_SERVER_ERROR);
275
/* load Lua inline script (w/ cache) sp = 1 */
276
rc = ngx_http_lua_cache_loadbuffer(L, llcf->content_src.value.data,
277
llcf->content_src.value.len, llcf->content_src_key,
278
"content_by_lua", &err, llcf->enable_code_cache);
282
err = "unknown error";
285
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
286
"Failed to load Lua inlined code: %s", err);
288
return NGX_HTTP_INTERNAL_SERVER_ERROR;
291
rc = ngx_http_lua_content_by_chunk(L, r);
293
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
297
if (rc == NGX_DONE) {
301
if (rc == NGX_AGAIN) {
302
#if defined(nginx_version) && nginx_version >= 8011