Commit 5889b656 authored by Bruce Dawson's avatar Bruce Dawson Committed by Commit Bot

Revert "Implement the WindowsSystemProxyResolutionService/Request"

This reverts commit 33f234e7.

Reason for revert: Windows 7 test bots are failing

This is because WinHttpCreateProxyResolver requires Windows 8+.
https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpcreateproxyresolver

Original change's description:
> Implement the WindowsSystemProxyResolutionService/Request
> 
> This change creates a functional proxy resolver for Windows that relies
> on WinHttp APIs. This is not in its final state, though. This CL
> represents the simplest, least-work way to implement this proxy
> resolution service. Work still to come includes:
> - Complete NetLogs
> - Better error reporting from WinHttp APIs
> - Proxy Delegate
> - Proxy retry info
> - Assurance that the proxy configs we're receiving are from the system
> 
> The WindowsSystemProxyResolutionService is the object that external
> callers use to resolve a proxy. These callers can keep track of the
> status of this proxy resolution via a ProxyResolutionRequest,
> implemented here as a WindowsSystemProxyResolutionRequest. The request
> object is mainly intended to kick off a specific proxy resolution and
> report a result via a caller-provided callback. Both of these objects
> deal with a WindowsSystemProxyResolver.
> 
> The WindowsSystemProxyResolver is a new class that does all the required
> interfacing with WinHttp APIs. It is a reference counted object created
> by the WindowsSystemProxyResolutionService. Once created, it is used for
> the lifetime of the WindowsSystemProxyResolutionService. Throughout that
> time, the Resolver indirectly keeps a WinHttp session handle open. Each
> WindowsSystemProxyResolutionRequest is given a reference to the new
> resolver. When the Request object attempts to resolve a proxy for a
> given URL, it'll call into the Resolver object. Under the hood, the
> Resolver object creates a handle for the proxy resolution and runs the
> async call to WinHttp. At any time, the Request object can choose to
> ignore a pending result from the Resolver (ex: shutdown). The Resolver
> object must be reference counted because async WinHttp calls call back
> directly into the Resolver object, so it needs to stay alive as long as
> we're waiting for an async response from WinHttp.
> 
> The only other new object is the WinHttpAPIWrapper, which is just a thin
> wrapper over WinHttp APIs which we use to enable easier testing and
> to simplify some interactions with WinHttp. A WinHttpAPIWrapper is owned
> by a WindowsSystemProxyResolver. The Resolver object is the only object
> that should interact with the Wrapper object in any meaningful way.
> Internally, the WinHttpAPIWrapper keeps track of the opened WinHttp
> session handle that we're using for the lifetime of the Resolver object.
> 
> This change includes tests for the WindowsSystemProxyResolver layer (by
> mocking out the WinHttpAPIWrapper) and the
> WindowsSystemProxyResolutionService (by mocking out the
> WindowsSystemProxyResolver).
> 
> Bug: 1032820
> Change-Id: Ic1c60033ff148e6e8f3708e37a2af366613fefac
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159128
> Commit-Queue: Nicolas Arciniega <niarci@microsoft.com>
> Reviewed-by: Ramin Halavati <rhalavati@chromium.org>
> Reviewed-by: Eric Roman <eroman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#790493}

TBR=eroman@chromium.org,rhalavati@chromium.org,niarci@microsoft.com

