/// <summary> /// Gets the proxy URI. (IWebProxy interface) /// </summary> public Uri GetProxy(Uri uri) { if (_proxyHelper.ManualSettingsOnly) { if (_bypassLocal) { IPAddress address = null; if (uri.IsLoopback) { // This is optimization for loopback addresses. // Unfortunately this does not work for all local addresses. return(null); } // Pre-Check if host may be IP address to avoid parsing. if (uri.HostNameType == UriHostNameType.IPv6 || uri.HostNameType == UriHostNameType.IPv4) { // RFC1123 allows labels to start with number. // Leading number may or may not be IP address. // IPv6 [::1] notation. '[' is not valid character in names. if (IPAddress.TryParse(uri.IdnHost, out address)) { // Host is valid IP address. // Check if it belongs to local system. foreach (IPAddress a in _localIp) { if (a.Equals(address)) { return(null); } } } } if (uri.HostNameType != UriHostNameType.IPv6 && !uri.IdnHost.Contains('.')) { // Not address and does not have a dot. // Hosts without FQDN are considered local. return(null); } } // Check if we have other rules for bypass. if (_bypass != null) { foreach (Regex entry in _bypass) { // IdnHost does not have []. if (entry.IsMatch(uri.IdnHost)) { return(null); } } } // We did not find match on bypass list. return((uri.Scheme == UriScheme.Https || uri.Scheme == UriScheme.Wss) ? _secureProxyUri : _insecureProxyUri); } // For anything else ask WinHTTP. To improve performance, we don't call into // WinHTTP if there was a recent failure to detect a PAC file on the network. if (!_proxyHelper.RecentAutoDetectionFailure) { var proxyInfo = new Interop.WinHttp.WINHTTP_PROXY_INFO(); try { if (_proxyHelper.GetProxyForUrl(_sessionHandle, uri, out proxyInfo)) { return(GetUriFromString(Marshal.PtrToStringUni(proxyInfo.Proxy))); } } finally { Marshal.FreeHGlobal(proxyInfo.Proxy); Marshal.FreeHGlobal(proxyInfo.ProxyBypass); } } return(null); }
private static void RequestCallback( IntPtr handle, WinHttpRequestState state, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { try { switch (internetStatus) { case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: OnRequestHandleClosing(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: OnRequestSendRequestComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE: Debug.Assert(statusInformationLength == Marshal.SizeOf <int>()); int bytesAvailable = Marshal.ReadInt32(statusInformation); OnRequestDataAvailable(state, bytesAvailable); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_READ_COMPLETE: OnRequestReadComplete(state, statusInformationLength); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: OnRequestWriteComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: OnRequestReceiveResponseHeadersComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REDIRECT: string redirectUriString = Marshal.PtrToStringUni(statusInformation); var redirectUri = new Uri(redirectUriString); OnRequestRedirect(state, redirectUri); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDING_REQUEST: OnRequestSendingRequest(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: Debug.Assert( statusInformationLength == Marshal.SizeOf <Interop.WinHttp.WINHTTP_ASYNC_RESULT>(), "RequestCallback: statusInformationLength=" + statusInformationLength + " must be sizeof(WINHTTP_ASYNC_RESULT)=" + Marshal.SizeOf <Interop.WinHttp.WINHTTP_ASYNC_RESULT>()); var asyncResult = Marshal.PtrToStructure <Interop.WinHttp.WINHTTP_ASYNC_RESULT>(statusInformation); OnRequestError(state, asyncResult); return; default: return; } } catch (Exception ex) { Interop.WinHttp.WinHttpCloseHandle(handle); state.SavedException = ex; } }