| 160 | """ |
| 161 | |
| 162 | def __init__(self, pattern: str) -> None: |
| 163 | from ._urls import URL |
| 164 | |
| 165 | if pattern and ":" not in pattern: |
| 166 | raise ValueError( |
| 167 | f"Proxy keys should use proper URL forms rather " |
| 168 | f"than plain scheme strings. " |
| 169 | f'Instead of "{pattern}", use "{pattern}://"' |
| 170 | ) |
| 171 | |
| 172 | url = URL(pattern) |
| 173 | self.pattern = pattern |
| 174 | self.scheme = "" if url.scheme == "all" else url.scheme |
| 175 | self.host = "" if url.host == "*" else url.host |
| 176 | self.port = url.port |
| 177 | if not url.host or url.host == "*": |
| 178 | self.host_regex: typing.Pattern[str] | None = None |
| 179 | elif url.host.startswith("*."): |
| 180 | # *.example.com should match "www.example.com", but not "example.com" |
| 181 | domain = re.escape(url.host[2:]) |
| 182 | self.host_regex = re.compile(f"^.+\\.{domain}$") |
| 183 | elif url.host.startswith("*"): |
| 184 | # *example.com should match "www.example.com" and "example.com" |
| 185 | domain = re.escape(url.host[1:]) |
| 186 | self.host_regex = re.compile(f"^(.+\\.)?{domain}$") |
| 187 | else: |
| 188 | # example.com should match "example.com" but not "www.example.com" |
| 189 | domain = re.escape(url.host) |
| 190 | self.host_regex = re.compile(f"^{domain}$") |
| 191 | |
| 192 | def matches(self, other: URL) -> bool: |
| 193 | if self.scheme and self.scheme != other.scheme: |