static int ts_lua_http_set_parent_proxy(lua_State *L) { int n = 0; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); n = lua_gettop(L); if (n == 2) { const char *hostname; size_t hostname_len; int port = 0; hostname = luaL_checklstring(L, 1, &hostname_len); port = luaL_checkinteger(L, 2); TSHttpTxnParentProxySet(http_ctx->txnp, hostname, port); } else { return luaL_error(L, "incorrect # of arguments for set_parent_proxy, receiving %d instead of 2", n); } return 0; }
static int ts_lua_server_request_server_addr_get_outgoing_port(lua_State *L) { struct sockaddr const *outgoing_addr; ts_lua_http_ctx *http_ctx; int port; GET_HTTP_CONTEXT(http_ctx, L); outgoing_addr = TSHttpTxnOutgoingAddrGet(http_ctx->txnp); if (outgoing_addr == NULL) { lua_pushnil(L); } else { if (outgoing_addr->sa_family == AF_INET) { port = ((struct sockaddr_in *)outgoing_addr)->sin_port; } else { port = ((struct sockaddr_in6 *)outgoing_addr)->sin6_port; } lua_pushnumber(L, ntohs(port)); } return 1; }
static int ts_lua_remap_get_to_uri(lua_State *L) { char uri[TS_LUA_MAX_URL_LENGTH]; const char *path; int path_len; int uri_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); if (http_ctx->rri != NULL) { path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->rri->mapToUrl, &path_len); uri_len = snprintf(uri, TS_LUA_MAX_URL_LENGTH, "/%.*s", path_len, path); if (uri_len >= TS_LUA_MAX_URL_LENGTH) { lua_pushlstring(L, uri, TS_LUA_MAX_URL_LENGTH - 1); } else { lua_pushlstring(L, uri, uri_len); } } else { lua_pushnil(L); } return 1; }
static int ts_lua_server_request_get_uri(lua_State *L) { char uri[TS_LUA_MAX_URL_LENGTH]; const char *path; int path_len; int uri_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TS_LUA_CHECK_SERVER_REQUEST_URL(http_ctx); path = TSUrlPathGet(http_ctx->server_request_bufp, http_ctx->server_request_url, &path_len); uri_len = snprintf(uri, TS_LUA_MAX_URL_LENGTH, "/%.*s", path_len, path); if (uri_len >= TS_LUA_MAX_URL_LENGTH) { lua_pushlstring(L, uri, TS_LUA_MAX_URL_LENGTH - 1); } else { lua_pushlstring(L, uri, uri_len); } return 1; }
static int ts_lua_cached_response_header_get(lua_State *L) { const char *key; const char *val; int val_len; size_t key_len; TSMLoc field_loc; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); /* we skip the first argument that is the table */ key = luaL_checklstring(L, 2, &key_len); TS_LUA_CHECK_CACHED_RESPONSE_HDR(http_ctx); if (key && key_len) { field_loc = TSMimeHdrFieldFind(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, key, key_len); if (field_loc) { val = TSMimeHdrFieldValueStringGet(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, field_loc, -1, &val_len); lua_pushlstring(L, val, val_len); TSHandleMLocRelease(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, field_loc); } else { lua_pushnil(L); } } else { lua_pushnil(L); } return 1; }
static int ts_lua_server_request_server_addr_get_ip(lua_State *L) { struct sockaddr const *server_ip; char sip[128]; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); server_ip = TSHttpTxnServerAddrGet(http_ctx->txnp); if (server_ip == NULL) { lua_pushnil(L); } else { if (server_ip->sa_family == AF_INET) { inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)server_ip)->sin_addr, sip, sizeof(sip)); } else { inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)server_ip)->sin6_addr, sip, sizeof(sip)); } lua_pushstring(L, sip); } return 1; }
static int ts_lua_remap_get_to_url(lua_State *L) { char output[TS_LUA_MAX_URL_LENGTH]; char *url; int url_len; int output_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); if (http_ctx->rri != NULL) { url = TSUrlStringGet(http_ctx->client_request_bufp, http_ctx->rri->mapToUrl, &url_len); output_len = snprintf(output, TS_LUA_MAX_URL_LENGTH, "%.*s", url_len, url); if (output_len >= TS_LUA_MAX_URL_LENGTH) { lua_pushlstring(L, output, TS_LUA_MAX_URL_LENGTH - 1); } else { lua_pushlstring(L, output, output_len); } TSfree(url); } else { lua_pushnil(L); } return 1; }
static int ts_lua_server_response_get_version(lua_State *L) { int version; char buf[32]; int n; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TS_LUA_CHECK_SERVER_RESPONSE_HDR(http_ctx); version = TSHttpHdrVersionGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp); n = snprintf(buf, sizeof(buf), "%d.%d", TS_HTTP_MAJOR(version), TS_HTTP_MINOR(version)); if (n >= (int)sizeof(buf)) { lua_pushlstring(L, buf, sizeof(buf) - 1); } else if (n > 0) { lua_pushlstring(L, buf, n); } return 1; }
static int ts_lua_http_get_remap_to_url(lua_State *L) { TSMLoc url = TS_NULL_MLOC; char *str = NULL; int len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); if (TSRemapToUrlGet(http_ctx->txnp, &url) != TS_SUCCESS) { lua_pushnil(L); goto done; } str = TSUrlStringGet(NULL, url, &len); lua_pushlstring(L, str, len >= TS_LUA_MAX_URL_LENGTH ? TS_LUA_MAX_URL_LENGTH - 1 : len); done: if (str != NULL) { TSfree(str); } return 1; }
static int ts_lua_http_set_cache_lookup_url(lua_State *L) { const char *url; size_t url_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); url = luaL_checklstring(L, 1, &url_len); if (url && url_len) { const char *start = url; const char *end = url + url_len; TSMLoc new_url_loc; if (TSUrlCreate(http_ctx->client_request_bufp, &new_url_loc) == TS_SUCCESS && TSUrlParse(http_ctx->client_request_bufp, new_url_loc, &start, end) == TS_PARSE_DONE && TSHttpTxnCacheLookupUrlSet(http_ctx->txnp, http_ctx->client_request_bufp, new_url_loc) == TS_SUCCESS) { TSDebug(TS_LUA_DEBUG_TAG, "Set cache lookup URL"); } else { TSError("[ts_lua] Failed to set cache lookup URL"); } } return 0; }
static int ts_lua_server_request_get_headers(lua_State *L) { const char *name; const char *value; int name_len; int value_len; TSMLoc field_loc; TSMLoc next_field_loc; const char *tvalue; size_t tvalue_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TS_LUA_CHECK_SERVER_REQUEST_HDR(http_ctx); lua_newtable(L); field_loc = TSMimeHdrFieldGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, 0); while (field_loc != TS_NULL_MLOC) { name = TSMimeHdrFieldNameGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, &name_len); if (name && name_len) { // retrieve the header name from table lua_pushlstring(L, name, name_len); lua_gettable(L, -2); if (lua_isnil(L, -1)) { // if header name does not exist in the table, insert it lua_pop(L, 1); value = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &value_len); lua_pushlstring(L, name, name_len); lua_pushlstring(L, value, value_len); lua_rawset(L, -3); } else { // if header name exists in the table, append a command and the new value to the end of the existing value tvalue = lua_tolstring(L, -1, &tvalue_len); lua_pop(L, 1); value = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &value_len); lua_pushlstring(L, name, name_len); lua_pushlstring(L, tvalue, tvalue_len); lua_pushlstring(L, ",", 1); lua_pushlstring(L, value, value_len); lua_concat(L, 3); lua_rawset(L, -3); } } next_field_loc = TSMimeHdrFieldNext(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); field_loc = next_field_loc; } return 1; }
static int ts_lua_client_response_set_error_resp(lua_State *L) { int n, status; const char *body; const char *reason; int reason_len; size_t body_len; int resp_len; char *resp_buf; TSMLoc field_loc; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx); n = lua_gettop(L); status = luaL_checkinteger(L, 1); reason = TSHttpHdrReasonLookup(status); reason_len = strlen(reason); TSHttpHdrStatusSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, status); TSHttpHdrReasonSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, reason, reason_len); body_len = 0; if (n == 2) { body = luaL_checklstring(L, 2, &body_len); } if (body_len && body) { resp_buf = TSmalloc(body_len); memcpy(resp_buf, body, body_len); resp_len = body_len; } else { resp_buf = TSmalloc(reason_len); memcpy(resp_buf, reason, reason_len); resp_len = reason_len; } field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, TS_MIME_FIELD_TRANSFER_ENCODING, TS_MIME_LEN_TRANSFER_ENCODING); if (field_loc) { TSMimeHdrFieldDestroy(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc); TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc); } TSHttpTxnErrorBodySet(http_ctx->txnp, resp_buf, resp_len, NULL); return 0; }
static int ts_lua_server_request_header_set(lua_State *L) { const char *key; const char *val; size_t val_len; size_t key_len; int remove; TSMLoc field_loc; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); remove = 0; val = NULL; /* we skip the first argument that is the table */ key = luaL_checklstring(L, 2, &key_len); if (lua_isnil(L, 3)) { remove = 1; } else { val = luaL_checklstring(L, 3, &val_len); } if (!http_ctx->server_request_hdrp) { if (TSHttpTxnServerReqGet(http_ctx->txnp, &http_ctx->server_request_bufp, &http_ctx->server_request_hdrp) != TS_SUCCESS) { return 0; } } field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len); if (remove) { if (field_loc) { TSMimeHdrFieldDestroy(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); } } else if (field_loc) { TSMimeHdrFieldValueStringSet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, val, val_len); } else if (TSMimeHdrFieldCreateNamed(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len, &field_loc) != TS_SUCCESS) { TSError("[ts_lua][%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__); return 0; } else { TSMimeHdrFieldValueStringSet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, val, val_len); TSMimeHdrFieldAppend(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); } if (field_loc) TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); return 0; }
static int ts_lua_http_is_websocket(lua_State *L) { ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); lua_pushboolean(L, TSHttpTxnIsWebsocket(http_ctx->txnp)); return 1; }
static int ts_lua_http_get_id(lua_State *L) { ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); uint64_t id = TSHttpTxnIdGet(http_ctx->txnp); lua_pushnumber(L, id); return 1; }
static int ts_lua_server_request_header_get(lua_State *L) { const char *key; const char *val; int val_len; size_t key_len; int count; TSMLoc field_loc, next_field_loc; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); /* we skip the first argument that is the table */ key = luaL_checklstring(L, 2, &key_len); if (!http_ctx->server_request_hdrp) { if (TSHttpTxnServerReqGet(http_ctx->txnp, &http_ctx->server_request_bufp, &http_ctx->server_request_hdrp) != TS_SUCCESS) { lua_pushnil(L); return 1; } } if (key && key_len) { field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len); if (field_loc != TS_NULL_MLOC) { count = 0; while (field_loc != TS_NULL_MLOC) { val = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &val_len); next_field_loc = TSMimeHdrFieldNextDup(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); lua_pushlstring(L, val, val_len); count++; // multiple headers with the same name must be semantically the same as one value which is comma seperated if (next_field_loc != TS_NULL_MLOC) { lua_pushlstring(L, ",", 1); count++; } TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); field_loc = next_field_loc; } lua_concat(L, count); } else { lua_pushnil(L); } } else { lua_pushnil(L); } return 1; }
static int ts_lua_http_get_server_state(lua_State *L) { ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TSServerState ss = TSHttpTxnServerStateGet(http_ctx->txnp); lua_pushnumber(L, ss); return 1; }
static int ts_lua_http_set_retstatus(lua_State *L) { int status; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); status = luaL_checkinteger(L, 1); TSHttpTxnSetHttpRetStatus(http_ctx->txnp, status); return 0; }
static int ts_lua_http_get_plugin_tag(lua_State *L) { ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); const char *tag = TSHttpTxnPluginTagGet(http_ctx->txnp); lua_pushstring(L, tag); return 1; }
static int ts_lua_server_request_get_body_size(lua_State *L) { int64_t body_size; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); body_size = TSHttpTxnServerReqBodyBytesGet(http_ctx->txnp); lua_pushnumber(L, body_size); return 1; }
static int ts_lua_http_set_retbody(lua_State *L) { const char *body; size_t body_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); body = luaL_checklstring(L, 1, &body_len); TSHttpTxnErrorBodySet(http_ctx->txnp, TSstrdup(body), body_len, NULL); // Defaults to text/html return 0; }
static int ts_lua_server_request_get_header_size(lua_State *L) { int header_size; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); header_size = TSHttpTxnServerReqHdrBytesGet(http_ctx->txnp); lua_pushnumber(L, header_size); return 1; }
static int ts_lua_http_skip_remapping_set(lua_State *L) { int action; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); action = luaL_checkinteger(L, 1); TSSkipRemappingSet(http_ctx->txnp, action); return 0; }
static int ts_lua_http_resp_cache_untransformed(lua_State *L) { int action; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); action = luaL_checkinteger(L, 1); TSHttpTxnUntransformedRespCache(http_ctx->txnp, action); return 0; }
static int ts_lua_http_server_push(lua_State *L) { const char *url; size_t url_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); url = luaL_checklstring(L, 1, &url_len); TSHttpTxnServerPush(http_ctx->txnp, url, url_len); return 0; }
static int ts_lua_http_server_packet_dscp_set(lua_State *L) { int value; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); value = luaL_checkinteger(L, 1); TSDebug(TS_LUA_DEBUG_TAG, "server packet dscp set"); TSHttpTxnServerPacketDscpSet(http_ctx->txnp, value); return 0; }
static int ts_lua_http_client_packet_tos_set(lua_State *L) { int value; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); value = luaL_checkinteger(L, 1); TSDebug(TS_LUA_DEBUG_TAG, "client packet tos set"); TSHttpTxnClientPacketTosSet(http_ctx->txnp, value); return 0; }
static int ts_lua_http_set_debug(lua_State *L) { int value; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); value = luaL_checkinteger(L, 1); TSDebug(TS_LUA_DEBUG_TAG, "set debug"); TSHttpTxnDebugSet(http_ctx->txnp, value); return 0; }
static int ts_lua_http_enable_redirect(lua_State *L) { int value; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); value = luaL_checkinteger(L, 1); TSDebug(TS_LUA_DEBUG_TAG, "enable redirect"); TSHttpTxnFollowRedirect(http_ctx->txnp, value); return 0; }
static int ts_lua_http_set_cache_lookup_status(lua_State *L) { int status; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); status = luaL_checknumber(L, 1); TSHttpTxnCacheLookupStatusSet(http_ctx->txnp, status); return 0; }