aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/proxy/httptrafficinspector.h
blob: f4af0e77ed65afaf1c6f31dc2b69a017ed46d2b2 (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
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/logging.h>
#include <zencore/uid.h>

ZEN_THIRD_PARTY_INCLUDES_START
#include <http_parser.h>
ZEN_THIRD_PARTY_INCLUDES_END

#include <atomic>
#include <cstdint>
#include <string>
#include <string_view>

namespace zen {

class HttpTrafficInspector
{
public:
	enum class Direction
	{
		Request,
		Response
	};

	HttpTrafficInspector(Direction Dir, std::string_view SessionLabel);

	void Inspect(const char* Data, size_t Length);

	uint64_t GetMessageCount() const { return m_MessageCount.load(std::memory_order_relaxed); }
	bool	 IsUpgraded() const { return m_Upgraded.load(std::memory_order_relaxed); }
	Oid		 GetSessionId() const;
	bool	 HasSessionId() const;

	void SetObserver(class IHttpTrafficObserver* Observer) { m_Observer = Observer; }

private:
	int OnUrl(const char* Data, size_t Length);
	int OnHeaderField(const char* Data, size_t Length);
	int OnHeaderValue(const char* Data, size_t Length);
	int OnHeadersComplete();
	int OnMessageComplete();

	void ResetMessageState();

	static HttpTrafficInspector* GetThis(http_parser* Parser) { return static_cast<HttpTrafficInspector*>(Parser->data); }

	static http_parser_settings s_RequestSettings;
	static http_parser_settings s_ResponseSettings;

	LoggerRef Log() { return m_Log; }

	LoggerRef	m_Log;
	http_parser m_Parser;
	Direction	m_Direction;
	std::string m_SessionLabel;
	bool		m_Disabled = false;

	// Per-message state
	std::string			  m_Url;
	std::string			  m_Method;
	uint16_t			  m_StatusCode	  = 0;
	int64_t				  m_ContentLength = -1;
	std::string			  m_CurrentHeaderField;
	std::atomic<uint64_t> m_MessageCount{0};
	std::atomic<bool>	  m_Upgraded{false};
	Oid					  m_SessionId		  = Oid::Zero;
	bool				  m_SessionIdCaptured = false;
	IHttpTrafficObserver* m_Observer		  = nullptr;
};

class IHttpTrafficObserver
{
public:
	virtual ~IHttpTrafficObserver()						  = default;
	virtual void OnMessageComplete(HttpTrafficInspector::Direction Dir,
								   std::string_view				   Method,
								   std::string_view				   Url,
								   uint16_t						   StatusCode,
								   int64_t						   ContentLength) = 0;
};

}  // namespace zen