Example #1
0
        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;
        }
Example #2
0
        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();
            }
        }
Example #3
0
 //[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);
Example #4
0
        public void Dispose()
        {
            // close the session handle
            SafeHINTERNET handle = this.session;

            this.session = null;
            if (handle != null)
            {
                handle.Close();
            }

            return;
        }
Example #5
0
        /// <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
        /// "&lt;local&gt;" 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);
        }
Example #6
0
        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);
        }
Example #7
0
        [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}");
        }
Example #8
0
 internal static extern bool WinHttpGetProxyForUrl(SafeHINTERNET hSession, string lpcwszUrl, [In] ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions, out WINHTTP_PROXY_INFO pProxyInfo);
Example #9
0
 internal static extern bool WinHttpSetTimeouts(SafeHINTERNET hInternet, int dwResolveTimeout, int dwConnectTimeout, int dwSendTimeout, int dwReceiveTimeout);