Retrieve PAC script using WPAD on OSX

后端 未结 2 1589
梦谈多话
梦谈多话 2021-02-06 15:49

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 co

相关标签:
2条回答
  • 2021-02-06 16:16

    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.

    0 讨论(0)
  • 2021-02-06 16:21

    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.

    0 讨论(0)
提交回复
热议问题