aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-10-10 13:30:07 +0200
committerGitHub <[email protected]>2023-10-10 13:30:07 +0200
commit7905d0d21af95c6016768d7a8a81dd9204b34d24 (patch)
tree076329f5fad1c33503ee611f6399853da2490567 /src/zenhttp/include
parentcache reference tracking (#455) (diff)
downloadzen-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.h49
-rw-r--r--src/zenhttp/include/zenhttp/transportplugin.h97
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)();