Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_url.py190 linesDownload Raw Back to websocket
1import ipaddress2import os3from typing import Optional4from urllib.parse import unquote, urlparse5from ._exceptions import WebSocketProxyException6 7"""8_url.py9websocket - WebSocket client library for Python10 11Copyright 2025 engn33r12 13Licensed under the Apache License, Version 2.0 (the "License");14you may not use this file except in compliance with the License.15You may obtain a copy of the License at16 17    http://www.apache.org/licenses/LICENSE-2.018 19Unless required by applicable law or agreed to in writing, software20distributed under the License is distributed on an "AS IS" BASIS,21WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.22See the License for the specific language governing permissions and23limitations under the License.24"""25 26__all__ = ["parse_url", "get_proxy_info"]27 28 29def parse_url(url: str) -> tuple:30    """31    parse url and the result is tuple of32    (hostname, port, resource path and the flag of secure mode)33 34    Parameters35    ----------36    url: str37        url string.38    """39    if ":" not in url:40        raise ValueError("url is invalid")41 42    scheme, url = url.split(":", 1)43 44    parsed = urlparse(url, scheme="http")45    if parsed.hostname:46        hostname = parsed.hostname47    else:48        raise ValueError("hostname is invalid")49    port = 050    if parsed.port:51        port = parsed.port52 53    is_secure = False54    if scheme == "ws":55        if not port:56            port = 8057    elif scheme == "wss":58        is_secure = True59        if not port:60            port = 44361    else:62        raise ValueError("scheme %s is invalid" % scheme)63 64    if parsed.path:65        resource = parsed.path66    else:67        resource = "/"68 69    if parsed.query:70        resource += f"?{parsed.query}"71 72    return hostname, port, resource, is_secure73 74 75def _is_ip_address(addr: str) -> bool:76    if not isinstance(addr, str):77        raise TypeError("_is_ip_address() argument 1 must be str")78    try:79        ipaddress.ip_address(addr)80    except ValueError:81        return False82    else:83        return True84 85 86def _is_subnet_address(hostname: str) -> bool:87    try:88        ipaddress.ip_network(hostname)89    except ValueError:90        return False91    else:92        return True93 94 95def _is_address_in_network(ip: str, net: str) -> bool:96    try:97        return ipaddress.ip_network(ip).subnet_of(ipaddress.ip_network(net))98    except TypeError:99        return False100 101 102def _is_no_proxy_host(hostname: str, no_proxy: Optional[list[str]]) -> bool:103    if not no_proxy:104        if v := os.environ.get("no_proxy", os.environ.get("NO_PROXY", "")).replace(105            " ", ""106        ):107            no_proxy = v.split(",")108 109    if not no_proxy:110        no_proxy = []111 112    if "*" in no_proxy:113        return True114    if hostname in no_proxy:115        return True116    if _is_ip_address(hostname):117        return any(118            [119                _is_address_in_network(hostname, subnet)120                for subnet in no_proxy121                if _is_subnet_address(subnet)122            ]123        )124    for domain in [domain for domain in no_proxy if domain.startswith(".")]:125        endDomain = domain.lstrip(".")126        if hostname.endswith(endDomain):127            return True128    return False129 130 131def get_proxy_info(132    hostname: str,133    is_secure: bool,134    proxy_host: Optional[str] = None,135    proxy_port: int = 0,136    proxy_auth: Optional[tuple] = None,137    no_proxy: Optional[list[str]] = None,138    proxy_type: str = "http",139) -> tuple:140    """141    Try to retrieve proxy host and port from environment142    if not provided in options.143    Result is (proxy_host, proxy_port, proxy_auth).144    proxy_auth is tuple of username and password145    of proxy authentication information.146 147    Parameters148    ----------149    hostname: str150        Websocket server name.151    is_secure: bool152        Is the connection secure? (wss) looks for "https_proxy" in env153        instead of "http_proxy"154    proxy_host: str155        http proxy host name.156    proxy_port: str or int157        http proxy port.158    no_proxy: list159        Whitelisted host names that don't use the proxy.160    proxy_auth: tuple161        HTTP proxy auth information. Tuple of username and password. Default is None.162    proxy_type: str163        Specify the proxy protocol (http, socks4, socks4a, socks5, socks5h). Default is "http".164        Use socks4a or socks5h if you want to send DNS requests through the proxy.165    """166    if _is_no_proxy_host(hostname, no_proxy):167        return None, 0, None168 169    if proxy_host:170        if not proxy_port:171            raise WebSocketProxyException("Cannot use port 0 when proxy_host specified")172        port = proxy_port173        auth = proxy_auth174        return proxy_host, port, auth175 176    env_key = "https_proxy" if is_secure else "http_proxy"177    value = os.environ.get(env_key, os.environ.get(env_key.upper(), "")).replace(178        " ", ""179    )180    if value:181        proxy = urlparse(value)182        auth = (183            (unquote(proxy.username or ""), unquote(proxy.password or ""))184            if proxy.username185            else None186        )187        return proxy.hostname, proxy.port, auth188 189    return None, 0, None190 
codekingpro/portable-devtools · Team Ai