How do I retrieve the PAC script using WPAD on OSX? is it enough to fetch the contents of "http://wpad/wpad.dat" in hopes that the DNS has "wpad" pre-configured for this convention?
is there a more "formal" method of doing this?
How do I retrieve the PAC script using WPAD on OSX? is it enough to fetch the contents of "http://wpad/wpad.dat" in hopes that the DNS has "wpad" pre-configured for this convention?
is there a more "formal" method of doing this?
Here is how to get PAC proxies for a given URL:
#import <Foundation/Foundation.h> #import <CoreServices/CoreServices.h> #import <SystemConfiguration/SystemConfiguration.h> CFArrayRef CopyPACProxiesForURL(CFURLRef targetURL, CFErrorRef *error) { CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); if (!proxies) return NULL; CFNumberRef pacEnabled; if ((pacEnabled = (CFNumberRef)CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoConfigEnable))) { int enabled; if (CFNumberGetValue(pacEnabled, kCFNumberIntType, &enabled) && enabled) { CFStringRef pacLocation = (CFStringRef)CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoConfigURLString); CFURLRef pacUrl = CFURLCreateWithString(kCFAllocatorDefault, pacLocation, NULL); CFDataRef pacData; SInt32 errorCode; if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, pacUrl, &pacData, NULL, NULL, &errorCode)) return NULL; CFStringRef pacScript = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, pacData, kCFStringEncodingISOLatin1); if (!pacScript) return NULL; CFArrayRef pacProxies = CFNetworkCopyProxiesForAutoConfigurationScript(pacScript, targetURL, error); return pacProxies; } } return NULL; } int main(int argc, const char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; CFURLRef targetURL = (CFURLRef)[NSURL URLWithString : @"http://stackoverflow.com/questions/4379156/retrieve-pac-script-using-wpad-on-osx/"]; CFErrorRef error = NULL; CFArrayRef proxies = CopyPACProxiesForURL(targetURL, &error); if (proxies) { for (CFIndex i = 0; i < CFArrayGetCount(proxies); i++) { CFDictionaryRef proxy = CFArrayGetValueAtIndex(proxies, i); NSLog(@"%d\n%@", i, [(id)proxy description]); } CFRelease(proxies); } [pool drain]; }
For the sake of simplicity, this code is full of leaks (you should release everything you got through Copy and Create functions) and does not handle any potential error.
See section 8 of the WPAD draft on compliance. Using only DNS as you suggest would make you "minimally compliant".
To be fully compliant, you should check to see if the host has received WPAD configuration from DHCP prior to using DNS. You should be able to use the System Configuration framework to see if the host received an option 252 parameter from the DHCP server.
EDIT: Actually, you can get the WPAD URL directly from the system configuration framework. Looks like you'd be interested in kSCPropNetProxiesProxyAutoConfigEnable
, and if that's set to 1
, the WPAD URL should be in kSCPropNetProxiesProxyAutoConfigURLString
.