• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MarkProxiesAsBadUntil(const ProxyInfo & results,base::TimeDelta retry_delay,const std::vector<ProxyChain> & additional_bad_proxies,const NetLogWithSource & net_log)114 bool WindowsSystemProxyResolutionService::MarkProxiesAsBadUntil(
115     const ProxyInfo& results,
116     base::TimeDelta retry_delay,
117     const std::vector<ProxyChain>& additional_bad_proxies,
118     const NetLogWithSource& net_log) {
119   // TODO(https://crbug.com/1032820): Implement bad proxy cache. We should be
120   // able to share logic with the ConfiguredProxyResolutionService to accomplish
121   // this.
122   return false;
123 }
124 
ClearBadProxiesCache()125 void WindowsSystemProxyResolutionService::ClearBadProxiesCache() {
126   proxy_retry_info_.clear();
127 }
128 
proxy_retry_info() const129 const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info()
130     const {
131   return proxy_retry_info_;
132 }
133 
GetProxyNetLogValues()134 base::Value::Dict WindowsSystemProxyResolutionService::GetProxyNetLogValues() {
135   // TODO (https://crbug.com/1032820): Implement net logs.
136   return base::Value::Dict();
137 }
138 
139 bool WindowsSystemProxyResolutionService::
CastToConfiguredProxyResolutionService(ConfiguredProxyResolutionService ** configured_proxy_resolution_service)140     CastToConfiguredProxyResolutionService(
141         ConfiguredProxyResolutionService**
142             configured_proxy_resolution_service) {
143   *configured_proxy_resolution_service = nullptr;
144   return false;
145 }
146 
ContainsPendingRequest(WindowsSystemProxyResolutionRequest * req)147 bool WindowsSystemProxyResolutionService::ContainsPendingRequest(
148     WindowsSystemProxyResolutionRequest* req) {
149   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
150   return pending_requests_.count(req) == 1;
151 }
152 
RemovePendingRequest(WindowsSystemProxyResolutionRequest * req)153 void WindowsSystemProxyResolutionService::RemovePendingRequest(
154     WindowsSystemProxyResolutionRequest* req) {
155   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
156   DCHECK(ContainsPendingRequest(req));
157   pending_requests_.erase(req);
158 }
159 
DidFinishResolvingProxy(const GURL & url,const std::string & method,ProxyInfo * result,WinHttpStatus winhttp_status,const NetLogWithSource & net_log)160 int WindowsSystemProxyResolutionService::DidFinishResolvingProxy(
161     const GURL& url,
162     const std::string& method,
163     ProxyInfo* result,
164     WinHttpStatus winhttp_status,
165     const NetLogWithSource& net_log) {
166   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
167 
168   // TODO(https://crbug.com/1032820): Implement net logs.
169   // TODO(https://crbug.com/1032820): Implement proxy delegate.
170   // TODO(https://crbug.com/1032820): Implement proxy retry info.
171 
172   if (winhttp_status != WinHttpStatus::kOk)
173     result->UseDirect();
174 
175   net_log.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
176   return OK;
177 }
178 
179 }  // namespace net
180