views:

5440

answers:

5

I am writing a command-line tool for Windows that uses libcurl to download files from the internet.

Obviously, the downloading doesn't work when the user is behind a proxy server, because the proxy needs to be configured. I want to keep my tool as simple as possible however, and not have to burden the user with having to configure the proxy. My tool doesn't even have a config file, so the user would otherwise have to pass in the proxy settings on every command, or set an environment variable or somesuch -- way too much hassle.

So I thought, everyone's browser will usually already be set up properly, proxy configured and everything. This will be true for even the most basic user because otherwise "their internet wouldn't work".

So I figure that I can find out whether to use a proxy by looking at IE's proxy settings.

How do I go about this? More specifically:

  • Is there one set of "proxy settings" in Windows, used by all browsers (probably IE's), or would I have to write different routines for IE, Firefox, Opera, etc?
  • I know that I can probably read the values directly out of the appropriate registry locations if they are configured manually, but does this also work with "automatically detect proxy server?" Do I even have to bother with that option, or is it (almost) never used?

Before people start suggesting alternatives: I'm using C, so I'm limited to the Win32 API, and I really really want to keep using C and libcurl.

A: 

There are registry keys for these values that you could get to directly of course. You could also do this in .NET without much hassle at all. I believe the WebClient object negotiates the proxy settings for you based on the current settings. This would look like this in C#:

using System.Net;

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

Or something close to that.

justin.m.chase
By the way you can also use the same class to detect the proxy. There is a Proxy property with a GetProxy() method.
justin.m.chase
Thanks, but I'm using C so this is kind of out of the question (and I don't want to resort to COM if I can avoid it). I've edited the question to clarify.
rix0rrr
A: 

first off all, you should use C# to wrte the command line, in this way you have all the power of the .NET framework and then use this article for example to send requests behind firewalls and ssl.

or, if you want to keep the good'ld ANSI C, try this that will give you the register settings in this webpage

remember: Google is your friend ;)

balexandre
+12  A: 

The function you're looking for is WinHttpGetIEProxyConfigForCurrentUser(), which is documented at http://msdn.microsoft.com/en-us/library/aa384096(VS.85).aspx. This function is used by Firefox and Opera to get their proxy settings by default, although you can override them per-browser. Don't do that, though. The right thing to do (which is what everybody else does) is to just get the IE settings and assume that they're correct, since they almost always are.

Here's a sample of the relevant logic, which you should adapt for your needs:

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

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

if( fAutoProxy )
{
    // basic flags you almost always want
    autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
    autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    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
    }
}
JSBangs
A: 

For Firefox/Seamonkey, the problem is a bit more tricky because of the existence of many profiles.

If you want to assume there is only one profile then you just need to find prefs.js. You parse the network.proxy.type, and then use it to decide, which related values to read.

I'm working on some documents for mozilla, so put your followup questions in here (checked wiki box), and I'll try to give you the info you need.

benc
A: 

Hi JS Bangs, Would you have the same code in C# 2.0?

Thanks

Manish