a
    LDf^                     @  s   d Z ddlmZ ddlZeeZddlmZm	Z	 erBddl
m
Z
 ddlmZ dZdd	d
dddZddddddZddddddZddddddZdS )zc Provide some utility functions useful for implementing different
components in ``bokeh.server``.

    )annotationsN)TYPE_CHECKINGSequence)socket)netutil)bind_socketscheck_allowlistcreate_hosts_allowlist
match_hostz
str | Noneintztuple[list[socket], int])addressportreturnc                 C  s`   t j|p
d| d}t|sJ dd |D }t|dks@J d| }|rX||ksXJ ||fS )a   Bind a socket to a port on an address.

    Args:
        address (str) :
            An address to bind a port on, e.g. ``"localhost"``

        port (int) :
            A port number to bind.

            Pass 0 to have the OS automatically choose a free port.

    This function returns a 2-tuple with the new socket as the first element,
    and the port that was bound as the second. (Useful when passing 0 as a port
    number to bind any free port.)

    Returns:
        (socket, port)

    r   )r   r   c                 S  s   h | ]}|  d  qS )   )getsockname).0s r   ^/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/bokeh/server/util.py	<setcomp>F       zbind_sockets.<locals>.<setcomp>r   zMultiple ports assigned??)r   r   lenpop)r   r   ssZportsactual_portr   r   r   r   0   s    r   strzSequence[str]bool)host	allowlistr   c                   s2   d vr d   |v rdS t  fdd|D S )a   Check a given request host against a allowlist.

    Args:
        host (str) :
            A host string to compare against a allowlist.

            If the host does not specify a port, then ``":80"`` is implicitly
            assumed.

        allowlist (seq[str]) :
            A list of host patterns to match against

    Returns:
        ``True``, if ``host`` matches any pattern in ``allowlist``, otherwise
        ``False``

     ::80Tc                 3  s   | ]}t  |V  qd S )N)r
   )r   patternr   r   r   	<genexpr>e   r   z"check_allowlist.<locals>.<genexpr>)any)r   r   r   r"   r   r   M   s
    r   zSequence[str] | Nonez
int | Nonez	list[str])	host_listr   r   c              	   C  s   | sdt | gS g }| D ]}d|v r2td| |dkrF|| q|d}t|dkr|d dkrptd||d	  qt|d
krzt|d  W n ty   td| Y n0 |d dkrtd|| qtd| q|S )an  

    This allowlist can be used to restrict websocket or other connections to
    only those explicitly originating from approved hosts.

    Args:
        host_list (seq[str]) :
            A list of string `<name>` or `<name>:<port>` values to add to the
            allowlist.

            If no port is specified in a host string, then ``":80"``  is
            implicitly assumed.

        port (int) :
            If ``host_list`` is empty or ``None``, then the allowlist will
            be the single item list `` [ 'localhost:<port>' ]``

            If ``host_list`` is not empty, this parameter has no effect.

    Returns:
        list[str]

    Raises:
        ValueError, if host or port values are invalid

    Note:
        If any host in ``host_list`` contains a wildcard ``*`` a warning will
        be logged regarding permissive websocket connections.

    z
localhost:*zHost wildcard %r will allow connections originating from multiple (or possibly all) hostnames or IPs. Use non-wildcard values to restrict access explicitlyr   r   r    zEmpty host valuer       zInvalid port in host value: %szInvalid host value: %s)r   logwarningappendsplitr   
ValueErrorr   )r%   r   hostsr   partsr   r   r   r	   g   s6    

r	   )r   r!   r   c                 C  s   d}d| v r|  dd\} }d}d|v rD| dd\}}|dkrDd}|durX||krXdS | d}|d}t|t|krdS t||D ]"\}}||ks|dkrqq dS qdS )aa   Match a host string against a pattern

    Args:
        host (str)
            A hostname to compare to the given pattern

        pattern (str)
            A string representing a hostname pattern, possibly including
            wildcards for ip address octets or ports.

    This function will return ``True`` if the hostname matches the pattern,
    including any wildcards. If the pattern contains a port, the host string
    must also contain a matching port.

    Returns:
        bool

    Examples:

        >>> match_host('192.168.0.1:80', '192.168.0.1:80')
        True
        >>> match_host('192.168.0.1:80', '192.168.0.1')
        True
        >>> match_host('192.168.0.1:80', '192.168.0.1:8080')
        False
        >>> match_host('192.168.0.1', '192.168.0.2')
        False
        >>> match_host('192.168.0.1', '192.168.*.*')
        True
        >>> match_host('alice', 'alice')
        True
        >>> match_host('alice:80', 'alice')
        True
        >>> match_host('alice', 'bob')
        False
        >>> match_host('foo.example.com', 'foo.example.com.net')
        False
        >>> match_host('alice', '*')
        True
        >>> match_host('alice', '*:*')
        True
        >>> match_host('alice:80', '*')
        True
        >>> match_host('alice:80', '*:80')
        True
        >>> match_host('alice:8080', '*:80')
        False

    Nr   r   r&   F.T)rsplitr,   r   zip)r   r!   	host_portZpattern_portZ
host_partspattern_partshpr   r   r   r
      s&    2

r
   )__doc__
__future__r   logging	getLogger__name__r)   typingr   r   r   Ztornador   __all__r   r   r	   r
   r   r   r   r   <module>   s   
?