Repository: trafficserver Updated Branches: refs/heads/master bdf84381d -> 68b4d8536
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/68b4d853/plugins/experimental/ts_lua/ts_lua_transform.c ---------------------------------------------------------------------- diff --git a/plugins/experimental/ts_lua/ts_lua_transform.c b/plugins/experimental/ts_lua/ts_lua_transform.c index 3be1932..ce7db9b 100644 --- a/plugins/experimental/ts_lua/ts_lua_transform.c +++ b/plugins/experimental/ts_lua/ts_lua_transform.c @@ -20,22 +20,26 @@ #include "ts_lua_util.h" -static int ts_lua_transform_handler(TSCont contp, ts_lua_transform_ctx *transform_ctx); +static int ts_lua_transform_handler(TSCont contp, ts_lua_http_transform_ctx *transform_ctx, TSEvent event, int n); int -ts_lua_transform_entry(TSCont contp, TSEvent event, void *edata ATS_UNUSED) +ts_lua_transform_entry(TSCont contp, TSEvent ev, void *edata) { + int n, event; TSVIO input_vio; + ts_lua_http_transform_ctx *transform_ctx; - ts_lua_transform_ctx *transform_ctx = (ts_lua_transform_ctx *)TSContDataGet(contp); + event = (int)ev; + transform_ctx = (ts_lua_http_transform_ctx *)TSContDataGet(contp); if (TSVConnClosedGet(contp)) { - TSContDestroy(contp); - ts_lua_destroy_transform_ctx(transform_ctx); + ts_lua_destroy_http_transform_ctx(transform_ctx); return 0; } + n = 0; + switch (event) { case TS_EVENT_ERROR: input_vio = TSVConnWriteVIOGet(contp); @@ -46,9 +50,12 @@ ts_lua_transform_entry(TSCont contp, TSEvent event, void *edata ATS_UNUSED) TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1); break; + case TS_LUA_EVENT_COROUTINE_CONT: + n = (intptr_t)edata; + case TS_EVENT_VCONN_WRITE_READY: default: - ts_lua_transform_handler(contp, transform_ctx); + ts_lua_transform_handler(contp, transform_ctx, event, n); break; } @@ -56,61 +63,91 @@ ts_lua_transform_entry(TSCont contp, TSEvent event, void *edata ATS_UNUSED) } static int -ts_lua_transform_handler(TSCont contp, ts_lua_transform_ctx *transform_ctx) +ts_lua_transform_handler(TSCont contp, ts_lua_http_transform_ctx *transform_ctx, TSEvent event, int n) { TSVConn output_conn; TSVIO input_vio; TSIOBufferReader input_reader; TSIOBufferBlock blk; - int64_t towrite, blk_len, upstream_done, avail, left; + int64_t toread, towrite, blk_len, upstream_done, input_avail, l; const char *start; const char *res; size_t res_len; - int ret, eos; + int ret, eos, write_down, rc, top; + ts_lua_coroutine *crt; + ts_lua_cont_info *ci; lua_State *L; TSMutex mtxp; - L = transform_ctx->hctx->lua; - mtxp = transform_ctx->hctx->mctx->mutexp; + ci = &transform_ctx->cinfo; + crt = &ci->routine; + + mtxp = crt->mctx->mutexp; + L = crt->lua; output_conn = TSTransformOutputVConnGet(contp); input_vio = TSVConnWriteVIOGet(contp); - input_reader = TSVIOReaderGet(input_vio); - - if (!transform_ctx->output_buffer) { - transform_ctx->output_buffer = TSIOBufferCreate(); - transform_ctx->output_reader = TSIOBufferReaderAlloc(transform_ctx->output_buffer); - transform_ctx->output_vio = TSVConnWrite(output_conn, contp, transform_ctx->output_reader, INT64_MAX); - } if (!TSVIOBufferGet(input_vio)) { - TSVIONBytesSet(transform_ctx->output_vio, transform_ctx->total); - TSVIOReenable(transform_ctx->output_vio); - return 1; + if (transform_ctx->output.vio) { + TSVIONBytesSet(transform_ctx->output.vio, transform_ctx->total); + TSVIOReenable(transform_ctx->output.vio); + } + return 0; } - if (transform_ctx->eos) { - return 1; + input_reader = TSVIOReaderGet(input_vio); + + if (!transform_ctx->output.buffer) { + transform_ctx->output.buffer = TSIOBufferCreate(); + transform_ctx->output.reader = TSIOBufferReaderAlloc(transform_ctx->output.buffer); + + transform_ctx->reserved.buffer = TSIOBufferCreate(); + transform_ctx->reserved.reader = TSIOBufferReaderAlloc(transform_ctx->reserved.buffer); + + transform_ctx->upstream_bytes = TSVIONBytesGet(input_vio); + transform_ctx->downstream_bytes = INT64_MAX; } - left = towrite = TSVIONTodoGet(input_vio); + input_avail = TSIOBufferReaderAvail(input_reader); upstream_done = TSVIONDoneGet(input_vio); - avail = TSIOBufferReaderAvail(input_reader); - eos = 0; + toread = TSVIONTodoGet(input_vio); - if (left <= avail) + if (toread <= input_avail) { // upstream finished eos = 1; + } else { + eos = 0; + } - if (towrite > avail) - towrite = avail; + if (input_avail > 0) { + // move to the reserved.buffer + TSIOBufferCopy(transform_ctx->reserved.buffer, input_reader, input_avail, 0); - TSMutexLock(mtxp); + // reset input + TSIOBufferReaderConsume(input_reader, input_avail); + TSVIONDoneSet(input_vio, upstream_done + input_avail); + } - blk = TSIOBufferReaderStart(input_reader); + write_down = 0; + towrite = TSIOBufferReaderAvail(transform_ctx->reserved.reader); + + TSMutexLock(mtxp); + ts_lua_set_cont_info(L, ci); do { - start = TSIOBufferBlockReadStart(blk, input_reader, &blk_len); + if (event == TS_LUA_EVENT_COROUTINE_CONT) { + event = 0; + goto launch; + } else { + n = 2; + } + + if (towrite == 0) + break; + + blk = TSIOBufferReaderStart(transform_ctx->reserved.reader); + start = TSIOBufferBlockReadStart(blk, transform_ctx->reserved.reader, &blk_len); lua_pushlightuserdata(L, transform_ctx); lua_rawget(L, LUA_GLOBALSINDEX); /* push function */ @@ -118,54 +155,90 @@ ts_lua_transform_handler(TSCont contp, ts_lua_transform_ctx *transform_ctx) if (towrite > blk_len) { lua_pushlstring(L, start, (size_t)blk_len); towrite -= blk_len; + TSIOBufferReaderConsume(transform_ctx->reserved.reader, blk_len); } else { lua_pushlstring(L, start, (size_t)towrite); + TSIOBufferReaderConsume(transform_ctx->reserved.reader, towrite); towrite = 0; } if (!towrite && eos) { - lua_pushinteger(L, 1); /* second param, not finish */ + lua_pushinteger(L, 1); /* second param, data finished */ } else { - lua_pushinteger(L, 0); /* second param, not finish */ + lua_pushinteger(L, 0); /* second param, data not finish */ } - if (lua_pcall(L, 2, 2, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(L, -1)); + launch: + rc = lua_resume(L, n); + top = lua_gettop(L); + + switch (rc) { + case LUA_YIELD: // coroutine yield + TSMutexUnlock(mtxp); + return 0; + + case 0: // coroutine success + if (top == 2) { + ret = lua_tointeger(L, -1); /* 0 is not finished, 1 is finished */ + res = lua_tolstring(L, -2, &res_len); + } else { // what hells code are you writing ? + ret = 0; + res = NULL; + res_len = 0; + } + break; + + default: // coroutine failed + ee("lua_resume failed: %s", lua_tostring(L, -1)); + ret = 1; + res = NULL; + res_len = 0; + break; } - ret = lua_tointeger(L, -1); /* 0 is not finished, 1 is finished */ - res = lua_tolstring(L, -2, &res_len); + if (res && res_len > 0) { + if (!transform_ctx->output.vio) { + l = transform_ctx->downstream_bytes; + if (ret) { + l = res_len; + } + + transform_ctx->output.vio = TSVConnWrite(output_conn, contp, transform_ctx->output.reader, l); // HttpSM go on + } - if (res && res_len) { - TSIOBufferWrite(transform_ctx->output_buffer, res, res_len); + TSIOBufferWrite(transform_ctx->output.buffer, res, res_len); transform_ctx->total += res_len; + write_down = 1; } - lua_pop(L, 2); + lua_pop(L, top); if (ret || (eos && !towrite)) { // EOS eos = 1; break; } - blk = TSIOBufferBlockNext(blk); - - } while (blk && towrite > 0); + } while (towrite > 0); TSMutexUnlock(mtxp); - TSIOBufferReaderConsume(input_reader, avail); - TSVIONDoneSet(input_vio, upstream_done + avail); + if (eos && !transform_ctx->output.vio) + transform_ctx->output.vio = TSVConnWrite(output_conn, contp, transform_ctx->output.reader, 0); + + if (write_down || eos) + TSVIOReenable(transform_ctx->output.vio); - if (eos) { - transform_ctx->eos = 1; - TSVIONBytesSet(transform_ctx->output_vio, transform_ctx->total); - TSVIOReenable(transform_ctx->output_vio); + if (toread > input_avail) { // upstream not finished. + if (eos) { + TSVIONBytesSet(transform_ctx->output.vio, transform_ctx->total); + TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_EOS, input_vio); + } else { + TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_READY, input_vio); + } + } else { // upstream is finished. + TSVIONBytesSet(transform_ctx->output.vio, transform_ctx->total); TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_COMPLETE, input_vio); - } else { - TSVIOReenable(transform_ctx->output_vio); - TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_READY, input_vio); } - return 1; + return 0; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/68b4d853/plugins/experimental/ts_lua/ts_lua_util.c ---------------------------------------------------------------------- diff --git a/plugins/experimental/ts_lua/ts_lua_util.c b/plugins/experimental/ts_lua/ts_lua_util.c index c7833c8..31bf80f 100644 --- a/plugins/experimental/ts_lua/ts_lua_util.c +++ b/plugins/experimental/ts_lua/ts_lua_util.c @@ -19,6 +19,7 @@ #include "ts_lua_util.h" #include "ts_lua_remap.h" +#include "ts_lua_constant.h" #include "ts_lua_client_request.h" #include "ts_lua_server_request.h" #include "ts_lua_server_response.h" @@ -33,6 +34,8 @@ #include "ts_lua_mgmt.h" #include "ts_lua_package.h" #include "ts_lua_stat.h" +#include "ts_lua_fetch.h" +#include "ts_lua_http_intercept.h" static lua_State *ts_lua_new_state(); static void ts_lua_init_registry(lua_State *L); @@ -261,6 +264,7 @@ ts_lua_inject_ts_api(lua_State *L) lua_newtable(L); ts_lua_inject_remap_api(L); + ts_lua_inject_constant_api(L); ts_lua_inject_client_request_api(L); ts_lua_inject_server_request_api(L); @@ -273,11 +277,13 @@ ts_lua_inject_ts_api(lua_State *L) ts_lua_inject_hook_api(L); ts_lua_inject_http_api(L); + ts_lua_inject_intercept_api(L); ts_lua_inject_misc_api(L); ts_lua_inject_crypto_api(L); ts_lua_inject_mgmt_api(L); ts_lua_inject_package_api(L); ts_lua_inject_stat_api(L); + ts_lua_inject_fetch_api(L); lua_getglobal(L, "package"); lua_getfield(L, -1, "loaded"); @@ -311,6 +317,28 @@ ts_lua_get_instance_conf(lua_State *L) } void +ts_lua_set_cont_info(lua_State *L, ts_lua_cont_info *ci) +{ + lua_pushliteral(L, "__ts_cont_info"); + lua_pushlightuserdata(L, ci); + lua_rawset(L, LUA_GLOBALSINDEX); +} + +ts_lua_cont_info * +ts_lua_get_cont_info(lua_State *L) +{ + ts_lua_cont_info *ci; + + lua_pushliteral(L, "__ts_cont_info"); + lua_rawget(L, LUA_GLOBALSINDEX); + ci = lua_touserdata(L, -1); + + lua_pop(L, 1); // pop the coroutine out + + return ci; +} + +void ts_lua_set_http_ctx(lua_State *L, ts_lua_http_ctx *ctx) { lua_pushliteral(L, "__ts_http_ctx"); @@ -335,22 +363,19 @@ ts_lua_get_http_ctx(lua_State *L) ts_lua_http_ctx * ts_lua_create_http_ctx(ts_lua_main_ctx *main_ctx, ts_lua_instance_conf *conf) { - size_t i, size; + ts_lua_coroutine *crt; ts_lua_http_ctx *http_ctx; lua_State *L; lua_State *l; L = main_ctx->lua; - size = TS_LUA_MEM_ALIGN(sizeof(ts_lua_http_ctx)); - http_ctx = TSmalloc(size); - - for (i = 0; i < TS_LUA_ALIGN_COUNT(size); i++) { - ((void **)http_ctx)[i] = 0; - } + http_ctx = TSmalloc(sizeof(ts_lua_http_ctx)); + memset(http_ctx, 0, sizeof(ts_lua_http_ctx)); - http_ctx->lua = lua_newthread(L); - l = http_ctx->lua; + // create coroutine for http_ctx + crt = &http_ctx->cinfo.routine; + l = lua_newthread(L); lua_pushlightuserdata(L, conf); lua_rawget(L, LUA_REGISTRYINDEX); @@ -366,13 +391,15 @@ ts_lua_create_http_ctx(ts_lua_main_ctx *main_ctx, ts_lua_instance_conf *conf) lua_replace(l, LUA_GLOBALSINDEX); - http_ctx->ref = luaL_ref(L, LUA_REGISTRYINDEX); + // init coroutine + crt->ref = luaL_ref(L, LUA_REGISTRYINDEX); + crt->lua = l; + crt->mctx = main_ctx; - http_ctx->mctx = main_ctx; http_ctx->instance_conf = conf; - ts_lua_set_http_ctx(http_ctx->lua, http_ctx); - ts_lua_create_context_table(http_ctx->lua); + ts_lua_set_http_ctx(l, http_ctx); + ts_lua_create_context_table(l); return http_ctx; } @@ -381,9 +408,9 @@ ts_lua_create_http_ctx(ts_lua_main_ctx *main_ctx, ts_lua_instance_conf *conf) void ts_lua_destroy_http_ctx(ts_lua_http_ctx *http_ctx) { - ts_lua_main_ctx *main_ctx; + ts_lua_cont_info *ci; - main_ctx = http_ctx->mctx; + ci = &http_ctx->cinfo; if (!http_ctx->remap) { if (http_ctx->client_request_bufp) { @@ -413,7 +440,7 @@ ts_lua_destroy_http_ctx(ts_lua_http_ctx *http_ctx) TSMBufferDestroy(http_ctx->cached_response_bufp); } - luaL_unref(main_ctx->lua, LUA_REGISTRYINDEX, http_ctx->ref); + ts_lua_release_cont_info(ci); TSfree(http_ctx); } @@ -440,29 +467,40 @@ ts_lua_get_http_intercept_ctx(lua_State *L) } ts_lua_http_intercept_ctx * -ts_lua_create_http_intercept_ctx(ts_lua_http_ctx *http_ctx) +ts_lua_create_http_intercept_ctx(lua_State *L, ts_lua_http_ctx *http_ctx, int n) { - size_t i, size; - lua_State *L; + int i; + lua_State *l; + ts_lua_cont_info *hci; + ts_lua_coroutine *crt; ts_lua_http_intercept_ctx *ictx; - L = http_ctx->lua; + hci = &http_ctx->cinfo; - size = TS_LUA_MEM_ALIGN(sizeof(ts_lua_http_intercept_ctx)); - ictx = TSmalloc(size); + ictx = TSmalloc(sizeof(ts_lua_http_intercept_ctx)); + memset(ictx, 0, sizeof(ts_lua_http_intercept_ctx)); - for (i = 0; i < TS_LUA_ALIGN_COUNT(size); i++) { - ((void **)ictx)[i] = 0; - } + ictx->hctx = http_ctx; - ictx->lua = lua_newthread(L); + // create lua_thread + l = lua_newthread(L); - ictx->ref = luaL_ref(L, LUA_REGISTRYINDEX); + // init the coroutine + crt = &ictx->cinfo.routine; + crt->mctx = hci->routine.mctx; + crt->lua = l; + crt->ref = luaL_ref(L, LUA_REGISTRYINDEX); - ictx->mctx = http_ctx->mctx; - ictx->hctx = http_ctx; + // Todo: replace the global, context table for crt->lua - ts_lua_set_http_intercept_ctx(ictx->lua, ictx); + // replicate the param + for (i = 0; i < n; i++) { + lua_pushvalue(L, i + 1); + } + + lua_xmove(L, l, n); // move the intercept function and params to the new lua_thread + + ts_lua_set_http_intercept_ctx(l, ictx); return ictx; } @@ -470,240 +508,276 @@ ts_lua_create_http_intercept_ctx(ts_lua_http_ctx *http_ctx) void ts_lua_destroy_http_intercept_ctx(ts_lua_http_intercept_ctx *ictx) { - ts_lua_main_ctx *main_ctx; - struct ict_item *node, *snode; + ts_lua_cont_info *ci; - main_ctx = ictx->mctx; + ci = &ictx->cinfo; - if (ictx->net_vc) + if (ictx->net_vc) { TSVConnClose(ictx->net_vc); + } TS_LUA_RELEASE_IO_HANDLE((&ictx->input)); TS_LUA_RELEASE_IO_HANDLE((&ictx->output)); - node = ictx->ict_chain; + ts_lua_release_cont_info(ci); + TSfree(ictx); +} - while (node) { - if (node->cleanup) - node->cleanup(node); +void +ts_lua_set_http_transform_ctx(lua_State *L, ts_lua_http_transform_ctx *tctx) +{ + lua_pushliteral(L, "__ts_http_transform_ctx"); + lua_pushlightuserdata(L, tctx); + lua_rawset(L, LUA_GLOBALSINDEX); +} - snode = node; - node = node->next; +ts_lua_http_transform_ctx * +ts_lua_get_http_transform_ctx(lua_State *L) +{ + ts_lua_http_transform_ctx *tctx; - TSfree(snode); - } + lua_pushliteral(L, "__ts_http_transform_ctx"); + lua_rawget(L, LUA_GLOBALSINDEX); + tctx = lua_touserdata(L, -1); - luaL_unref(main_ctx->lua, LUA_REGISTRYINDEX, ictx->ref); - TSfree(ictx); - return; + lua_pop(L, 1); // pop the ictx out + + return tctx; +} + +ts_lua_http_transform_ctx * +ts_lua_create_http_transform_ctx(ts_lua_http_ctx *http_ctx, TSVConn connp) +{ + lua_State *L; + ts_lua_cont_info *hci; + ts_lua_cont_info *ci; + ts_lua_coroutine *crt; + ts_lua_http_transform_ctx *transform_ctx; + + hci = &http_ctx->cinfo; + L = hci->routine.lua; + + transform_ctx = (ts_lua_http_transform_ctx *)TSmalloc(sizeof(ts_lua_http_transform_ctx)); + memset(transform_ctx, 0, sizeof(ts_lua_http_transform_ctx)); + + transform_ctx->hctx = http_ctx; + TSContDataSet(connp, transform_ctx); + + ci = &transform_ctx->cinfo; + ci->contp = connp; + ci->mutex = TSContMutexGet((TSCont)http_ctx->txnp); + + crt = &ci->routine; + crt->mctx = hci->routine.mctx; + crt->lua = lua_newthread(L); + crt->ref = luaL_ref(L, LUA_REGISTRYINDEX); + ts_lua_set_http_transform_ctx(crt->lua, transform_ctx); + + lua_pushlightuserdata(L, transform_ctx); + lua_pushvalue(L, 2); + lua_rawset(L, LUA_GLOBALSINDEX); // L[GLOBAL][transform_ctx] = transform handler + + return transform_ctx; } void -ts_lua_destroy_transform_ctx(ts_lua_transform_ctx *transform_ctx) +ts_lua_destroy_http_transform_ctx(ts_lua_http_transform_ctx *transform_ctx) { + ts_lua_cont_info *ci; + if (!transform_ctx) return; - if (transform_ctx->output_reader) - TSIOBufferReaderFree(transform_ctx->output_reader); + ci = &transform_ctx->cinfo; + + TS_LUA_RELEASE_IO_HANDLE((&transform_ctx->output)); + TS_LUA_RELEASE_IO_HANDLE((&transform_ctx->reserved)); - if (transform_ctx->output_buffer) - TSIOBufferDestroy(transform_ctx->output_buffer); + ts_lua_release_cont_info(ci); TSfree(transform_ctx); } int -ts_lua_http_cont_handler(TSCont contp, TSEvent event, void *edata) +ts_lua_http_cont_handler(TSCont contp, TSEvent ev, void *edata) { - TSHttpTxn txnp = (TSHttpTxn)edata; - int ret; - lua_State *l; + TSHttpTxn txnp; + int event, ret, rc, n, t; + lua_State *L; ts_lua_http_ctx *http_ctx; ts_lua_main_ctx *main_ctx; + ts_lua_cont_info *ci; + ts_lua_coroutine *crt; + event = (int)ev; http_ctx = (ts_lua_http_ctx *)TSContDataGet(contp); - main_ctx = http_ctx->mctx; + ci = &http_ctx->cinfo; + crt = &ci->routine; + + main_ctx = crt->mctx; + L = crt->lua; + + txnp = http_ctx->txnp; - ret = 0; - l = http_ctx->lua; + rc = ret = 0; TSMutexLock(main_ctx->mutexp); + ts_lua_set_cont_info(L, ci); switch (event) { case TS_EVENT_HTTP_POST_REMAP: - lua_getglobal(l, TS_LUA_FUNCTION_POST_REMAP); + lua_getglobal(L, TS_LUA_FUNCTION_POST_REMAP); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: - lua_getglobal(l, TS_LUA_FUNCTION_CACHE_LOOKUP_COMPLETE); + lua_getglobal(L, TS_LUA_FUNCTION_CACHE_LOOKUP_COMPLETE); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_SEND_REQUEST_HDR: - lua_getglobal(l, TS_LUA_FUNCTION_SEND_REQUEST); + lua_getglobal(L, TS_LUA_FUNCTION_SEND_REQUEST); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: - lua_getglobal(l, TS_LUA_FUNCTION_READ_RESPONSE); + lua_getglobal(L, TS_LUA_FUNCTION_READ_RESPONSE); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_SEND_RESPONSE_HDR: - lua_getglobal(l, TS_LUA_FUNCTION_SEND_RESPONSE); + lua_getglobal(L, TS_LUA_FUNCTION_SEND_RESPONSE); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_READ_REQUEST_HDR: - lua_getglobal(l, TS_LUA_FUNCTION_READ_REQUEST); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_READ_REQUEST); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_TXN_START: - lua_getglobal(l, TS_LUA_FUNCTION_TXN_START); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_TXN_START); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_PRE_REMAP: - lua_getglobal(l, TS_LUA_FUNCTION_PRE_REMAP); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_PRE_REMAP); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_OS_DNS: - lua_getglobal(l, TS_LUA_FUNCTION_OS_DNS); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_OS_DNS); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_SELECT_ALT: - lua_getglobal(l, TS_LUA_FUNCTION_SELECT_ALT); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_SELECT_ALT); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_READ_CACHE_HDR: - lua_getglobal(l, TS_LUA_FUNCTION_READ_CACHE); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); - } - - ret = lua_tointeger(l, -1); + lua_getglobal(L, TS_LUA_FUNCTION_READ_CACHE); + if (lua_type(L, -1) == LUA_TFUNCTION) { + ret = lua_resume(L, 0); } break; case TS_EVENT_HTTP_TXN_CLOSE: - lua_getglobal(l, TS_LUA_FUNCTION_TXN_CLOSE); - if (lua_type(l, -1) == LUA_TFUNCTION) { - if (lua_pcall(l, 0, 1, 0)) { - TSError("lua_pcall failed: %s", lua_tostring(l, -1)); + lua_getglobal(L, TS_LUA_FUNCTION_TXN_CLOSE); + if (lua_type(L, -1) == LUA_TFUNCTION) { + if (lua_pcall(L, 0, 1, 0)) { + TSError("lua_pcall failed: %s", lua_tostring(L, -1)); } - - ret = lua_tointeger(l, -1); } ts_lua_destroy_http_ctx(http_ctx); - TSContDestroy(contp); break; + case TS_LUA_EVENT_COROUTINE_CONT: + n = (intptr_t)edata; + ret = lua_resume(L, n); + default: break; } + switch (ret) { + case 0: // coroutine succeed + t = lua_gettop(L); + if (t > 0) { + rc = lua_tointeger(L, -1); + lua_pop(L, 1); + } + break; + + case LUA_YIELD: // coroutine yield + rc = 1; + break; + + default: // coroutine failed + ee("lua_resume failed: %s", lua_tostring(L, -1)); + rc = -1; + lua_pop(L, 1); + break; + } + TSMutexUnlock(main_ctx->mutexp); - if (ret) { + if (rc == 0) { + TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); + + } else if (rc < 0) { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); } else { - TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); + // wait for async } return 0; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/68b4d853/plugins/experimental/ts_lua/ts_lua_util.h ---------------------------------------------------------------------- diff --git a/plugins/experimental/ts_lua/ts_lua_util.h b/plugins/experimental/ts_lua/ts_lua_util.h index c2b259c..d8a003b 100644 --- a/plugins/experimental/ts_lua/ts_lua_util.h +++ b/plugins/experimental/ts_lua/ts_lua_util.h @@ -36,15 +36,21 @@ int ts_lua_del_instance(ts_lua_instance_conf *conf); void ts_lua_set_instance_conf(lua_State *L, ts_lua_instance_conf *conf); ts_lua_instance_conf *ts_lua_get_instance_conf(lua_State *L); +void ts_lua_set_cont_info(lua_State *L, ts_lua_cont_info *ci); +ts_lua_cont_info *ts_lua_get_cont_info(lua_State *L); + void ts_lua_set_http_ctx(lua_State *L, ts_lua_http_ctx *ctx); ts_lua_http_ctx *ts_lua_get_http_ctx(lua_State *L); ts_lua_http_ctx *ts_lua_create_http_ctx(ts_lua_main_ctx *mctx, ts_lua_instance_conf *conf); void ts_lua_destroy_http_ctx(ts_lua_http_ctx *http_ctx); -void ts_lua_destroy_transform_ctx(ts_lua_transform_ctx *transform_ctx); +ts_lua_http_transform_ctx *ts_lua_create_http_transform_ctx(ts_lua_http_ctx *http_ctx, TSVConn connp); +void ts_lua_destroy_http_transform_ctx(ts_lua_http_transform_ctx *transform_ctx); +void ts_lua_set_http_transform_ctx(lua_State *L, ts_lua_http_transform_ctx *tctx); +ts_lua_http_transform_ctx *ts_lua_get_http_transform_ctx(lua_State *L); -ts_lua_http_intercept_ctx *ts_lua_create_http_intercept_ctx(ts_lua_http_ctx *http_ctx); +ts_lua_http_intercept_ctx *ts_lua_create_http_intercept_ctx(lua_State *L, ts_lua_http_ctx *http_ctx, int n); ts_lua_http_intercept_ctx *ts_lua_get_http_intercept_ctx(lua_State *L); void ts_lua_destroy_http_intercept_ctx(ts_lua_http_intercept_ctx *ictx);
