#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;