Click here to Skip to main content
Click here to Skip to main content
Go to top

Using PAC files proxy

, 4 Nov 2005
Rate this:
Please Sign up or sign in to vote.
This article explains how to set a proxy using PAC files.

Introduction

This article explains how to set a proxy using PAC files. PAC files are Proxy Automatic Configuration files, which define a proxy for a specific URL. The solution presented in the article uses the WinHttp.dll for obtaining a proxy URL.

Background

Using the code

I’ve created a simple testing application that sends a web request to www.google.com using a proxy obtained from a PAC file.

In order to run the application you need to put the proxy.pac file into your home directory for the default web site. Usually this directory is c:\inetpub\wwwroot.

The main function that returns the proxy for a specific URL is GetProxyForUrlUsingPac that is defined in the Proxy class:

public static string GetProxyForUrlUsingPac ( string DestinationUrl, string PacUri ){

     IntPtr WinHttpSession = Win32Api.WinHttpOpen("User",
                                    Win32Api.WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
                                    IntPtr.Zero, 
                                    IntPtr.Zero, 
                                    0);

     Win32Api.WINHTTP_AUTOPROXY_OPTIONS  ProxyOptions = 
              new Win32Api.WINHTTP_AUTOPROXY_OPTIONS();
     Win32Api.WINHTTP_PROXY_INFO ProxyInfo = 
                     new Win32Api.WINHTTP_PROXY_INFO(); 
            
     ProxyOptions.dwFlags           = Win32Api.WINHTTP_AUTOPROXY_CONFIG_URL;
     ProxyOptions.dwAutoDetectFlags = (Win32Api.WINHTTP_AUTO_DETECT_TYPE_DHCP |
                                       Win32Api.WINHTTP_AUTO_DETECT_TYPE_DNS_A);
     ProxyOptions.lpszAutoConfigUrl = PacUri;
            
     // Get Proxy 
     bool IsSuccess = Win32Api.WinHttpGetProxyForUrl( WinHttpSession, 
                                                      DestinationUrl,
                                                      ref ProxyOptions,
                                                      ref ProxyInfo );
            
     Win32Api.WinHttpCloseHandle(WinHttpSession);

     if ( IsSuccess ){
         return ProxyInfo.lpszProxy;
     }else {
         Console.WriteLine("Error: {0}", Win32Api.GetLastError() );
         return null;
     }
}

The Win32Api class contains a definition of the Win32 functions:

/// <summary>
/// This function implements the Web Proxy Auto-Discovery (WPAD) protocol
/// for automatically configuring the proxy settings for an HTTP request.
/// The WPAD protocol downloads a Proxy Auto-Configuration (PAC) file,
/// which is a script that identifies the proxy server to use for a given
/// target URL. PAC files are typically deployed by the IT department within
/// a corporate network environment. The URL of the PAC file can either be
/// specified explicitly or WinHttpGetProxyForUrl can be instructed to
/// automatically discover the location of the PAC file on the local network.
/// </summary>
/// <param name="hSession">The WinHTTP session handle
///         returned by the WinHttpOpen function</param>
/// <param name="lpcwszUrl">A pointer
/// to a null-terminated Unicode string that contains the
/// URL of the HTTP request that the application is preparing to send.</param>
/// <param name="pAutoProxyOptions">A pointer
/// to a WINHTTP_AUTOPROXY_OPTIONS structure that
/// specifies the auto-proxy options to use.</param>
/// <param name="pProxyInfo">A pointer
/// to a WINHTTP_PROXY_INFO structure that receives the
/// proxy setting. This structure is then applied to the request handle using the
/// WINHTTP_OPTION_PROXY option.</param>
/// <returns></returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern bool WinHttpGetProxyForUrl(
            IntPtr hSession,
            string lpcwszUrl,
            ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions,
            ref WINHTTP_PROXY_INFO pProxyInfo);

/// <summary>
/// The function initializes, for an application, the use of WinHTTP
/// functions and returns a WinHTTP-session handle
/// </summary>
/// <param name="pwszUserAgent">A pointer
/// to a string variable that contains the name of the
/// application or entity calling the WinHTTP functions.</param>
/// <param name="dwAccessType">Type of access required.
///     This can be one of the following values</param>
/// <param name="pwszProxyName"> A pointer
/// to a string variable that contains the name of the
/// proxy server to use when proxy access
/// is specified by setting dwAccessType to
/// WINHTTP_ACCESS_TYPE_NAMED_PROXY. The WinHTTP functions
/// recognize only CERN type proxies for HTTP.
/// If dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY,
/// this parameter must be set
/// to WINHTTP_NO_PROXY_NAME</param>
/// <param name="pwszProxyBypass">A pointer
/// to a string variable that contains an optional list
/// of host names or IP addresses, or both,
/// that should not be routed through the proxy when
/// dwAccessType is set to WINHTTP_ACCESS_TYPE_NAMED_PROXY.
/// The list can contain wildcard characters.
/// Do not use an empty string, because
/// the WinHttpOpen function uses it as the proxy bypass list.
/// If this parameter specifies the "<local>" macro
/// as the only entry, this function bypasses
/// any host name that does not contain a period.
/// If dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY,
/// this parameter must be set to WINHTTP_NO_PROXY_BYPASS.</param>
/// <param name="dwFlags">Unsigned long integer value
/// that contains the flags that indicate various options
/// affecting the behavior of this function</param>
/// <returns>Returns a valid session handle
///    if successful, or NULL otherwise</returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern IntPtr WinHttpOpen(
            string pwszUserAgent,
            int dwAccessType,
            IntPtr pwszProxyName,
            IntPtr pwszProxyBypass,
            int dwFlags
            );

/// <summary>
/// The function closes a single HINTERNET handle
/// </summary>
/// <param name="hInternet">Valid HINTERNET handle to be closed.</param>
/// <returns>Returns TRUE if the handle
///    is successfully closed, or FALSE otherwise</returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern bool WinHttpCloseHandle(IntPtr hInternet);

The main function that uses the GetProxyForUrlUsingPac is:

// Create test request
WebRequest TestRequest = WebRequest.Create ( DestinationUrl );
           
// Optain Proxy address for the URL
string ProxyAddresForUrl = Proxy.GetProxyForUrlUsingPac (DestinationUrl, PacUri);
if ( ProxyAddresForUrl != null ){
   Console.WriteLine ("Found Proxy: {0}", ProxyAddresForUrl );
   TestRequest.Proxy = new WebProxy ( ProxyAddresForUrl ) ;
}else{
   Console.WriteLine ( "Proxy Not Found. Send request directly."  );
}

That's it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Glaxalg
Software Developer (Senior)
United States United States
No Biography provided

Comments and Discussions

 
Generalcan't read the host name Pinmemberx_kanaga24-Jul-08 20:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 4 Nov 2005
Article Copyright 2005 by Glaxalg
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid