ó
ú2ec        	   @   sÒ  d  Z  d d l Z d d l m Z d d l m Z m Z y d d l m	 Z	 m
 Z
 Wn' e k
 r{ d d l m	 Z	 m
 Z
 n Xy d d l m Z Wn! e k
 r³ d d l m Z n Xd d l Z d d l m Z d	 d
 d d d d d d d g	 Z d „  Z d „  Z d „  Z d „  Z e d d d „ Z e e d d d d „ Z d „  Z d „  Z d „  Z i d d 6d d 6d d  6Z  d! „  Z! d e f d" „  ƒ  YZ" d# „  Z# e# e j$ _% e& d$ k rÎd d l' Z' e' j( ƒ  n  d S(%   sÑ  
This module provides helper routines with work directly on a WSGI
environment to solve common requirements.

   * get_cookies(environ)
   * parse_querystring(environ)
   * parse_formvars(environ, include_get_vars=True)
   * construct_url(environ, with_query_string=True, with_path_info=True,
                   script_name=None, path_info=None, querystring=None)
   * path_info_split(path_info)
   * path_info_pop(environ)
   * resolve_relative_url(url, environ)

iÿÿÿÿN(   t   parse(   t   quotet	   parse_qsl(   t   SimpleCookiet   CookieError(   t	   DictMixin(   t   MutableMapping(   t	   MultiDictt   get_cookiest   get_cookie_dictt   parse_querystringt   parse_formvarst   construct_urlt   path_info_splitt   path_info_popt   resolve_relative_urlt   EnvironHeadersc         C   sƒ   |  j  d d ƒ } d |  k rA |  d \ } } | | k rA | Sn  t ƒ  } y | j | ƒ Wn t k
 rn n X| | f |  d <| S(   sµ   
    Gets a cookie object (which is a dictionary-like object) from the
    request environment; caches this value in case get_cookies is
    called again for the same request.

    t   HTTP_COOKIEt    s   paste.cookies(   t   getR   t   loadR   (   t   environt   headert   cookiest   check_header(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR   *   s    	c         C   s²   |  j  d ƒ } | s i  Sd |  k rH |  d \ } } | | k rH | Sn  t ƒ  } y | j | ƒ Wn t k
 ru n Xi  } x | D] } | | j | | <qƒ W| | f |  d <| S(   s#  Return a *plain* dictionary of cookies as found in the request.

    Unlike ``get_cookies`` this returns a dictionary, not a
    ``SimpleCookie`` object.  For incoming cookies a dictionary fully
    represents the information.  Like ``get_cookies`` this caches and
    checks the cache.
    R   s   paste.cookies.dict(   R   R   R   R   t   value(   R   R   R   R   t   resultt   name(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR	   >   s"    	c         C   sw   |  j  d d ƒ } | s g  Sd |  k rK |  d \ } } | | k rK | Sn  t | d t d t ƒ} | | f |  d <| S(   s<  
    Parses a query string into a list like ``[(name, value)]``.
    Caches this value in case parse_querystring is called again
    for the same request.

    You can pass the result to ``dict()``, but be aware that keys that
    appear multiple times will be lost (only the last value will be
    preserved).

    t   QUERY_STRINGR   s   paste.parsed_querystringt   keep_blank_valuest   strict_parsing(   R   R   t   Truet   False(   R   t   sourcet   parsedt   check_source(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR
   X   s    	c         C   s†   |  j  d d ƒ } | s t ƒ  Sd |  k rN |  d \ } } | | k rN | Sn  t | d t d t ƒ} t | ƒ } | | f |  d <| S(   sÊ  Parses a query string like parse_querystring, but returns a MultiDict

    Caches this value in case parse_dict_querystring is called again
    for the same request.

    Example::

        >>> environ = {'QUERY_STRING': 'day=Monday&user=fred&user=jane'}
        >>> parsed = parse_dict_querystring(environ)

        >>> parsed['day']
        'Monday'
        >>> parsed['user']
        'fred'
        >>> parsed.getall('user')
        ['fred', 'jane']

    R   R   s   paste.parsed_dict_querystringR   R   (   R   R   R   R   R    (   R   R!   R"   R#   t   multi(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   parse_dict_querystringo   s    	c         C   sô  |  d } d |  k rU |  d \ } } | | k rU | rN | j  t |  ƒ ƒ n  | Sn  t ƒ  } |  j d d ƒ j d ƒ d j ƒ  } | d k }	 |  j d	 ƒ s« d
 |  d	 <n  |	 rÄ|  j d d ƒ }
 d |  d <|  d } i  } t j r| rù | | d <n  | r| | d <qn  t j	 d | d |  d t
 |  } |
 |  d <t | j t ƒ rÄxr | j ƒ  D]a } | | } t | t ƒ s„| g } n  x3 | D]+ } | j s¦| j } n  | j | | ƒ q‹WqYWqÄn  | | f |  d <| rð| j  t |  ƒ ƒ n  | S(   s¥  Parses the request, returning a MultiDict of form variables.

    If ``include_get_vars`` is true then GET (query string) variables
    will also be folded into the MultiDict.

    All values should be strings, except for file uploads which are
    left as ``FieldStorage`` instances.

    If the request was not a normal form request (e.g., a POST with an
    XML body) then ``environ['wsgi.input']`` won't be read.
    s
   wsgi.inputs   paste.parsed_formvarst   CONTENT_TYPER   t   ;i    s!   application/x-www-form-urlencodeds   multipart/form-datat   CONTENT_LENGTHt   0R   t   encodingt   errorst   fpR   R   (   R   s!   application/x-www-form-urlencodeds   multipart/form-data(   t   updateR
   R   R   t	   partitiont   lowert   sixt   PY3t   cgit   FieldStorageR   t
   isinstanceR   t   listt   keyst   filenamet   add(   R   t   include_get_varsR*   R+   R!   R"   R#   t   formvarst   ctt   use_cgit   old_query_stringt   inpt   kwparmst   fsR   t   valuesR   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR      sR    
	%	

		

	c   	      C   s	  |  d d } |  j  d ƒ rÈ |  d } d } d | k r¤ | j d d ƒ \ } } |  d d k ry | d k r¡ d } q¡ q¤ |  d d k r¤ | d	 k r¡ d } q¡ q¤ n  | | 7} | r3| d
 | 7} q3nk | |  d 7} |  d d k r|  d d k r3| d |  d 7} q3n% |  d d	 k r3| d |  d 7} n  | d k r^| t |  j  d d ƒ ƒ 7} n | t | ƒ 7} | r²| d k rŸ| t |  j  d d ƒ ƒ 7} q²| t | ƒ 7} n  | r| d k rë|  j  d ƒ r| d |  d 7} qq| r| d | 7} qn  | S(   s“   Reconstructs the URL from the WSGI environment.

    You may override SCRIPT_NAME, PATH_INFO, and QUERYSTRING with
    the keyword arguments.

    s   wsgi.url_schemes   ://t	   HTTP_HOSTt   :i   t   httpst   443t   httpt   80s   :%st   SERVER_NAMEt   SERVER_PORTt   SCRIPT_NAMER   t	   PATH_INFOR   t   ?N(   R   t   Nonet   splitR   (	   R   t   with_query_stringt   with_path_infot   script_namet	   path_infot   querystringt   urlt   hostt   port(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR   Ë   sF    

c         C   s"   t  | d t ƒ} t j | |  ƒ S(   s  
    Resolve the given relative URL as being relative to the
    location represented by the environment.  This can be used
    for redirecting to a relative path.  Note: if url is already
    absolute, this function will (intentionally) have no effect
    on it.

    RO   (   R   R    t   urlparset   urljoin(   RT   R   t   cur_url(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR   ý   s    	c         C   sx   |  s
 d S|  j d ƒ s) t d |  ƒ ‚ |  j d ƒ }  d |  k rj |  j d d ƒ \ } } | d | f S|  d f Sd S(   s   
    Splits off the first segment of the path.  Returns (first_part,
    rest_of_path).  first_part can be None (if PATH_INFO is empty), ''
    (if PATH_INFO is '/'), or a name without any /'s.  rest_of_path
    can be '' or a string starting with /.

    R   t   /s!   PATH_INFO should start with /: %ri   N(   NR   (   RM   t
   startswitht   AssertionErrort   lstripRN   (   RR   t   firstt   rest(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR   	  s    c         C   s´   |  j  d d ƒ } | s d Sx- | j d ƒ rK |  d c d 7<| d } q Wd | k rv |  d c | 7<d |  d <| S| j d d ƒ \ } } d | |  d <|  d c | 7<| Sd S(   s†  
    'Pops' off the next segment of PATH_INFO, pushing it onto
    SCRIPT_NAME, and returning that segment.

    For instance::

        >>> def call_it(script_name, path_info):
        ...     env = {'SCRIPT_NAME': script_name, 'PATH_INFO': path_info}
        ...     result = path_info_pop(env)
        ...     print('SCRIPT_NAME=%r; PATH_INFO=%r; returns=%r' % (
        ...         env['SCRIPT_NAME'], env['PATH_INFO'], result))
        >>> call_it('/foo', '/bar')
        SCRIPT_NAME='/foo/bar'; PATH_INFO=''; returns='bar'
        >>> call_it('/foo/bar', '')
        SCRIPT_NAME='/foo/bar'; PATH_INFO=''; returns=None
        >>> call_it('/foo/bar', '/')
        SCRIPT_NAME='/foo/bar/'; PATH_INFO=''; returns=''
        >>> call_it('', '/1/2/3')
        SCRIPT_NAME='/1'; PATH_INFO='/2/3'; returns='1'
        >>> call_it('', '//1/2')
        SCRIPT_NAME='//1'; PATH_INFO='/2'; returns='1'

    RK   R   RZ   RJ   i   N(   R   RM   R[   RN   (   R   t   patht   segment(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR     s    
t   Authorizationt   HTTP_CGI_AUTHORIZATIONs   Content-LengthR(   s   Content-TypeR&   c         c   sr   xk |  j  ƒ  D]] \ } } | t k r7 t | | f Vq | j d ƒ r | d j ƒ  j d d ƒ | f Vq q Wd S(   s‚   
    Parse the headers in the environment (like ``HTTP_HOST``) and
    yield a sequence of those (header_name, value) tuples.
    t   HTTP_i   t   _t   -N(   t	   iteritemst   _parse_headers_specialR[   t   titlet   replace(   R   t   cgi_varR   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   parse_headersK  s
    c           B   sh   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z RS(   sg  An object that represents the headers as present in a
    WSGI environment.

    This object is a wrapper (with no internal state) for a WSGI
    request object, representing the CGI-style HTTP_* keys as a
    dictionary.  Because a CGI environment can only hold one value for
    each key, this dictionary is single-valued (unlike outgoing
    headers).
    c         C   s   | |  _  d  S(   N(   R   (   t   selfR   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __init__b  s    c         C   sJ   d | j  d d ƒ j ƒ  } | d k r1 d } n | d k rF d } n  | S(   NRd   Rf   Re   t   HTTP_CONTENT_LENGTHR(   t   HTTP_CONTENT_TYPER&   (   Rj   t   upper(   Rm   R   t   key(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   _trans_namee  s    		c         C   sQ   | d k r d S| d k r  d S| j  d ƒ rI | d j d d ƒ j ƒ  Sd  Sd  S(	   NR&   s   Content-TypeR(   s   Content-LengthRd   i   Re   Rf   (   R[   Rj   Ri   RM   (   Rm   Rr   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt
   _trans_keym  s    c         C   s   t  |  j ƒ S(   N(   t   lenR   (   Rm   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __len__w  s    c         C   s   |  j  |  j | ƒ S(   N(   R   Rs   (   Rm   t   item(    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __getitem__z  s    c         C   s   | |  j  |  j | ƒ <d  S(   N(   R   Rs   (   Rm   Rw   R   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __setitem__}  s    c         C   s   |  j  |  j | ƒ =d  S(   N(   R   Rs   (   Rm   Rw   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __delitem__  s    c         c   s;   x4 |  j  D]) } |  j | ƒ } | d  k	 r
 | Vq
 q
 Wd  S(   N(   R   Rt   RM   (   Rm   Rr   R   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __iter__„  s    c         C   s   t  t |  ƒ ƒ S(   N(   R5   t   iter(   Rm   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR6   Š  s    c         C   s   |  j  | ƒ |  j k S(   N(   Rs   R   (   Rm   Rw   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   __contains__  s    (   t   __name__t
   __module__t   __doc__Rn   Rs   Rt   Rv   Rx   Ry   Rz   R{   R6   R}   (    (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyR   W  s   				
						c         C   s7   |  j  r d |  j |  j f Sd |  j |  j |  j f S(   sÛ    monkey patch for FieldStorage.__repr__

    Unbelievely, the default __repr__ on FieldStorage reads
    the entire file content instead of being sane about it.
    This is a simple replacement that doesn't do that
    s   FieldStorage(%r, %r)s   FieldStorage(%r, %r, %r)(   t   fileR   R7   R   (   Rm   (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   _cgi_FieldStorage__repr__patch  s
    	t   __main__()   R€   R2   t   six.moves.urllibR    RW   t   six.moves.urllib.parseR   R   t   http.cookiesR   R   t   ImportErrort   Cookiet   UserDictR   t   collections.abcR   R0   t   paste.util.multidictR   t   __all__R   R	   R
   R%   R   RM   R   R   R   R   R   Rh   Rl   R   R‚   R3   t   __repr__R~   t   doctestt   testmod(    (    (    s7   /usr/local/lib/python2.7/dist-packages/paste/request.pyt   <module>   sJ   						 <1			(
	9	