static int server_push_plugin(TSCont contp, TSEvent event, void *edata) { TSHttpSsn ssnp; TSHttpTxn txnp; switch (event) { case TS_EVENT_HTTP_SSN_START: ssnp = (TSHttpSsn)edata; TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_START_HOOK, contp); TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE); break; case TS_EVENT_HTTP_TXN_START: txnp = (TSHttpTxn)edata; TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; case TS_EVENT_HTTP_READ_REQUEST_HDR: txnp = (TSHttpTxn)edata; if (should_push(txnp)) { TSHttpTxnServerPush(txnp, url, strlen(url)); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; default: break; } return 0; }
static int transform_plugin(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: if (request_ok(txnp)) { TSHttpTxnHookAdd(txnp, TS_HTTP_READ_CACHE_HDR_HOOK, contp); TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, contp); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; case TS_EVENT_HTTP_READ_CACHE_HDR: if (cache_response_ok(txnp)) { TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, transform_create(txnp)); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: if (server_response_ok(txnp)) { TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, transform_create(txnp)); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; default: break; } return 0; }
static void ironbee_plugin_send_response_hdr(TSCont contp, TSHttpTxn txnp) { assert(contp != NULL); assert(txnp != NULL); tsib_txn_ctx *txndata; txndata = TSContDataGet(contp); if (txndata == NULL) { /* Ironbee is unavailable to help with our response. */ /* This contp is not ours, so we leave it. */ internal_error_response(txnp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return; } /* If ironbee has sent us into an error response then * we came here in our error path, with nonzero status. */ if (txndata->status != 0) { error_response(txnp, txndata); } /* Feed ironbee the headers if not done already. */ if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_STARTED)) { if (process_hdr(txndata, txnp, &tsib_direction_client_resp) != HDR_OK) { /* I think this is a shouldn't happen event, and that * if it does we have an ironbee bug or misconfiguration. * Log an error to catch if it happens in practice. */ ib_log_error_tx(txndata->tx, "process_hdr returned error in send_response_hdr event"); } } /* If there is an ironbee-generated response body, notify ironbee. * * NOTE: I do not see anywhere else to put this as the error body is * just a buffer and not delivered via normal IO channels, so * the error body will never get caught by an event. */ if ((txndata->status != 0) && (txndata->err_body != NULL)) { const char *data = txndata->err_body; size_t data_length = txndata->err_body_len; ib_log_debug_tx(txndata->tx, "error_response: calling ib_state_notify_response_body_data() %s:%d", __FILE__, __LINE__); ib_state_notify_response_body_data(txndata->tx->ib, txndata->tx, data, data_length); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
static void * reenable_txn(void *data) { TSHttpTxn txnp = (TSHttpTxn)data; TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return NULL; }
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; }
static int ssn_handler(TSCont contp, TSEvent event, void *edata) { TSHttpSsn ssnp; TSHttpTxn txnp; switch (event) { case TS_EVENT_HTTP_SSN_START: ssnp = (TSHttpSsn)edata; handle_session(ssnp, contp); TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE); return 0; case TS_EVENT_HTTP_TXN_START: txnp = (TSHttpTxn)edata; txn_handler(txnp, contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: TSDebug("tag_session", "In the default case: event = %d", event); break; } return 0; }
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); }
/* handle_hook * Fires on TS_EVENT_HTTP_READ_REQUEST_HDR events, gets the effectiveUrl * finds the host, gets the generation ID, gen_id, for the host * and runs TSCacheUrlSet to change the cache key for the read */ static int handle_hook(TSCont *contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; char *url = NULL, *host = NULL; int url_length; int gen_id; int ok = 1; switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: TSDebug(PLUGIN_NAME, "handling TS_EVENT_HTTP_READ_REQUEST_HDR"); if (ok) { url = TSHttpTxnEffectiveUrlStringGet(txnp, &url_length); if (!url) { TSError("[%s] could not retrieve request url", PLUGIN_NAME); ok = 0; } } if (ok) { get_genid_host(&host, url); if (!host) { TSError("[%s] could not retrieve request host", PLUGIN_NAME); ok = 0; } } if (ok) { TSDebug(PLUGIN_NAME, "From url (%s) discovered host (%s)", url, host); if ((gen_id = get_genid(host)) != 0) { if (TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_CACHE_GENERATION, gen_id) != TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Error, unable to modify cache url"); TSError("[%s] Unable to set cache generation for %s to %d", PLUGIN_NAME, url, gen_id); ok = 0; } } } /* Clean up */ if (url) { TSfree(url); } if (host) { TSfree(host); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; default: TSAssert(!"Unexpected event"); ok = 0; break; } return ok; }
static void handle_dns(TSHttpTxn txnp, TSCont contp) { TSMBuffer bufp; TSMLoc hdr_loc; TSMLoc url_loc; const char *host; int i; int host_length; if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) { TSError("[blacklist-0] Couldn't retrieve client request header"); goto done; } if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) { TSError("[blacklist-0] Couldn't retrieve request url"); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); goto done; } host = TSUrlHostGet(bufp, url_loc, &host_length); if (!host) { TSError("[blacklist-0] Couldn't retrieve request hostname"); TSHandleMLocRelease(bufp, hdr_loc, url_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); goto done; } for (i = 0; i < nsites; i++) { if (strncmp(host, sites[i], host_length) == 0) { printf("blacklisting site: %s\n", sites[i]); TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp); TSHandleMLocRelease(bufp, hdr_loc, url_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); return; } } TSHandleMLocRelease(bufp, hdr_loc, url_loc); TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc); done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
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 void destroy_continuation(TSHttpTxn txnp, TSCont contp) { cdata *cd = NULL; cd = (cdata *)TSContDataGet(contp); if (cd != NULL) { TSfree(cd); } TSContDestroy(contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return; }
static void ironbee_plugin_read_request_hdr(TSCont contp, TSHttpTxn txnp) { assert(contp != NULL); assert(txnp != NULL); tsib_txn_ctx *txndata; /* We got here from the same cont used for ssnstart. * If it's NULL we have a noib_error or just uninitialised IronBee * so we need to kill off the request as an internal error */ txndata = TSContDataGet(contp); if (txndata == NULL) { TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); } else { /* All's well */ TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); } }
static int main_handler(TSCont cont, TSEvent event, void *edata) { TSHttpTxn txn = (TSHttpTxn)edata; int status; invalidate_t *iptr; plugin_state_t *pstate; time_t date = 0, now = 0; char *url = NULL; int url_len = 0; switch (event) { case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: if (TSHttpTxnCacheLookupStatusGet(txn, &status) == TS_SUCCESS) { if (status == TS_CACHE_LOOKUP_HIT_FRESH) { pstate = (plugin_state_t *)TSContDataGet(cont); iptr = pstate->invalidate_list; while (iptr) { if (!date) { date = get_date_from_cached_hdr(txn); now = time(NULL); } if ((difftime(iptr->epoch, date) >= 0) && (difftime(iptr->expiry, now) >= 0)) { if (!url) { url = TSHttpTxnEffectiveUrlStringGet(txn, &url_len); } if (pcre_exec(iptr->regex, iptr->regex_extra, url, url_len, 0, 0, NULL, 0) >= 0) { TSHttpTxnCacheLookupStatusSet(txn, TS_CACHE_LOOKUP_HIT_STALE); iptr = NULL; TSDebug(LOG_PREFIX, "Forced revalidate - %.*s", url_len, url); } } if (iptr) { iptr = iptr->next; } } if (url) { TSfree(url); } } } break; default: break; } TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); 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; }
static void ironbee_plugin_send_request_hdr(TSCont contp, TSHttpTxn txnp) { assert(contp != NULL); assert(txnp != NULL); tsib_txn_ctx *txndata; txndata = TSContDataGet(contp); /* This event is about as late as we can possibly block * body attacks against the server. */ /* If we are not yet blocked, ask IronBee if we should block. */ if (!HTTP_CODE(txndata->status)) { if (!ib_flags_all(txndata->tx->flags, IB_TX_FREQ_FINISHED)) { ib_log_debug_tx( txndata->tx, "data_event: calling ib_state_notify_request_finished()" ); (tsib_direction_client_req.ib_notify_end)(txndata->tx->ib, txndata->tx); } /* We we've transitioned to blocking, * - Add a handler for response header. * - Reenable with an error. * - Return (so we don't double-reenable). */ if (HTTP_CODE(txndata->status)) { TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); return; } } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
static int handle_read_req_hdr(TSCont cont, TSEvent event ATS_UNUSED, void *edata) { TSHttpTxn txn = (TSHttpTxn) edata; config_t *config; void *txnd; config = (config_t *) TSContDataGet(cont); txnd = (void *) get_effective_host(txn); // low bit left 0 because we do not know that remap succeeded yet TSHttpTxnArgSet(txn, config->txn_slot, txnd); TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); TSDebug(DEBUG_TAG, "Read Req Handler Finished"); 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 int modify_response_header_plugin(TSCont contp ATS_UNUSED, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: TSDebug("resphdr", "Called back with TS_EVENT_HTTP_READ_RESPONSE_HDR"); modify_header(txnp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); /* fall through */ default: break; } return 0; }
static int request_buffer_plugin(TSCont contp, TSEvent event, void *edata) { TSDebug(PLUGIN_NAME, "request_buffer_plugin starting, event[%d]", event); TSHttpTxn txnp = (TSHttpTxn)(edata); if (event == TS_EVENT_HTTP_REQUEST_BUFFER_COMPLETE) { int len = 0; char *body = request_body_get(txnp, &len); TSDebug(PLUGIN_NAME, "request_buffer_plugin gets the request body with length[%d]", len); TSfree(body); TSContDestroy(contp); } else { ink_assert(0); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
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; }
static void handle_txn_start(TSCont contp ATS_UNUSED, TSHttpTxn txnp) { TSCont txn_contp; cdata *cd; txn_contp = TSContCreate((TSEventFunc)blacklist_plugin, TSMutexCreate()); /* create the data that'll be associated with the continuation */ cd = (cdata *)TSmalloc(sizeof(cdata)); TSContDataSet(txn_contp, cd); cd->txnp = txnp; TSHttpTxnHookAdd(txnp, TS_HTTP_OS_DNS_HOOK, txn_contp); TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
static int transform_plugin(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: if (transformable(txnp)) { transform_add(txnp); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: break; } 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); }
/*------------------------------------------------------------------------- read_response_handler Handler for events related to hook READ_RESPONSE Input: contp continuation for the current transaction event event received data pointer on eventual data Output : Return Value: -------------------------------------------------------------------------*/ static int read_response_handler(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: if (transformable(txnp)) { TSDebug(DBG_TAG, "Add a transformation"); transform_add(txnp); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: break; } return 0; }
static int main_hook(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; TSDebug(PLUGIN_NAME, "Checking transaction"); switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: if (enable_agent_check(txnp)) { TSDebug(PLUGIN_NAME, "Adding data sink to transaction"); client_add(txnp); } break; default: break; } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
static int global_plugin(TSCont contp ATS_UNUSED, TSEvent event, void *edata) { TSDebug(PLUGIN_NAME, "transform_plugin starting"); TSHttpTxn txnp = (TSHttpTxn)edata; switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: if (is_post_request(txnp)) { TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_REQUEST_BUFFER_ENABLED, 1); TSHttpTxnHookAdd(txnp, TS_HTTP_REQUEST_BUFFER_READ_COMPLETE_HOOK, TSContCreate(request_buffer_plugin, TSMutexCreate())); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: break; } return 0; }
static int handle_hook(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; pr_list *prl; int ok = 1; prl = (pr_list *)TSContDataGet(contp); switch (event) { case TS_EVENT_HTTP_READ_REQUEST_HDR: ok = rewrite_cacheurl(prl, txnp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); break; default: TSAssert(!"Unexpected event"); ok = 0; break; } return ok; }
static int handle_post_remap(TSCont cont, TSEvent event ATS_UNUSED, void *edata) { TSHttpTxn txn = (TSHttpTxn) edata; config_t *config; void *txnd = (void *) 0x01; // low bit 1 because we are post remap and thus success config = (config_t *) TSContDataGet(cont); if (config->post_remap_host) TSHttpTxnArgSet(txn, config->txn_slot, txnd); else { txnd = (void *) ((uintptr_t) txnd | (uintptr_t) TSHttpTxnArgGet(txn, config->txn_slot)); // We need the hostname pre-remap TSHttpTxnArgSet(txn, config->txn_slot, txnd); } TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); TSDebug(DEBUG_TAG, "Post Remap Handler Finished"); return 0; }
static int transform_plugin(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; TSDebug("null-transform", "Entering transform_plugin()"); switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: TSDebug("null-transform", "\tEvent is TS_EVENT_HTTP_READ_RESPONSE_HDR"); if (transformable(txnp)) { transform_add(txnp); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: break; } return 0; }