Ronald,

This version is now merged into urllib and commited as revision 63159 in the trunk.


Ahh, sorry I'm late. I was on vacation last week when you posted this. Here's an updated version with a bit less duplication (about 55 lines removed). This seems like it will be much easier to maintain (IMHO).

Also, I'm sure you know what you're doing so I left the code as it was, but this line (and other related lines) looked suspicious to me:

proxies["ftp"] = "http://%s:%i"; % (proxy, port)

Did you want the URL to be encoded with 'http://' on the front even though it is an FTP proxy? If not, simply use this in the attached script:

    proxies[protocol] = "%s://%s:%i" % (protocol, proxy, port)
else:
    proxies[protocol] = "%s://%s" % (protocol, proxy)


~ Daniel


def _CStringFromCFString(sc, value):
    from ctypes import create_string_buffer
    length = sc.CFStringGetLength(value) + 1
    buff = create_string_buffer(length)
    sc.CFStringGetCString(value, buff, length, 0)
    return buff.value

def _CFNumberToInt32(sc, cfnum):
    from ctypes import byref, c_int
    val = c_int()
    kCFNumberSInt32Type = 3
    sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val))
    return val.value


def proxybypass_macosx_sysconf(host):
    """
    Return True iff this host shouldn't be accessed using a proxy

    This function uses the MacOSX framework SystemConfiguration
    to fetch the proxy information.
    """
    from ctypes import cdll
    from ctypes.util import find_library
    import re
    import socket
    from fnmatch import fnmatch

    def ip2num(ipAddr):
        parts = ipAddr.split('.')
        parts = map(int, parts)
        if len(parts) != 4:
            parts = (parts + [0, 0, 0, 0])[:4]
        return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]

    sc = cdll.LoadLibrary(find_library("SystemConfiguration"))

    hostIP = None

    if not sc:
        return False

    kSCPropNetProxiesExceptionsList = sc.CFStringCreateWithCString(0, "ExceptionsList", 0)
    kSCPropNetProxiesExcludeSimpleHostnames = sc.CFStringCreateWithCString(0, "ExcludeSimpleHostnames", 0)

    
    proxy_dict = sc.SCDynamicStoreCopyProxies(None)

    try:
        # Check for simple host names:
        if '.' not in host:
            exclude_simple = sc.CFDictionaryGetValue(proxy_dict, kSCPropNetProxiesExcludeSimpleHostnames)
            if exclude_simple and _CFNumberToInt32(sc, exclude_simple):
                return True


        # Check the exceptions list:
        exceptions = sc.CFDictionaryGetValue(proxy_dict, kSCPropNetProxiesExceptionsList)
        if exceptions:
            # Items in the list are strings like these: *.local, 169.254/16
            for index in xrange(sc.CFArrayGetCount(exceptions)):
                value = sc.CFArrayGetValueAtIndex(exceptions, index)
                if not value: continue
                value = _CStringFromCFString(sc, value)

                m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value)
                if m is not None:
                    if hostIP is None:
                        hostIP = socket.gethostbyname(host)
                        hostIP = ip2num(hostIP)

                    base = ip2num(m.group(1))
                    mask = int(m.group(2)[1:])
                    mask = 32 - mask

                    if (hostIP >> mask) == (base >> mask):
                        return True

                elif fnmatch(host, value):
                    return True
                
        return False

    finally:
        sc.CFRelease(kSCPropNetProxiesExceptionsList)
        sc.CFRelease(kSCPropNetProxiesExcludeSimpleHostnames)



def getproxies_macosx_sysconf():
    """Return a dictionary of scheme -> proxy server URL mappings.
   
    This function uses the MacOSX framework SystemConfiguration
    to fetch the proxy information.
    """
    from ctypes import cdll
    from ctypes.util import find_library

    sc = cdll.LoadLibrary(find_library("SystemConfiguration"))

    if not sc:
        return {}

    proxy_keys = [
        ("http", "HTTPEnable", "HTTPProxy", "HTTPPort"),
        ("https", "HTTPSEnable", "HTTPSProxy", "HTTPSPort"),
        ("ftp", "FTPEnable", "FTPProxy", "FTPPort"),
        ("gopher", "GopherEnable", "GopherProxy", "GopherPort"),
    ]
    proxies = {}
    proxy_dict = sc.SCDynamicStoreCopyProxies(None)

    try:
        for protocol, enabled_key, proxy_key, port_key in proxy_keys:
            enabled_key = sc.CFStringCreateWithCString(0, enabled_key, 0)
            proxy_key = sc.CFStringCreateWithCString(0, proxy_key, 0)
            port_key = sc.CFStringCreateWithCString(0, port_key, 0)
            try:
                enabled = sc.CFDictionaryGetValue(proxy_dict, enabled_key)
                if enabled and _CFNumberToInt32(sc, enabled):
                    proxy = sc.CFDictionaryGetValue(proxy_dict, proxy_key)
                    port = sc.CFDictionaryGetValue(proxy_dict, port_key)
        
                    if proxy:
                        proxy = _CStringFromCFString(sc, proxy)
                        if port:
                            port = _CFNumberToInt32(sc, port)
                            proxies[protocol] = "http://%s:%i"; % (proxy, port)
                        else:
                            proxies[protocol] = "http://%s"; % (proxy, )
            finally:
                sc.CFRelease(enabled_key)
                sc.CFRelease(proxy_key)
                sc.CFRelease(port_key)
    finally:
        sc.CFRelease(proxy_dict)

    return proxies



print getproxies_macosx_sysconf()
print proxybypass_macosx_sysconf("169.254.10.10")
_______________________________________________
Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org
http://mail.python.org/mailman/listinfo/pythonmac-sig

Reply via email to