static int hdr_handler(TSCont contp, TSHttpTxn txnp) { TSMBuffer bufp; TSMLoc hdr_loc, field_loc; hdr_list *hdr; hdr = TSContDataGet(contp); if (hdr == NULL) { goto done; } if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("couldn't retrieve client response header\n"); goto done; } for (; hdr; hdr = hdr->next) { TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc); TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, hdr->name, strlen(hdr->name)); TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, hdr->val, strlen(hdr->val)); TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc); TSHandleMLocRelease(bufp, hdr_loc, field_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); } done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
void ts_lua_destroy_http_ctx(ts_lua_http_ctx* http_ctx) { ts_lua_main_ctx *main_ctx; main_ctx = http_ctx->mctx; if (http_ctx->server_request_bufp) { TSHandleMLocRelease(http_ctx->server_request_bufp, TS_NULL_MLOC, http_ctx->server_request_hdrp); } if (http_ctx->server_response_bufp) { TSHandleMLocRelease(http_ctx->server_response_bufp, TS_NULL_MLOC, http_ctx->server_response_hdrp); } if (http_ctx->client_response_bufp) { TSHandleMLocRelease(http_ctx->client_response_bufp, TS_NULL_MLOC, http_ctx->client_response_hdrp); } if (http_ctx->cached_response_bufp) { TSHandleMLocRelease(http_ctx->cached_response_bufp, TS_NULL_MLOC, http_ctx->cached_response_hdrp); } luaL_unref(main_ctx->lua, LUA_REGISTRYINDEX, http_ctx->ref); TSfree(http_ctx); }
static void handle_response(TSHttpTxn txnp) { TSMBuffer bufp; TSMLoc hdr_loc, newfield_loc; char *errormsg_body = "All requests from this IP address are redirected.\n"; char *tmp_body; if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("[%s] Couldn't retrieve client response header", PLUGIN_NAME); goto done; } TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_MOVED_PERMANENTLY); TSHttpHdrReasonSet(bufp, hdr_loc, TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY), strlen(TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY))); TSMimeHdrFieldCreate(bufp, hdr_loc, &newfield_loc); /* Probably should check for errors ... */ TSMimeHdrFieldNameSet(bufp, hdr_loc, newfield_loc, TS_MIME_FIELD_LOCATION, TS_MIME_LEN_LOCATION); TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, newfield_loc, -1, uri_redirect, strlen(uri_redirect)); TSMimeHdrFieldAppend(bufp, hdr_loc, newfield_loc); /* * Note that we can't directly use errormsg_body, as TSHttpTxnErrorBodySet() * will try to free the passed buffer with TSfree(). */ tmp_body = TSstrdup(errormsg_body); TSHttpTxnErrorBodySet(txnp, tmp_body, strlen(tmp_body), NULL); TSHandleMLocRelease(bufp, hdr_loc, newfield_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
//响应添加报文头 TSReturnCode StaSerRespMimeHdrFieldAppend(TSHttpTxn txnp,char *name,int name_length,char *value,int value_len) { TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc field_loc; if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { return TS_ERROR; } field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, name, name_length); if(field_loc != TS_NULL_MLOC){ TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc); TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len); TSHandleMLocRelease(bufp, hdr_loc, field_loc); }else{ if (TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc) != TS_SUCCESS) { return TS_ERROR; } TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc); TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc); TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, name, name_length); TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len); TSHandleMLocRelease(bufp, hdr_loc, field_loc); } TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); return TS_SUCCESS; }
static int server_response_ok(TSHttpTxn txnp) { /* Is the response the server sent OK for transformation. This is * a good place to check the server's response to see if it is * transformable. In this example, we will transform only "200 OK" * responses. */ TSMBuffer bufp; TSMLoc hdr_loc; TSHttpStatus resp_status; if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("Unable to get handle to Server Response"); return 0; } resp_status = TSHttpHdrStatusGet(bufp, hdr_loc); if (TS_HTTP_STATUS_OK == resp_status) { if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) != TS_SUCCESS) { TSError("Unable to release handle to server request"); } return 1; } else { if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) != TS_SUCCESS) { TSError("Unable to release handle to server request"); } return 0; } }
void ts_http_fetcher_extract(http_fetcher *fch) { TSMLoc cl_loc, te_loc; const char *val; int val_len; int i, n; fch->status_code = TSHttpHdrStatusGet(fch->hdr_bufp, fch->hdr_loc); cl_loc = TSMimeHdrFieldFind(fch->hdr_bufp, fch->hdr_loc, TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH); if (cl_loc) fch->resp_cl = TSMimeHdrFieldValueInt64Get(fch->hdr_bufp, fch->hdr_loc, cl_loc, -1); else fch->resp_cl = -1; te_loc = TSMimeHdrFieldFind(fch->hdr_bufp, fch->hdr_loc, TS_MIME_FIELD_TRANSFER_ENCODING, TS_MIME_LEN_TRANSFER_ENCODING); if (te_loc) { n = TSMimeHdrFieldValuesCount(fch->hdr_bufp, fch->hdr_loc, te_loc); for (i = 0; i < n; i++) { val = TSMimeHdrFieldValueStringGet(fch->hdr_bufp, fch->hdr_loc, te_loc, i, &val_len); if ((val_len == TS_HTTP_LEN_CHUNKED) && (strncasecmp(val, TS_HTTP_VALUE_CHUNKED, val_len) == 0)) { fch->chunked = 1; break; } } } if (cl_loc) TSHandleMLocRelease(fch->hdr_bufp, fch->hdr_loc, cl_loc); if (te_loc) { if (fch->flags & TS_FLAG_FETCH_FORCE_DECHUNK) TSMimeHdrFieldDestroy(fch->hdr_bufp, fch->hdr_loc, te_loc); TSHandleMLocRelease(fch->hdr_bufp, fch->hdr_loc, te_loc); } if (fch->chunked) { if (fch->flags & TS_FLAG_FETCH_FORCE_DECHUNK) { chunked_info_init(&fch->cinfo, 1); } else { chunked_info_init(&fch->cinfo, 0); } } else if (fch->resp_cl >= 0) { fch->resp_already = 0; } fch->flow_buffer = TSIOBufferCreate(); fch->flow_reader = TSIOBufferReaderAlloc(fch->flow_buffer); fch->body_buffer = TSIOBufferCreate(); fch->body_reader = TSIOBufferReaderAlloc(fch->body_buffer); }
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; }
static RequestInfo * create_request_info(TSHttpTxn txn) { RequestInfo *req_info; char *url; int url_len; TSMBuffer buf; TSMLoc loc; req_info = (RequestInfo *)TSmalloc(sizeof(RequestInfo)); url = TSHttpTxnEffectiveUrlStringGet(txn, &url_len); req_info->effective_url = TSstrndup(url, url_len); TSfree(url); TSHttpTxnClientReqGet(txn, &buf, &loc); req_info->buf = TSMBufferCreate(); TSHttpHdrClone(req_info->buf, buf, loc, &(req_info->http_hdr_loc)); TSHandleMLocRelease(buf, TS_NULL_MLOC, loc); req_info->client_addr = TSmalloc(sizeof(struct sockaddr)); memmove((void *)req_info->client_addr, (void *)TSHttpTxnClientAddrGet(txn), sizeof(struct sockaddr)); return req_info; }
static int transformable(TSHttpTxn txnp) { /* * We are only interested in transforming "200 OK" responses. */ TSMBuffer bufp; TSMLoc hdr_loc; TSHttpStatus resp_status; int retv; TSDebug("null-transform", "Entering transformable()"); TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc); resp_status = TSHttpHdrStatusGet(bufp, hdr_loc); retv = (resp_status == TS_HTTP_STATUS_OK); if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) == TS_ERROR) { TSError("[null-transform] Error releasing MLOC while checking " "header status\n"); } TSDebug("null-transform", "Exiting transformable with return %d", retv); return retv; }
static int ts_lua_client_request_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; http_ctx = ts_lua_get_http_ctx(L); /* we skip the first argument that is the table */ key = luaL_checklstring(L, 2, &key_len); if (key && key_len) { field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len); if (field_loc) { val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len); lua_pushlstring(L, val, val_len); TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); } else { lua_pushnil(L); } } else { lua_pushnil(L); } return 1; }
static int ts_lua_client_request_get_pristine_url(lua_State *L) { char *url; int url_len; TSMBuffer bufp; TSMLoc url_loc; ts_lua_http_ctx *http_ctx; http_ctx = ts_lua_get_http_ctx(L); if (TSHttpTxnPristineUrlGet(http_ctx->txnp, &bufp, &url_loc) != TS_SUCCESS) return 0; url = TSUrlStringGet(bufp, url_loc, &url_len); if (url) { lua_pushlstring(L, url, url_len); TSfree(url); } else { lua_pushnil(L); } TSHandleMLocRelease(bufp, NULL, url_loc); 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_client_response_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; http_ctx = ts_lua_get_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->client_response_hdrp) { if (TSHttpTxnClientRespGet(http_ctx->txnp, &http_ctx->client_response_bufp, &http_ctx->client_response_hdrp) != TS_SUCCESS) { return 0; } } field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, key, key_len); if (remove) { if (field_loc) { TSMimeHdrFieldDestroy(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc); } } else if (field_loc) { TSMimeHdrFieldValueStringSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, 0, val, val_len); } else if (TSMimeHdrFieldCreateNamed(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, key, key_len, &field_loc) != TS_SUCCESS) { TSError("[%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__); return 0; } else { TSMimeHdrFieldValueStringSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, -1, val, val_len); TSMimeHdrFieldAppend(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc); } if (field_loc) TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc); 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; }
/* 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; }
static void free_request_info(RequestInfo *req_info) { TSfree(req_info->effective_url); TSHandleMLocRelease(req_info->buf, TS_NULL_MLOC, req_info->http_hdr_loc); TSMBufferDestroy(req_info->buf); TSfree(req_info); }
static void free_response_info(ResponseInfo *resp_info) { TSHandleMLocRelease(resp_info->buf, TS_NULL_MLOC, resp_info->http_hdr_loc); TSMBufferDestroy(resp_info->buf); TSHttpParserDestroy(resp_info->parser); TSfree(resp_info); }
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 regex_match(TSCont contp, TSHttpTxn txnp) { static char *url; TSMBuffer bufp; TSMLoc hdr_loc, url_loc; int url_length; regex_t *re; int ovector[30], res; if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("couldn't retrieve client response header\n"); goto done; } if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) { TSError("couldn't retrieve request url\n"); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); goto done; } url = TSUrlStringGet(bufp, url_loc, &url_length); if (url == NULL) { TSError("couldn't get url"); goto done; } for (re = reg; re; re = re->next) { res = pcre_exec(re->re, NULL, url, strlen(url), 0, 0, ovector, 30); if (res <= 0) { goto done; } break; } TSContDataSet(contp, re->hdr); TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp); done: TSfree(url); TSHandleMLocRelease(bufp, hdr_loc, url_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
bool is_post_request(TSHttpTxn txnp) { TSMLoc req_loc; TSMBuffer req_bufp; if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) == TS_ERROR) { TSError("Error while retrieving client request header\n"); return false; } int method_len = 0; const char *method = TSHttpHdrMethodGet(req_bufp, req_loc, &method_len); if (method_len != (int)strlen(TS_HTTP_METHOD_POST) || strncasecmp(method, TS_HTTP_METHOD_POST, method_len) != 0) { TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc); return false; } TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc); return true; }
static time_t get_date_from_cached_hdr(TSHttpTxn txn) { TSMBuffer buf; TSMLoc hdr_loc, date_loc; time_t date = 0; if (TSHttpTxnCachedRespGet(txn, &buf, &hdr_loc) == TS_SUCCESS) { date_loc = TSMimeHdrFieldFind(buf, hdr_loc, TS_MIME_FIELD_DATE, TS_MIME_LEN_DATE); if (date_loc != TS_NULL_MLOC) { date = TSMimeHdrFieldValueDateGet(buf, hdr_loc, date_loc); TSHandleMLocRelease(buf, hdr_loc, date_loc); } TSHandleMLocRelease(buf, TS_NULL_MLOC, hdr_loc); } return date; }
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; }
//响应删除报文头 TSReturnCode StaSerRespMimeHdrFieldDestroy(TSHttpTxn txnp,char *name,int length) { TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc field_loc; TSReturnCode ret = TS_ERROR; if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { return TS_ERROR; } field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, name, length); if(field_loc != TS_NULL_MLOC) { ret = TSMimeHdrFieldDestroy(bufp,hdr_loc,field_loc); TSHandleMLocRelease(bufp, hdr_loc, field_loc); } TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); return ret; }
static void handle_response(TSHttpTxn txnp, TSCont contp ATS_UNUSED) { TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc url_loc; char *url_str; char *buf; int url_length; if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("[%s] Couldn't retrieve client response header", PLUGIN_NAME); goto done; } TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_FORBIDDEN); TSHttpHdrReasonSet(bufp, hdr_loc, TSHttpHdrReasonLookup(TS_HTTP_STATUS_FORBIDDEN), strlen(TSHttpHdrReasonLookup(TS_HTTP_STATUS_FORBIDDEN))); if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("[%s] Couldn't retrieve client request header", PLUGIN_NAME); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); goto done; } if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) { TSError("[%s] Couldn't retrieve request url", PLUGIN_NAME); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); goto done; } buf = (char *)TSmalloc(4096); url_str = TSUrlStringGet(bufp, url_loc, &url_length); sprintf(buf, "You are forbidden from accessing \"%s\"\n", url_str); TSfree(url_str); TSHandleMLocRelease(bufp, hdr_loc, url_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); TSHttpTxnErrorBodySet(txnp, buf, strlen(buf), NULL); done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
bool should_push(TSHttpTxn txnp) { TSMBuffer mbuf; TSMLoc hdr, url; if (TSHttpTxnClientReqGet(txnp, &mbuf, &hdr) != TS_SUCCESS) { return false; } if (TSHttpHdrUrlGet(mbuf, hdr, &url) != TS_SUCCESS) { return false; } int len; TSUrlHttpQueryGet(mbuf, url, &len); TSHandleMLocRelease(mbuf, hdr, url); TSHandleMLocRelease(mbuf, TS_NULL_MLOC, hdr); if (len > 0) { return true; } else { return false; } }
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; }
//获取源服务器响应的状态 TSHttpStatus StaServerRespStatusGet(TSHttpTxn txnp) { TSMBuffer resp_bufp; TSMLoc resp_loc; TSHttpStatus resp_status = TS_HTTP_STATUS_NONE; if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) { return TS_HTTP_STATUS_NONE; } resp_status = TSHttpHdrStatusGet(resp_bufp, resp_loc); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); return resp_status; }
//设置源服务器响应的状态 TSReturnCode StaServerRespStatusSet(TSHttpTxn txnp,TSHttpStatus status) { TSMBuffer resp_bufp; TSMLoc resp_loc; TSReturnCode ret; if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) { return TS_ERROR; } ret = TSHttpHdrStatusSet(resp_bufp, resp_loc, status); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); return ret; }
static int ts_lua_server_request_get_url_host(lua_State *L) { const char *host; int len = 0; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); TS_LUA_CHECK_SERVER_REQUEST_URL(http_ctx); host = TSUrlHostGet(http_ctx->server_request_bufp, http_ctx->server_request_url, &len); if (len == 0) { char *key = "Host"; char *l_key = "host"; int key_len = 4; TSMLoc field_loc; field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len); if (field_loc) { host = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &len); TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); } else { field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, l_key, key_len); if (field_loc) { host = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &len); TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc); } } } lua_pushlstring(L, host, len); return 1; }
static void replace_header(TSHttpTxn txnp) { TSMBuffer resp_bufp; TSMLoc resp_loc; TSMLoc field_loc; if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) { TSError("couldn't retrieve server response header.\n"); goto done; } field_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES); if (field_loc == TS_NULL_MLOC) { /* field was not found */ /* create a new field in the header */ TSMimeHdrFieldCreate(resp_bufp, resp_loc, &field_loc); /* Probably should check for errors. */ /* set its name */ TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES); /* set its value */ TSMimeHdrFieldValueAppend(resp_bufp, resp_loc, field_loc, -1, "none", 4); /* insert it into the header */ TSMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc); TSHandleMLocRelease(resp_bufp, resp_loc, field_loc); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); } else { /* clear the field */ TSMimeHdrFieldValuesClear(resp_bufp, resp_loc, field_loc); /* set the value to "none" */ TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, "none", 4); TSHandleMLocRelease(resp_bufp, resp_loc, field_loc); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); } done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }