HttpClient.h
1 #pragma once 2 3 #include <future> 4 #include <winrt/Windows.Foundation.h> 5 #include <winrt/Windows.Storage.Streams.h> 6 #include <winrt/Windows.Web.Http.h> 7 #include <winrt/Windows.Web.Http.Headers.h> 8 namespace http 9 { 10 using namespace winrt::Windows::Web::Http; 11 namespace storage = winrt::Windows::Storage; 12 13 const inline wchar_t USER_AGENT[] = L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"; 14 15 class HttpClient 16 { 17 public: 18 HttpClient() 19 { 20 auto headers = m_client.DefaultRequestHeaders(); 21 headers.UserAgent().TryParseAdd(USER_AGENT); 22 } 23 24 std::future<std::wstring> request(const winrt::Windows::Foundation::Uri& url) 25 { 26 auto response = co_await m_client.GetAsync(url); 27 (void)response.EnsureSuccessStatusCode(); 28 auto body = co_await response.Content().ReadAsStringAsync(); 29 co_return std::wstring(body); 30 } 31 32 std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath) 33 { 34 auto response = co_await m_client.GetAsync(url); 35 (void)response.EnsureSuccessStatusCode(); 36 auto file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways); 37 co_await response.Content().WriteToStreamAsync(file_stream); 38 file_stream.Close(); 39 } 40 41 std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath, const std::function<void(float)>& progressUpdateCallback) 42 { 43 auto response = co_await m_client.GetAsync(url, HttpCompletionOption::ResponseHeadersRead); 44 response.EnsureSuccessStatusCode(); 45 46 uint64_t totalBytes = response.Content().Headers().ContentLength().GetUInt64(); 47 auto contentStream = co_await response.Content().ReadAsInputStreamAsync(); 48 49 uint64_t totalBytesRead = 0; 50 storage::Streams::Buffer buffer(8192); 51 auto fileStream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways); 52 53 co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None); 54 while (buffer.Length() > 0) 55 { 56 co_await fileStream.WriteAsync(buffer); 57 totalBytesRead += buffer.Length(); 58 if (progressUpdateCallback) 59 { 60 float percentage = static_cast<float>(totalBytesRead) / totalBytes; 61 progressUpdateCallback(percentage); 62 } 63 64 co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None); 65 } 66 67 if (progressUpdateCallback) 68 { 69 progressUpdateCallback(1); 70 } 71 72 fileStream.Close(); 73 contentStream.Close(); 74 } 75 76 private: 77 winrt::Windows::Web::Http::HttpClient m_client; 78 }; 79 }