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_server_response_get_headers(lua_State * L) { const char *name; const char *value; int name_len; int value_len; TSMLoc field_loc; TSMLoc next_field_loc; ts_lua_http_ctx *http_ctx; http_ctx = ts_lua_get_http_ctx(L); TS_LUA_CHECK_SERVER_RESPONSE_HDR(http_ctx); lua_newtable(L); field_loc = TSMimeHdrFieldGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, 0); while (field_loc) { name = TSMimeHdrFieldNameGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc, &name_len); if (name && name_len) { value = TSMimeHdrFieldValueStringGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc, -1, &value_len); lua_pushlstring(L, name, name_len); lua_pushlstring(L, value, value_len); lua_rawset(L, -3); } next_field_loc = TSMimeHdrFieldNext(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc); TSHandleMLocRelease(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc); field_loc = next_field_loc; } return 1; }
static void add_header(TSHttpTxn txnp, TSCont contp) { TSMBuffer req_bufp; TSMLoc req_loc; TSMLoc field_loc; TSMLoc next_field_loc; TSMLoc new_field_loc; int retval; if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) != TS_SUCCESS) { TSError("[add_header] Error while retrieving client request header\n"); goto done; } field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0); if (field_loc == TS_NULL_MLOC) { TSError("[add_header] Error while getting field"); goto error; } /* Loop on our header containing fields to add */ while (field_loc) { /* First create a new field in the client request header */ if (TSMimeHdrFieldCreate(req_bufp, req_loc, &new_field_loc) != TS_SUCCESS) { TSError("[add_header] Error while creating new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* Then copy our new field at this new location */ retval = TSMimeHdrFieldCopy(req_bufp, req_loc, new_field_loc, hdr_bufp, hdr_loc, field_loc); if (retval == TS_ERROR) { TSError("[add_header] Error while copying new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* Add this field to the Http client request header */ retval = TSMimeHdrFieldAppend(req_bufp, req_loc, new_field_loc); if (retval != TS_SUCCESS) { TSError("[add_header] Error while appending new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* We can now release this handle */ TSHandleMLocRelease(req_bufp, req_loc, new_field_loc); next_field_loc = TSMimeHdrFieldNext(hdr_bufp, hdr_loc, field_loc); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); field_loc = next_field_loc; } error: TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc); done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
void TSPluginInit(int argc, const char *argv[]) { TSMLoc chk_field_loc; TSPluginRegistrationInfo info; info.plugin_name = "response-header-1"; info.vendor_name = "MyCompany"; info.support_email = "*****@*****.**"; if (TSPluginRegister(&info) != TS_SUCCESS) { TSError("Plugin registration failed.\n"); } init_buffer_status = 0; if (argc > 1) { TSError("usage: %s \n", argv[0]); TSError("warning: too many args %d\n", argc); TSError("warning: ignoring unused arguments beginning with %s\n", argv[1]); } /* * The following code sets up an "init buffer" containing an extension header * and its initial value. This will be the same for all requests, so we try * to be efficient and do all of the work here rather than on a per-transaction * basis. */ hdr_bufp = TSMBufferCreate(); TSMimeHdrCreate(hdr_bufp, &hdr_loc); mimehdr1_name = TSstrdup("x-num-served-from-cache"); mimehdr1_value = TSstrdup("0"); /* Create name here and set DateTime value when o.s. * response 200 is received */ mimehdr2_name = TSstrdup("x-date-200-recvd"); TSDebug("resphdr", "Inserting header %s with value %s into init buffer", mimehdr1_name, mimehdr1_value); TSMimeHdrFieldCreate(hdr_bufp, hdr_loc, &field_loc); /* Probably should check for errors */ TSMimeHdrFieldAppend(hdr_bufp, hdr_loc, field_loc); TSMimeHdrFieldNameSet(hdr_bufp, hdr_loc, field_loc, mimehdr1_name, strlen(mimehdr1_name)); TSMimeHdrFieldValueStringInsert(hdr_bufp, hdr_loc, field_loc, -1, mimehdr1_value, strlen(mimehdr1_value)); TSDebug("resphdr", "init buffer hdr, field and value locs are %p, %p and %p", hdr_loc, field_loc, value_loc); init_buffer_status = 1; TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, TSContCreate(modify_response_header_plugin, NULL)); /* * The following code demonstrates how to extract the field_loc from the header. * In this plugin, the init buffer and thus field_loc never changes. Code * similar to this may be used to extract header fields from any buffer. */ if (TS_NULL_MLOC == (chk_field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0))) { TSError("couldn't retrieve header field from init buffer"); TSError("marking init buffer as corrupt; no more plugin processing"); init_buffer_status = 0; /* bail out here and reenable transaction */ } else { if (field_loc != chk_field_loc) TSError("retrieved buffer field loc is %p when it should be %p", chk_field_loc, field_loc); } }