aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpsys.h
blob: 0453b87406a78a1f90b566affd8b30b1522ad0f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zenhttp/httpserver.h>

#ifndef ZEN_WITH_HTTPSYS
#	if ZEN_PLATFORM_WINDOWS
#		define ZEN_WITH_HTTPSYS 1
#	else
#		define ZEN_WITH_HTTPSYS 0
#	endif
#endif

#if ZEN_WITH_HTTPSYS
#	define _WINSOCKAPI_
#	include <zencore/windows.h>
#	include "iothreadpool.h"
#	include "workthreadpool.h"

#	include <http.h>

namespace spdlog {
class logger;
}

namespace zen {

/**
 * @brief Windows implementation of HTTP server based on http.sys
 *
 * This requires elevation to function
 */
class HttpSysServer : public HttpServer
{
	friend class HttpSysTransaction;

public:
	explicit HttpSysServer(unsigned int ThreadCount, unsigned int AsyncWorkThreadCount);
	~HttpSysServer();

	// HttpServer interface implementation

	virtual int	 Initialize(int BasePort) override;
	virtual void Run(bool TestMode) override;
	virtual void RequestExit() override;
	virtual void RegisterService(HttpService& Service) override;

	WorkerThreadPool& WorkPool() { return m_AsyncWorkPool; }

	inline bool IsOk() const { return m_IsOk; }
	inline bool IsAsyncResponseEnabled() const { return m_IsAsyncResponseEnabled; }

private:
	int	 InitializeServer(int BasePort);
	void Cleanup();

	void StartServer();
	void OnHandlingRequest();
	void IssueNewRequestMaybe();

	void RegisterService(const char* Endpoint, HttpService& Service);
	void UnregisterService(const char* Endpoint, HttpService& Service);

private:
	spdlog::logger& m_Log;
	spdlog::logger& m_RequestLog;
	spdlog::logger& Log() { return m_Log; }

	bool m_IsOk					   = false;
	bool m_IsHttpInitialized	   = false;
	bool m_IsRequestLoggingEnabled = false;
	bool m_IsAsyncResponseEnabled  = true;

	WinIoThreadPool	 m_ThreadPool;
	WorkerThreadPool m_AsyncWorkPool;

	std::vector<std::wstring> m_BaseUris;  // eg: http://*:nnnn/
	HTTP_SERVER_SESSION_ID	  m_HttpSessionId	   = 0;
	HTTP_URL_GROUP_ID		  m_HttpUrlGroupId	   = 0;
	HANDLE					  m_RequestQueueHandle = 0;
	std::atomic_int32_t		  m_PendingRequests{0};
	std::atomic_int32_t		  m_IsShuttingDown{0};
	int32_t					  m_MinPendingRequests = 16;
	int32_t					  m_MaxPendingRequests = 128;
	Event					  m_ShutdownEvent;
};

}  // namespace zen
#endif