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); }
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_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 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); }
static int ts_lua_http_set_resp(lua_State *L) { int n, status; const char *body; size_t body_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); n = lua_gettop(L); status = luaL_checkinteger(L, 1); TSHttpTxnSetHttpRetStatus(http_ctx->txnp, status); if (n == 2) { body = luaL_checklstring(L, 2, &body_len); TSHttpTxnErrorBodySet(http_ctx->txnp, TSstrdup(body), body_len, NULL); // Defaults to text/html } return 0; }
/* Before we can send the response, we want to modify it to a "200 OK" again, and produce some reasonable body output. */ static int on_send_response_header(TSHttpTxn txnp, TSCont contp, PurgeInstance *purge) { TSMBuffer bufp; TSMLoc hdr_loc; TSDebug(PLUGIN_NAME, "Fixing up the response on the successful PURGE"); if (TS_SUCCESS == TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc)) { char response[1024]; int len = snprintf(response, sizeof(response), "PURGED %s\r\n\r\n", purge->id); TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_OK); TSHttpHdrReasonSet(bufp, hdr_loc, "OK", 2); TSHttpTxnErrorBodySet(txnp, TSstrdup(response), len >= sizeof(response) ? sizeof(response) - 1 : len, NULL); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); } else { TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); } return TS_SUCCESS; }
/** * Handler function to generate an error response */ static void error_response(TSHttpTxn txnp, tsib_txn_ctx *txndata) { const char *reason; TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc field_loc; hdr_list *hdrs; TSReturnCode rv; /* make caller responsible for sanity checking */ assert((txndata != NULL) && (txndata->tx != NULL)); reason = TSHttpHdrReasonLookup(txndata->status); if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: couldn't retrieve client response header."); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return; } rv = TSHttpHdrStatusSet(bufp, hdr_loc, txndata->status); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSHttpHdrStatusSet"); } if (reason == NULL) { reason = "Other"; } rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason)); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSHttpHdrReasonSet"); } while (hdrs = txndata->err_hdrs, hdrs != 0) { txndata->err_hdrs = hdrs->next; rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSMimeHdrFieldCreate"); continue; } rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, hdrs->hdr, strlen(hdrs->hdr)); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSMimeHdrFieldNameSet"); goto errordoc_free1; } rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, hdrs->value, strlen(hdrs->value)); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSMimeHdrFieldValueStringInsert"); goto errordoc_free1; } rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSMimeHdrFieldAppend"); goto errordoc_free1; } errordoc_free1: rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSHandleMLocRelease 1"); continue; } } if (txndata->err_body) { /* this will free the body, so copy it first! */ TSHttpTxnErrorBodySet(txnp, txndata->err_body, txndata->err_body_len, NULL); } rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); if (rv != TS_SUCCESS) { ib_log_error_tx(txndata->tx, "ErrorDoc: TSHandleMLocRelease 2"); } ib_log_debug_tx(txndata->tx, "Sent error page %d \"%s\".", txndata->status, reason); }
/** * Handler function to generate an internal error response * when ironbee is unavailable to fill the fields or log errors. * * This may come from a TXN_START event, in which case we're * returning an HTTP/0.9 response and most of this is superfluous. */ static void internal_error_response(TSHttpTxn txnp) { TSReturnCode rv; const char *reason = "Server Unavailable"; TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc field_loc; char *body; char clen[8]; int i; const struct { const char *name; const char *val; } headers[2] = { { "Content-Type", "text/plain" }, { "Content-Length", clen } }; if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: couldn't retrieve client response header."); return; } rv = TSHttpHdrStatusSet(bufp, hdr_loc, 503); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSHttpHdrStatusSet"); } rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason)); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSHttpHdrReasonSet"); } /* this will free the body, so copy it first! */ body = TSstrdup("Server unavailable or disabled.\n"); snprintf(clen, sizeof(clen), "%zd", strlen(body)); for (i = 0; i < 2; ++i) { rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSMimeHdrFieldCreate"); continue; } rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, headers[i].name, strlen(headers[i].name)); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSMimeHdrFieldNameSet"); goto freehdr; } rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, headers[i].val, strlen(headers[i].val)); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSMimeHdrFieldValueStringInsert"); goto freehdr; } rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSMimeHdrFieldAppend"); goto freehdr; } freehdr: rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 3"); continue; } } TSHttpTxnErrorBodySet(txnp, body, strlen(body), NULL); rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); if (rv != TS_SUCCESS) { TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 4"); } }