ó
mÜJ]c           @` s   d  Z  d d l m Z m Z m Z m Z d d l Z e j e ƒ Z	 d d l
 m Z d Z d	 „  Z d
 „  Z d „  Z d „  Z d S(   uc    Provide some utility functions useful for implementing different
components in ``bokeh.server``.

i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsN(   t   netutilu   bind_socketsu   check_whitelistu   create_hosts_whitelistu
   match_hostc         C` s   t  j d | p d d |  ƒ } t | ƒ s0 t ‚ d „  | Dƒ } t | ƒ d k s^ t d ƒ ‚ | j ƒ  } | r… | | k s… t ‚ n  | | f S(   uô   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)

    t   porti    t   addressc         S` s    h  |  ] } | j  ƒ  d  ’ q S(   i   (   t   getsockname(   t   .0t   s(    (    s0   lib/python2.7/site-packages/bokeh/server/util.pys	   <setcomp>D   s   	 i   u   Multiple ports assigned??(   R   t   bind_socketst   lent   AssertionErrort   pop(   R   R   t   sst   portst   actual_port(    (    s0   lib/python2.7/site-packages/bokeh/server/util.pyR
   .   s    c         ` sC   d ˆ  k r ˆ  d ‰  n  ˆ  | k r) t  St ‡  f d †  | Dƒ ƒ S(   u¸   Check a given request host against a whitelist.

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

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

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

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

     u   :u   :80c         3` s   |  ] } t  ˆ  | ƒ Vq d  S(   N(   t
   match_host(   R   t   pattern(   t   host(    s0   lib/python2.7/site-packages/bokeh/server/util.pys	   <genexpr>c   s    (   t   Truet   any(   R   t	   whitelist(    (   R   s0   lib/python2.7/site-packages/bokeh/server/util.pyt   check_whitelistK   s
    c         C` sK  |  s d t  | ƒ g Sg  } x'|  D]} d | k rI t j d | ƒ n  | d k rh | j | ƒ q$ n  | j d ƒ } t | ƒ d k r¼ | d d k r¨ t d ƒ ‚ n  | j | d	 ƒ q$ t | ƒ d
 k r3y t | d ƒ Wn! t k
 rt d | ƒ ‚ n X| d d k r#t d ƒ ‚ n  | j | ƒ q$ t d | ƒ ‚ q$ W| S(   un  

    This whitelist 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
            whitelist.

            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 whitelist 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.

    u
   localhost:u   *u›   Host wildcard %r will allow connections originating from multiple (or possibly all) hostnames or IPs. Use non-wildcard values to restrict access explicitlyu   :i   i    u    u   Empty host valueu   :80i   u   Invalid port in host value: %su   Invalid host value: %s(   t   strt   logt   warningt   appendt   splitR   t
   ValueErrort   int(   t	   host_listR   t   hostsR   t   parts(    (    s0   lib/python2.7/site-packages/bokeh/server/util.pyt   create_hosts_whiteliste   s4    
c         C` s  d |  k r' |  j  d d ƒ \ }  } n d } d | k ri | j  d d ƒ \ } } | d k ro d } qo n d } | d k	 r‹ | | k r‹ t S|  j d ƒ }  | j d ƒ } t | ƒ t |  ƒ k rÅ t Sx? t |  | ƒ D]. \ } } | | k sÕ | d k rÿ qÕ qÕ t SqÕ Wt S(   ua   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

    u   :i   u   *u   .N(   t   rsplitt   Nonet   FalseR   R   t   zipR   (   R   R   t	   host_portt   pattern_portt   ht   p(    (    s0   lib/python2.7/site-packages/bokeh/server/util.pyR   ¤   s&    2(   u   bind_socketsu   check_whitelistu   create_hosts_whitelistu
   match_host(   t   __doc__t
   __future__R    R   R   R   t   loggingt	   getLoggert   __name__R   t   tornadoR   t   __all__R
   R   R"   R   (    (    (    s0   lib/python2.7/site-packages/bokeh/server/util.pyt   <module>
   s   "		   			?