Source code for pypac.wpad
"""
Tools for the Web Proxy Auto-Discovery Protocol.
"""
import logging
import socket
import tldextract
logger = logging.getLogger(__name__)
# First use of tldextract goes online to update its Public Suffix List cache. Stop it.
try:
no_fetch_extract = tldextract.TLDExtract(cache_dir=None, suffix_list_urls=None)
except TypeError:
# tldextract added cache_dir in v3.0.0, which also dropped PY27 support.
# Maintain PY27 support / allow old tldextract by retrying here.
no_fetch_extract = tldextract.TLDExtract(suffix_list_urls=None)
[docs]def proxy_urls_from_dns(local_hostname=None):
"""
Generate URLs from which to look for a PAC file, based on a hostname.
Fully-qualified hostnames are checked against the Public Suffix List to ensure that
generated URLs don't go outside the scope of the organization.
If the fully-qualified hostname doesn't have a recognized TLD,
such as in the case of intranets with '.local' or '.internal',
the TLD is assumed to be the part following the rightmost dot.
:param str local_hostname: Hostname to use for generating the WPAD URLs.
If not provided, the local hostname is used.
:return: PAC URLs to try in order, according to the WPAD protocol.
If the hostname isn't qualified or is otherwise invalid, an empty list is returned.
:rtype: list[str]
"""
if not local_hostname:
local_hostname = socket.getfqdn()
if (
"." not in local_hostname
or len(local_hostname) < 3
or local_hostname.startswith(".")
or local_hostname.endswith(".")
):
return []
parsed = no_fetch_extract(local_hostname)
return wpad_search_urls(parsed.subdomain, parsed.registered_domain or parsed.domain)
[docs]def wpad_search_urls(subdomain_or_host, fld):
"""
Generate URLs from which to look for a PAC file, based on the subdomain and TLD parts of
a fully-qualified host name.
:param str subdomain_or_host: Subdomain portion of the fully-qualified host name.
For foo.bar.example.com, this is foo.bar.
:param str fld: FLD portion of the fully-qualified host name.
For foo.bar.example.com, this is example.com.
:return: PAC URLs to try in order, according to the WPAD protocol.
:rtype: list[str]
"""
parts = subdomain_or_host.split(".")
search_urls = []
for i in range(1, len(parts) + 1):
# Chop off host and move up the subdomain hierarchy.
url = "http://wpad.{}/wpad.dat".format(".".join(parts[i:] + [fld]))
search_urls.append(url)
return search_urls