2008-10-14 31 views
24

Estoy escribiendo una herramienta de línea de comandos para Windows que usa libcurl para descargar archivos de Internet.¿Cómo puedo averiguar la configuración del proxy del navegador?

Obviamente, la descarga no funciona cuando el usuario está detrás de un servidor proxy, porque el proxy necesita ser configurado. Sin embargo, quiero mantener mi herramienta lo más simple posible y no tener que cargar al usuario con la necesidad de configurar el proxy. Mi herramienta ni siquiera tiene un archivo de configuración, por lo que el usuario tendría que pasar la configuración del proxy en cada comando, o establecer una variable de entorno o algo así - demasiada molestia.

Así que pensé, el navegador de todos normalmente ya estará configurado correctamente, proxy configurado y todo. Esto será cierto incluso para el usuario más básico porque de lo contrario "su internet no funcionaría".

Así que creo que puedo averiguar si se debe usar un proxy al mirar la configuración de proxy de IE.

¿Cómo puedo hacer esto? Más específicamente:

  • ¿Hay un conjunto de "configuración de proxy" en Windows, utilizado por todos los navegadores (IE), probablemente de, o tendría que escribir diferentes rutinas para IE, Firefox, Opera, etc?
  • Sé que probablemente pueda leer los valores directamente desde las ubicaciones de registro apropiadas si se configuran manualmente, pero ¿esto también funciona con "detectar automáticamente el servidor proxy?" ¿Tengo que molestarme con esa opción, o es (casi) nunca utilizada?

Antes de que la gente comience a sugerir alternativas: estoy usando C, por lo que estoy limitado a la API de Win32, y realmente quiero seguir usando C y libcurl.

+1

[Encuentra el código aquí para obtener la configuración del proxy de IE.] Http://stackoverflow.com/a/12601449/ 559746 –

Respuesta

33

La función que está buscando es WinHttpGetIEProxyConfigForCurrentUser(), que está documentada en http://msdn.microsoft.com/en-us/library/aa384096(VS.85).aspx. Esta función es utilizada por Firefox y Opera para obtener su configuración de proxy por defecto, aunque puede anularlos por navegador. No hagas eso, sin embargo. Lo correcto (lo que hacen todos los demás) es obtener la configuración de IE y asumir que son correctas, ya que casi siempre lo son.

He aquí una muestra de la lógica relevante, que debe adaptarse a sus necesidades:

if(WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) 
{ 
    if(ieProxyConfig.fAutoDetect) 
    { 
     fAutoProxy = TRUE; 
    } 

    if(ieProxyConfig.lpszAutoConfigUrl != NULL) 
    { 
     fAutoProxy = TRUE; 
     autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl; 
    } 
} 
else 
{ 
    // use autoproxy 
    fAutoProxy = TRUE; 
} 

if(fAutoProxy) 
{ 
    if (autoProxyOptions.lpszAutoConfigUrl != NULL) 
    { 
     autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; 
    } 
    else 
    { 
     autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 
     autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; 
    } 

    // basic flags you almost always want 
    autoProxyOptions.fAutoLogonIfChallenged = TRUE; 

    // here we reset fAutoProxy in case an auto-proxy isn't actually 
    // configured for this url 
    fAutoProxy = WinHttpGetProxyForUrl(hiOpen, pwszUrl, &autoProxyOptions, &autoProxyInfo); 
} 

if (fAutoProxy) 
{ 
    // set proxy options for libcurl based on autoProxyInfo 
} 
else 
{ 
    if(ieProxyConfig.lpszProxy != NULL) 
    { 
     // IE has an explicit proxy. set proxy options for libcurl here 
     // based on ieProxyConfig 
     // 
     // note that sometimes IE gives just a single or double colon 
     // for proxy or bypass list, which means "no proxy" 
    } 
    else 
    { 
     // there is no auto proxy and no manually configured proxy 
    } 
} 
+2

Esta es una muy buena respuesta, pero es muy probable que también haya credenciales de proxy en caché (nombre de usuario y contraseña) que de alguna manera deben ser reenviadas al servidor proxy, y no creo que haya una manera de lograr eso con esta técnica ? – Antony

1

Existen claves de registro para estos valores a las que se puede acceder directamente, por supuesto. También podría hacer esto en .NET sin mucha molestia. Creo que el objeto WebClient negocia las configuraciones de proxy en función de la configuración actual. Esto se vería así en C#:

using System.Net; 

string url = "http://www.example.com"; 
WebClient client = new WebClient(); 
byte[] fileBuffer = client.DownloadFile(url); 

O algo así.

+0

Por cierto, también puede usar la misma clase para detectar el proxy. Hay una propiedad Proxy con un método GetProxy(). –

+0

Gracias, pero estoy usando C así que esto está fuera de lugar (y no quiero recurrir a COM si puedo evitarlo). He editado la pregunta para aclarar. – rix0rrr

0

Para Firefox/SeaMonkey, el problema es un poco más complejo debido a la existencia de muchos perfiles.

Si desea suponer que solo hay un perfil, solo necesita encontrar prefs.js. Analiza network.proxy.type y luego lo usa para decidir qué valores relacionados leer.

Estoy trabajando en algunos documentos para mozilla, así que ponga sus preguntas de seguimiento aquí (recuadro del recuadro marcado), e intentaré darle la información que necesita.

3

Aquí es un ejemplo de código completo cómo llamar WinHttpGetIEProxyConfigForCurrentUser método de winhttp.dll biblioteca en C#

[TestClass] 
public class UnitTest1 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct WinhttpCurrentUserIeProxyConfig 
    { 
     [MarshalAs(UnmanagedType.Bool)] 
     public bool AutoDetect; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string AutoConfigUrl; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string Proxy; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string ProxyBypass; 

    } 

    [DllImport("winhttp.dll", SetLastError = true)] 
    static extern bool WinHttpGetIEProxyConfigForCurrentUser(ref WinhttpCurrentUserIeProxyConfig pProxyConfig); 

    [TestMethod] 
    public void TestMethod1() 
    { 
     var config = new WinhttpCurrentUserIeProxyConfig(); 

     WinHttpGetIEProxyConfigForCurrentUser(ref config); 

     Console.WriteLine(config.Proxy); 
     Console.WriteLine(config.AutoConfigUrl); 
     Console.WriteLine(config.AutoDetect); 
     Console.WriteLine(config.ProxyBypass); 
    } 
} 
Cuestiones relacionadas