View | Details | Raw Unified | Return to bug 983582
Collapse All | Expand All

(-)a/Doc/library/urllib.request.rst (+2 lines)
Lines 166-171 Link Here
166
   in a case insensitive approach, for all operating systems first, and when it
166
   in a case insensitive approach, for all operating systems first, and when it
167
   cannot find it, looks for proxy information from Mac OSX System
167
   cannot find it, looks for proxy information from Mac OSX System
168
   Configuration for Mac OS X and Windows Systems Registry for Windows.
168
   Configuration for Mac OS X and Windows Systems Registry for Windows.
169
   If both lowercase and uppercase environment variables exist (and disagree),
170
   lowercase is preferred.
169
171
170
172
171
The following classes are provided:
173
The following classes are provided:
(-)a/Lib/test/test_urllib.py (-1 / +39 lines)
Lines 226-233 Link Here
226
        # getproxies_environment use lowered case truncated (no '_proxy') keys
226
        # getproxies_environment use lowered case truncated (no '_proxy') keys
227
        self.assertEqual('localhost', proxies['no'])
227
        self.assertEqual('localhost', proxies['no'])
228
        # List of no_proxies with space.
228
        # List of no_proxies with space.
229
        self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
229
        self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com:1234')
230
        self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
230
        self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
231
        self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com:8888'))
232
        self.assertTrue(urllib.request.proxy_bypass_environment('newdomain.com:1234'))
233
234
235
class ProxyTests_withOrderedEnv(unittest.TestCase):
236
237
    def setUp(self):
238
        # We need to test conditions, where variable order _is_ significant
239
        self._saved_env = os.environ
240
        # Monkey patch os.environ, start with empty fake environment
241
        os.environ = collections.OrderedDict()
242
243
    def tearDown(self):
244
        os.environ = self._saved_env
245
246
    def test_getproxies_environment_prefer_lowercase(self):
247
        # Test lowercase preference with removal
248
        os.environ['no_proxy'] = ''
249
        os.environ['No_Proxy'] = 'localhost'
250
        self.assertFalse(urllib.request.proxy_bypass_environment('localhost'))
251
        self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary'))
252
        os.environ['http_proxy'] = ''
253
        os.environ['HTTP_PROXY'] = 'http://somewhere:3128'
254
        proxies = urllib.request.getproxies_environment()
255
        self.assertEqual({}, proxies)
256
        # Test lowercase preference of proxy bypass and correct matching including ports
257
        os.environ['no_proxy'] = 'localhost, noproxy.com, my.proxy:1234'
258
        os.environ['No_Proxy'] = 'xyz.com'
259
        self.assertTrue(urllib.request.proxy_bypass_environment('localhost'))
260
        self.assertTrue(urllib.request.proxy_bypass_environment('noproxy.com:5678'))
261
        self.assertTrue(urllib.request.proxy_bypass_environment('my.proxy:1234'))
262
        self.assertFalse(urllib.request.proxy_bypass_environment('my.proxy'))
263
        self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary'))
264
        # Test lowercase preference with replacement
265
        os.environ['http_proxy'] = 'http://somewhere:3128'
266
        os.environ['Http_Proxy'] = 'http://somewhereelse:3128'
267
        proxies = urllib.request.getproxies_environment()
268
        self.assertEqual('http://somewhere:3128', proxies['http'])
231
269
232
class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin):
270
class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin):
233
    """Test urlopen() opening a fake http connection."""
271
    """Test urlopen() opening a fake http connection."""
(-)a/Lib/urllib/request.py (-11 / +35 lines)
Lines 2395-2413 Link Here
2395
2395
2396
    """
2396
    """
2397
    proxies = {}
2397
    proxies = {}
2398
    # in order to prefer lowercase variables, process environment in
2399
    # two passes: first matches any, second pass matches lowercase only
2398
    for name, value in os.environ.items():
2400
    for name, value in os.environ.items():
2399
        name = name.lower()
2401
        name = name.lower()
2400
        if value and name[-6:] == '_proxy':
2402
        if value and name[-6:] == '_proxy':
2401
            proxies[name[:-6]] = value
2403
            proxies[name[:-6]] = value
