diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h b/Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h new file mode 100644 index 00000000..91ae1afe --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/HTTP.h @@ -0,0 +1,257 @@ +/* + * HTTP.h + * ------ + * Purpose: Simple HTTP client interface. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#include "openmpt/all/BuildSettings.hpp" + +#include <functional> +#include <iosfwd> +#include <optional> + + +OPENMPT_NAMESPACE_BEGIN + + +struct URI +{ + mpt::ustring scheme; + mpt::ustring username; + mpt::ustring password; + mpt::ustring host; + mpt::ustring port; + mpt::ustring path; + mpt::ustring query; + mpt::ustring fragment; +}; + +class bad_uri + : public std::runtime_error +{ +public: + bad_uri(const std::string &msg) + : std::runtime_error(msg) + { + } +}; + +URI ParseURI(mpt::ustring str); + + +namespace HTTP +{ + + +class exception + : public std::runtime_error +{ +private: + mpt::ustring message; +public: + exception(const mpt::ustring &m); + mpt::ustring GetMessage() const; +}; + + +class status_exception + : public std::runtime_error +{ +public: + status_exception(uint64 status) + : std::runtime_error(MPT_AFORMAT("HTTP status {}")(status)) + { + return; + } +}; + + +class Abort + : public exception +{ +public: + Abort() : + exception(U_("Operation aborted.")) + { + return; + } +}; + + +struct NativeHandle; + + +class Handle +{ +private: + std::unique_ptr<NativeHandle> handle; +public: + Handle(); + Handle(const Handle &) = delete; + Handle & operator=(const Handle &) = delete; + explicit operator bool() const; + bool operator!() const; + Handle(NativeHandle h); + Handle & operator=(NativeHandle h); + operator NativeHandle (); + ~Handle(); +}; + + +class InternetSession +{ +private: + Handle internet; +public: + InternetSession(mpt::ustring userAgent); + operator NativeHandle (); + template <typename TRequest> + auto operator()(const TRequest &request) -> decltype(request(*this)) + { + return request(*this); + } + template <typename TRequest> + auto Request(const TRequest &request) -> decltype(request(*this)) + { + return request(*this); + } +}; + + +enum class Protocol +{ + HTTP, + HTTPS, +}; + + +enum class Port : uint16 +{ + Default = 0, + HTTP = 80, + HTTPS = 443, +}; + + +enum class Method +{ + Get, + Head, + Post, + Put, + Delete, + Trace, + Options, + Connect, + Patch, +}; + + +using Query = std::vector<std::pair<mpt::ustring, mpt::ustring>>; + + +namespace MimeType { + inline std::string Text() { return "text/plain"; } + inline std::string JSON() { return "application/json"; } + inline std::string Binary() { return "application/octet-stream"; } +} + + +using AcceptMimeTypes = std::vector<std::string>; +namespace MimeTypes { + inline AcceptMimeTypes Text() { return {"text/*"}; } + inline AcceptMimeTypes JSON() { return {MimeType::JSON()}; } + inline AcceptMimeTypes Binary() { return {MimeType::Binary()}; } +} + + +using Headers = std::vector<std::pair<std::string, std::string>>; + + +enum Flags +{ + None = 0x00u, + NoCache = 0x01u, + AutoRedirect = 0x02u, +}; + + +struct Result +{ + uint64 Status = 0; + std::optional<uint64> ContentLength; + std::vector<std::byte> Data; + + void CheckStatus(uint64 expected) const + { + if(Status != expected) + { + throw status_exception(Status); + } + } + +}; + + +enum class Progress +{ + Start = 1, + ConnectionEstablished = 2, + RequestOpened = 3, + RequestSent = 4, + ResponseReceived = 5, + TransferBegin = 6, + TransferRunning = 7, + TransferDone = 8, +}; + + +struct Request +{ + + Protocol protocol = Protocol::HTTPS; + mpt::ustring host; + Port port = Port::Default; + mpt::ustring username; + mpt::ustring password; + Method method = Method::Get; + mpt::ustring path = U_("/"); + Query query; + mpt::ustring referrer; + AcceptMimeTypes acceptMimeTypes; + Flags flags = None; + Headers headers; + std::string dataMimeType; + mpt::const_byte_span data; + + std::ostream *outputStream = nullptr; + std::function<void(Progress, uint64, std::optional<uint64>)> progressCallback = nullptr; + + Request &SetURI(const URI &uri); + +#if defined(MPT_BUILD_RETRO) + Request &InsecureTLSDowngradeWindowsXP(); +#endif // MPT_BUILD_RETRO + + Result operator()(InternetSession &internet) const; + +private: + + void progress(Progress progress, uint64 transferred, std::optional<uint64> expectedSize) const; + +}; + + +Result SimpleGet(InternetSession &internet, Protocol protocol, const mpt::ustring &host, const mpt::ustring &path); + + +} // namespace HTTP + + +OPENMPT_NAMESPACE_END |