Change-Id: I54d4659d5165261af912c427fdeb8f372a7bb2bf
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1032820
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2311063Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790602}
parent 6ca73b8f
...@@ -1343,10 +1343,6 @@ component("net") { ...@@ -1343,10 +1343,6 @@ component("net") {
"proxy_resolution/win/windows_system_proxy_resolution_request.h", "proxy_resolution/win/windows_system_proxy_resolution_request.h",
"proxy_resolution/win/windows_system_proxy_resolution_service.cc", "proxy_resolution/win/windows_system_proxy_resolution_service.cc",
"proxy_resolution/win/windows_system_proxy_resolution_service.h", "proxy_resolution/win/windows_system_proxy_resolution_service.h",
"proxy_resolution/win/windows_system_proxy_resolver.cc",
"proxy_resolution/win/windows_system_proxy_resolver.h",
"proxy_resolution/win/winhttp_api_wrapper.cc",
"proxy_resolution/win/winhttp_api_wrapper.h",
"socket/tcp_socket_win.cc", "socket/tcp_socket_win.cc",
"socket/tcp_socket_win.h", "socket/tcp_socket_win.h",
"socket/udp_socket_win.cc", "socket/udp_socket_win.cc",
...@@ -4501,7 +4497,6 @@ test("net_unittests") { ...@@ -4501,7 +4497,6 @@ test("net_unittests") {
"proxy_resolution/win/dhcp_pac_file_fetcher_win_unittest.cc", "proxy_resolution/win/dhcp_pac_file_fetcher_win_unittest.cc",
"proxy_resolution/win/proxy_config_service_win_unittest.cc", "proxy_resolution/win/proxy_config_service_win_unittest.cc",
"proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc", "proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc",
"proxy_resolution/win/windows_system_proxy_resolver_unittest.cc",
"ssl/client_cert_store_win_unittest.cc", "ssl/client_cert_store_win_unittest.cc",
"ssl/ssl_platform_key_win_unittest.cc", "ssl/ssl_platform_key_win_unittest.cc",
] ]
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "net/base/proxy_delegate.h" #include "net/base/proxy_delegate.h"
#include "net/base/url_util.h" #include "net/base/url_util.h"
#include "net/log/net_log.h" #include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h" #include "net/log/net_log_event_type.h"
#include "net/log/net_log_util.h" #include "net/log/net_log_util.h"
#include "net/log/net_log_with_source.h" #include "net/log/net_log_with_source.h"
......
...@@ -362,6 +362,9 @@ class NET_EXPORT ConfiguredProxyResolutionService ...@@ -362,6 +362,9 @@ class NET_EXPORT ConfiguredProxyResolutionService
base::Optional<ProxyConfigWithAnnotation> fetched_config_; base::Optional<ProxyConfigWithAnnotation> fetched_config_;
base::Optional<ProxyConfigWithAnnotation> config_; base::Optional<ProxyConfigWithAnnotation> config_;
// The time when the proxy configuration was last read from the system.
base::TimeTicks config_last_update_time_;
// Map of the known bad proxies and the information about the retry time. // Map of the known bad proxies and the information about the retry time.
ProxyRetryInfoMap proxy_retry_info_; ProxyRetryInfoMap proxy_retry_info_;
......
...@@ -4,167 +4,15 @@ ...@@ -4,167 +4,15 @@
#include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h" #include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h"
#include <utility>
#include "net/base/net_errors.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/proxy_resolution/proxy_list.h"
#include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h"
#include "net/proxy_resolution/win/windows_system_proxy_resolver.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net { namespace net {
namespace { WindowsSystemProxyResolutionRequest::WindowsSystemProxyResolutionRequest() =
default;
constexpr net::NetworkTrafficAnnotationTag kWindowsResolverTrafficAnnotation = WindowsSystemProxyResolutionRequest::~WindowsSystemProxyResolutionRequest() =
net::DefineNetworkTrafficAnnotation("proxy_config_windows_resolver", R"( default;
semantics {
sender: "Proxy Config for Windows System Resolver"
description:
"Establishing a connection through a proxy server using system proxy "
"settings and Windows system proxy resolution code."
trigger:
"Whenever a network request is made when the system proxy settings "
"are used, the Windows system proxy resolver is enabled, and the "
"result indicates usage of a proxy server."
data:
"Proxy configuration."
destination: OTHER
destination_other:
"The proxy server specified in the configuration."
}
policy {
cookies_allowed: NO
setting:
"User cannot override system proxy settings, but can change them "
"through 'Advanced/System/Open proxy settings'."
policy_exception_justification:
"Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' "
"policies can set Chrome to use a specific proxy settings and avoid "
"system proxy."
})");
} // namespace
WindowsSystemProxyResolutionRequest::WindowsSystemProxyResolutionRequest(
WindowsSystemProxyResolutionService* service,
const GURL& url,
const std::string& method,
ProxyInfo* results,
CompletionOnceCallback user_callback,
const NetLogWithSource& net_log,
scoped_refptr<WindowsSystemProxyResolver> windows_system_proxy_resolver)
: windows_system_proxy_resolver_(windows_system_proxy_resolver),
service_(service),
user_callback_(std::move(user_callback)),
results_(results),
url_(url),
method_(method),
net_log_(net_log),
creation_time_(base::TimeTicks::Now()) {
DCHECK(!user_callback_.is_null());
DCHECK(windows_system_proxy_resolver_);
}
WindowsSystemProxyResolutionRequest::~WindowsSystemProxyResolutionRequest() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (service_) {
service_->RemovePendingRequest(this);
net_log_.AddEvent(NetLogEventType::CANCELLED);
if (IsStarted())
CancelResolveJob();
net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
}
}
LoadState WindowsSystemProxyResolutionRequest::GetLoadState() const { LoadState WindowsSystemProxyResolutionRequest::GetLoadState() const {
// TODO(https://crbug.com/1032820): Consider adding a LoadState for "We're return LOAD_STATE_IDLE;
// waiting on system APIs to do their thing".
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
}
int WindowsSystemProxyResolutionRequest::Start() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!was_completed());
DCHECK(!IsStarted());
// Kicks off an asynchronous call that'll eventually call back into
// AsynchronousProxyResolutionComplete() with a result.
if (!windows_system_proxy_resolver_->GetProxyForUrl(this, url_.spec()))
return ERR_FAILED;
// Asynchronous proxy resolution has begun.
return ERR_IO_PENDING;
}
void WindowsSystemProxyResolutionRequest::CancelResolveJob() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(IsStarted());
// The request may already be running in the resolver.
// TODO(https://crbug.com/1032820): Cancel callback instead of just ignoring
// it.
windows_system_proxy_resolver_->RemovePendingCallbackTarget(this);
DCHECK(!IsStarted());
}
bool WindowsSystemProxyResolutionRequest::IsStarted() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return windows_system_proxy_resolver_->HasPendingCallbackTarget(this);
}
int WindowsSystemProxyResolutionRequest::UpdateResultsOnProxyResolutionComplete(
const ProxyList& proxy_list,
int net_error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!was_completed());
results_->UseProxyList(proxy_list);
// Make sure IsStarted() returns false while DidFinishResolvingProxy() runs.
windows_system_proxy_resolver_->RemovePendingCallbackTarget(this);
// Note that DidFinishResolvingProxy might modify |results_|.
const int updated_result = service_->DidFinishResolvingProxy(
url_, method_, results_, net_error, net_log_);
// Make a note in the results which configuration was in use at the
// time of the resolve.
results_->set_proxy_resolve_start_time(creation_time_);
results_->set_proxy_resolve_end_time(base::TimeTicks::Now());
results_->set_traffic_annotation(
MutableNetworkTrafficAnnotationTag(kWindowsResolverTrafficAnnotation));
return updated_result;
}
int WindowsSystemProxyResolutionRequest::SynchronousProxyResolutionComplete(
int net_error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ProxyList proxy_list;
const int updated_result =
UpdateResultsOnProxyResolutionComplete(proxy_list, net_error);
service_ = nullptr;
return updated_result;
}
void WindowsSystemProxyResolutionRequest::AsynchronousProxyResolutionComplete(
const ProxyList& proxy_list,
int net_error,
int windows_error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(https://crbug.com/1032820): Log Windows error |windows_error|.
net_error = UpdateResultsOnProxyResolutionComplete(proxy_list, net_error);
CompletionOnceCallback callback = std::move(user_callback_);
service_->RemovePendingRequest(this);
service_ = nullptr;
user_callback_.Reset();
std::move(callback).Run(net_error);
} }
} // namespace net } // namespace net
...@@ -5,40 +5,17 @@ ...@@ -5,40 +5,17 @@
#ifndef NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_ #ifndef NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_
#define NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_ #define NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_
#include <memory>
#include <string>
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/base/network_isolation_key.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_resolution_request.h" #include "net/proxy_resolution/proxy_resolution_request.h"
#include "url/gurl.h"
namespace net { namespace net {
class ProxyInfo;
class ProxyList;
class WindowsSystemProxyResolutionService;
class WindowsSystemProxyResolver;
// This is the concrete implementation of ProxyResolutionRequest used by // This is the concrete implementation of ProxyResolutionRequest used by
// WindowsSystemProxyResolutionService. Manages a single asynchronous proxy // WindowsSystemProxyResolutionService. Manages a single asynchronous proxy
// resolution request. // resolution request.
class NET_EXPORT WindowsSystemProxyResolutionRequest class WindowsSystemProxyResolutionRequest final
: public ProxyResolutionRequest { : public ProxyResolutionRequest {
public: public:
WindowsSystemProxyResolutionRequest( WindowsSystemProxyResolutionRequest();
WindowsSystemProxyResolutionService* service,
const GURL& url,
const std::string& method,
ProxyInfo* results,
const CompletionOnceCallback user_callback,
const NetLogWithSource& net_log,
scoped_refptr<WindowsSystemProxyResolver> windows_system_proxy_resolver);
WindowsSystemProxyResolutionRequest( WindowsSystemProxyResolutionRequest(
const WindowsSystemProxyResolutionRequest&) = delete; const WindowsSystemProxyResolutionRequest&) = delete;
...@@ -47,62 +24,7 @@ class NET_EXPORT WindowsSystemProxyResolutionRequest ...@@ -47,62 +24,7 @@ class NET_EXPORT WindowsSystemProxyResolutionRequest
~WindowsSystemProxyResolutionRequest() override; ~WindowsSystemProxyResolutionRequest() override;
// ProxyResolutionRequest
LoadState GetLoadState() const override; LoadState GetLoadState() const override;
// Starts the resolve proxy request.
int Start();
// Cancels the callback from the resolver for a previously started proxy
// resolution.
void CancelResolveJob();
bool IsStarted();
// Returns true if the request has been completed.
bool was_completed() const { return user_callback_.is_null(); }
// Helper to call after ProxyResolver completion (both synchronous and
// asynchronous). Fixes up the result that is to be returned to user.
int UpdateResultsOnProxyResolutionComplete(const ProxyList& proxy_list,
int net_error);
// Helper to call if the request completes synchronously, since in that case
// the request will not be added to |pending_requests_| (in
// WindowsSystemProxyResolutionService).
int SynchronousProxyResolutionComplete(int net_error);
// Callback for when the WinHttp request has completed. This is the main way
// that proxy resolutions will complete. The |proxy_list| is the list of
// proxies returned by WinHttp translated into Chromium-friendly terms. The
// |net_error| describes the status of the proxy resolution request. If
// WinHttp fails for some reason, |windows_error| contains the specific error
// returned by WinHttp.
virtual void AsynchronousProxyResolutionComplete(const ProxyList& proxy_list,
int net_error,
int windows_error);
protected:
// The resolver will do the work of talking to system APIs and translating the
// results into something Chromium understands.
scoped_refptr<WindowsSystemProxyResolver> windows_system_proxy_resolver_;
private:
// Note that Request holds a bare pointer to the
// WindowsSystemProxyResolutionService. Outstanding requests are cancelled
// during ~WindowsSystemProxyResolutionService, so this is guaranteed to be
// valid throughout the lifetime of this object.
WindowsSystemProxyResolutionService* service_;
CompletionOnceCallback user_callback_;
ProxyInfo* results_;
const GURL url_;
const std::string method_;
NetLogWithSource net_log_;
// Time when the request was created. Stored here rather than in |results_|
// because the time in |results_| will be cleared.
base::TimeTicks creation_time_;
SEQUENCE_CHECKER(sequence_checker_);
}; };
} // namespace net } // namespace net
......
...@@ -4,37 +4,15 @@ ...@@ -4,37 +4,15 @@
#include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h" #include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h"
#include <utility>
#include "base/values.h" #include "base/values.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h"
#include "net/proxy_resolution/win/windows_system_proxy_resolver.h"
namespace net { namespace net {
WindowsSystemProxyResolutionService::WindowsSystemProxyResolutionService( WindowsSystemProxyResolutionService::WindowsSystemProxyResolutionService() =
NetLog* net_log) default;
: create_proxy_resolver_function_for_testing_(nullptr), net_log_(net_log) {} WindowsSystemProxyResolutionService::~WindowsSystemProxyResolutionService() =
default;
WindowsSystemProxyResolutionService::~WindowsSystemProxyResolutionService() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Cancel any in-progress requests.
// This cancels the internal requests, but leaves the responsibility of
// canceling the high-level Request (by deleting it) to the client.
// Since |pending_requests_| might be modified in one of the requests'
// callbacks (if it deletes another request), iterating through the set in a
// for-loop will not work.
while (!pending_requests_.empty()) {
WindowsSystemProxyResolutionRequest* req = *pending_requests_.begin();
ProxyList empty_list;
req->AsynchronousProxyResolutionComplete(empty_list, ERR_ABORTED, 0);
pending_requests_.erase(req);
}
}
int WindowsSystemProxyResolutionService::ResolveProxy( int WindowsSystemProxyResolutionService::ResolveProxy(
const GURL& url, const GURL& url,
...@@ -44,64 +22,26 @@ int WindowsSystemProxyResolutionService::ResolveProxy( ...@@ -44,64 +22,26 @@ int WindowsSystemProxyResolutionService::ResolveProxy(
CompletionOnceCallback callback, CompletionOnceCallback callback,
std::unique_ptr<ProxyResolutionRequest>* request, std::unique_ptr<ProxyResolutionRequest>* request,
const NetLogWithSource& net_log) { const NetLogWithSource& net_log) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return ERR_NOT_IMPLEMENTED;
DCHECK(!callback.is_null());
DCHECK(request);
net_log.BeginEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
// TODO(https://crbug.com/1032820): Use a more detailed error.
if (!CreateWindowsSystemProxyResolverIfNeeded())
return DidFinishResolvingProxy(url, method, results, ERR_FAILED, net_log);
auto req = std::make_unique<WindowsSystemProxyResolutionRequest>(
this, url, method, results, std::move(callback), net_log,
windows_system_proxy_resolver_);
const int net_error = req->Start();
if (net_error != ERR_IO_PENDING)
return req->SynchronousProxyResolutionComplete(net_error);
DCHECK(!ContainsPendingRequest(req.get()));
pending_requests_.insert(req.get());
// Completion will be notified through |callback|, unless the caller cancels
// the request using |request|.
*request = std::move(req);
return net_error;
} }
void WindowsSystemProxyResolutionService::ReportSuccess( void WindowsSystemProxyResolutionService::ReportSuccess(
const ProxyInfo& proxy_info) { const ProxyInfo& proxy_info) {}
// TODO(https://crbug.com/1032820): Update proxy retry info with new proxy
// resolution data.
}
void WindowsSystemProxyResolutionService::SetProxyDelegate( void WindowsSystemProxyResolutionService::SetProxyDelegate(
ProxyDelegate* delegate) { ProxyDelegate* delegate) {}
// TODO(https://crbug.com/1032820): Implement proxy delegates.
}
void WindowsSystemProxyResolutionService::OnShutdown() { void WindowsSystemProxyResolutionService::OnShutdown() {}
// TODO(https://crbug.com/1032820): Add cleanup here as necessary. If cleanup
// is unnecessary, update the interface to not require an implementation for
// this so OnShutdown() can be removed.
}
bool WindowsSystemProxyResolutionService::MarkProxiesAsBadUntil( bool WindowsSystemProxyResolutionService::MarkProxiesAsBadUntil(
const ProxyInfo& results, const ProxyInfo& results,
base::TimeDelta retry_delay, base::TimeDelta retry_delay,
const std::vector<ProxyServer>& additional_bad_proxies, const std::vector<ProxyServer>& additional_bad_proxies,
const NetLogWithSource& net_log) { const NetLogWithSource& net_log) {
// TODO(https://crbug.com/1032820): Implement bad proxy cache. We should be
// able to share logic with the ConfiguredProxyResolutionService to accomplish
// this.
return false; return false;
} }
void WindowsSystemProxyResolutionService::ClearBadProxiesCache() { void WindowsSystemProxyResolutionService::ClearBadProxiesCache() {}
proxy_retry_info_.clear();
}
const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info() const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info()
const { const {
...@@ -110,7 +50,6 @@ const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info() ...@@ -110,7 +50,6 @@ const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info()
base::Value WindowsSystemProxyResolutionService::GetProxyNetLogValues( base::Value WindowsSystemProxyResolutionService::GetProxyNetLogValues(
int info_sources) { int info_sources) {
// TODO (https://crbug.com/1032820): Implement net logs.
base::Value net_info_dict(base::Value::Type::DICTIONARY); base::Value net_info_dict(base::Value::Type::DICTIONARY);
return net_info_dict; return net_info_dict;
} }
...@@ -123,66 +62,4 @@ bool WindowsSystemProxyResolutionService:: ...@@ -123,66 +62,4 @@ bool WindowsSystemProxyResolutionService::
return false; return false;
} }
void WindowsSystemProxyResolutionService::
SetCreateWindowsSystemProxyResolverFunctionForTesting(
CreateWindowsSystemProxyResolverFunctionForTesting function) {
create_proxy_resolver_function_for_testing_ = function;
}
void WindowsSystemProxyResolutionService::
SetWindowsSystemProxyResolverForTesting(
scoped_refptr<WindowsSystemProxyResolver>
windows_system_proxy_resolver) {
windows_system_proxy_resolver_ = windows_system_proxy_resolver;
}
bool WindowsSystemProxyResolutionService::ContainsPendingRequest(
WindowsSystemProxyResolutionRequest* req) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return pending_requests_.count(req) == 1;
}
void WindowsSystemProxyResolutionService::RemovePendingRequest(
WindowsSystemProxyResolutionRequest* req) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(ContainsPendingRequest(req));
pending_requests_.erase(req);
}
bool WindowsSystemProxyResolutionService::
CreateWindowsSystemProxyResolverIfNeeded() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (windows_system_proxy_resolver_)
return true;
if (create_proxy_resolver_function_for_testing_) {
windows_system_proxy_resolver_ =
create_proxy_resolver_function_for_testing_();
} else {
windows_system_proxy_resolver_ =
WindowsSystemProxyResolver::CreateWindowsSystemProxyResolver();
}
return !!windows_system_proxy_resolver_;
}
int WindowsSystemProxyResolutionService::DidFinishResolvingProxy(
const GURL& url,
const std::string& method,
ProxyInfo* result,
int result_code,
const NetLogWithSource& net_log) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(https://crbug.com/1032820): Implement net logs.
// TODO(https://crbug.com/1032820): Implement proxy delegate.
// TODO(https://crbug.com/1032820): Implement proxy retry info.
if (result_code != OK)
result->UseDirect();
net_log.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
return OK;
}
} // namespace net } // namespace net
...@@ -7,24 +7,12 @@ ...@@ -7,24 +7,12 @@
#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/proxy_resolution/proxy_resolution_service.h"
#include <memory>
#include <set>
#include <string> #include <string>
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "net/base/net_export.h" #include "net/base/net_export.h"
namespace net { namespace net {
class NetLog;
class WindowsSystemProxyResolutionRequest;
class WindowsSystemProxyResolver;
using CreateWindowsSystemProxyResolverFunctionForTesting =
scoped_refptr<WindowsSystemProxyResolver> (*)();
// This class decides which proxy server(s) to use for a particular URL request. // This class decides which proxy server(s) to use for a particular URL request.
// It does NOT support passing in fetched proxy configurations. Instead, it // It does NOT support passing in fetched proxy configurations. Instead, it
// relies entirely on WinHttp APIs to determine the proxy that should be used // relies entirely on WinHttp APIs to determine the proxy that should be used
...@@ -32,7 +20,7 @@ using CreateWindowsSystemProxyResolverFunctionForTesting = ...@@ -32,7 +20,7 @@ using CreateWindowsSystemProxyResolverFunctionForTesting =
class NET_EXPORT WindowsSystemProxyResolutionService class NET_EXPORT WindowsSystemProxyResolutionService
: public ProxyResolutionService { : public ProxyResolutionService {
public: public:
explicit WindowsSystemProxyResolutionService(NetLog* net_log); WindowsSystemProxyResolutionService();
WindowsSystemProxyResolutionService( WindowsSystemProxyResolutionService(
const WindowsSystemProxyResolutionService&) = delete; const WindowsSystemProxyResolutionService&) = delete;
...@@ -64,57 +52,9 @@ class NET_EXPORT WindowsSystemProxyResolutionService ...@@ -64,57 +52,9 @@ class NET_EXPORT WindowsSystemProxyResolutionService
ConfiguredProxyResolutionService** configured_proxy_resolution_service) ConfiguredProxyResolutionService** configured_proxy_resolution_service)
override WARN_UNUSED_RESULT; override WARN_UNUSED_RESULT;
// Used in tests to provide a fake |windows_system_proxy_resolver_|.
void SetCreateWindowsSystemProxyResolverFunctionForTesting(
CreateWindowsSystemProxyResolverFunctionForTesting function);
void SetWindowsSystemProxyResolverForTesting(
scoped_refptr<WindowsSystemProxyResolver> windows_system_proxy_resolver);
private: private:
friend class WindowsSystemProxyResolutionRequest;
friend class WindowsSystemProxyResolutionServiceTest;
typedef std::set<WindowsSystemProxyResolutionRequest*> PendingRequests;
bool ContainsPendingRequest(WindowsSystemProxyResolutionRequest* req)
WARN_UNUSED_RESULT;
void RemovePendingRequest(WindowsSystemProxyResolutionRequest* req);
// Lazily creates |windows_system_proxy_resolver_|.
bool CreateWindowsSystemProxyResolverIfNeeded() WARN_UNUSED_RESULT;
size_t PendingRequestSizeForTesting() const {
return pending_requests_.size();
}
// Called when proxy resolution has completed (either synchronously or
// asynchronously). Handles logging the result, and cleaning out
// bad entries from the results list.
int DidFinishResolvingProxy(const GURL& url,
const std::string& method,
ProxyInfo* result,
int result_code,
const NetLogWithSource& net_log);
CreateWindowsSystemProxyResolverFunctionForTesting
create_proxy_resolver_function_for_testing_;
// Map of the known bad proxies and the information about the retry time. // Map of the known bad proxies and the information about the retry time.
ProxyRetryInfoMap proxy_retry_info_; ProxyRetryInfoMap proxy_retry_info_;
// Set of pending/in-progress requests.
PendingRequests pending_requests_;
// This is the log for any generated events.
NetLog* net_log_;
// This object encapsulates all WinHttp logic in Chromium-friendly terms. It
// manages the lifetime of the WinHttp session (which is
// per-resolution-service). This will get handed off to individual resolution
// requests so that they can query/cancel proxy resolution as needed.
scoped_refptr<WindowsSystemProxyResolver> windows_system_proxy_resolver_;
SEQUENCE_CHECKER(sequence_checker_);
}; };
} // namespace net } // namespace net
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLVER_H_
#define NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLVER_H_
#include <windows.h>
#include <winhttp.h>
#include <memory>
#include <string>
#include <unordered_map>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/proxy_list.h"
namespace net {
class WindowsSystemProxyResolutionRequest;
class WinHttpAPIWrapper;
// This provides a layer of abstraction between calling code Windows-specific
// code. It is shared between the WindowsSystemProxyResolutionService and
// inflight WinHttp callbacks. Internally, it takes care of all interaction with
// WinHttp. The only time this object is ever access outside of its sequence is
// during the WinHttp callback. For the sake of that callback, this must be
// RefcountedThreadSafe.
class NET_EXPORT WindowsSystemProxyResolver
: public base::RefCountedThreadSafe<WindowsSystemProxyResolver> {
public:
static scoped_refptr<WindowsSystemProxyResolver>
CreateWindowsSystemProxyResolver();
WindowsSystemProxyResolver(const WindowsSystemProxyResolver&) = delete;
WindowsSystemProxyResolver& operator=(const WindowsSystemProxyResolver&) =
delete;
// This will first fetch the current system proxy settings by calling into
// WinHttpGetIEProxyConfigForCurrentUser() and then resolve the proxy using
// those settings as an input into WinHttpGetProxyForUrlEx().
virtual bool GetProxyForUrl(
WindowsSystemProxyResolutionRequest* callback_target,
const std::string& url) WARN_UNUSED_RESULT;
// After calling GetProxyForUrl(), a |callback_target| is saved internally for
// when proxy resolution is complete. When a
// WindowsSystemProxyResolutionRequest wants to avoid receiving a callback,
// it must remove itself from the list of pending callback targets.
virtual void RemovePendingCallbackTarget(
WindowsSystemProxyResolutionRequest* callback_target);
virtual bool HasPendingCallbackTarget(
WindowsSystemProxyResolutionRequest* callback_target) const
WARN_UNUSED_RESULT;
protected:
explicit WindowsSystemProxyResolver(
std::unique_ptr<WinHttpAPIWrapper> winhttp_api_wrapper);
virtual ~WindowsSystemProxyResolver();
private:
friend class base::RefCountedThreadSafe<WindowsSystemProxyResolver>;
friend class WindowsSystemProxyResolverTest;
// Sets up the WinHttp session that will be used throughout the lifetime of
// this object.
bool Initialize();
// These will interact with |pending_callback_target_map_|.
void AddPendingCallbackTarget(
WindowsSystemProxyResolutionRequest* callback_target,
HINTERNET handle);
WindowsSystemProxyResolutionRequest* LookupCallbackTargetFromResolverHandle(
HINTERNET resolver_handle) const;
// This is the callback provided to WinHttp. Once a call to resolve a proxy
// succeeds or errors out, it'll call into here with |context| being a pointer
// to a WindowsSystemProxyResolver that has been kept alive. This callback can
// hit in any thread and will immediately post a task to the right sequence.
static void __stdcall WinHttpStatusCallback(HINTERNET resolver_handle,
DWORD_PTR context,
DWORD status,
void* info,
DWORD info_len);
// Called from WinHttpStatusCallback on the right sequence. This will make
// decisions about what to do from the results of the proxy resolution call.
// Note that the WindowsSystemProxyResolutionRequest that asked for this proxy
// may have decided they no longer need an answer (ex: the request has gone
// away), so this function has to deal with that situation too.
void DoWinHttpStatusCallback(HINTERNET resolver_handle,
DWORD status,
int windows_error);
// On a successful call to WinHttpGetProxyForUrlEx(), this translates WinHttp
// results into Chromium-friendly structures before notifying the right
// WindowsSystemProxyResolutionRequest.
void GetProxyResultForCallbackTarget(
WindowsSystemProxyResolutionRequest* callback_target,
HINTERNET resolver_handle);
// On a failed call to WinHttpGetProxyForUrlEx(), this will notify the right
// WindowsSystemProxyResolutionRequest of the error.
void HandleErrorForCallbackTarget(
WindowsSystemProxyResolutionRequest* callback_target,
int windows_error);
// This is a thin wrapper over WinHttp APIs that may be overridden for
// testing.
std::unique_ptr<WinHttpAPIWrapper> winhttp_api_wrapper_;
// This is the mapping of WindowsSystemProxyResolutionRequest objects that
// called GetProxyForUrl() to the handle that's being used for their proxy
// resolution call. Upon receiving a callback from WinHttp (which includes an
// HINTERNET handle), a reverse lookup here will get the right
// WindowsSystemProxyResolutionRequest to use.
std::unordered_map<WindowsSystemProxyResolutionRequest*, HINTERNET>
pending_callback_target_map_;
SEQUENCE_CHECKER(sequence_checker_);
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
};
} // namespace net
#endif // NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLVER_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/proxy_resolution/win/winhttp_api_wrapper.h"
#include <utility>
#include "base/check_op.h"
#include "base/macros.h"
#include "base/strings/string16.h"
namespace net {
// TODO(https://crbug.com/1032820): Capture telemetry for WinHttp APIs if
// interesting.
ScopedIEConfig::ScopedIEConfig() = default;
ScopedIEConfig::~ScopedIEConfig() {
if (ie_config.lpszAutoConfigUrl)
GlobalFree(ie_config.lpszAutoConfigUrl);
if (ie_config.lpszProxy)
GlobalFree(ie_config.lpszProxy);
if (ie_config.lpszProxyBypass)
GlobalFree(ie_config.lpszProxyBypass);
}
WinHttpAPIWrapper::WinHttpAPIWrapper() = default;
WinHttpAPIWrapper::~WinHttpAPIWrapper() {
if (session_handle_)
ignore_result(CallWinHttpSetStatusCallback(nullptr));
CloseSessionHandle();
}
bool WinHttpAPIWrapper::CallWinHttpOpen() {
DCHECK_EQ(nullptr, session_handle_);
session_handle_ =
WinHttpOpen(nullptr, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC);
return (session_handle_ != nullptr);
}
bool WinHttpAPIWrapper::CallWinHttpSetTimeouts(int resolve_timeout,
int connect_timeout,
int send_timeout,
int receive_timeout) {
DCHECK_NE(nullptr, session_handle_);
return (!!WinHttpSetTimeouts(session_handle_, resolve_timeout,
connect_timeout, send_timeout, receive_timeout));
}
bool WinHttpAPIWrapper::CallWinHttpSetStatusCallback(
WINHTTP_STATUS_CALLBACK internet_callback) {
DCHECK_NE(nullptr, session_handle_);
const WINHTTP_STATUS_CALLBACK winhttp_status_callback =
WinHttpSetStatusCallback(
session_handle_, internet_callback,
WINHTTP_CALLBACK_FLAG_REQUEST_ERROR |
WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE,
0);
return (winhttp_status_callback != WINHTTP_INVALID_STATUS_CALLBACK);
}
bool WinHttpAPIWrapper::CallWinHttpGetIEProxyConfigForCurrentUser(
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_proxy_config) {
return !!WinHttpGetIEProxyConfigForCurrentUser(ie_proxy_config);
}
bool WinHttpAPIWrapper::CallWinHttpCreateProxyResolver(
HINTERNET* out_resolver_handle) {
DCHECK_NE(nullptr, session_handle_);
const DWORD result =
WinHttpCreateProxyResolver(session_handle_, out_resolver_handle);
return (result == ERROR_SUCCESS);
}
bool WinHttpAPIWrapper::CallWinHttpGetProxyForUrlEx(
HINTERNET resolver_handle,
const std::string& url,
WINHTTP_AUTOPROXY_OPTIONS* autoproxy_options,
DWORD_PTR context) {
const base::string16 wide_url(url.begin(), url.end());
// TODO(https://crbug.com/1032820): Upgrade to WinHttpGetProxyForUrlEx2()
// if there is a clear reason to do so.
const DWORD result = WinHttpGetProxyForUrlEx(resolver_handle, wide_url.data(),
autoproxy_options, context);
return (result == ERROR_IO_PENDING);
}
bool WinHttpAPIWrapper::CallWinHttpGetProxyResult(
HINTERNET resolver_handle,
WINHTTP_PROXY_RESULT* proxy_result) {
const DWORD result = WinHttpGetProxyResult(resolver_handle, proxy_result);
return (result == ERROR_SUCCESS);
}
VOID WinHttpAPIWrapper::CallWinHttpFreeProxyResult(
WINHTTP_PROXY_RESULT* proxy_result) {
WinHttpFreeProxyResult(proxy_result);
}
void WinHttpAPIWrapper::CallWinHttpCloseHandle(HINTERNET internet_handle) {
WinHttpCloseHandle(internet_handle);
}
void WinHttpAPIWrapper::CloseSessionHandle() {
if (session_handle_) {
CallWinHttpCloseHandle(session_handle_);
session_handle_ = nullptr;
}
}
} // namespace net
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_PROXY_RESOLUTION_WIN_WINHTTP_API_WRAPPER_H_
#define NET_PROXY_RESOLUTION_WIN_WINHTTP_API_WRAPPER_H_
#include <windows.h>
#include <winhttp.h>
#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
namespace net {
// This is a utility class that encapsulates the memory management necessary for
// WINHTTP_CURRENT_USER_IE_PROXY_CONFIG in RAII style.
class ScopedIEConfig final {
public:
ScopedIEConfig();
ScopedIEConfig(const ScopedIEConfig&) = delete;
ScopedIEConfig& operator=(const ScopedIEConfig&) = delete;
~ScopedIEConfig();
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config() { return &ie_config; }
private:
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
};
// This provides a layer of abstraction between calling code and WinHTTP APIs,
// allowing them to be mocked out for testing. This object is not thread safe
// and it's expected that the caller will handle using it on the same thread or
// sequence. In general, documentation for these APIs can be found here:
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/
class NET_EXPORT WinHttpAPIWrapper {
public:
WinHttpAPIWrapper();
WinHttpAPIWrapper(const WinHttpAPIWrapper&) = delete;
WinHttpAPIWrapper& operator=(const WinHttpAPIWrapper&) = delete;
virtual ~WinHttpAPIWrapper();
// Creates our WinHttp session handle |session_handle_|. The lifetime of that
// session handle is determined by the lifetime of this object. It'll get
// closed when this object destructs.
virtual bool CallWinHttpOpen() WARN_UNUSED_RESULT;
// Controls the timeout for WinHttpGetProxyForUrlEx().
virtual bool CallWinHttpSetTimeouts(int resolve_timeout,
int connect_timeout,
int send_timeout,
int receive_timeout) WARN_UNUSED_RESULT;
// Sets the callback WinHttp will call into with the result of any
// asynchronous call.
virtual bool CallWinHttpSetStatusCallback(
WINHTTP_STATUS_CALLBACK internet_callback) WARN_UNUSED_RESULT;
// Fetches the proxy configs for the current active network connection and
// current Windows user. The |ie_proxy_config| says whether or not
// AutoProxy (WPAD) is enabled and if there's a PAC URL configured for this
// connection/user.
virtual bool CallWinHttpGetIEProxyConfigForCurrentUser(
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_proxy_config) WARN_UNUSED_RESULT;
// Creates a handle |resolver_handle| that should be used for the call to
// WinHttpGetProxyForUrlEx().
virtual bool CallWinHttpCreateProxyResolver(HINTERNET* out_resolver_handle)
WARN_UNUSED_RESULT;
// Using the specific |resolver_handle| handle from
// CallWinHttpCreateProxyResolver(), resolve a proxy for a specific |url| with
// the aid of some |autoproxy_options|. When WinHttpGetProxyForUrlEx()
// finishes its work or hits an error, it'll call into the callback set by
// CallWinHttpSetStatusCallback() above exactly once and supply the provided
// |context|.
//
// WinHttpGetProxyForUrlEx() will go async to do all necessary logic. As long
// as it receives good inputs (valid handle, valid combination of flags,
// non-null PAC URL if needed), this API will almost always return
// ERROR_IO_PENDING. It'll only fail for reasons like running out of memory.
// When it returns ERROR_IO_PENDING, CallWinHttpGetProxyForUrlEx() will return
// true.
//
// WinHttpGetProxyForUrlEx() will do proxy fallback internally and return to
// a proxy result. It will first check WPAD (if enabled). If that fails, it'll
// attempt to download and run any provided PAC script. If the PAC script was
// not provided or if it fails, it'll use the right per-interface static
// proxy. If all else fails or isn't configured, it'll simply return DIRECT.
// WinHttpGetProxyForUrlEx() supports commonly used enterprise proxy features
// such as DirectAccess/NRPT.
virtual bool CallWinHttpGetProxyForUrlEx(
HINTERNET resolver_handle,
const std::string& url,
WINHTTP_AUTOPROXY_OPTIONS* autoproxy_options,
DWORD_PTR context) WARN_UNUSED_RESULT;
// As long as CallWinHttpGetProxyForUrlEx() doesn't hit any errors, there will
// be a proxy result to examine. This function retrieves that proxy resolution
// result |proxy_result| using the resolver's handle |resolver_handle|. The
// result must be freed with CallWinHttpFreeProxyResult().
virtual bool CallWinHttpGetProxyResult(HINTERNET resolver_handle,
WINHTTP_PROXY_RESULT* proxy_result)
WARN_UNUSED_RESULT;
// Frees the |proxy_result| retrieved by CallWinHttpGetProxyResult().
virtual void CallWinHttpFreeProxyResult(WINHTTP_PROXY_RESULT* proxy_result);
// Every opened HINTERNET handle must be closed. This closes handle
// |internet_handle|. After being closed, WinHttp calls cannot be made using
// that handle.
virtual void CallWinHttpCloseHandle(HINTERNET internet_handle);
private:
// Closes |session_handle_|.
void CloseSessionHandle();
HINTERNET session_handle_ = nullptr;
};
} // namespace net
#endif // NET_PROXY_RESOLUTION_WIN_WINHTTP_API_WRAPPER_H_
...@@ -238,7 +238,6 @@ Refer to README.md for content description and update process. ...@@ -238,7 +238,6 @@ Refer to README.md for content description and update process.
<item id="proxy_config_headless" hash_code="133221587" type="0" content_hash_code="77459277" os_list="linux,windows" file_path="headless/lib/browser/headless_request_context_manager.cc"/> <item id="proxy_config_headless" hash_code="133221587" type="0" content_hash_code="77459277" os_list="linux,windows" file_path="headless/lib/browser/headless_request_context_manager.cc"/>
<item id="proxy_config_settings" hash_code="136468456" type="0" content_hash_code="19527377" os_list="linux,windows" file_path="components/proxy_config/pref_proxy_config_tracker_impl.cc"/> <item id="proxy_config_settings" hash_code="136468456" type="0" content_hash_code="19527377" os_list="linux,windows" file_path="components/proxy_config/pref_proxy_config_tracker_impl.cc"/>
<item id="proxy_config_system" hash_code="11258689" type="0" content_hash_code="77057929" os_list="linux,windows" file_path="net/proxy_resolution/configured_proxy_resolution_service.cc"/> <item id="proxy_config_system" hash_code="11258689" type="0" content_hash_code="77057929" os_list="linux,windows" file_path="net/proxy_resolution/configured_proxy_resolution_service.cc"/>
<item id="proxy_config_windows_resolver" hash_code="13924805" type="0" content_hash_code="123023599" os_list="windows" file_path="net/proxy_resolution/win/windows_system_proxy_resolution_request.cc"/>
<item id="proxy_script_fetcher" hash_code="37531401" type="0" deprecated="2018-03-16" content_hash_code="31866133" file_path=""/> <item id="proxy_script_fetcher" hash_code="37531401" type="0" deprecated="2018-03-16" content_hash_code="31866133" file_path=""/>
<item id="puch_client_channel" hash_code="34459548" type="0" deprecated="2020-01-23" content_hash_code="92475475" file_path=""/> <item id="puch_client_channel" hash_code="34459548" type="0" deprecated="2020-01-23" content_hash_code="92475475" file_path=""/>
<item id="qr_code_save" hash_code="87963126" type="0" content_hash_code="72717245" os_list="linux,windows" file_path="chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc"/> <item id="qr_code_save" hash_code="87963126" type="0" content_hash_code="72717245" os_list="linux,windows" file_path="chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment