xref: /aosp_15_r20/external/cronet/net/proxy_resolution/win/windows_system_proxy_resolution_service.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h"
6 
7 #include <utility>
8 
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/values.h"
12 #include "base/win/windows_version.h"
13 #include "net/base/net_errors.h"
14 #include "net/log/net_log.h"
15 #include "net/log/net_log_event_type.h"
16 #include "net/log/net_log_with_source.h"
17 #include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h"
18 #include "net/proxy_resolution/win/windows_system_proxy_resolver.h"
19 
20 namespace net {
21 
22 // static
IsSupported()23 bool WindowsSystemProxyResolutionService::IsSupported() {
24   // The sandbox required to run the WinHttp functions  used in the resolver is
25   // only supported in RS1 and later.
26   if (base::win::GetVersion() < base::win::Version::WIN10_RS1) {
27     LOG(WARNING) << "WindowsSystemProxyResolutionService is only supported for "
28                     "Windows 10 Version 1607 (RS1) and later.";
29     return false;
30   }
31 
32   return true;
33 }
34 
35 // static
36 std::unique_ptr<WindowsSystemProxyResolutionService>
Create(std::unique_ptr<WindowsSystemProxyResolver> windows_system_proxy_resolver,NetLog * net_log)37 WindowsSystemProxyResolutionService::Create(
38     std::unique_ptr<WindowsSystemProxyResolver> windows_system_proxy_resolver,
39     NetLog* net_log) {
40   if (!IsSupported() || !windows_system_proxy_resolver)
41     return nullptr;
42 
43   return base::WrapUnique(new WindowsSystemProxyResolutionService(
44       std::move(windows_system_proxy_resolver), net_log));
45 }
46 
WindowsSystemProxyResolutionService(std::unique_ptr<WindowsSystemProxyResolver> windows_system_proxy_resolver,NetLog * net_log)47 WindowsSystemProxyResolutionService::WindowsSystemProxyResolutionService(
48     std::unique_ptr<WindowsSystemProxyResolver> windows_system_proxy_resolver,
49     NetLog* net_log)
50     : windows_system_proxy_resolver_(std::move(windows_system_proxy_resolver)),
51       net_log_(net_log) {}
52 
~WindowsSystemProxyResolutionService()53 WindowsSystemProxyResolutionService::~WindowsSystemProxyResolutionService() {
54   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
55   // Cancel any in-progress requests.
56   // This cancels the internal requests, but leaves the responsibility of
57   // canceling the high-level ProxyResolutionRequest (by deleting it) to the
58   // client. Since |pending_requests_| might be modified in one of the requests'
59   // callbacks (if it deletes another request), iterating through the set in a
60   // for-loop will not work.
61   while (!pending_requests_.empty()) {
62     WindowsSystemProxyResolutionRequest* req = *pending_requests_.begin();
63     req->ProxyResolutionComplete(ProxyList(), WinHttpStatus::kAborted, 0);
64     pending_requests_.erase(req);
65   }
66 }
67 
ResolveProxy(const GURL & url,const std::string & method,const NetworkAnonymizationKey & network_anonymization_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<ProxyResolutionRequest> * request,const NetLogWithSource & net_log)68 int WindowsSystemProxyResolutionService::ResolveProxy(
69     const GURL& url,
70     const std::string& method,
71     const NetworkAnonymizationKey& network_anonymization_key,
72     ProxyInfo* results,
73     CompletionOnceCallback callback,
74     std::unique_ptr<ProxyResolutionRequest>* request,
75     const NetLogWithSource& net_log) {
76   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
77   DCHECK(!callback.is_null());
78   DCHECK(request);
79 
80   net_log.BeginEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
81 
82   // Once it's created, the WindowsSystemProxyResolutionRequest immediately
83   // kicks off proxy resolution in a separate process.
84   auto req = std::make_unique<WindowsSystemProxyResolutionRequest>(
85       this, url, method, results, std::move(callback), net_log,
86       windows_system_proxy_resolver_.get());
87 
88   DCHECK(!ContainsPendingRequest(req.get()));
89   pending_requests_.insert(req.get());
90 
91   // Completion will be notified through |callback|, unless the caller cancels
92   // the request using |request|.
93   *request = std::move(req);
94   return ERR_IO_PENDING;
95 }
96 
ReportSuccess(const ProxyInfo & proxy_info)97 void WindowsSystemProxyResolutionService::ReportSuccess(
98     const ProxyInfo& proxy_info) {
99   // TODO(https://crbug.com/1032820): Update proxy retry info with new proxy
100   // resolution data.
101 }
102 
SetProxyDelegate(ProxyDelegate * delegate)103 void WindowsSystemProxyResolutionService::SetProxyDelegate(
104     ProxyDelegate* delegate) {
105   // TODO(https://crbug.com/1032820): Implement proxy delegates.
106 }
107 
OnShutdown()108 void WindowsSystemProxyResolutionService::OnShutdown() {
109   // TODO(https://crbug.com/1032820): Add cleanup here as necessary. If cleanup
110   // is unnecessary, update the interface to not require an implementation for
111   // this so OnShutdown() can be removed.
112 }
113 
ClearBadProxiesCache()114 void WindowsSystemProxyResolutionService::ClearBadProxiesCache() {
115   proxy_retry_info_.clear();
116 }
117 
proxy_retry_info() const118 const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info()
119     const {
120   return proxy_retry_info_;
121 }
122 
GetProxyNetLogValues()123 base::Value::Dict WindowsSystemProxyResolutionService::GetProxyNetLogValues() {
124   // TODO (https://crbug.com/1032820): Implement net logs.
125   return base::Value::Dict();
126 }
127 
128 bool WindowsSystemProxyResolutionService::
CastToConfiguredProxyResolutionService(ConfiguredProxyResolutionService ** configured_proxy_resolution_service)129     CastToConfiguredProxyResolutionService(
130         ConfiguredProxyResolutionService**
131             configured_proxy_resolution_service) {
132   *configured_proxy_resolution_service = nullptr;
133   return false;
134 }
135 
ContainsPendingRequest(WindowsSystemProxyResolutionRequest * req)136 bool WindowsSystemProxyResolutionService::ContainsPendingRequest(
137     WindowsSystemProxyResolutionRequest* req) {
138   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
139   return pending_requests_.count(req) == 1;
140 }
141 
RemovePendingRequest(WindowsSystemProxyResolutionRequest * req)142 void WindowsSystemProxyResolutionService::RemovePendingRequest(
143     WindowsSystemProxyResolutionRequest* req) {
144   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
145   DCHECK(ContainsPendingRequest(req));
146   pending_requests_.erase(req);
147 }
148 
DidFinishResolvingProxy(const GURL & url,const std::string & method,ProxyInfo * result,WinHttpStatus winhttp_status,const NetLogWithSource & net_log)149 int WindowsSystemProxyResolutionService::DidFinishResolvingProxy(
150     const GURL& url,
151     const std::string& method,
152     ProxyInfo* result,
153     WinHttpStatus winhttp_status,
154     const NetLogWithSource& net_log) {
155   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
156 
157   // TODO(https://crbug.com/1032820): Implement net logs.
158   // TODO(https://crbug.com/1032820): Implement proxy delegate.
159   // TODO(https://crbug.com/1032820): Implement proxy retry info.
160 
161   if (winhttp_status != WinHttpStatus::kOk)
162     result->UseDirect();
163 
164   net_log.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
165   return OK;
166 }
167 
168 }  // namespace net
169