| /** | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| /** | |
| * @file TransformationPlugin.h | |
| */ | |
| // The C++ Plugin API is deprecated in ATS 10, and will be removed in ATS 11. | |
| #pragma once | |
| #include <string_view> | |
| #include "tscpp/api/Transaction.h" | |
| #include "tscpp/api/TransactionPlugin.h" | |
| namespace atscppapi | |
| { | |
| struct TransformationPluginState; | |
| class Continuation; | |
| /** | |
| * @brief The interface used when you wish to transform Request or Response body content. | |
| * | |
| * Transformations are deceptively simple, transformations are chained so the output | |
| * of one TransformationPlugin becomes the input of another TransformationPlugin. As | |
| * data arrives it will fire a consume() and when all the data has been sent | |
| * you will receive a handleInputComplete(). Data can be sent to the next TransformationPlugin | |
| * in the chain by calling produce() and when the transformation has no data left to send | |
| * it will fire a setOutputCompete(). | |
| * | |
| * Since a TransformationPlugin is a type of TransactionPlugin you can call registerHook() and | |
| * establish any hook for a Transaction also; however, remember that you must implement | |
| * the appropriate callback for any hooks you register. | |
| * | |
| * A simple example of how to use the TransformationPlugin interface follows, this is an example | |
| * of a Response transformation, the available options are REQUEST_TRANSFORMATION and RESPONSE_TRANSFORMATION | |
| * which are defined in Type. | |
| * | |
| * This example is a Null Transformation, meaning it will just spit out the content it receives without | |
| * actually doing any work on it. | |
| * | |
| * \code | |
| * class NullTransformationPlugin : public TransformationPlugin { | |
| * public: | |
| * NullTransformationPlugin(Transaction &transaction) | |
| * : TransformationPlugin(transaction, RESPONSE_TRANSFORMATION) { | |
| * registerHook(HOOK_SEND_RESPONSE_HEADERS); | |
| * } | |
| * void handleSendResponseHeaders(Transaction &transaction) { | |
| * transaction.getClientResponse().getHeaders().set("X-Content-Transformed", "1"); | |
| * transaction.resume(); | |
| * } | |
| * void consume(std::string_view data) { | |
| * produce(data); | |
| * } | |
| * void handleInputComplete() { | |
| * setOutputComplete(); | |
| * } | |
| * }; | |
| * \endcode | |
| * | |
| * @see Plugin | |
| * @see TransactionPlugin | |
| * @see Type | |
| * @see HookType | |
| */ | |
| class TransformationPlugin : public TransactionPlugin | |
| { | |
| public: | |
| /** | |
| * The available types of Transformations. | |
| */ | |
| enum Type { | |
| REQUEST_TRANSFORMATION = 0, /**< Transform the Request body content */ | |
| RESPONSE_TRANSFORMATION, /**< Transform the Response body content */ | |
| CLIENT_RESPONSE_SINK_TRANSFORMATION, /**< Sink transformation, meaning you get a separate stream of the Response | |
| body content that does not get hooked up to a downstream input */ | |
| CLIENT_REQUEST_SINK_TRANSFORMATION, /**< Sink transformation, meaning you get a separate stream of the Request | |
| body content that does not get hooked up to a downstream input */ | |
| }; | |
| /** | |
| * A method that you must implement when writing a TransformationPlugin, this method will be | |
| * fired whenever an upstream TransformationPlugin has produced output. | |
| */ | |
| virtual void consume(std::string_view data) = 0; | |
| /** | |
| * Call this method if you wish to pause the transformation. | |
| */ | |
| void pause(); | |
| /** | |
| * Returns true if the transformation is paused, false otherwise. | |
| */ | |
| bool isPaused() const; | |
| /** | |
| * Returns a reference to the Continuation to schedule to resume (unpause) the transformation. It will be resumed when this | |
| * continuation is executed. Must not call this unless the transformation is paused. | |
| */ | |
| Continuation &resumeCont(); | |
| /** | |
| * A method that you must implement when writing a TransformationPlugin, this method | |
| * will be fired whenever the upstream TransformationPlugin has completed writing data. | |
| */ | |
| virtual void handleInputComplete() = 0; | |
| ~TransformationPlugin() override; /**< Destructor for a TransformationPlugin */ | |
| protected: | |
| /** | |
| * This method is how a TransformationPlugin will produce output for the downstream | |
| * transformation plugin. | |
| */ | |
| size_t produce(std::string_view); | |
| /** | |
| * This is the method that you must call when you're done producing output for | |
| * the downstream TransformationPlugin. | |
| */ | |
| size_t setOutputComplete(); | |
| /** a TransformationPlugin must implement this interface, it cannot be constructed directly */ | |
| TransformationPlugin(Transaction &transaction, Type type); | |
| private: | |
| std::unique_ptr<TransformationPluginState> state_; /** Internal state for a TransformationPlugin */ | |
| size_t doProduce(std::string_view); | |
| static int resumeCallback(TSCont cont, TSEvent event, void *edata); /** Resume callback*/ | |
| }; | |
| } // namespace atscppapi |