public AutoConfigActualProxy(bool useAutoDetection, string autoConfigUrl, int timeout = DefaultTimeout) { // argument checks // autoConfigUrl can be null if (useAutoDetection == false && string.IsNullOrEmpty(autoConfigUrl)) { throw new ArgumentException($"Either auto detection mode or auto config file mode must be enabled."); } // open a WinHttp session // give settings for downloading the PAC file: no user agent and no proxy. SafeHINTERNET handle = WinHttpOpen(null, WINHTTP_ACCESS_TYPE_NO_PROXY, null, null, 0); if (handle == null || handle.IsInvalid) { LogWin32Error("WinHttpOpen"); throw new ApplicationException(""); // ToDo: message } // set the timeout if (WinHttpSetTimeouts(handle, timeout, timeout, timeout, timeout) == false) { LogWin32Error("WinHttpSetTimeouts"); // continue (not fatal) } // initialize members this.useAutoDetection = useAutoDetection; this.autoConfigUrl = autoConfigUrl; this.session = handle; return; }
public void WinHttpGetProxyForUrlExTest() { // Use WinHttpOpen to obtain a session handle. using SafeHINTERNET hSession = WinHttpOpen(userAgent, dwFlags: WINHTTP_OPEN_FLAG.WINHTTP_FLAG_ASYNC); Assert.That(hSession, ResultIs.ValidHandle); if (!WinHttpGetIEProxyConfigForCurrentUser(out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG prxCfg)) { Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_FILE_NOT_FOUND); } Assert.That(WinHttpCreateProxyResolver(hSession, out SafeHINTERNET hResolver), ResultIs.Successful); using System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false); Win32Error cbErr = Win32Error.ERROR_SUCCESS; IntPtr prevCb = WinHttpSetStatusCallback(hResolver, callback, WINHTTP_CALLBACK_FLAG.WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG.WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE); Assert.That(prevCb, Is.Not.EqualTo(WINHTTP_INVALID_STATUS_CALLBACK)); WINHTTP_AUTOPROXY_OPTIONS opts; if (prxCfg.fAutoDetect) { opts = new() { dwFlags = WINHTTP_AUTOPROXY.WINHTTP_AUTOPROXY_AUTO_DETECT, dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DNS_A | WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DHCP, fAutoLogonIfChallenged = true, }; // Call WinHttpGetProxyForUrl with our target URL, then set the proxy info on the request handle. Assert.That(WinHttpGetProxyForUrlEx(hResolver, "https://www.microsoft.com/ms.htm", opts), Is.EqualTo((Win32Error)Win32Error.ERROR_IO_PENDING)); } evt.WaitOne(5000); Assert.That(cbErr, ResultIs.Successful); void callback(HINTERNET hInternet, IntPtr dwContext, WINHTTP_CALLBACK_STATUS dwInternetStatus, IntPtr lpvStatusInformation, uint dwStatusInformationLength) { if (dwInternetStatus == WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) { WINHTTP_ASYNC_RESULT res = lpvStatusInformation.ToStructure <WINHTTP_ASYNC_RESULT>(dwStatusInformationLength); if (res.dwResult != ASYNC_RESULT.API_GET_PROXY_FOR_URL) { return; } cbErr = res.dwError; } else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) { cbErr = WinHttpGetProxyResult(hInternet, out WINHTTP_PROXY_RESULT proxyRes); if (cbErr.Succeeded) { proxyRes.WriteValues(); WinHttpFreeProxyResult(ref proxyRes); } } evt.Set(); } }
//[Test] // Can't get this ever pass public void WinHttpQueryConnectionGroupTest() { // Use WinHttpOpen to obtain a session handle. using SafeHINTERNET hSession = WinHttpOpen(userAgent); Assert.That(hSession, ResultIs.ValidHandle); // Specify an HTTP server. using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTPS_PORT); Assert.That(hConnect, ResultIs.ValidHandle); try { IntPtr res = default; Assert.That(WinHttpQueryConnectionGroup(hConnect, default, 0, ref res), ResultIs.Successful);
public void Dispose() { // close the session handle SafeHINTERNET handle = this.session; this.session = null; if (handle != null) { handle.Close(); } return; }
/// <summary> /// Initializes a new instance of the <a onclick="return false;" href="InternetProxyOptions" /// originaltag="see">InternetProxyOptions</a> class by creating a session with options. /// </summary> /// <param name="agentName"> /// String that specifies the name of the application or entity calling the functions. This name is used as the user agent in the /// HTTP protocol. /// </param> /// <param name="manualProxyUrl"> /// String that specifies the name of the proxy server(s) to use. Do not use an empty string, because it will be used as the proxy /// name. Only CERN type proxies (HTTP only) and the TIS FTP gateway (FTP only) are recognized. /// </param> /// <param name="proxyBypassEntries"> /// An optional list of host names or IP addresses, or both, that should not be routed through the proxy. The list can contain /// wildcards. Do not use an empty string, because it will be used as a proxy bypass. If this parameter specifies the /// "<local>" macro, the function bypasses the proxy for any host name that does not contain a period. /// <para> /// By default, the proxy will bypass requests that use the host names "localhost", "loopback", "127.0.0.1", or "[::1]". This /// behavior exists because a remote proxy server typically will not resolve these addresses properly. /// </para> /// </param> /// <param name="offline"> /// If <see langword="true"/>, does not make network requests. All entities are returned from the cache. If the requested item is /// not in the cache, a suitable error is returned. /// </param> /// <param name="asyncOnly">If <see langword="true"/>, makes only asynchronous requests.</param> public InternetProxyOptions(string agentName, string manualProxyUrl, string[] proxyBypassEntries = null, bool offline = false, bool asyncOnly = false) { InternetApiFlags flags = 0; if (offline) { flags |= InternetApiFlags.INTERNET_FLAG_OFFLINE; } if (asyncOnly) { flags |= InternetApiFlags.INTERNET_FLAG_ASYNC; } hInet = InternetOpen(agentName, InternetOpenType.INTERNET_OPEN_TYPE_PROXY, manualProxyUrl, proxyBypassEntries is null ? null : string.Join(";", proxyBypassEntries), flags); Win32Error.ThrowLastErrorIfInvalid(hInet); }
public void WinHttpGetProxyForUrlTest() { // Use WinHttpOpen to obtain a session handle. using SafeHINTERNET hSession = WinHttpOpen(userAgent); Assert.That(hSession, ResultIs.ValidHandle); // Specify an HTTP server. using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTP_PORT); Assert.That(hConnect, ResultIs.ValidHandle); // Create an HTTP request handle. using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", "ms.htm", "HTTP/1.1"); Assert.That(hRequest, ResultIs.ValidHandle); // Call WinHttpGetProxyForUrl with our target URL, then set the proxy info on the request handle. WINHTTP_AUTOPROXY_OPTIONS opts = new() { dwFlags = WINHTTP_AUTOPROXY.WINHTTP_AUTOPROXY_AUTO_DETECT, dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DNS_A | WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DHCP, fAutoLogonIfChallenged = true, }; Assert.That(WinHttpGetProxyForUrl(hSession, "https://www.microsoft.com/ms.htm", opts, out WINHTTP_PROXY_INFO info), ResultIs.Successful); try { TestContext.WriteLine($"{info.dwAccessType}; {info.lpszProxy}; {info.lpszProxyBypass}"); // A proxy configuration was found, set it on the request handle. Assert.That(WinHttpSetOption(hRequest, WINHTTP_OPTION.WINHTTP_OPTION_PROXY, info), ResultIs.Successful); } finally { info.FreeMemory(); } // Send the request. Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); // Wait for the response. Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); }
[Test] // TODO: Need to find URL where this works public void WinHttpQueryAuthSchemesTest() { // Use WinHttpOpen to obtain a session handle. using SafeHINTERNET hSession = WinHttpOpen(userAgent); Assert.That(hSession, ResultIs.ValidHandle); // Specify an HTTP server. using SafeHINTERNET hConnect = WinHttpConnect(hSession, "drive.google.com", INTERNET_DEFAULT_HTTPS_PORT); Assert.That(hConnect, ResultIs.ValidHandle); // Create an HTTP request handle. using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", "file/d/0ByJOdIdwOr5COHpTRTNFakgzSk0/view?usp=sharing&resourcekey=0-TUcpJ5N1-M9-Mw1DP4VT7A", dwFlags: WINHTTP_OPENREQ_FLAG.WINHTTP_FLAG_SECURE); Assert.That(hRequest, ResultIs.ValidHandle); // Send the request. Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); // Wait for the response. Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); var stat = WinHttpQueryHeaders <uint>(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_STATUS_CODE); Assert.That(stat, Is.EqualTo(401).Or.EqualTo(407)); Assert.That(WinHttpQueryAuthSchemes(hRequest, out var sch, out var first, out var target), ResultIs.Successful); TestContext.Write($"Auth: {sch}, {first}, {target}"); }
internal static extern bool WinHttpGetProxyForUrl(SafeHINTERNET hSession, string lpcwszUrl, [In] ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions, out WINHTTP_PROXY_INFO pProxyInfo);
internal static extern bool WinHttpSetTimeouts(SafeHINTERNET hInternet, int dwResolveTimeout, int dwConnectTimeout, int dwSendTimeout, int dwReceiveTimeout);