Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <unistd.h>
- #include <ts/ts.h>
- #include <stdint.h>
- #include <fstream>
- #include <stdlib.h>
- #include <assert.h>
- #include <cstring>
- #include <libconfig.h++>
- #include "ZookeeperRecord.h"
- #include "PluginCoreData.h"
- #include "EspressoException.hpp"
- #include "EspressoPlugin.h"
- #include "SingleResponseHandler.h"
- #include "ZookeeperRecord.h"
- #include "ZooKeeperClient.h"
- #include "Logger.h"
- #include <execinfo.h>
- static const int LOCAL_IP_ADDRESS = 0x0100007f;
- static const int LOCAL_PORT = 8080;
- static const int FETCH_EVENT_SUCCESS = 10000;
- static const int FETCH_EVENT_FAILURE = 10001;
- static const int FETCH_EVENT_TIMEOUT = 10002;
- typedef struct pluginData{
- TSIOBuffer req_buffer;
- TSIOBufferReader req_reader;
- TSIOBuffer resp_buffer;
- TSIOBufferReader resp_reader;
- TSVConn vconn;
- } pluginData;
- static int
- per_transaction_local_thread(TSCont contp, TSEvent event, void *edata)
- {
- switch(event)
- {
- case FETCH_EVENT_SUCCESS: {
- LOG_DEBUG("Fetch event SUCCESS! \n");
- char data1[] = "HTTP/1.1 200 OK\r\nContent-Length:11\r\n\r\nhello world";
- pluginData *data = (pluginData *)TSContDataGet(contp);
- int amountWritten = TSIOBufferWrite(data->resp_buffer, data1,strlen(data1));
- LOG_DEBUG("The data to write is %s and is %d bytes long", data1, amountWritten);
- TSVConnWrite(data->vconn, contp,data->resp_reader, amountWritten );
- }
- break;
- case TS_EVENT_NET_ACCEPT:
- {
- LOG_DEBUG("Event is net_accept");
- pluginData *data = new pluginData;
- data->vconn = (TSVConn) edata;
- data->req_buffer = TSIOBufferCreate();
- data->req_reader = TSIOBufferReaderAlloc(data->req_buffer);
- data->resp_buffer = TSIOBufferCreate();
- data->resp_reader = TSIOBufferReaderAlloc(data->resp_buffer);
- TSContDataSet(contp, data);
- TSVConnRead(data->vconn, contp, data->req_buffer, INT64_MAX);
- }
- break;
- case TS_EVENT_VCONN_READ_READY:
- {
- LOG_DEBUG("Event is read_ready");
- pluginData *data = (pluginData *)TSContDataGet(contp);
- char request[] = "GET / HTTP/1.0\r\nHost:localhost:8080\r\n\r\n";
- TSFetchEvent eventIds;
- eventIds.success_event_id = FETCH_EVENT_SUCCESS;
- eventIds.failure_event_id = FETCH_EVENT_FAILURE;
- eventIds.timeout_event_id = FETCH_EVENT_TIMEOUT;
- TSFetchUrl((const char *)request,strlen(request), LOCAL_IP_ADDRESS, LOCAL_PORT , contp, AFTER_BODY, eventIds);
- }
- break;
- case TS_EVENT_VCONN_WRITE_COMPLETE:
- {
- LOG_DEBUG("Event is write_complete");
- pluginData *data = (pluginData *)TSContDataGet(contp);
- if (data->req_buffer) {
- TSIOBufferDestroy(data->req_buffer);
- data->req_buffer = NULL;
- }
- if (data->resp_buffer) {
- TSIOBufferDestroy(data->resp_buffer);
- data->req_buffer = NULL;
- }
- TSVConnShutdown(data->vconn,1,1);
- TSVConnClose(data->vconn);
- TSContDestroy(contp);
- delete data;
- }
- break;
- default:
- {
- LOG_DEBUG("unhandled event");
- }
- }
- }
- /**
- * The plugin continuation which handles the handling of the hook
- * @param contp
- * The Espresso Plugin continuation
- * @param event
- * The event is associated with the continuation
- * @param edata
- * The data associated with continuation
- */
- static int
- espresso_plugin_boot(TSCont contp, TSEvent event, void *edata) {
- TSDebug("espresso", "Espresso plugin started processing the request\n");
- TSVConn vconn;
- TSHttpTxn txnp;
- switch (event) {
- /** The hook for read request */
- case TS_EVENT_HTTP_READ_REQUEST_HDR: {
- TSDebug("espresso", "Event is TS_HTTP_READ_REQUEST_HDR_HOOK");
- // Extract the transaction from the edata
- txnp = (TSHttpTxn) edata;
- /**
- * Check if it's an internal request - It it's internal request
- * skip the from processing it. Otherwise we end up on infinite recursion.
- */
- if ( TSHttpIsInternalRequest(txnp) == TS_SUCCESS) {
- TSDebug("espresso", "Internal request, skipping any further processing \n");
- //resume
- TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
- return 0;
- }
- //Important Note, this always has to spawn a new continuation as it's shared by multiple requests, *Global continuation*
- TSCont localCont = TSContCreate(per_transaction_local_thread, TSMutexCreate());
- TSHttpTxnServerIntercept (localCont, txnp);
- TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
- LOG_DEBUG("Resuming the transaction");
- }
- return 0;
- }
- }
- /**
- * Check the Traffic Server version check.
- */
- int
- check_ts_version() {
- const char *ts_version = TSTrafficServerVersionGet();
- int result = 0;
- if (ts_version) {
- int major_ts_version = 0;
- int minor_ts_version = 0;
- int patch_ts_version = 0;
- if (sscanf(ts_version, "%d.%d.%d", &major_ts_version, &minor_ts_version, &patch_ts_version) != 3) {
- return 0;
- }
- /** Need at least TS 2.0 */
- if (major_ts_version >= 2) {
- result = 1;
- }
- }
- return result;
- }
- /**
- * The plugin intialization module
- *
- */
- void
- TSPluginInit(int argc, const char *argv[]) {
- TSPluginRegistrationInfo info;
- info.plugin_name = (char *)"espresso";
- //These are special debug messages, the first parameter on TSDebug should be specified in the config file
- //proxy.config.diags.debug.enabled should be set to 1 to print debug messages
- TSDebug("espresso", "\n plugin init");
- if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
- TSError("[espresso] Plugin registration failed.\n");
- }
- if (!check_ts_version()) {
- TSError("[espresso] Plugin requires Traffic Server 3.0 " "or later\n");
- }
- TSCont espressoPlugin = TSContCreate(espresso_plugin_boot, TSMutexCreate());
- TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, espressoPlugin);
- TSDebug("espresso", "\n Added hook on TS_HTTP_READ_REQUEST_HDR");
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement