Returns whether we should bypass proxies or not. :rtype: bool
(url: str, no_proxy: str | None)
| 808 | |
| 809 | |
| 810 | def should_bypass_proxies(url: str, no_proxy: str | None) -> bool: |
| 811 | """ |
| 812 | Returns whether we should bypass proxies or not. |
| 813 | |
| 814 | :rtype: bool |
| 815 | """ |
| 816 | |
| 817 | # Prioritize lowercase environment variables over uppercase |
| 818 | # to keep a consistent behaviour with other http projects (curl, wget). |
| 819 | def get_proxy(key: str) -> str | None: |
| 820 | return os.environ.get(key) or os.environ.get(key.upper()) |
| 821 | |
| 822 | # First check whether no_proxy is defined. If it is, check that the URL |
| 823 | # we're getting isn't in the no_proxy list. |
| 824 | no_proxy_arg = no_proxy |
| 825 | if no_proxy is None: |
| 826 | no_proxy = get_proxy("no_proxy") |
| 827 | parsed = urlparse(url) |
| 828 | hostname = parsed.hostname |
| 829 | |
| 830 | if hostname is None: |
| 831 | # URLs don't always have hostnames, e.g. file:/// urls. |
| 832 | return True |
| 833 | |
| 834 | if no_proxy: |
| 835 | # We need to check whether we match here. We need to see if we match |
| 836 | # the end of the hostname, both with and without the port. |
| 837 | no_proxy_hosts = (host for host in no_proxy.replace(" ", "").split(",") if host) |
| 838 | |
| 839 | if is_ipv4_address(hostname): |
| 840 | for proxy_ip in no_proxy_hosts: |
| 841 | if is_valid_cidr(proxy_ip): |
| 842 | if address_in_network(hostname, proxy_ip): |
| 843 | return True |
| 844 | elif hostname == proxy_ip: |
| 845 | # If no_proxy ip was defined in plain IP notation instead of cidr notation & |
| 846 | # matches the IP of the index |
| 847 | return True |
| 848 | else: |
| 849 | host_with_port = hostname |
| 850 | if parsed.port: |
| 851 | host_with_port += f":{parsed.port}" |
| 852 | |
| 853 | for host in no_proxy_hosts: |
| 854 | host = host.lstrip(".") |
| 855 | if hostname == host or host_with_port == host: |
| 856 | return True |
| 857 | host = "." + host |
| 858 | if hostname.endswith(host) or host_with_port.endswith(host): |
| 859 | return True |
| 860 | |
| 861 | with set_environ("no_proxy", no_proxy_arg): |
| 862 | try: |
| 863 | bypass = proxy_bypass(hostname) |
| 864 | except (TypeError, socket.gaierror): |
| 865 | bypass = False |
| 866 | |
| 867 | if bypass: |