Merged revisions 74962 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r74962 | ronald.oussoren | 2009-09-20 12:31:22 +0200 (Sun, 20 Sep 2009) | 2 lines

  Fix for issue 6851: urllib.urlopen crashes in a thread on OSX 10.6
........
This commit is contained in:
Ronald Oussoren 2009-09-20 10:37:33 +00:00
parent 04606fbcbe
commit 40617a8eae
3 changed files with 36 additions and 183 deletions

View File

@ -1331,38 +1331,7 @@ def proxy_bypass_environment(host):
if sys.platform == 'darwin': if sys.platform == 'darwin':
from _scproxy import _get_proxy_settings, _get_proxies
def _CFSetup(sc):
from ctypes import c_int32, c_void_p, c_char_p, c_int
sc.CFStringCreateWithCString.argtypes = [ c_void_p, c_char_p, c_int32 ]
sc.CFStringCreateWithCString.restype = c_void_p
sc.SCDynamicStoreCopyProxies.argtypes = [ c_void_p ]
sc.SCDynamicStoreCopyProxies.restype = c_void_p
sc.CFDictionaryGetValue.argtypes = [ c_void_p, c_void_p ]
sc.CFDictionaryGetValue.restype = c_void_p
sc.CFStringGetLength.argtypes = [ c_void_p ]
sc.CFStringGetLength.restype = c_int32
sc.CFStringGetCString.argtypes = [ c_void_p, c_char_p, c_int32, c_int32 ]
sc.CFStringGetCString.restype = c_int32
sc.CFNumberGetValue.argtypes = [ c_void_p, c_int, c_void_p ]
sc.CFNumberGetValue.restype = c_int32
sc.CFRelease.argtypes = [ c_void_p ]
sc.CFRelease.restype = None
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 proxy_bypass_macosx_sysconf(host): def proxy_bypass_macosx_sysconf(host):
""" """
@ -1371,8 +1340,6 @@ if sys.platform == 'darwin':
This function uses the MacOSX framework SystemConfiguration This function uses the MacOSX framework SystemConfiguration
to fetch the proxy information. to fetch the proxy information.
""" """
from ctypes import cdll
from ctypes.util import find_library
import re import re
import socket import socket
from fnmatch import fnmatch from fnmatch import fnmatch
@ -1384,63 +1351,35 @@ if sys.platform == 'darwin':
parts = (parts + [0, 0, 0, 0])[:4] parts = (parts + [0, 0, 0, 0])[:4]
return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]
sc = cdll.LoadLibrary(find_library("SystemConfiguration")) proxy_settings = _get_proxy_settings()
_CFSetup(sc)
hostIP = None # Check for simple host names:
if '.' not in host:
if proxy_settings['exclude_simple']:
return True
if not sc: for value in proxy_settings.get('exceptions'):
return False # Items in the list are strings like these: *.local, 169.254/16
value = sc.CFArrayGetValueAtIndex(exceptions, index)
if not value: continue
kSCPropNetProxiesExceptionsList = sc.CFStringCreateWithCString(0, "ExceptionsList", 0) m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value)
kSCPropNetProxiesExcludeSimpleHostnames = sc.CFStringCreateWithCString(0, if m is not None:
"ExcludeSimpleHostnames", 0) 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
proxyDict = sc.SCDynamicStoreCopyProxies(None) if (hostIP >> mask) == (base >> mask):
if proxyDict is None:
return False
try:
# Check for simple host names:
if '.' not in host:
exclude_simple = sc.CFDictionaryGetValue(proxyDict,
kSCPropNetProxiesExcludeSimpleHostnames)
if exclude_simple and _CFNumberToInt32(sc, exclude_simple):
return True return True
elif fnmatch(host, value):
return True
# Check the exceptions list: return False
exceptions = sc.CFDictionaryGetValue(proxyDict, 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(): def getproxies_macosx_sysconf():
@ -1449,106 +1388,7 @@ if sys.platform == 'darwin':
This function uses the MacOSX framework SystemConfiguration This function uses the MacOSX framework SystemConfiguration
to fetch the proxy information. to fetch the proxy information.
""" """
from ctypes import cdll return _get_proxies()
from ctypes.util import find_library
sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
_CFSetup(sc)
if not sc:
return {}
kSCPropNetProxiesHTTPEnable = sc.CFStringCreateWithCString(0, "HTTPEnable", 0)
kSCPropNetProxiesHTTPProxy = sc.CFStringCreateWithCString(0, "HTTPProxy", 0)
kSCPropNetProxiesHTTPPort = sc.CFStringCreateWithCString(0, "HTTPPort", 0)
kSCPropNetProxiesHTTPSEnable = sc.CFStringCreateWithCString(0, "HTTPSEnable", 0)
kSCPropNetProxiesHTTPSProxy = sc.CFStringCreateWithCString(0, "HTTPSProxy", 0)
kSCPropNetProxiesHTTPSPort = sc.CFStringCreateWithCString(0, "HTTPSPort", 0)
kSCPropNetProxiesFTPEnable = sc.CFStringCreateWithCString(0, "FTPEnable", 0)
kSCPropNetProxiesFTPPassive = sc.CFStringCreateWithCString(0, "FTPPassive", 0)
kSCPropNetProxiesFTPPort = sc.CFStringCreateWithCString(0, "FTPPort", 0)
kSCPropNetProxiesFTPProxy = sc.CFStringCreateWithCString(0, "FTPProxy", 0)
kSCPropNetProxiesGopherEnable = sc.CFStringCreateWithCString(0, "GopherEnable", 0)
kSCPropNetProxiesGopherPort = sc.CFStringCreateWithCString(0, "GopherPort", 0)
kSCPropNetProxiesGopherProxy = sc.CFStringCreateWithCString(0, "GopherProxy", 0)
proxies = {}
proxyDict = sc.SCDynamicStoreCopyProxies(None)
try:
# HTTP:
enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable)
if enabled and _CFNumberToInt32(sc, enabled):
proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy)
port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort)
if proxy:
proxy = _CStringFromCFString(sc, proxy)
if port:
port = _CFNumberToInt32(sc, port)
proxies["http"] = "http://%s:%i" % (proxy, port)
else:
proxies["http"] = "http://%s" % (proxy, )
# HTTPS:
enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSEnable)
if enabled and _CFNumberToInt32(sc, enabled):
proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSProxy)
port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSPort)
if proxy:
proxy = _CStringFromCFString(sc, proxy)
if port:
port = _CFNumberToInt32(sc, port)
proxies["https"] = "http://%s:%i" % (proxy, port)
else:
proxies["https"] = "http://%s" % (proxy, )
# FTP:
enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPEnable)
if enabled and _CFNumberToInt32(sc, enabled):
proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPProxy)
port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPPort)
if proxy:
proxy = _CStringFromCFString(sc, proxy)
if port:
port = _CFNumberToInt32(sc, port)
proxies["ftp"] = "http://%s:%i" % (proxy, port)
else:
proxies["ftp"] = "http://%s" % (proxy, )
# Gopher:
enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherEnable)
if enabled and _CFNumberToInt32(sc, enabled):
proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherProxy)
port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherPort)
if proxy:
proxy = _CStringFromCFString(sc, proxy)
if port:
port = _CFNumberToInt32(sc, port)
proxies["gopher"] = "http://%s:%i" % (proxy, port)
else:
proxies["gopher"] = "http://%s" % (proxy, )
finally:
sc.CFRelease(proxyDict)
sc.CFRelease(kSCPropNetProxiesHTTPEnable)
sc.CFRelease(kSCPropNetProxiesHTTPProxy)
sc.CFRelease(kSCPropNetProxiesHTTPPort)
sc.CFRelease(kSCPropNetProxiesFTPEnable)
sc.CFRelease(kSCPropNetProxiesFTPPassive)
sc.CFRelease(kSCPropNetProxiesFTPPort)
sc.CFRelease(kSCPropNetProxiesFTPProxy)
sc.CFRelease(kSCPropNetProxiesGopherEnable)
sc.CFRelease(kSCPropNetProxiesGopherPort)
sc.CFRelease(kSCPropNetProxiesGopherProxy)
return proxies

