diff options
| author | Stefan Boberg <[email protected]> | 2023-10-10 13:30:07 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-10 13:30:07 +0200 |
| commit | 7905d0d21af95c6016768d7a8a81dd9204b34d24 (patch) | |
| tree | 076329f5fad1c33503ee611f6399853da2490567 /src/zenhttp/include | |
| parent | cache reference tracking (#455) (diff) | |
| download | zen-7905d0d21af95c6016768d7a8a81dd9204b34d24.tar.xz zen-7905d0d21af95c6016768d7a8a81dd9204b34d24.zip | |
experimental pluggable transport support (#436)
this change adds a `--http=plugin` mode where we support pluggable transports. Currently this defaults to a barebones blocking winsock implementation but there is also support for dynamic loading of transport plugins, which will be further developed in the near future.
Diffstat (limited to 'src/zenhttp/include')
| -rw-r--r-- | src/zenhttp/include/zenhttp/httpplugin.h | 49 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/transportplugin.h | 97 |
2 files changed, 146 insertions, 0 deletions
diff --git a/src/zenhttp/include/zenhttp/httpplugin.h b/src/zenhttp/include/zenhttp/httpplugin.h new file mode 100644 index 000000000..409eb1b61 --- /dev/null +++ b/src/zenhttp/include/zenhttp/httpplugin.h @@ -0,0 +1,49 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/refcount.h> +#include <zencore/thread.h> + +#if !defined(ZEN_WITH_PLUGINS) +# if ZEN_PLATFORM_WINDOWS +# define ZEN_WITH_PLUGINS 1 +# else +# define ZEN_WITH_PLUGINS 0 +# endif +#endif + +#if ZEN_WITH_PLUGINS +# include "transportplugin.h" +# include <zenhttp/httpserver.h> + +namespace zen { + +struct HttpPluginServerImpl; + +class HttpPluginServer : public HttpServer +{ +public: + HttpPluginServer(unsigned int ThreadCount); + ~HttpPluginServer(); + + virtual void RegisterService(HttpService& Service) override; + virtual int Initialize(int BasePort) override; + virtual void Run(bool IsInteractiveSession) override; + virtual void RequestExit() override; + virtual void Close() override; + + void AddPlugin(Ref<TransportPluginInterface> Plugin); + void RemovePlugin(Ref<TransportPluginInterface> Plugin); + +private: + Event m_ShutdownEvent; + int m_BasePort = 0; + unsigned int m_ThreadCount = 0; + + HttpPluginServerImpl* m_Impl = nullptr; +}; + +} // namespace zen + +#endif diff --git a/src/zenhttp/include/zenhttp/transportplugin.h b/src/zenhttp/include/zenhttp/transportplugin.h new file mode 100644 index 000000000..38b07d471 --- /dev/null +++ b/src/zenhttp/include/zenhttp/transportplugin.h @@ -0,0 +1,97 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <stdint.h> + +// Important note: this header is meant to compile standalone +// and should therefore not depend on anything from the Zen codebase + +class TransportConnectionInterface; +class TransportPluginInterface; +class TransportServerConnectionHandler; +class TransportServerInterface; + +/************************************************************************* + + The following interfaces are implemented on the server side, and instances + are provided to the plugins. + +*************************************************************************/ + +/** Plugin-server interface for connection + * + * This is how the transport feeds data to the connection handler + * which will parse the incoming messages and dispatch to + * appropriate request handlers and ultimately call into functions + * which write data back to the client. + */ +class TransportServerConnectionHandler +{ +public: + virtual uint32_t AddRef() const = 0; + virtual uint32_t Release() const = 0; + virtual void OnBytesRead(const void* Buffer, size_t DataSize) = 0; +}; + +/** Plugin-server interface + * + * There will be one instance of this per plugin, and the plugin + * should use this to manage lifetimes of connections and any + * other resources. + */ +class TransportServerInterface +{ +public: + virtual TransportServerConnectionHandler* CreateConnectionHandler(TransportConnectionInterface* Connection) = 0; +}; + +/************************************************************************* + + The following interfaces are to be implemented by transport plugins. + +*************************************************************************/ + +/** Interface which needs to be implemented by a transport plugin + * + * This is responsible for setting up and running the communication + * for a given transport. + */ +class TransportPluginInterface +{ +public: + virtual uint32_t AddRef() const = 0; + virtual uint32_t Release() const = 0; + virtual void Initialize(TransportServerInterface* ServerInterface) = 0; + virtual void Shutdown() = 0; + + /** Check whether this transport is usable. + */ + virtual bool IsAvailable() = 0; +}; + +/** A transport plugin provider needs to implement this interface + * + * There will be one instance of this per established connection and + * this interface is used to write response data back to the client. + */ +class TransportConnectionInterface +{ +public: + virtual int64_t WriteBytes(const void* Buffer, size_t DataSize) = 0; + virtual void Shutdown(bool Receive, bool Transmit) = 0; + virtual void CloseConnection() = 0; +}; + +#if defined(_MSC_VER) +# define DLL_TRANSPORT_API __declspec(dllexport) +#else +# define DLL_TRANSPORT_API +#endif + +extern "C" +{ + DLL_TRANSPORT_API TransportPluginInterface* CreateTransportPluginInterface(); +} + +typedef TransportPluginInterface* (*PfnCreateTransportPluginInterface)(); |