This source file includes following definitions.
- FreeInfo
- session_handle_
- GetProxyForURL
- CancelRequest
- GetLoadState
- CancelSetPacScript
- SetPacScript
- OpenWinHttpSession
- CloseWinHttpSession
#include "net/proxy/proxy_resolver_winhttp.h"
#include <windows.h>
#include <winhttp.h>
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_info.h"
#include "url/gurl.h"
#pragma comment(lib, "winhttp.lib")
using base::TimeDelta;
using base::TimeTicks;
namespace net {
static void FreeInfo(WINHTTP_PROXY_INFO* info) {
if (info->lpszProxy)
GlobalFree(info->lpszProxy);
if (info->lpszProxyBypass)
GlobalFree(info->lpszProxyBypass);
}
ProxyResolverWinHttp::ProxyResolverWinHttp()
: ProxyResolver(false ), session_handle_(NULL) {
}
ProxyResolverWinHttp::~ProxyResolverWinHttp() {
CloseWinHttpSession();
}
int ProxyResolverWinHttp::GetProxyForURL(const GURL& query_url,
ProxyInfo* results,
const CompletionCallback& ,
RequestHandle* ,
const BoundNetLog& ) {
if (!session_handle_ && !OpenWinHttpSession())
return ERR_FAILED;
WINHTTP_AUTOPROXY_OPTIONS options = {0};
options.fAutoLogonIfChallenged = FALSE;
options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
std::wstring pac_url_wide = base::ASCIIToWide(pac_url_.spec());
options.lpszAutoConfigUrl = pac_url_wide.c_str();
WINHTTP_PROXY_INFO info = {0};
DCHECK(session_handle_);
BOOL ok = WinHttpGetProxyForUrl(session_handle_,
base::ASCIIToWide(query_url.spec()).c_str(),
&options, &info);
if (!ok) {
if (ERROR_WINHTTP_LOGIN_FAILURE == GetLastError()) {
options.fAutoLogonIfChallenged = TRUE;
ok = WinHttpGetProxyForUrl(
session_handle_, base::ASCIIToWide(query_url.spec()).c_str(),
&options, &info);
}
if (!ok) {
DWORD error = GetLastError();
if (ERROR_WINHTTP_TIMEOUT == error ||
ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR == error) {
CloseWinHttpSession();
}
return ERR_FAILED;
}
}
int rv = OK;
switch (info.dwAccessType) {
case WINHTTP_ACCESS_TYPE_NO_PROXY:
results->UseDirect();
break;
case WINHTTP_ACCESS_TYPE_NAMED_PROXY:
results->UseNamedProxy(base::UTF16ToASCII(info.lpszProxy));
break;
default:
NOTREACHED();
rv = ERR_FAILED;
}
FreeInfo(&info);
return rv;
}
void ProxyResolverWinHttp::CancelRequest(RequestHandle request) {
NOTREACHED();
}
LoadState ProxyResolverWinHttp::GetLoadState(RequestHandle request) const {
NOTREACHED();
return LOAD_STATE_IDLE;
}
void ProxyResolverWinHttp::CancelSetPacScript() {
NOTREACHED();
}
int ProxyResolverWinHttp::SetPacScript(
const scoped_refptr<ProxyResolverScriptData>& script_data,
const CompletionCallback& ) {
if (script_data->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT) {
pac_url_ = GURL("http://wpad/wpad.dat");
} else {
pac_url_ = script_data->url();
}
return OK;
}
bool ProxyResolverWinHttp::OpenWinHttpSession() {
DCHECK(!session_handle_);
session_handle_ = WinHttpOpen(NULL,
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
if (!session_handle_)
return false;
BOOL rv = WinHttpSetTimeouts(session_handle_, 10000, 10000, 5000, 5000);
DCHECK(rv);
return true;
}
void ProxyResolverWinHttp::CloseWinHttpSession() {
if (session_handle_) {
WinHttpCloseHandle(session_handle_);
session_handle_ = NULL;
}
}
}