http_downloader.h (2388B)
1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "common/types.h" 7 8 #include <atomic> 9 #include <functional> 10 #include <memory> 11 #include <mutex> 12 #include <string> 13 #include <string_view> 14 #include <vector> 15 16 class ProgressCallback; 17 18 class HTTPDownloader 19 { 20 public: 21 enum : s32 22 { 23 HTTP_STATUS_CANCELLED = -3, 24 HTTP_STATUS_TIMEOUT = -2, 25 HTTP_STATUS_ERROR = -1, 26 HTTP_STATUS_OK = 200 27 }; 28 29 struct Request 30 { 31 using Data = std::vector<u8>; 32 using Callback = std::function<void(s32 status_code, const std::string& content_type, Data data)>; 33 34 enum class Type 35 { 36 Get, 37 Post, 38 }; 39 40 enum class State 41 { 42 Pending, 43 Cancelled, 44 Started, 45 Receiving, 46 Complete, 47 }; 48 49 HTTPDownloader* parent; 50 Callback callback; 51 ProgressCallback* progress; 52 std::string url; 53 std::string post_data; 54 std::string content_type; 55 Data data; 56 u64 start_time; 57 s32 status_code = 0; 58 u32 content_length = 0; 59 u32 last_progress_update = 0; 60 Type type = Type::Get; 61 std::atomic<State> state{State::Pending}; 62 }; 63 64 HTTPDownloader(); 65 virtual ~HTTPDownloader(); 66 67 static std::unique_ptr<HTTPDownloader> Create(std::string user_agent = DEFAULT_USER_AGENT); 68 static std::string GetExtensionForContentType(const std::string& content_type); 69 70 void SetTimeout(float timeout); 71 void SetMaxActiveRequests(u32 max_active_requests); 72 73 void CreateRequest(std::string url, Request::Callback callback, ProgressCallback* progress = nullptr); 74 void CreatePostRequest(std::string url, std::string post_data, Request::Callback callback, 75 ProgressCallback* progress = nullptr); 76 void PollRequests(); 77 void WaitForAllRequests(); 78 bool HasAnyRequests(); 79 80 static const char DEFAULT_USER_AGENT[]; 81 82 protected: 83 virtual Request* InternalCreateRequest() = 0; 84 virtual void InternalPollRequests() = 0; 85 86 virtual bool StartRequest(Request* request) = 0; 87 virtual void CloseRequest(Request* request) = 0; 88 89 void LockedAddRequest(Request* request); 90 u32 LockedGetActiveRequestCount(); 91 void LockedPollRequests(std::unique_lock<std::mutex>& lock); 92 93 float m_timeout; 94 u32 m_max_active_requests; 95 96 std::mutex m_pending_http_request_lock; 97 std::vector<Request*> m_pending_http_requests; 98 };