private void SetRequestHandleProxyOptions(WinHttpRequestState state)
{
// We've already set the proxy on the session handle if we're using no proxy or default proxy settings.
// We only need to change it on the request handle if we have a specific IWebProxy or need to manually
// implement Wininet-style auto proxy detection.
if (state.WindowsProxyUsePolicy == WindowsProxyUsePolicy.UseCustomProxy ||
state.WindowsProxyUsePolicy == WindowsProxyUsePolicy.UseWinInetProxy)
{
var proxyInfo = new Interop.WinHttp.WINHTTP_PROXY_INFO();
bool updateProxySettings = false;
Uri uri = state.RequestMessage.RequestUri;
try
{
if (state.Proxy != null)
{
Debug.Assert(state.WindowsProxyUsePolicy == WindowsProxyUsePolicy.UseCustomProxy);
updateProxySettings = true;
if (state.Proxy.IsBypassed(uri))
{
proxyInfo.AccessType = Interop.WinHttp.WINHTTP_ACCESS_TYPE_NO_PROXY;
}
else
{
proxyInfo.AccessType = Interop.WinHttp.WINHTTP_ACCESS_TYPE_NAMED_PROXY;
Uri proxyUri = state.Proxy.GetProxy(uri);
string proxyString = proxyUri.Scheme + "://" + proxyUri.Authority;
proxyInfo.Proxy = Marshal.StringToHGlobalUni(proxyString);
}
}
else if (_proxyHelper != null && _proxyHelper.AutoSettingsUsed)
{
if (_proxyHelper.GetProxyForUrl(_sessionHandle, uri, out proxyInfo))
{
updateProxySettings = true;
}
}
if (updateProxySettings)
{
GCHandle pinnedHandle = GCHandle.Alloc(proxyInfo, GCHandleType.Pinned);
try
{
SetWinHttpOption(
state.RequestHandle,
Interop.WinHttp.WINHTTP_OPTION_PROXY,
pinnedHandle.AddrOfPinnedObject(),
(uint)Marshal.SizeOf(proxyInfo));
}
finally
{
pinnedHandle.Free();
}
}
}
finally
{
Marshal.FreeHGlobal(proxyInfo.Proxy);
Marshal.FreeHGlobal(proxyInfo.ProxyBypass);
}
}
}