blob: ce8a69451f404aa693f8de47d0b96960ae6c168f [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2019 The Chromium Authors
Sorin Jianu95fb33d2019-02-21 16:59:332// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Roger Tawac0a1b9c2021-09-23 23:34:045#ifndef COMPONENTS_WINHTTP_NETWORK_FETCHER_H_
6#define COMPONENTS_WINHTTP_NETWORK_FETCHER_H_
Sorin Jianu95fb33d2019-02-21 16:59:337
Sorin Jianu40b6bd02024-01-11 00:25:048#include <windows.h>
Sorin Jianubf44a912019-03-02 01:35:019
Takuto Ikutac8d6b16f2024-04-15 16:59:1910#include <stdint.h>
11
Sorin Jianu95fb33d2019-02-21 16:59:3312#include <memory>
S. Ganeshe02679752024-06-05 21:41:4413#include <optional>
Sorin Jianu95fb33d2019-02-21 16:59:3314#include <string>
Lei Zhang692788372023-11-08 19:37:2815#include <string_view>
Sorin Jianubf44a912019-03-02 01:35:0116#include <vector>
Sorin Jianu95fb33d2019-02-21 16:59:3317
Roger Tawac0a1b9c2021-09-23 23:34:0418#include "base/containers/flat_map.h"
Sorin Jianubf44a912019-03-02 01:35:0119#include "base/files/file.h"
20#include "base/files/file_path.h"
Sorin Jianu92a26c92022-10-19 17:07:2021#include "base/functional/callback.h"
Sorin Jianu622be9c2024-02-15 00:17:4222#include "base/memory/ref_counted.h"
Sorin Jianu0c01aed2020-03-10 14:42:3323#include "base/memory/scoped_refptr.h"
Sorin Jianued722422020-05-29 19:17:1424#include "base/sequence_checker.h"
Roger Tawac0a1b9c2021-09-23 23:34:0425#include "components/winhttp/proxy_configuration.h"
26#include "components/winhttp/scoped_hinternet.h"
S. Ganeshe02679752024-06-05 21:41:4427#include "components/winhttp/scoped_winttp_proxy_info.h"
Sorin Jianubf44a912019-03-02 01:35:0128#include "url/gurl.h"
29
30namespace base {
Sorin Jianu6092b8c12023-02-01 17:40:0531class SequencedTaskRunner;
Sorin Jianubf44a912019-03-02 01:35:0132}
Sorin Jianu95fb33d2019-02-21 16:59:3333
Roger Tawac0a1b9c2021-09-23 23:34:0434namespace winhttp {
Sorin Jianu95fb33d2019-02-21 16:59:3335
Sorin Jianubf44a912019-03-02 01:35:0136// Implements a network fetcher in terms of WinHTTP. The class is ref-counted
Sorin Jianu6092b8c12023-02-01 17:40:0537// as it is accessed from the main sequence and the worker threads in WinHTTP.
Roger Tawac0a1b9c2021-09-23 23:34:0438class NetworkFetcher : public base::RefCountedThreadSafe<NetworkFetcher> {
Sorin Jianu95fb33d2019-02-21 16:59:3339 public:
Sebastien Lalancettee26adaec2022-01-05 15:32:4640 using FetchCompleteCallback = base::OnceCallback<void(int response_code)>;
Sorin Jianu520cfc02019-03-04 23:49:2941 using FetchStartedCallback =
Roger Tawac0a1b9c2021-09-23 23:34:0442 base::OnceCallback<void(int response_code, int64_t content_length)>;
43 using FetchProgressCallback = base::RepeatingCallback<void(int64_t current)>;
Sorin Jianu95fb33d2019-02-21 16:59:3344
Sorin Jianu622be9c2024-02-15 00:17:4245 NetworkFetcher(scoped_refptr<SharedHInternet> session_handle,
Roger Tawac0a1b9c2021-09-23 23:34:0446 scoped_refptr<ProxyConfiguration> proxy_configuration);
47 NetworkFetcher(const NetworkFetcher&) = delete;
48 NetworkFetcher& operator=(const NetworkFetcher&) = delete;
Sorin Jianu95fb33d2019-02-21 16:59:3349
Sorin Jianubf44a912019-03-02 01:35:0150 void Close();
51
Sorin Jianu95fb33d2019-02-21 16:59:3352 void PostRequest(
53 const GURL& url,
54 const std::string& post_data,
Sorin Jianuc2e91392020-06-18 01:05:3055 const std::string& content_type,
Sorin Jianu95fb33d2019-02-21 16:59:3356 const base::flat_map<std::string, std::string>& post_additional_headers,
Sorin Jianubf44a912019-03-02 01:35:0157 FetchStartedCallback fetch_started_callback,
Sorin Jianu520cfc02019-03-04 23:49:2958 FetchProgressCallback fetch_progress_callback,
Sorin Jianubf44a912019-03-02 01:35:0159 FetchCompleteCallback fetch_complete_callback);
Sorin Jianued722422020-05-29 19:17:1460
61 // Downloads the content of the |url| to a file identified by |file_path|.
62 // The content is written to the file as it is being retrieved from the
Joshua Pawlickibb0a3f5c2023-09-20 01:08:3663 // network. Returns a closure that can be run to cancel the download.
64 base::OnceClosure DownloadToFile(
65 const GURL& url,
66 const base::FilePath& file_path,
67 FetchStartedCallback fetch_started_callback,
68 FetchProgressCallback fetch_progress_callback,
69 FetchCompleteCallback fetch_complete_callback);
Sorin Jianubf44a912019-03-02 01:35:0170
Roger Tawac0a1b9c2021-09-23 23:34:0471 HRESULT QueryHeaderString(const std::wstring& name,
72 std::wstring* value) const;
73 HRESULT QueryHeaderInt(const std::wstring& name, int* value) const;
Sorin Jianubf44a912019-03-02 01:35:0174 std::string GetResponseBody() const;
75 HRESULT GetNetError() const;
Sorin Jianubf44a912019-03-02 01:35:0176 base::FilePath GetFilePath() const;
Sorin Jianued722422020-05-29 19:17:1477
78 // Returns the number of bytes retrieved from the network. This may be
79 // different than the content length if an error occurred.
Sorin Jianubf44a912019-03-02 01:35:0180 int64_t GetContentSize() const;
Sorin Jianu95fb33d2019-02-21 16:59:3381
82 private:
Roger Tawac0a1b9c2021-09-23 23:34:0483 friend class base::RefCountedThreadSafe<NetworkFetcher>;
Sorin Jianubf44a912019-03-02 01:35:0184 using WriteDataCallback = base::RepeatingCallback<void()>;
85
Roger Tawac0a1b9c2021-09-23 23:34:0486 ~NetworkFetcher();
Sorin Jianubf44a912019-03-02 01:35:0187
88 static void __stdcall WinHttpStatusCallback(HINTERNET handle,
89 DWORD_PTR context,
90 DWORD status,
91 void* info,
92 DWORD info_len);
93
Sorin Jianu92a26c92022-10-19 17:07:2094 // Invoked by the last WinHTTPstatus status callback.
95 void HandleClosing();
Sorin Jianubf44a912019-03-02 01:35:0196
Sorin Jianu92a26c92022-10-19 17:07:2097 DWORD_PTR context() const { return reinterpret_cast<DWORD_PTR>(this); }
Sorin Jianubf44a912019-03-02 01:35:0198
99 HRESULT BeginFetch(
100 const std::string& data,
S. Ganeshe02679752024-06-05 21:41:44101 const base::flat_map<std::string, std::string>& additional_headers);
102 std::optional<ScopedWinHttpProxyInfo> GetProxyForUrl();
103 void ContinueFetch(
104 const std::string& data,
105 base::flat_map<std::string, std::string> additional_headers,
106 std::optional<ScopedWinHttpProxyInfo> winhttp_proxy_info);
107
Roger Tawac0a1b9c2021-09-23 23:34:04108 ScopedHInternet Connect();
109 ScopedHInternet OpenRequest();
Sorin Jianubf44a912019-03-02 01:35:01110 HRESULT SendRequest(const std::string& data);
111 void SendRequestComplete();
112 HRESULT ReceiveResponse();
Sorin Jianu617e7792020-05-30 00:53:53113 void HeadersAvailable();
114 HRESULT ReadData();
Sorin Jianubf44a912019-03-02 01:35:01115 void ReadDataComplete(size_t num_bytes_read);
Sorin Jianu92a26c92022-10-19 17:07:20116 void RequestError(DWORD error);
Sorin Jianu660bfa82020-05-31 15:28:56117 void CompleteFetch();
Sorin Jianubf44a912019-03-02 01:35:01118
119 void WriteDataToMemory();
120 void WriteDataToFile();
121 bool WriteDataToFileBlocking();
122 void WriteDataToFileComplete(bool is_eof);
123
Sorin Jianued722422020-05-29 19:17:14124 SEQUENCE_CHECKER(sequence_checker_);
Sorin Jianu6092b8c12023-02-01 17:40:05125 scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
Sorin Jianubf44a912019-03-02 01:35:01126
Sorin Jianu622be9c2024-02-15 00:17:42127 scoped_refptr<SharedHInternet> session_handle_;
Maciek Kumorek1d1e5c22020-07-25 22:49:39128 scoped_refptr<ProxyConfiguration> proxy_configuration_;
Roger Tawac0a1b9c2021-09-23 23:34:04129 ScopedHInternet connect_handle_;
130 ScopedHInternet request_handle_;
Sorin Jianubf44a912019-03-02 01:35:01131
132 // Keeps an outstanding reference count on itself as long as there is a
133 // valid request handle and the context for the handle is set to this
134 // instance.
Roger Tawac0a1b9c2021-09-23 23:34:04135 scoped_refptr<NetworkFetcher> self_;
Sorin Jianubf44a912019-03-02 01:35:01136
137 GURL url_;
138 bool is_https_ = false;
139 std::string host_;
140 int port_ = 0;
141 std::string path_for_request_;
142
Lei Zhang692788372023-11-08 19:37:28143 std::wstring_view verb_;
Xiaoling Bao3d98e162022-11-12 03:32:18144 std::string request_data_;
Maciek Kumorek50ead5c5c2020-07-08 15:10:14145 // The value of Content-Type header, e.g. "application/json".
146 std::string content_type_;
Sorin Jianubf44a912019-03-02 01:35:01147 WriteDataCallback write_data_callback_;
148 HRESULT net_error_ = S_OK;
Sorin Jianubf44a912019-03-02 01:35:01149 std::vector<char> read_buffer_;
Sebastien Lalancettee26adaec2022-01-05 15:32:46150 int response_code_ = 0;
Sorin Jianubf44a912019-03-02 01:35:01151 std::string post_response_body_;
152 base::FilePath file_path_;
153 base::File file_;
154 int64_t content_size_ = 0;
155
156 FetchStartedCallback fetch_started_callback_;
Sorin Jianu520cfc02019-03-04 23:49:29157 FetchProgressCallback fetch_progress_callback_;
Sorin Jianubf44a912019-03-02 01:35:01158 FetchCompleteCallback fetch_complete_callback_;
Sorin Jianu95fb33d2019-02-21 16:59:33159};
160
Roger Tawac0a1b9c2021-09-23 23:34:04161} // namespace winhttp
Sorin Jianu95fb33d2019-02-21 16:59:33162
Roger Tawac0a1b9c2021-09-23 23:34:04163#endif // COMPONENTS_WINHTTP_NETWORK_FETCHER_H_