Pergunta

Eu estou escrevendo uma ferramenta de linha de comando para Windows que usa libcurl para baixar arquivos da internet.

Obviamente, a descarga não funciona quando o usuário está atrás de um servidor proxy, porque as necessidades de proxy para ser configurado. Eu quero manter a minha ferramenta tão simples quanto possível, no entanto, e não tem a carga ao usuário ter que configurar o proxy. Minha ferramenta nem sequer tem um arquivo de configuração, para que o usuário de outra forma teriam de passar nas configurações de proxy em cada comando, ou definir uma variável de ambiente ou algo assim -. Maneira muito trabalho

Então eu pensei, navegador de todos costumam já estar configurado corretamente, proxy configurado e tudo. Isso vai ser verdade para até mesmo o usuário mais básico, porque caso contrário "a sua internet não iria funcionar".

Então eu acho que eu posso descobrir se a usar um proxy, olhando para as configurações de proxy do IE.

Como posso fazer isso? Mais especificamente:

  • Existe um conjunto de "configurações de proxy" no Windows, usado por todos os navegadores (provavelmente do IE), ou eu teria que escrever rotinas diferentes para IE, Firefox, Opera, etc?
  • Eu sei que eu provavelmente pode ler os valores diretamente dos locais de registro apropriadas se forem configurados manualmente, mas faz isso também trabalho com a "detectar automaticamente o servidor proxy?" Eu ainda tem que se preocupar com essa opção, ou é (quase) nunca usou?

Antes das pessoas começam sugerindo alternativas:. Eu estou usando C, por isso estou limitado à API Win32, e eu realmente quero continuar usando C e libcurl

Foi útil?

Solução

A função que você está procurando WinHttpGetIEProxyConfigForCurrentUser (), que está documentado em http://msdn.microsoft.com/en-us/library/aa384096 (VS.85) .aspx . Esta função é usada pelo Firefox e Opera para obter suas configurações de proxy por padrão, mas você pode substituí-los por browser. Não faça isso, no entanto. A coisa certa a fazer (que é o que todo mundo faz) é apenas para obter as configurações do IE e assumir que eles estão corretos, uma vez que quase sempre são.

Aqui está um exemplo da lógica relevante, o que você deve se adaptar às suas necessidades:

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
    }
}

Outras dicas

Aqui está um exemplo de código completo como chamar método WinHttpGetIEProxyConfigForCurrentUser da biblioteca winhttp.dll em 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);
    }
}

Existem chaves de registro para estes valores que você poderia chegar diretamente claro. Você também pode fazer isso em .NET sem muita trabalheira de todo. Eu acredito que o objeto WebClient negocia as configurações de proxy para você com base nas configurações atuais. Isso seria parecido com isso em C #:

using System.Net;

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

Ou algo perto disso.

Para Firefox / Seamonkey, o problema é um pouco mais complicado devido à existência de muitos perfis.

Se você quiser supor que há apenas um perfil, então você só precisa encontrar prefs.js. Você analisar o network.proxy.type e, em seguida, usá-lo para decidir, que os valores relacionados a ler.

Eu estou trabalhando em alguns documentos para mozilla, para colocar as suas questões de acompanhamento aqui (caixa wiki marcada), e eu vou tentar dar-lhe a informação que você precisa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top