2404
    for name, value in os.environ.items():
2405
        if name[-6:] == '_proxy':
2406
            name = name.lower()
2407
            if value:
2408
                proxies[name[:-6]] = value
2409
            else:
2410
                proxies.pop(name[:-6], None)
2402
    return proxies
2411
    return proxies
2403
2412
2404
def proxy_bypass_environment(host):
2413
def proxy_bypass_environment(host, proxies=None):
2405
    """Test if proxies should not be used for a particular host.
2414
    """Test if proxies should not be used for a particular host.
2406
2415
2407
    Checks the environment for a variable named no_proxy, which should
2416
    Checks the proxy dict for the value of no_proxy, which should
2408
    be a list of DNS suffixes separated by commas, or '*' for all hosts.
2417
    be a list of comma separated DNS suffixes, or '*' for all hosts.
2418
2409
    """
2419
    """
2410
    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
2420
    if proxies is None:
2421
        proxies = getproxies_environment()
2422
    # don't bypass, if no_proxy isn't specified
2423
    try:
2424
        no_proxy = proxies['no']
2425
    except KeyError:
2426
        return 0
2411
    # '*' is special case for always bypass
2427
    # '*' is special case for always bypass
2412
    if no_proxy == '*':
2428
    if no_proxy == '*':
2413
        return 1
2429
        return 1
Lines 2502-2509 Link Here
2502
2518
2503
2519
2504
    def proxy_bypass(host):
2520
    def proxy_bypass(host):
2505
        if getproxies_environment():
2521
        """Return True, if host should be bypassed.
2506
            return proxy_bypass_environment(host)
2522
2523
        Checks proxy settings gathered from the environment, if specified,
2524
        or from the MacOSX framework SystemConfiguration.
2525
2526
        """
2527
        proxies = getproxies_environment()
2528
        if proxies:
2529
            return proxy_bypass_environment(host, proxies)
2507
        else:
2530
        else:
2508
            return proxy_bypass_macosx_sysconf(host)
2531
            return proxy_bypass_macosx_sysconf(host)
2509
2532
Lines 2617-2630 Link Here
2617
        return 0
2640
        return 0
2618
2641
2619
    def proxy_bypass(host):
2642
    def proxy_bypass(host):
2620
        """Return a dictionary of scheme -> proxy server URL mappings.
2643
        """Return True, if host should be bypassed.
2621
2644
2622
        Returns settings gathered from the environment, if specified,
2645
        Checks proxy settings gathered from the environment, if specified,
2623
        or the registry.
2646
        or the registry.
2624
2647
2625
        """
2648
        """
2626
        if getproxies_environment():
2649
        proxies = getproxies_environment()
2627
            return proxy_bypass_environment(host)
2650
        if proxies:
2651
            return proxy_bypass_environment(host, proxies)
2628
        else:
2652
        else:
2629
            return proxy_bypass_registry(host)
2653
            return proxy_bypass_registry(host)
2630
2654
(-)a/Misc/ACKS (+1 lines)
Lines 670-675 Link Here
670
Bertrand Janin
670
Bertrand Janin
671
Geert Jansen
671
Geert Jansen
672
Jack Jansen
672
Jack Jansen
673
Hans-Peter Jansen
673
Bill Janssen
674
Bill Janssen
674
Thomas Jarosch
675
Thomas Jarosch
675
Juhana Jauhiainen
676
Juhana Jauhiainen
(-)a/Misc/NEWS (+4 lines)
Lines 107-112 Link Here
107
Library
107
Library
108
-------
108
-------
109
109
110
- Issue #26804: urllib.request will prefer lower_case proxy environment
111
  variables over UPPER_CASE or Mixed_Case ones. Patch contributed by Hans-Peter
112
  Jansen.
113
110
- Issue #26837: assertSequenceEqual() now correctly outputs non-stringified
114
- Issue #26837: assertSequenceEqual() now correctly outputs non-stringified
111
  differing items (like bytes in the -b mode).  This affects assertListEqual()
115
  differing items (like bytes in the -b mode).  This affects assertListEqual()
112
  and assertTupleEqual().
116
  and assertTupleEqual().

Return to bug 983582