TSRemapStatus TSRemapDoRemap(void* ih, TSHttpTxn rh, TSRemapRequestInfo *rri) { int ret; uint64_t req_id; TSCont contp; lua_State *L; ts_lua_main_ctx *main_ctx; ts_lua_http_ctx *http_ctx; ts_lua_cont_info *ci; ts_lua_instance_conf *instance_conf; instance_conf = (ts_lua_instance_conf*)ih; req_id = __sync_fetch_and_add(&ts_lua_http_next_id, 1); main_ctx = &ts_lua_main_ctx_array[req_id%TS_LUA_MAX_STATE_COUNT]; TSMutexLock(main_ctx->mutexp); http_ctx = ts_lua_create_http_ctx(main_ctx, instance_conf); http_ctx->txnp = rh; http_ctx->client_request_bufp = rri->requestBufp; http_ctx->client_request_hdrp = rri->requestHdrp; http_ctx->client_request_url = rri->requestUrl; http_ctx->rri = rri; ci = &http_ctx->cinfo; L = ci->routine.lua; contp = TSContCreate(ts_lua_http_cont_handler, NULL); TSContDataSet(contp, http_ctx); ci->contp = contp; ci->mutex = TSContMutexGet((TSCont)rh); // push do_remap function on the stack, and no async operation should exist here. lua_getglobal(L, TS_LUA_FUNCTION_REMAP); if (lua_pcall(L, 0, 1, 0) != 0) { ee("lua_pcall failed: %s", lua_tostring(L, -1)); ret = TSREMAP_NO_REMAP; } else { ret = lua_tointeger(L, -1); } lua_pop(L, 1); // pop the result if (http_ctx->hooks > 0) { TSMutexUnlock(main_ctx->mutexp); TSHttpTxnHookAdd(rh, TS_HTTP_TXN_CLOSE_HOOK, contp); } else { ts_lua_destroy_http_ctx(http_ctx); TSMutexUnlock(main_ctx->mutexp); } return ret; }
void TSPluginInit(int argc, const char *argv[]) { int ret = 0; ts_lua_g_main_ctx_array = TSmalloc(sizeof(ts_lua_main_ctx) * TS_LUA_MAX_STATE_COUNT); memset(ts_lua_g_main_ctx_array, 0, sizeof(ts_lua_main_ctx) * TS_LUA_MAX_STATE_COUNT); ret = ts_lua_create_vm(ts_lua_g_main_ctx_array, TS_LUA_MAX_STATE_COUNT); if (ret) { ts_lua_destroy_vm(ts_lua_g_main_ctx_array, TS_LUA_MAX_STATE_COUNT); TSfree(ts_lua_g_main_ctx_array); return; } if (argc < 2) { TSError("[%s] lua script file required !!", __FUNCTION__); return; } if (strlen(argv[1]) >= TS_LUA_MAX_SCRIPT_FNAME_LENGTH - 16) { TSError("[%s] lua script file name too long !!", __FUNCTION__); return; } ts_lua_instance_conf *conf = TSmalloc(sizeof(ts_lua_instance_conf)); if (!conf) { TSError("[%s] TSmalloc failed !!", __FUNCTION__); return; } memset(conf, 0, sizeof(ts_lua_instance_conf)); sprintf(conf->script, "%s", argv[1]); ts_lua_init_instance(conf); ret = ts_lua_add_module(conf, ts_lua_g_main_ctx_array, TS_LUA_MAX_STATE_COUNT, argc - 1, (char **) &argv[1]); if (ret != 0) { TSError("[%s] ts_lua_add_module failed", __FUNCTION__); return; } TSCont global_contp = TSContCreate(globalHookHandler, NULL); if (!global_contp) { TSError("[%s] could not create transaction start continuation", __FUNCTION__); return; } TSContDataSet(global_contp, conf); //adding hook based on whether the lua global function exists. ts_lua_main_ctx *main_ctx = &ts_lua_g_main_ctx_array[0]; ts_lua_http_ctx *http_ctx = ts_lua_create_http_ctx(main_ctx, conf); lua_State *l = http_ctx->lua; lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_REQUEST); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_SEND_REQUEST_HDR_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "send_request_hdr_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_READ_RESPONSE); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "read_response_hdr_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_RESPONSE); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_SEND_RESPONSE_HDR_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "send_response_hdr_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_CACHE_LOOKUP_COMPLETE); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "cache_lookup_complete_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_READ_REQUEST); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "read_request_hdr_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_START); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_TXN_START_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "txn_start_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_PRE_REMAP); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_PRE_REMAP_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "pre_remap_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_POST_REMAP); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_POST_REMAP_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "post_remap_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_SELECT_ALT); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_SELECT_ALT_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "select_alt_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_OS_DNS); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "os_dns_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_READ_CACHE); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_READ_CACHE_HDR_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "read_cache_hdr_hook added"); } lua_pop(l, 1); lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_CLOSE); if (lua_type(l, -1) == LUA_TFUNCTION) { TSHttpHookAdd(TS_HTTP_TXN_CLOSE_HOOK, global_contp); TSDebug(TS_LUA_DEBUG_TAG, "txn_close_hook added"); } lua_pop(l, 1); ts_lua_destroy_http_ctx(http_ctx); }
static int globalHookHandler(TSCont contp, TSEvent event ATS_UNUSED, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc url_loc; int ret; uint64_t req_id; TSCont txn_contp; lua_State *l; ts_lua_main_ctx *main_ctx; ts_lua_http_ctx *http_ctx; ts_lua_instance_conf *conf = (ts_lua_instance_conf *) TSContDataGet(contp); req_id = __sync_fetch_and_add(&ts_lua_g_http_next_id, 1); main_ctx = &ts_lua_g_main_ctx_array[req_id % TS_LUA_MAX_STATE_COUNT]; TSDebug(TS_LUA_DEBUG_TAG, "[%s] req_id: %" PRId64, __FUNCTION__, req_id); TSMutexLock(main_ctx->mutexp); http_ctx = ts_lua_create_http_ctx(main_ctx, conf); http_ctx->txnp = txnp; http_ctx->remap = 0; http_ctx->has_hook = 0; if (!http_ctx->client_request_bufp) { if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) == TS_SUCCESS) { http_ctx->client_request_bufp = bufp; http_ctx->client_request_hdrp = hdr_loc; if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) == TS_SUCCESS) { http_ctx->client_request_url = url_loc; } } } if (!http_ctx->client_request_hdrp) { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; } txn_contp = TSContCreate(ts_lua_http_cont_handler, NULL); TSContDataSet(txn_contp, http_ctx); http_ctx->main_contp = txn_contp; l = http_ctx->lua; switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_REQUEST); break; case TS_EVENT_HTTP_SEND_REQUEST_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_REQUEST); break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_RESPONSE); break; case TS_EVENT_HTTP_SEND_RESPONSE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_RESPONSE); break; case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: lua_getglobal(l, TS_LUA_FUNCTION_G_CACHE_LOOKUP_COMPLETE); break; case TS_EVENT_HTTP_TXN_START: lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_START); break; case TS_EVENT_HTTP_PRE_REMAP: lua_getglobal(l, TS_LUA_FUNCTION_G_PRE_REMAP); break; case TS_EVENT_HTTP_POST_REMAP: lua_getglobal(l, TS_LUA_FUNCTION_G_POST_REMAP); break; case TS_EVENT_HTTP_SELECT_ALT: lua_getglobal(l, TS_LUA_FUNCTION_G_SELECT_ALT); break; case TS_EVENT_HTTP_OS_DNS: lua_getglobal(l, TS_LUA_FUNCTION_G_OS_DNS); break; case TS_EVENT_HTTP_READ_CACHE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_CACHE); break; case TS_EVENT_HTTP_TXN_CLOSE: lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_CLOSE); break; default: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; break; } if (lua_type(l, -1) != LUA_TFUNCTION) { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); lua_pop(l, 1); return 0; } if (lua_pcall(l, 0, 1, 0) != 0) { TSError("lua_pcall failed: %s", lua_tostring(l, -1)); } ret = lua_tointeger(l, -1); lua_pop(l, 1); if(http_ctx->has_hook) { // add a hook to release resources for context TSDebug(TS_LUA_DEBUG_TAG, "[%s] has txn hook -> adding txn close hook handler to release resources", __FUNCTION__); TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp); } else { TSDebug(TS_LUA_DEBUG_TAG, "[%s] no txn hook -> release resources now", __FUNCTION__); ts_lua_destroy_http_ctx(http_ctx); TSContDestroy(txn_contp); } TSMutexUnlock(main_ctx->mutexp); if(ret) { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); } else { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); } return 0; }
TSRemapStatus TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo * rri) { int ret; uint64_t req_id; TSCont contp; lua_State *l; ts_lua_main_ctx *main_ctx; ts_lua_http_ctx *http_ctx; ts_lua_instance_conf *instance_conf; instance_conf = (ts_lua_instance_conf *) ih; req_id = __sync_fetch_and_add(&ts_lua_http_next_id, 1); main_ctx = &ts_lua_main_ctx_array[req_id % TS_LUA_MAX_STATE_COUNT]; TSMutexLock(main_ctx->mutexp); http_ctx = ts_lua_create_http_ctx(main_ctx, instance_conf); http_ctx->txnp = rh; http_ctx->client_request_bufp = rri->requestBufp; http_ctx->client_request_hdrp = rri->requestHdrp; http_ctx->client_request_url = rri->requestUrl; http_ctx->remap = 1; http_ctx->has_hook = 0; contp = TSContCreate(ts_lua_http_cont_handler, NULL); TSContDataSet(contp, http_ctx); http_ctx->main_contp = contp; l = http_ctx->lua; lua_getglobal(l, TS_LUA_FUNCTION_REMAP); if (lua_type(l, -1) != LUA_TFUNCTION) { TSMutexUnlock(main_ctx->mutexp); return TSREMAP_NO_REMAP; } if (lua_pcall(l, 0, 1, 0) != 0) { TSError("lua_pcall failed: %s", lua_tostring(l, -1)); } ret = lua_tointeger(l, -1); lua_pop(l, 1); if(http_ctx->has_hook) { TSDebug(TS_LUA_DEBUG_TAG, "[%s] has txn hook -> adding txn close hook handler to release resources", __FUNCTION__); TSHttpTxnHookAdd(rh, TS_HTTP_TXN_CLOSE_HOOK, contp); } else { TSDebug(TS_LUA_DEBUG_TAG, "[%s] no txn hook -> release resources now", __FUNCTION__); ts_lua_destroy_http_ctx(http_ctx); TSContDestroy(contp); } TSMutexUnlock(main_ctx->mutexp); return ret; }
static int globalHookHandler(TSCont contp, TSEvent event ATS_UNUSED, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc url_loc; int ret; uint64_t req_id; TSCont txn_contp; lua_State *l; ts_lua_main_ctx *main_ctx; ts_lua_http_ctx *http_ctx; ts_lua_cont_info *ci; ts_lua_instance_conf *conf = (ts_lua_instance_conf *)TSContDataGet(contp); req_id = __sync_fetch_and_add(&ts_lua_g_http_next_id, 1); main_ctx = &ts_lua_g_main_ctx_array[req_id % TS_LUA_MAX_STATE_COUNT]; TSDebug(TS_LUA_DEBUG_TAG, "[%s] req_id: %" PRId64, __FUNCTION__, req_id); TSMutexLock(main_ctx->mutexp); http_ctx = ts_lua_create_http_ctx(main_ctx, conf); http_ctx->txnp = txnp; http_ctx->rri = NULL; http_ctx->has_hook = 0; if (!http_ctx->client_request_bufp) { if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) == TS_SUCCESS) { http_ctx->client_request_bufp = bufp; http_ctx->client_request_hdrp = hdr_loc; if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) == TS_SUCCESS) { http_ctx->client_request_url = url_loc; } } } if (!http_ctx->client_request_hdrp) { ts_lua_destroy_http_ctx(http_ctx); TSMutexUnlock(main_ctx->mutexp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; } txn_contp = TSContCreate(ts_lua_http_cont_handler, NULL); TSContDataSet(txn_contp, http_ctx); ci = &http_ctx->cinfo; ci->contp = txn_contp; ci->mutex = TSContMutexGet((TSCont)txnp); l = ci->routine.lua; switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_REQUEST); break; case TS_EVENT_HTTP_SEND_REQUEST_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_REQUEST); break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_RESPONSE); break; case TS_EVENT_HTTP_SEND_RESPONSE_HDR: // client response can be changed within a transaction // (e.g. due to the follow redirect feature). So, clearing the pointers // to allow API(s) to fetch the pointers again when it re-enters the hook if (http_ctx->client_response_hdrp != NULL) { TSHandleMLocRelease(http_ctx->client_response_bufp, TS_NULL_MLOC, http_ctx->client_response_hdrp); http_ctx->client_response_hdrp = NULL; } lua_getglobal(l, TS_LUA_FUNCTION_G_SEND_RESPONSE); break; case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: lua_getglobal(l, TS_LUA_FUNCTION_G_CACHE_LOOKUP_COMPLETE); break; case TS_EVENT_HTTP_TXN_START: lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_START); break; case TS_EVENT_HTTP_PRE_REMAP: lua_getglobal(l, TS_LUA_FUNCTION_G_PRE_REMAP); break; case TS_EVENT_HTTP_POST_REMAP: lua_getglobal(l, TS_LUA_FUNCTION_G_POST_REMAP); break; case TS_EVENT_HTTP_SELECT_ALT: lua_getglobal(l, TS_LUA_FUNCTION_G_SELECT_ALT); break; case TS_EVENT_HTTP_OS_DNS: lua_getglobal(l, TS_LUA_FUNCTION_G_OS_DNS); break; case TS_EVENT_HTTP_READ_CACHE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_G_READ_CACHE); break; case TS_EVENT_HTTP_TXN_CLOSE: lua_getglobal(l, TS_LUA_FUNCTION_G_TXN_CLOSE); break; default: ts_lua_destroy_http_ctx(http_ctx); TSMutexUnlock(main_ctx->mutexp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; } if (lua_type(l, -1) != LUA_TFUNCTION) { lua_pop(l, 1); ts_lua_destroy_http_ctx(http_ctx); TSMutexUnlock(main_ctx->mutexp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; } ts_lua_set_cont_info(l, NULL); if (lua_pcall(l, 0, 1, 0) != 0) { TSError("[ts_lua] lua_pcall failed: %s", lua_tostring(l, -1)); } ret = lua_tointeger(l, -1); lua_pop(l, 1); if (http_ctx->has_hook) { // add a hook to release resources for context TSDebug(TS_LUA_DEBUG_TAG, "[%s] has txn hook -> adding txn close hook handler to release resources", __FUNCTION__); TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp); } else { TSDebug(TS_LUA_DEBUG_TAG, "[%s] no txn hook -> release resources now", __FUNCTION__); ts_lua_destroy_http_ctx(http_ctx); } TSMutexUnlock(main_ctx->mutexp); if (ret) { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); } else { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); } return 0; }
static TSRemapStatus ts_lua_remap_plugin_init(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) { int ret; uint64_t req_id; TSCont contp; lua_State *L; ts_lua_main_ctx *main_ctx; ts_lua_http_ctx *http_ctx; ts_lua_cont_info *ci; ts_lua_instance_conf *instance_conf; int remap = (rri == NULL ? 0 : 1); instance_conf = (ts_lua_instance_conf *)ih; req_id = __sync_fetch_and_add(&ts_lua_http_next_id, 1); main_ctx = &ts_lua_main_ctx_array[req_id % TS_LUA_MAX_STATE_COUNT]; TSMutexLock(main_ctx->mutexp); http_ctx = ts_lua_create_http_ctx(main_ctx, instance_conf); http_ctx->txnp = rh; http_ctx->has_hook = 0; http_ctx->rri = rri; if (rri != NULL) { http_ctx->client_request_bufp = rri->requestBufp; http_ctx->client_request_hdrp = rri->requestHdrp; http_ctx->client_request_url = rri->requestUrl; } ci = &http_ctx->cinfo; L = ci->routine.lua; contp = TSContCreate(ts_lua_http_cont_handler, NULL); TSContDataSet(contp, http_ctx); ci->contp = contp; ci->mutex = TSContMutexGet((TSCont)rh); lua_getglobal(L, (remap ? TS_LUA_FUNCTION_REMAP : TS_LUA_FUNCTION_OS_RESPONSE)); if (lua_type(L, -1) != LUA_TFUNCTION) { TSMutexUnlock(main_ctx->mutexp); return TSREMAP_NO_REMAP; } ts_lua_set_cont_info(L, NULL); if (lua_pcall(L, 0, 1, 0) != 0) { TSError("[ts_lua] lua_pcall failed: %s", lua_tostring(L, -1)); ret = TSREMAP_NO_REMAP; } else { ret = lua_tointeger(L, -1); } lua_pop(L, 1); if (http_ctx->has_hook) { TSDebug(TS_LUA_DEBUG_TAG, "[%s] has txn hook -> adding txn close hook handler to release resources", __FUNCTION__); TSHttpTxnHookAdd(rh, TS_HTTP_TXN_CLOSE_HOOK, contp); } else { TSDebug(TS_LUA_DEBUG_TAG, "[%s] no txn hook -> release resources now", __FUNCTION__); ts_lua_destroy_http_ctx(http_ctx); } TSMutexUnlock(main_ctx->mutexp); return ret; }
int ts_lua_http_cont_handler(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; lua_State *l; ts_lua_http_ctx *http_ctx; ts_lua_main_ctx *main_ctx; http_ctx = (ts_lua_http_ctx*)TSContDataGet(contp); main_ctx = http_ctx->mctx; l = http_ctx->lua; TSMutexLock(main_ctx->mutexp); switch (event) { case TS_EVENT_HTTP_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)) { fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1)); } } break; case TS_EVENT_HTTP_SEND_REQUEST_HDR: lua_getglobal(l, TS_LUA_FUNCTION_SEND_REQUEST); if (lua_type(l, -1) == LUA_TFUNCTION) { if (lua_pcall(l, 0, 1, 0)) { fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1)); } } break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_READ_RESPONSE); if (lua_type(l, -1) == LUA_TFUNCTION) { if (lua_pcall(l, 0, 1, 0)) { fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1)); } } break; case TS_EVENT_HTTP_SEND_RESPONSE_HDR: lua_getglobal(l, TS_LUA_FUNCTION_SEND_RESPONSE); if (lua_type(l, -1) == LUA_TFUNCTION) { if (lua_pcall(l, 0, 1, 0)) { fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1)); } } break; case TS_EVENT_HTTP_TXN_CLOSE: ts_lua_destroy_http_ctx(http_ctx); TSContDestroy(contp); break; default: break; } TSMutexUnlock(main_ctx->mutexp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }