#pragma once #include <Geode/loader/Loader.hpp> // another great circular dependency fix #include <matjson.hpp> #include "Result.hpp" #include "Task.hpp" #include <chrono> #include <optional> namespace geode::utils::web { GEODE_DLL void openLinkInBrowser(std::string const& url); // https://curl.se/libcurl/c/CURLOPT_HTTPAUTH.html namespace http_auth { constexpr static long BASIC = 0x0001; constexpr static long DIGEST = 0x0002; constexpr static long DIGEST_IE = 0x0004; constexpr static long BEARER = 0x0008; constexpr static long NEGOTIATE = 0x0010; constexpr static long NTLM = 0x0020; constexpr static long NTLM_WB = 0x0040; constexpr static long ANY = 0x0080; constexpr static long ANYSAFE = 0x0100; constexpr static long ONLY = 0x0200; constexpr static long AWS_SIGV4 = 0x0400; } // https://curl.se/libcurl/c/CURLOPT_PROXYTYPE.html enum class ProxyType { HTTP, // HTTP HTTPS, // HTTPS HTTPS2, // HTTPS (attempt to use HTTP/2) SOCKS4, // Socks4 SOCKS4A, // Socks4 with hostname resolution SOCKS5, // Socks5 SOCKS5H, // Socks5 with hostname resolution }; struct ProxyOpts { std::string address; // Proxy address/FQDN std::optional<std::uint16_t> port; // Proxy port ProxyType type = ProxyType::HTTP; // Proxy type long auth = http_auth::BASIC; // HTTP proxy auth method std::string username; // Proxy username std::string password; // Proxy password bool tunneling = false; // Enable HTTP tunneling bool certVerification = true; // Enable HTTPS certificate verification }; class WebRequest; class GEODE_DLL WebResponse final { private: class Impl; std::shared_ptr<Impl> m_impl; friend class WebRequest; public: // Must be default-constructible for use in Promise WebResponse(); bool ok() const; int code() const; Result<std::string> string() const; Result<matjson::Value> json() const; ByteVector data() const; Result<> into(std::filesystem::path const& path) const; std::vector<std::string> headers() const; std::optional<std::string> header(std::string_view name) const; }; class GEODE_DLL WebProgress final { private: class Impl; std::shared_ptr<Impl> m_impl; friend class WebRequest; public: // Must be default-constructible for use in Promise WebProgress(); size_t downloaded() const; size_t downloadTotal() const; std::optional<float> downloadProgress() const; size_t uploaded() const; size_t uploadTotal() const; std::optional<float> uploadProgress() const; }; using WebTask = Task<WebResponse, WebProgress>; class GEODE_DLL WebRequest final { private: class Impl; std::shared_ptr<Impl> m_impl; public: WebRequest(); ~WebRequest(); WebTask send(std::string_view method, std::string_view url); WebTask post(std::string_view url); WebTask get(std::string_view url); WebTask put(std::string_view url); WebTask patch(std::string_view url); WebRequest& header(std::string_view name, std::string_view value); WebRequest& param(std::string_view name, std::string_view value); template <std::integral T> WebRequest& param(std::string_view name, T value) { return this->param(name, std::to_string(value)); } WebRequest& userAgent(std::string_view name); WebRequest& timeout(std::chrono::seconds time); WebRequest& certVerification(bool enabled); WebRequest& CABundleContent(std::string_view content); WebRequest& proxyOpts(ProxyOpts const& proxyOpts); WebRequest& body(ByteVector raw); WebRequest& bodyString(std::string_view str); WebRequest& bodyJSON(matjson::Value const& json); }; }