Getting the proxy settings for a URL

Hi,


My application needs to make web requests, and I am trying to get it to behave well and automatically detect and use the user's network proxy settings.


My first attempt was to just use CFNetworkCopySystemProxySettings and CFNetworkProxiesForURL. But if I go into the network system preferences and enable a manual proxy (for http for example) or an auto configuration script url, CFNetworkProxiesForURL always returns kCFProxyTypeNone. I assume that this is because the CFProxySupport Reference documents these APIs to 'take advantage of the global proxy configuration settings'. I am not sure where to set these global proxy settings, but they do not appear to be the ones that users would normally configure in their preferences.


I have found a few references suggesting to use the System Configuration APIs to get the proxy dictionary from the dynamic store. So I tried calling SCDynamicStoreCopyProxies to get the dictionary. Now this does appear to return the settings I am looking for, but poses another problem. The sample code I found was looking for the proxy keys (for example "HTTPProxy" in the root of this dictionary. But when I run it, I do not see any of these keys in the root of that dictionary. (I assume these would be the global settings the same as above, and are missing because I do not have any global proxy settings.) But what I do see in this dictionary is the following:


{

__SCOPED__: {

en0: {

HTTPEnable: 1,

HTTPProxy: 127.0.0.1,

HTTPPort: 8888,

...

}

}

}


The proxy settings I am after are scoped under the interface device. That makes sense because each interface device can have its own proxy settings. But my problem is how to determine which interface device will be used for the URL that I will be calling. Are the interfaces under __SCOPED__ returned in any meaningful order? It appears that if I disable an interface, it is not returned in the dictionary. If there are multiple enabled interfaces, are the returned in the order they would be used? If there are global proxy settings, should they be used before the (first?) scoped interface's settings are used, or should it be the other way around?


Any info would be helpful (details are hard to find in any documentation or samples).


Thanks,


Kris

Replies

My application needs to make web requests, and I am trying to get it to behave well and automatically detect and use the user's network proxy settings.

If you use high-level APIs (NSURLSession, NSURLConnection), those take care of proxies for you. Based on your question I presume you’re not using those high-level APIs. Why not?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This is in a larger cross platform application using various components, making web requests with libraries such as libcurl and the cpprestsdk, both of which mostly rely on the proxy handling be done on the client side. So we can allow the user to configure the application with the proxy settings to use, but I am trying to do a better job with automatic detection through these Core Framework and System Configuration APIs that appear to be for that purpose.


Kris

Is this on iOS or macOS?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This is on MacOS

OK. I have some more information. After checking with another user's outputs from SCDynamicStoreCopyProxies, they were always seeing that the proxy settings for the first active interface were in the root of the dictionary. (The first active interface being the first connected interface in the 'Network' dialog's list of interface as defined by the service order.)


The difference between our configurations was that I was connected through VPN and he was not. Sure enough, if I disconnect my VPN, I now see the first interfaces proxy settings properly copied into the root of the dictionary, but when connected through VPN they are not. This appears to be a bug in SCDynamicStoreCopyProxies when running under VPN (the proxy settings for the current adapter are not copied into the root).


Unfortunately, because of this it appears there is no good way to reliably determine what proxy settings are active from the results of this call. Perhaps if I could determine the name of the first active interface, I could look for the settings of that interface in the __SCOPED___ sub-dictionary?


Kris