static int ts_lua_http_intercept(lua_State *L) { TSCont contp; int type; ts_lua_http_ctx *http_ctx; http_ctx = ts_lua_get_http_ctx(L); http_ctx->has_hook = 1; type = lua_type(L, 1); if (type != LUA_TFUNCTION) { TSError("[%s] param in ts.http.intercept should be a function", __FUNCTION__); return 0; } lua_pushvalue(L, 1); lua_setglobal(L, TS_LUA_FUNCTION_HTTP_INTERCEPT); http_ctx->intercept_type = TS_LUA_TYPE_HTTP_INTERCEPT; contp = TSContCreate(ts_lua_http_intercept_entry, TSMutexCreate()); TSContDataSet(contp, http_ctx); TSHttpTxnIntercept(contp, http_ctx->txnp); return 0; }
static int stats_origin(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata) { TSCont icontp; stats_state *my_state; TSHttpTxn txnp = (TSHttpTxn)edata; TSMBuffer reqp; TSMLoc hdr_loc = NULL, url_loc = NULL; TSEvent reenable = TS_EVENT_HTTP_CONTINUE; TSDebug(PLUGIN_NAME, "in the read stuff"); if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc) != TS_SUCCESS) { goto cleanup; } if (TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc) != TS_SUCCESS) { goto cleanup; } int path_len = 0; const char *path = TSUrlPathGet(reqp, url_loc, &path_len); TSDebug(PLUGIN_NAME, "Path: %.*s", path_len, path); if (!(path_len != 0 && path_len == url_path_len && !memcmp(path, url_path, url_path_len))) { goto notforme; } TSSkipRemappingSet(txnp, 1); // not strictly necessary, but speed is everything these days /* This is us -- register our intercept */ TSDebug(PLUGIN_NAME, "Intercepting request"); icontp = TSContCreate(stats_dostuff, TSMutexCreate()); my_state = (stats_state *)TSmalloc(sizeof(*my_state)); memset(my_state, 0, sizeof(*my_state)); TSContDataSet(icontp, my_state); TSHttpTxnIntercept(icontp, txnp); goto cleanup; notforme: cleanup: if (url_loc) { TSHandleMLocRelease(reqp, hdr_loc, url_loc); } if (hdr_loc) { TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); } TSHttpTxnReenable(txnp, reenable); return 0; }
/* Read-request header continuation, used to kick off the server intercept if necessary */ static int health_check_origin(TSCont contp, TSEvent event, void *edata) { TSMBuffer reqp; TSMLoc hdr_loc = NULL, url_loc = NULL; TSCont icontp; HCState *my_state; TSHttpTxn txnp = (TSHttpTxn) edata; HCFileInfo *info = g_config; if ((TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) && (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc))) { int path_len = 0; const char* path = TSUrlPathGet(reqp, url_loc, &path_len); while (info) { if (info->p_len == path_len && !memcmp(info->path, path, path_len)) break; info = info->_next; } if (!info) goto cleanup; TSSkipRemappingSet(txnp, 1); /* not strictly necessary, but speed is everything these days */ /* This is us -- register our intercept */ icontp = TSContCreate(hc_intercept, TSMutexCreate()); my_state = (HCState *)TSmalloc(sizeof(*my_state)); memset(my_state, 0, sizeof(*my_state)); my_state->info = info; my_state->data = info->data; TSContDataSet(icontp, my_state); TSHttpTxnIntercept(icontp, txnp); } cleanup: if (url_loc) TSHandleMLocRelease(reqp, hdr_loc, url_loc); if (hdr_loc) TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
/* Read-request header continuation, used to kick off the server intercept if necessary */ static int acme_hook(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata) { TSMBuffer reqp; TSMLoc hdr_loc = NULL, url_loc = NULL; TSCont icontp; AcmeState *my_state; TSHttpTxn txnp = (TSHttpTxn)edata; TSDebug(PLUGIN_NAME, "kicking off ACME hook"); if ((TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) && (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc))) { int path_len = 0; const char *path = TSUrlPathGet(reqp, url_loc, &path_len); /* Short circuit the / path, common case */ if (!path || path_len < (int)(strlen(ACME_WK_PATH) + 2) || *path != '.' || memcmp(path, ACME_WK_PATH, strlen(ACME_WK_PATH))) { TSDebug(PLUGIN_NAME, "skipping URL path = %.*s", path_len, path); goto cleanup; } TSSkipRemappingSet(txnp, 1); /* not strictly necessary, but speed is everything these days */ /* This request is for us -- register our intercept */ icontp = TSContCreate(acme_intercept, TSMutexCreate()); my_state = make_acme_state(); open_acme_file(my_state, path + strlen(ACME_WK_PATH), path_len - strlen(ACME_WK_PATH)); TSContDataSet(icontp, my_state); TSHttpTxnIntercept(icontp, txnp); TSDebug(PLUGIN_NAME, "created intercept hook"); } cleanup: if (url_loc) { TSHandleMLocRelease(reqp, hdr_loc, url_loc); } if (hdr_loc) { TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
static int astats_origin(TSCont cont, TSEvent event, void *edata) { TSCont icontp; stats_state *my_state; config_t* config; TSHttpTxn txnp = (TSHttpTxn) edata; TSMBuffer reqp; TSMLoc hdr_loc = NULL, url_loc = NULL; TSEvent reenable = TS_EVENT_HTTP_CONTINUE; config = get_config(cont); TSDebug(PLUGIN_TAG, "in the read stuff"); if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc) != TS_SUCCESS) goto cleanup; if (TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc) != TS_SUCCESS) goto cleanup; int path_len = 0; const char* path = TSUrlPathGet(reqp,url_loc,&path_len); TSDebug(PLUGIN_TAG,"Path: %.*s",path_len,path); TSDebug(PLUGIN_TAG,"Path: %.*s",path_len,path); if (!(path_len == config->stats_path_len && !memcmp(path, config->stats_path, config->stats_path_len))) { // TSDebug(PLUGIN_TAG, "not right path: %.*s",path_len,path); goto notforme; } const struct sockaddr *addr = TSHttpTxnClientAddrGet(txnp); if(!is_ip_allowed(config, addr)) { TSDebug(PLUGIN_TAG, "not right ip"); goto notforme; } // TSDebug(PLUGIN_TAG,"Path...: %.*s",path_len,path); int query_len; char *query = (char*)TSUrlHttpQueryGet(reqp,url_loc,&query_len); TSDebug(PLUGIN_TAG,"query: %.*s",query_len,query); TSSkipRemappingSet(txnp,1); //not strictly necessary, but speed is everything these days /* This is us -- register our intercept */ TSDebug(PLUGIN_TAG, "Intercepting request"); icontp = TSContCreate(stats_dostuff, TSMutexCreate()); my_state = (stats_state *) TSmalloc(sizeof(*my_state)); memset(my_state, 0, sizeof(*my_state)); my_state->recordTypes = config->recordTypes; if (query_len) { my_state->query = nstrl(query, query_len); TSDebug(PLUGIN_TAG,"new query: %s", my_state->query); stats_fillState(my_state, my_state->query, query_len); } TSContDataSet(icontp, my_state); TSHttpTxnIntercept(icontp, txnp); goto cleanup; notforme: cleanup: #if (TS_VERSION_NUMBER < 2001005) if (path) TSHandleStringRelease(reqp, url_loc, path); #endif if (url_loc) TSHandleMLocRelease(reqp, hdr_loc, url_loc); if (hdr_loc) TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); TSHttpTxnReenable(txnp, reenable); return 0; }