Как узнать настройки прокси в браузере?

Я пишу инструмент командной строки для Windows, который использует libcurl для загрузки файлов из Интернета.

Очевидно, что загрузка не работает, когда пользователь находится за прокси-сервером, потому что прокси необходимо настроить. Однако я хочу, чтобы мой инструмент был как можно более простым и не обременял пользователя настройкой прокси. У моего инструмента даже нет файла конфигурации, поэтому пользователю в противном случае пришлось бы передавать настройки прокси для каждой команды, или устанавливать переменную среды или что-то подобное - слишком много хлопот.

Итак, я подумал, что у всех браузер, как правило, уже настроен должным образом, настроен прокси и все такое. Это будет верно даже для самого обычного пользователя, потому что в противном случае «их Интернет не работал бы».

Итак, я полагаю, что могу узнать, использовать ли прокси-сервер, просмотрев настройки прокси-сервера IE.

Как мне это сделать? Более конкретно:

  • Есть ли в Windows один набор «настроек прокси», используемый всеми браузерами (возможно, IE), или мне придется писать разные процедуры для IE, Firefox, Opera и т. Д.?
  • Я знаю, что я, вероятно, могу прочитать значения непосредственно из соответствующих мест реестра, если они настроены вручную, но работает ли это также с «автоматическим обнаружением прокси-сервера?» Придется ли мне вообще возиться с этой опцией, или она (почти) никогда не используется?

Прежде чем люди начнут предлагать альтернативы: я использую C, поэтому я ограничен API Win32, и я действительно действительно хочу продолжать использовать C и libcurl.


person rix0rrr    schedule 14.10.2008    source источник
comment
[Найдите здесь код, чтобы получить настройки прокси IE.] stackoverflow.com/a/12601449/559746   -  person PTT    schedule 26.09.2012


Ответы (4)


Вам нужна функция WinHttpGetIEProxyConfigForCurrentUser (), которая задокументирована по адресу http://msdn.microsoft.com/en-us/library/aa384096(VS.85).aspx. Эта функция используется Firefox и Opera для получения настроек прокси по умолчанию, хотя вы можете переопределить их для каждого браузера. Но не делай этого. Правильнее всего (что делают все остальные) просто получить настройки IE и предположить, что они верны, поскольку они почти всегда таковы.

Вот образец соответствующей логики, которую вы должны адаптировать к своим потребностям:

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
    }
}
person JSBձոգչ    schedule 14.10.2008
comment
Это очень хороший ответ, но очень вероятно, что также будут кешированы учетные данные прокси (имя пользователя и пароль), которые каким-то образом нужно перенаправить на прокси-сервер, и я не думаю, что есть способ добиться этого с помощью этой техники? - person Antony; 21.11.2016

Вот полный пример кода, как вызвать метод WinHttpGetIEProxyConfigForCurrentUser из библиотеки winhttp.dll на 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);
    }
}
person Maksym Kozlenko    schedule 01.08.2012

Есть ключи реестра для этих значений, к которым вы, конечно же, можете добраться напрямую. Вы также можете сделать это в .NET без особых хлопот. Я считаю, что объект WebClient согласовывает для вас настройки прокси на основе текущих настроек. На C # это будет выглядеть так:

using System.Net;

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

Или что-то близкое к этому.

person justin.m.chase    schedule 14.10.2008
comment
Кстати, вы также можете использовать тот же класс для обнаружения прокси. Есть свойство Proxy с методом GetProxy (). - person justin.m.chase; 15.10.2008
comment
Спасибо, но я использую C, поэтому об этом не может быть и речи (и я не хочу прибегать к COM, если я могу этого избежать). Я отредактировал вопрос, чтобы уточнить. - person rix0rrr; 15.10.2008

Для Firefox / Seamonkey проблема немного сложнее из-за существования множества профилей.

Если вы хотите предположить, что существует только один профиль, вам просто нужно найти prefs.js. Вы анализируете network.proxy.type, а затем используете его, чтобы решить, какие связанные значения читать.

Я работаю над некоторыми документами для Mozilla, поэтому задайте здесь дополнительные вопросы (отмечен флажком вики), и я постараюсь предоставить вам необходимую информацию.

person Community    schedule 23.10.2008