| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/proxy_resolver_win/winhttp_api_wrapper_impl.h" |
| |
| #include <string> |
| #include <tuple> |
| #include <utility> |
| |
| #include "base/check_op.h" |
| |
| namespace proxy_resolver_win { |
| |
| // 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); |
| } |
| |
| WinHttpAPIWrapperImpl::WinHttpAPIWrapperImpl() = default; |
| WinHttpAPIWrapperImpl::~WinHttpAPIWrapperImpl() { |
| if (session_handle_) |
| std::ignore = CallWinHttpSetStatusCallback(nullptr); |
| CloseSessionHandle(); |
| } |
| |
| bool WinHttpAPIWrapperImpl::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 WinHttpAPIWrapperImpl::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 WinHttpAPIWrapperImpl::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 WinHttpAPIWrapperImpl::CallWinHttpGetIEProxyConfigForCurrentUser( |
| WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_proxy_config) { |
| return !!::WinHttpGetIEProxyConfigForCurrentUser(ie_proxy_config); |
| } |
| |
| bool WinHttpAPIWrapperImpl::CallWinHttpCreateProxyResolver( |
| HINTERNET* out_resolver_handle) { |
| DCHECK_NE(nullptr, session_handle_); |
| const DWORD result = |
| ::WinHttpCreateProxyResolver(session_handle_, out_resolver_handle); |
| return (result == ERROR_SUCCESS); |
| } |
| |
| bool WinHttpAPIWrapperImpl::CallWinHttpGetProxyForUrlEx( |
| HINTERNET resolver_handle, |
| const std::string& url, |
| WINHTTP_AUTOPROXY_OPTIONS* autoproxy_options, |
| DWORD_PTR context) { |
| const std::wstring 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 WinHttpAPIWrapperImpl::CallWinHttpGetProxyResult( |
| HINTERNET resolver_handle, |
| WINHTTP_PROXY_RESULT* proxy_result) { |
| const DWORD result = ::WinHttpGetProxyResult(resolver_handle, proxy_result); |
| return (result == ERROR_SUCCESS); |
| } |
| |
| VOID WinHttpAPIWrapperImpl::CallWinHttpFreeProxyResult( |
| WINHTTP_PROXY_RESULT* proxy_result) { |
| WinHttpFreeProxyResult(proxy_result); |
| } |
| |
| void WinHttpAPIWrapperImpl::CallWinHttpCloseHandle(HINTERNET internet_handle) { |
| ::WinHttpCloseHandle(internet_handle); |
| } |
| |
| void WinHttpAPIWrapperImpl::CloseSessionHandle() { |
| if (session_handle_) { |
| CallWinHttpCloseHandle(session_handle_); |
| session_handle_ = nullptr; |
| } |
| } |
| |
| } // namespace proxy_resolver_win |