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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#pragma once
enum class ScriptContext;
// These definitions below should match on the Squirrel side so we can easily pass them along through a function.
/**
* Allowed methods for an HttpRequest.
*/
namespace HttpRequestMethod
{
enum Type
{
HRM_GET = 0,
HRM_POST = 1,
HRM_HEAD = 2,
HRM_PUT = 3,
HRM_DELETE = 4,
HRM_PATCH = 5,
HRM_OPTIONS = 6,
};
/** Returns the HTTP string representation of the given method. */
inline std::string ToString(HttpRequestMethod::Type method)
{
switch (method)
{
case HttpRequestMethod::HRM_GET:
return "GET";
case HttpRequestMethod::HRM_POST:
return "POST";
case HttpRequestMethod::HRM_HEAD:
return "HEAD";
case HttpRequestMethod::HRM_PUT:
return "PUT";
case HttpRequestMethod::HRM_DELETE:
return "DELETE";
case HttpRequestMethod::HRM_PATCH:
return "PATCH";
case HttpRequestMethod::HRM_OPTIONS:
return "OPTIONS";
default:
return "INVALID";
}
}
/** Whether or not the given method should be treated like a POST for curlopts. */
bool UsesCurlPostOptions(HttpRequestMethod::Type method)
{
switch (method)
{
case HttpRequestMethod::HRM_POST:
case HttpRequestMethod::HRM_PUT:
case HttpRequestMethod::HRM_DELETE:
case HttpRequestMethod::HRM_PATCH:
return true;
default:
return false;
}
}
/** Whether or not the given http request method can have query parameters in the URL. */
bool CanHaveQueryParameters(HttpRequestMethod::Type method)
{
return method == HttpRequestMethod::HRM_GET || UsesCurlPostOptions(method);
}
}; // namespace HttpRequestMethod
/** Contains data about an http request that has been queued. */
struct HttpRequest
{
/** Method used for this http request. */
HttpRequestMethod::Type method;
/** Base URL of this http request. */
std::string baseUrl;
/** Headers used for this http request. Some may get overridden or ignored. */
std::unordered_map<std::string, std::vector<std::string>> headers;
/** Query parameters for this http request. */
std::unordered_map<std::string, std::vector<std::string>> queryParameters;
/** The content type of this http request. Defaults to text/plain & UTF-8 charset. */
std::string contentType = "text/plain; charset=utf-8";
/** The body of this http request. If set, will override queryParameters.*/
std::string body;
/** The timeout for the http request, in seconds. Must be between 1 and 60. */
int timeout;
/** If set, the override to use for the User-Agent header. */
std::string userAgent;
};
/**
* Handles making HTTP requests and sending the responses back to Squirrel.
*/
class HttpRequestHandler
{
public:
HttpRequestHandler();
// Start/Stop the HTTP request handler. Right now this doesn't do much.
void StartHttpRequestHandler();
void StopHttpRequestHandler();
// Whether or not this http request handler is currently running.
bool IsRunning() const { return m_bIsHttpRequestHandlerRunning; }
/**
* Creates a new thread to execute an HTTP request.
* @param requestParameters The parameters to use for this http request.
* @returns The handle for the http request being sent, or -1 if the request failed.
*/
template <ScriptContext context> int MakeHttpRequest(const HttpRequest& requestParameters);
/** Registers the HTTP request Squirrel functions for the given script context. */
template <ScriptContext context> void RegisterSQFuncs();
private:
int m_iLastRequestHandle = 0;
std::atomic_bool m_bIsHttpRequestHandlerRunning = false;
};
extern HttpRequestHandler* g_httpRequestHandler;
|