View File

@ -82,6 +82,8 @@ Core and Builtins
Library Library
------- -------
- Issue #6851: Fix urllib.urlopen crash on secondairy threads on OSX 10.6
- Issue #6947: Fix distutils test on windows. Patch by Hirokazu Yamamoto. - Issue #6947: Fix distutils test on windows. Patch by Hirokazu Yamamoto.
- Issue #4606: Passing 'None' if ctypes argtype is set to POINTER(...) - Issue #4606: Passing 'None' if ctypes argtype is set to POINTER(...)

View File

@ -1402,6 +1402,17 @@ class PyBuildExt(build_ext):
addMacExtension('_CF', core_kwds, ['cf/pycfbridge.c']) addMacExtension('_CF', core_kwds, ['cf/pycfbridge.c'])
addMacExtension('autoGIL', core_kwds) addMacExtension('autoGIL', core_kwds)
# _scproxy
sc_kwds = {
'extra_compile_args': carbon_extra_compile_args,
'extra_link_args': [
'-framework', 'SystemConfiguration',
'-framework', 'CoreFoundation'
],
}
addMacExtension("_scproxy", sc_kwds)
# Carbon # Carbon
carbon_kwds = {'extra_compile_args': carbon_extra_compile_args, carbon_kwds = {'extra_compile_args': carbon_extra_compile_args,
'extra_link_args': ['-framework', 'Carbon'], 'extra_link_args': ['-framework', 'Carbon'],