@@ -1321,44 +1321,214 @@ def proxy_bypass_environment(host):
1321
1321
1322
1322
1323
1323
if sys .platform == 'darwin' :
1324
- def getproxies_internetconfig ():
1325
- """Return a dictionary of scheme -> proxy server URL mappings.
1326
-
1327
- By convention the mac uses Internet Config to store
1328
- proxies. An HTTP proxy, for instance, is stored under
1329
- the HttpProxy key.
1324
+ def _CStringFromCFString (sc , value ):
1325
+ from ctypes import create_string_buffer
1326
+ length = sc .CFStringGetLength (value ) + 1
1327
+ buff = create_string_buffer (length )
1328
+ sc .CFStringGetCString (value , buff , length , 0 )
1329
+ return buff .value
1330
+
1331
+ def _CFNumberToInt32 (sc , cfnum ):
1332
+ from ctypes import byref , c_int
1333
+ val = c_int ()
1334
+ kCFNumberSInt32Type = 3
1335
+ sc .CFNumberGetValue (cfnum , kCFNumberSInt32Type , byref (val ))
1336
+ return val .value
1337
+
1338
+
1339
+ def proxy_bypass_macosx_sysconf (host ):
1340
+ """
1341
+ Return True iff this host shouldn't be accessed using a proxy
1330
1342
1343
+ This function uses the MacOSX framework SystemConfiguration
1344
+ to fetch the proxy information.
1331
1345
"""
1332
- try :
1333
- import ic
1334
- except ImportError :
1335
- return {}
1346
+ from ctypes import cdll
1347
+ from ctypes .util import find_library
1348
+ import re
1349
+ import socket
1350
+ from fnmatch import fnmatch
1351
+
1352
+ def ip2num (ipAddr ):
1353
+ parts = ipAddr .split ('.' )
1354
+ parts = map (int , parts )
1355
+ if len (parts ) != 4 :
1356
+ parts = (parts + [0 , 0 , 0 , 0 ])[:4 ]
1357
+ return (parts [0 ] << 24 ) | (parts [1 ] << 16 ) | (parts [2 ] << 8 ) | parts [3 ]
1358
+
1359
+ sc = cdll .LoadLibrary (find_library ("SystemConfiguration" ))
1360
+
1361
+ hostIP = None
1362
+
1363
+ if not sc :
1364
+ return False
1365
+
1366
+ kSCPropNetProxiesExceptionsList = sc .CFStringCreateWithCString (0 , "ExceptionsList" , 0 )
1367
+ kSCPropNetProxiesExcludeSimpleHostnames = sc .CFStringCreateWithCString (0 ,
1368
+ "ExcludeSimpleHostnames" , 0 )
1369
+
1370
+
1371
+ proxyDict = sc .SCDynamicStoreCopyProxies (None )
1336
1372
1337
1373
try :
1338
- config = ic .IC ()
1339
- except ic .error :
1374
+ # Check for simple host names:
1375
+ if '.' not in host :
1376
+ exclude_simple = sc .CFDictionaryGetValue (proxyDict ,
1377
+ kSCPropNetProxiesExcludeSimpleHostnames )
1378
+ if exclude_simple and _CFNumberToInt32 (sc , exclude_simple ):
1379
+ return True
1380
+
1381
+
1382
+ # Check the exceptions list:
1383
+ exceptions = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesExceptionsList )
1384
+ if exceptions :
1385
+ # Items in the list are strings like these: *.local, 169.254/16
1386
+ for index in xrange (sc .CFArrayGetCount (exceptions )):
1387
+ value = sc .CFArrayGetValueAtIndex (exceptions , index )
1388
+ if not value : continue
1389
+ value = _CStringFromCFString (sc , value )
1390
+
1391
+ m = re .match (r"(\d+(?:\.\d+)*)(/\d+)?" , value )
1392
+ if m is not None :
1393
+ if hostIP is None :
1394
+ hostIP = socket .gethostbyname (host )
1395
+ hostIP = ip2num (hostIP )
1396
+
1397
+ base = ip2num (m .group (1 ))
1398
+ mask = int (m .group (2 )[1 :])
1399
+ mask = 32 - mask
1400
+
1401
+ if (hostIP >> mask ) == (base >> mask ):
1402
+ return True
1403
+
1404
+ elif fnmatch (host , value ):
1405
+ return True
1406
+
1407
+ return False
1408
+
1409
+ finally :
1410
+ sc .CFRelease (kSCPropNetProxiesExceptionsList )
1411
+ sc .CFRelease (kSCPropNetProxiesExcludeSimpleHostnames )
1412
+
1413
+
1414
+
1415
+ def getproxies_macosx_sysconf ():
1416
+ """Return a dictionary of scheme -> proxy server URL mappings.
1417
+
1418
+ This function uses the MacOSX framework SystemConfiguration
1419
+ to fetch the proxy information.
1420
+ """
1421
+ from ctypes import cdll
1422
+ from ctypes .util import find_library
1423
+
1424
+ sc = cdll .LoadLibrary (find_library ("SystemConfiguration" ))
1425
+
1426
+ if not sc :
1340
1427
return {}
1428
+
1429
+
1430
+ kSCPropNetProxiesHTTPEnable = sc .CFStringCreateWithCString (0 , "HTTPEnable" , 0 )
1431
+ kSCPropNetProxiesHTTPProxy = sc .CFStringCreateWithCString (0 , "HTTPProxy" , 0 )
1432
+ kSCPropNetProxiesHTTPPort = sc .CFStringCreateWithCString (0 , "HTTPPort" , 0 )
1433
+
1434
+ kSCPropNetProxiesHTTPSEnable = sc .CFStringCreateWithCString (0 , "HTTPSEnable" , 0 )
1435
+ kSCPropNetProxiesHTTPSProxy = sc .CFStringCreateWithCString (0 , "HTTPSProxy" , 0 )
1436
+ kSCPropNetProxiesHTTPSPort = sc .CFStringCreateWithCString (0 , "HTTPSPort" , 0 )
1437
+
1438
+ kSCPropNetProxiesFTPEnable = sc .CFStringCreateWithCString (0 , "FTPEnable" , 0 )
1439
+ kSCPropNetProxiesFTPPassive = sc .CFStringCreateWithCString (0 , "FTPPassive" , 0 )
1440
+ kSCPropNetProxiesFTPPort = sc .CFStringCreateWithCString (0 , "FTPPort" , 0 )
1441
+ kSCPropNetProxiesFTPProxy = sc .CFStringCreateWithCString (0 , "FTPProxy" , 0 )
1442
+
1443
+ kSCPropNetProxiesGopherEnable = sc .CFStringCreateWithCString (0 , "GopherEnable" , 0 )
1444
+ kSCPropNetProxiesGopherPort = sc .CFStringCreateWithCString (0 , "GopherPort" , 0 )
1445
+ kSCPropNetProxiesGopherProxy = sc .CFStringCreateWithCString (0 , "GopherProxy" , 0 )
1446
+
1341
1447
proxies = {}
1342
- # HTTP:
1343
- if 'UseHTTPProxy' in config and config ['UseHTTPProxy' ]:
1344
- try :
1345
- value = config ['HTTPProxyHost' ]
1346
- except ic .error :
1347
- pass
1348
- else :
1349
- proxies ['http' ] = 'http://%s' % value
1350
- # FTP: XXX To be done.
1351
- # Gopher: XXX To be done.
1448
+ proxyDict = sc .SCDynamicStoreCopyProxies (None )
1449
+
1450
+ try :
1451
+ # HTTP:
1452
+ enabled = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPEnable )
1453
+ if enabled and _CFNumberToInt32 (sc , enabled ):
1454
+ proxy = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPProxy )
1455
+ port = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPPort )
1456
+
1457
+ if proxy :
1458
+ proxy = _CStringFromCFString (sc , proxy )
1459
+ if port :
1460
+ port = _CFNumberToInt32 (sc , port )
1461
+ proxies ["http" ] = "http://%s:%i" % (proxy , port )
1462
+ else :
1463
+ proxies ["http" ] = "http://%s" % (proxy , )
1464
+
1465
+ # HTTPS:
1466
+ enabled = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPSEnable )
1467
+ if enabled and _CFNumberToInt32 (sc , enabled ):
1468
+ proxy = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPSProxy )
1469
+ port = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesHTTPSPort )
1470
+
1471
+ if proxy :
1472
+ proxy = _CStringFromCFString (sc , proxy )
1473
+ if port :
1474
+ port = _CFNumberToInt32 (sc , port )
1475
+ proxies ["https" ] = "http://%s:%i" % (proxy , port )
1476
+ else :
1477
+ proxies ["https" ] = "http://%s" % (proxy , )
1478
+
1479
+ # FTP:
1480
+ enabled = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesFTPEnable )
1481
+ if enabled and _CFNumberToInt32 (sc , enabled ):
1482
+ proxy = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesFTPProxy )
1483
+ port = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesFTPPort )
1484
+
1485
+ if proxy :
1486
+ proxy = _CStringFromCFString (sc , proxy )
1487
+ if port :
1488
+ port = _CFNumberToInt32 (sc , port )
1489
+ proxies ["ftp" ] = "http://%s:%i" % (proxy , port )
1490
+ else :
1491
+ proxies ["ftp" ] = "http://%s" % (proxy , )
1492
+
1493
+ # Gopher:
1494
+ enabled = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesGopherEnable )
1495
+ if enabled and _CFNumberToInt32 (sc , enabled ):
1496
+ proxy = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesGopherProxy )
1497
+ port = sc .CFDictionaryGetValue (proxyDict , kSCPropNetProxiesGopherPort )
1498
+
1499
+ if proxy :
1500
+ proxy = _CStringFromCFString (sc , proxy )
1501
+ if port :
1502
+ port = _CFNumberToInt32 (sc , port )
1503
+ proxies ["gopher" ] = "http://%s:%i" % (proxy , port )
1504
+ else :
1505
+ proxies ["gopher" ] = "http://%s" % (proxy , )
1506
+ finally :
1507
+ sc .CFRelease (proxyDict )
1508
+
1509
+ sc .CFRelease (kSCPropNetProxiesHTTPEnable )
1510
+ sc .CFRelease (kSCPropNetProxiesHTTPProxy )
1511
+ sc .CFRelease (kSCPropNetProxiesHTTPPort )
1512
+ sc .CFRelease (kSCPropNetProxiesFTPEnable )
1513
+ sc .CFRelease (kSCPropNetProxiesFTPPassive )
1514
+ sc .CFRelease (kSCPropNetProxiesFTPPort )
1515
+ sc .CFRelease (kSCPropNetProxiesFTPProxy )
1516
+ sc .CFRelease (kSCPropNetProxiesGopherEnable )
1517
+ sc .CFRelease (kSCPropNetProxiesGopherPort )
1518
+ sc .CFRelease (kSCPropNetProxiesGopherProxy )
1519
+
1352
1520
return proxies
1353
1521
1522
+
1523
+
1354
1524
def proxy_bypass (host ):
1355
1525
if getproxies_environment ():
1356
1526
return proxy_bypass_environment (host )
1357
1527
else :
1358
- return 0
1528
+ return proxy_bypass_macosx_sysconf ( host )
1359
1529
1360
1530
def getproxies ():
1361
- return getproxies_environment () or getproxies_internetconfig ()
1531
+ return getproxies_environment () or getproxies_macosx_sysconf ()
1362
1532
1363
1533
elif os .name == 'nt' :
1364
1534
def getproxies_registry ():
0 commit comments