diff options
author | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
commit | 3f33461e4948bf05e60bdff35ec6c57a649c7860 (patch) | |
tree | 284c2ba95a41536ae1bff6bea710db0709a64739 /ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c | |
download | openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.tar.gz openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.zip |
openresty bundle
Diffstat (limited to 'ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c')
-rw-r--r-- | ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c new file mode 100644 index 0000000..61f27b5 --- /dev/null +++ b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_prereadby.c @@ -0,0 +1,335 @@ + +/* + * Copyright (C) OpenResty Inc. + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + + +#include <nginx.h> +#include "ngx_stream_lua_prereadby.h" +#include "ngx_stream_lua_util.h" +#include "ngx_stream_lua_exception.h" +#include "ngx_stream_lua_cache.h" + + +static ngx_int_t ngx_stream_lua_preread_by_chunk(lua_State *L, + ngx_stream_lua_request_t *r); + + +ngx_int_t +ngx_stream_lua_preread_handler(ngx_stream_session_t *s) +{ + ngx_int_t rc; + ngx_stream_lua_ctx_t *ctx; + ngx_stream_lua_srv_conf_t *lscf; + ngx_stream_lua_main_conf_t *lmcf; + ngx_stream_lua_request_t *r; + + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "lua preread handler"); + + lmcf = ngx_stream_get_module_main_conf(s, ngx_stream_lua_module); + + if (!lmcf->postponed_to_preread_phase_end) { + ngx_stream_core_main_conf_t *cmcf; + ngx_stream_phase_handler_t tmp; + ngx_stream_phase_handler_t *ph; + ngx_stream_phase_handler_t *cur_ph; + ngx_stream_phase_handler_t *last_ph; + + lmcf->postponed_to_preread_phase_end = 1; + + cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); + + ph = cmcf->phase_engine.handlers; + cur_ph = &ph[s->phase_handler]; + last_ph = &ph[cur_ph->next - 1]; + + if (cur_ph < last_ph) { + tmp = *cur_ph; + + ngx_memmove(cur_ph, cur_ph + 1, (last_ph - cur_ph) + * sizeof (ngx_stream_phase_handler_t)); + + *last_ph = tmp; + + s->phase_handler--; /* redo the current ph */ + + return NGX_DECLINED; + } + } + + lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_lua_module); + + if (lscf->preread_handler == NULL) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "no preread handler found"); + return NGX_DECLINED; + } + + ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module); + + dd("ctx = %p", ctx); + + if (ctx == NULL) { + ctx = ngx_stream_lua_create_ctx(s); + if (ctx == NULL) { + return NGX_STREAM_INTERNAL_SERVER_ERROR; + } + } + + r = ctx->request; + + dd("entered? %d", (int) ctx->entered_preread_phase); + + if (ctx->entered_preread_phase) { + dd("calling wev handler"); + rc = ctx->resume_handler(r); + dd("wev handler returns %d", (int) rc); + + if (rc == NGX_ERROR || rc > NGX_OK) { + ngx_stream_lua_finalize_request(ctx->request, rc); + return NGX_DONE; + } + + if (rc == NGX_DONE && ctx->peek_needs_more_data) { + return NGX_AGAIN; + } + + if (rc == NGX_OK || rc == NGX_DONE) { + return rc; + } + + return NGX_DECLINED; + } + + r->connection->read->handler = ngx_stream_lua_request_handler; + r->connection->write->handler = ngx_stream_lua_request_handler; + + dd("calling preread handler"); + rc = lscf->preread_handler(r); + + if (rc == NGX_ERROR || rc > NGX_OK) { + ngx_stream_lua_finalize_request(ctx->request, rc); + return NGX_DONE; + } + + return rc; +} + + +ngx_int_t +ngx_stream_lua_preread_handler_inline(ngx_stream_lua_request_t *r) +{ + ngx_int_t rc; + lua_State *L; + ngx_stream_lua_srv_conf_t *lscf; + + lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module); + + L = ngx_stream_lua_get_lua_vm(r, NULL); + + /* load Lua inline script (w/ cache) sp = 1 */ + rc = ngx_stream_lua_cache_loadbuffer(r->connection->log, L, + lscf->preread_src.value.data, + lscf->preread_src.value.len, + lscf->preread_src_key, + (const char *) + lscf->preread_chunkname); + + if (rc != NGX_OK) { + return NGX_STREAM_INTERNAL_SERVER_ERROR; + } + + return ngx_stream_lua_preread_by_chunk(L, r); +} + + +ngx_int_t +ngx_stream_lua_preread_handler_file(ngx_stream_lua_request_t *r) +{ + u_char *script_path; + ngx_int_t rc; + ngx_str_t eval_src; + lua_State *L; + ngx_stream_lua_srv_conf_t *lscf; + + lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module); + + /* Eval nginx variables in code path string first */ + if (ngx_stream_complex_value(r->session, &lscf->preread_src, &eval_src) + != NGX_OK) + { + return NGX_ERROR; + } + + script_path = ngx_stream_lua_rebase_path(r->pool, eval_src.data, + eval_src.len); + + if (script_path == NULL) { + return NGX_ERROR; + } + + L = ngx_stream_lua_get_lua_vm(r, NULL); + + /* load Lua script file (w/ cache) sp = 1 */ + rc = ngx_stream_lua_cache_loadfile(r->connection->log, L, script_path, + lscf->preread_src_key); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_stream_lua_assert(lua_isfunction(L, -1)); + + return ngx_stream_lua_preread_by_chunk(L, r); +} + + +static ngx_int_t +ngx_stream_lua_preread_by_chunk(lua_State *L, ngx_stream_lua_request_t *r) +{ + int co_ref; + ngx_int_t rc; + lua_State *co; + ngx_event_t *rev; + ngx_connection_t *c; + ngx_stream_lua_ctx_t *ctx; + ngx_stream_lua_cleanup_t *cln; + + ngx_stream_lua_srv_conf_t *lscf; + + /* {{{ new coroutine to handle request */ + co = ngx_stream_lua_new_thread(r, L, &co_ref); + + if (co == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "lua: failed to create new coroutine " + "to handle request"); + + return NGX_STREAM_INTERNAL_SERVER_ERROR; + } + + /* move code closure to new coroutine */ + lua_xmove(L, co, 1); + +#ifndef OPENRESTY_LUAJIT + /* set closure's env table to new coroutine's globals table */ + ngx_stream_lua_get_globals_table(co); + lua_setfenv(co, -2); +#endif + + /* save nginx request in coroutine globals table */ + ngx_stream_lua_set_req(co, r); + + /* {{{ initialize request context */ + ctx = ngx_stream_lua_get_module_ctx(r, ngx_stream_lua_module); + + dd("ctx = %p", ctx); + + if (ctx == NULL) { + return NGX_ERROR; + } + + ngx_stream_lua_reset_ctx(r, L, ctx); + + ctx->entered_preread_phase = 1; + + ctx->cur_co_ctx = &ctx->entry_co_ctx; + ctx->cur_co_ctx->co = co; + ctx->cur_co_ctx->co_ref = co_ref; +#ifdef NGX_LUA_USE_ASSERT + ctx->cur_co_ctx->co_top = 1; +#endif + + ngx_stream_lua_attach_co_ctx_to_L(co, ctx->cur_co_ctx); + + /* }}} */ + + /* {{{ register request cleanup hooks */ + if (ctx->cleanup == NULL) { + cln = ngx_stream_lua_cleanup_add(r, 0); + if (cln == NULL) { + return NGX_STREAM_INTERNAL_SERVER_ERROR; + } + + cln->handler = ngx_stream_lua_request_cleanup_handler; + cln->data = ctx; + ctx->cleanup = &cln->handler; + } + /* }}} */ + + ctx->context = NGX_STREAM_LUA_CONTEXT_PREREAD; + + lscf = ngx_stream_lua_get_module_srv_conf(r, ngx_stream_lua_module); + + if (lscf->check_client_abort) { + r->read_event_handler = ngx_stream_lua_rd_check_broken_connection; + + rev = r->connection->read; + + if (!rev->active) { + if (ngx_add_event(rev, NGX_READ_EVENT, 0) != NGX_OK) { + return NGX_ERROR; + } + } + + } else { + r->read_event_handler = ngx_stream_lua_block_reading; + } + + rc = ngx_stream_lua_run_thread(L, r, ctx, 0); + + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, r->connection->log, 0, + "preread run thread returned %d", (int) rc); + + if (rc == NGX_ERROR || rc > NGX_OK) { + return rc; + } + + c = r->connection; + + if (rc == NGX_AGAIN) { + rc = ngx_stream_lua_run_posted_threads(c, L, r, ctx, 0); + + if (rc == NGX_DONE && ctx->peek_needs_more_data) { + return NGX_AGAIN; + } + + if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) { + return rc; + } + + if (rc != NGX_OK) { + return NGX_DECLINED; + } + + } else if (rc == NGX_DONE) { + ngx_stream_lua_finalize_request(r, NGX_DONE); + + rc = ngx_stream_lua_run_posted_threads(c, L, r, ctx, 0); + + if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) { + return rc; + } + + if (rc != NGX_OK) { + return NGX_DECLINED; + } + } + +#if 1 + if (rc == NGX_OK) { + return NGX_OK; + } +#endif + + return NGX_DECLINED; +} + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ |