|
17 | 17 | import json |
18 | 18 | import re |
19 | 19 | import ssl |
| 20 | +from urllib.parse import urlparse |
| 21 | +from urllib.request import getproxies, proxy_bypass |
20 | 22 |
|
21 | 23 | import urllib3 |
22 | 24 |
|
| 25 | +from openapi_client.configuration import Configuration |
23 | 26 | from openapi_client.exceptions import ApiException, ApiValueError |
24 | 27 |
|
25 | 28 | SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"} |
@@ -60,7 +63,7 @@ def getheader(self, name, default=None): |
60 | 63 |
|
61 | 64 | class RESTClientObject: |
62 | 65 |
|
63 | | - def __init__(self, configuration) -> None: |
| 66 | + def __init__(self, configuration: Configuration) -> None: |
64 | 67 | # urllib3.PoolManager will pass all kw parameters to connectionpool |
65 | 68 | # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 |
66 | 69 | # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 |
@@ -100,14 +103,23 @@ def __init__(self, configuration) -> None: |
100 | 103 | # https pool manager |
101 | 104 | self.pool_manager: urllib3.PoolManager |
102 | 105 |
|
103 | | - if configuration.proxy: |
104 | | - if is_socks_proxy_url(configuration.proxy): |
| 106 | + parsed = urlparse(configuration.host) |
| 107 | + proxy = getproxies().get(parsed.scheme) if configuration.proxy is None else configuration.proxy |
| 108 | + if proxy: |
| 109 | + if configuration.no_proxy is not None: |
| 110 | + if _proxy_bypass(parsed.netloc, configuration.no_proxy): |
| 111 | + proxy = None |
| 112 | + elif proxy_bypass(parsed.netloc): |
| 113 | + proxy = None |
| 114 | + |
| 115 | + if proxy: |
| 116 | + if is_socks_proxy_url(proxy): |
105 | 117 | from urllib3.contrib.socks import SOCKSProxyManager |
106 | | - pool_args["proxy_url"] = configuration.proxy |
| 118 | + pool_args["proxy_url"] = proxy |
107 | 119 | pool_args["headers"] = configuration.proxy_headers |
108 | 120 | self.pool_manager = SOCKSProxyManager(**pool_args) |
109 | 121 | else: |
110 | | - pool_args["proxy_url"] = configuration.proxy |
| 122 | + pool_args["proxy_url"] = proxy |
111 | 123 | pool_args["proxy_headers"] = configuration.proxy_headers |
112 | 124 | self.pool_manager = urllib3.ProxyManager(**pool_args) |
113 | 125 | else: |
@@ -257,3 +269,27 @@ def request( |
257 | 269 | raise ApiException(status=0, reason=msg) |
258 | 270 |
|
259 | 271 | return RESTResponse(r) |
| 272 | + |
| 273 | +# Adapted from urllib.request.proxy_bypass_environment |
| 274 | +def _proxy_bypass(netloc: str, no_proxy: str): |
| 275 | + if no_proxy == '*': |
| 276 | + return True |
| 277 | + |
| 278 | + host = netloc.lower() |
| 279 | + if match := re.match(r'(.*):([0-9]*)', host): |
| 280 | + hostonly, _port = match.groups() |
| 281 | + else: |
| 282 | + hostonly = host |
| 283 | + |
| 284 | + for name in no_proxy.split(','): |
| 285 | + name = name.strip() |
| 286 | + if name: |
| 287 | + name = name.lstrip('.') |
| 288 | + name = name.lower() |
| 289 | + if hostonly == name or host == name: |
| 290 | + return True |
| 291 | + name = '.' + name |
| 292 | + if hostonly.endswith(name) or host.endswith(name): |
| 293 | + return True |
| 294 | + |
| 295 | + return False |
0 commit comments