ó
µ[PEc           @   só   d  Z  d d l Z d d l Z d d l Z d d l Z d d l Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ	 d e
 f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d e f d „  ƒ  YZ e j d ƒ Z d d „ Z d d „ Z e d „ Z e d „ Z d S(   s™  

This module contains classes to support HTTP State Management
Mechanism, also known as Cookies. The classes provide simple
ways for creating, parsing and digitally signing cookies, as
well as the ability to store simple Python objects in Cookies
(using marshalling).

The behaviour of the classes is designed to be most useful
within mod_python applications.

The current state of HTTP State Management standardization is
rather unclear. It appears that the de-facto standard is the
original Netscape specification, even though already two RFC's
have been put out (RFC2109 (1997) and RFC2965 (2000)). The
RFC's add a couple of useful features (e.g. using Max-Age instead
of Expires, but my limited tests show that Max-Age is ignored
by the two browsers tested (IE and Safari). As a result of this,
perhaps trying to be RFC-compliant (by automatically providing
Max-Age and Version) could be a waste of cookie space...

iÿÿÿÿNt   CookieErrorc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR    4   s   t
   metaCookiec           B   s   e  Z d  „  Z RS(   c         C   se   d } | d } | | d <| | d <d „  } d „  } t  d | d | ƒ | d <t j |  | | | ƒ S(   Nt   versiont   patht   domaint   securet   commentt   expirest   max_aget
   commentURLt   discardt   portt   httponlyt   namet   valuet   _valuet   _expirest   __data__t   _valid_attrt	   __slots__c         S   s“   t  | ƒ t  d ƒ k ra y t j | d ƒ } Wn t k
 rN t d | ‚ n Xt j | ƒ } n! | } t j d t j | ƒ ƒ } d | |  _ d  S(   Nt    s   %a, %d-%b-%Y %H:%M:%S GMTs   Invalid expires time: %ss   %s(   t   typet   timet   strptimet
   ValueErrort   mktimet   strftimet   gmtimeR   (   t   selfR   t   t(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   set_expiresL   s    	c         S   s   |  j  S(   N(   R   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   get_expires_   s    t   fgett   fset(   s   versions   pathR   R   R   R	   R
   R   s   discardR   R   (   s   names   valueR   s   _expiress   __data__(   t   propertyR   t   __new__(   t   clst   clsnamet   basest   clsdictR   R   R    R!   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR%   9   s       

		(   R   R   R%   (    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR   7   s   t   Cookiec           B   sV   e  Z d  Z e Z d Z d Z d Z d „  Z e	 e ƒ Z d „  Z
 d „  Z d „  Z RS(   sÁ   
    This class implements the basic Cookie functionality. Note that
    unlike the Python Standard Library Cookie class, this class represents
    a single cookie (not a list of Morsels).
    i    i   i   c         K   s   t  | |  |  } | S(   s¯   
        Parse a Cookie or Set-Cookie header value, and return
        a dict of Cookies. Note: the string should NOT include the
        header name, only the value.
        (   t   _parse_cookie(   t   Classt   strt   kwt   dict(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   parses   s    c         K   sK   | | |  _  |  _ x( | D]  } t |  | j ƒ  | | ƒ q Wi  |  _ d S(   sÉ   
        This constructor takes at least a name and value as the
        arguments, as well as optionally any of allowed cookie attributes
        as defined in the existing cookie standards. 
        N(   R   R   t   setattrt   lowerR   (   R   R   R   R.   t   k(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   __init__   s    c         C   sˆ   d |  j  |  j f g } x_ |  j D]T } t |  | ƒ r# | d k rT | j | ƒ qw | j d | t |  | ƒ f ƒ q# q# Wd j | ƒ S(   s¤  
        Provides the string representation of the Cookie suitable for
        sending to the browser. Note that the actual header name will
        not be part of the string.

        This method makes no attempt to automatically double-quote
        strings that contain special characters, even though the RFC's
        dictate this. This is because doing so seems to confuse most
        browsers out there.
        s   %s=%sR   R   R   s   ; (   s   secures   discards   httponly(   R   R   R   t   hasattrt   appendt   getattrt   join(   R   t   resultR   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   __str__   s    'c         C   s   d |  j  j t |  ƒ f S(   Ns   <%s: %s>(   t	   __class__R   R-   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   __repr__¥   s    (   R   R   t   __doc__R   t   __metaclass__t	   DOWNGRADEt   IGNOREt	   EXCEPTIONR0   t   classmethodR4   R:   R<   (    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR*   f   s   	
		t   SignedCookiec           B   sP   e  Z d  Z e j d „ Z e e ƒ Z d d „ Z d „  Z	 d „  Z
 d „  Z RS(   sx  
    This is a variation of Cookie that provides automatic
    cryptographic signing of cookies and verification. It uses
    the HMAC support in the Python standard library. This ensures
    that the cookie has not been tamprered with on the client side.

    Note that this class does not encrypt cookie data, thus it
    is still plainly visible as part of the cookie.
    c   	      K   sÈ   t  | |  |  } g  } x‘ | D]‰ } | | } y | j | ƒ Wq t k
 r§ | t j k re ‚  q¨ | t j k r„ | j | ƒ q¨ t j t j | ƒ ƒ | | | <q Xq Wx | D] } | | =q³ W| S(   N(	   R+   t   unsignR    R*   RA   R@   R6   R0   R:   (	   R,   t   st   secrett   mismatchR.   R/   t   del_listR3   t   c(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR0   µ   s    
(c         K   s'   t  j |  | | |  | |  j d <d  S(   NRF   (   R*   R4   R   (   R   R   R   RF   R.   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR4   Î   s    c         C   sL   |  j  d s t d ‚ n  t j |  j  d |  j ƒ } | j | ƒ | j ƒ  S(   NRF   s   Cannot sign without a secret(   R   R    t   hmact   newR   t   updatet	   hexdigest(   R   R-   t   _hmac(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyRM   Ó   s
    c         C   s—   d |  j  |  j |  j ƒ |  j f g } x_ |  j D]T } t |  | ƒ r2 | d k rc | j | ƒ q† | j d | t |  | ƒ f ƒ q2 q2 Wd j | ƒ S(   Ns   %s=%s%sR   R   R   s   %s=%ss   ; (   s   secures   discards   httponly(   R   RM   R   R   R5   R6   R7   R8   (   R   R9   R   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR:   Ú   s    'c         C   s…   |  j  d  |  j  d } } t j | |  j ƒ } | j | ƒ | j ƒ  | k rh | |  _  | |  j d <n t d |  j |  j  f ‚ d  S(   Ni    RF   s    Incorrectly Signed Cookie: %s=%s(   R   RJ   RK   R   RL   RM   R   R    (   R   RF   t   sigt   valt   mac(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyRD   æ   s    	N(   R   R   R=   R*   R?   R0   RB   t   NoneR4   RM   R:   RD   (    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyRC   ª   s   			t   MarshalCookiec           B   s;   e  Z d  Z e j d „ Z e e ƒ Z d „  Z d „  Z RS(   sä  
    This is a variation of SignedCookie that can store more than
    just strings. It will automatically marshal the cookie value,
    therefore any marshallable object can be used as value.

    The standard library Cookie module provides the ability to pickle
    data, which is a major security problem. It is believed that unmarshalling
    (as opposed to unpickling) is safe, yet we still err on the side of caution
    which is why this class is a subclass of SignedCooke making sure what
    we are about to unmarshal passes the digital signature test.

    Here is a link to a sugesstion that marshalling is safer than unpickling
    http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=7xn0hcugmy.fsf%40ruckus.brouhaha.com
    c   	      K   sÈ   t  | |  |  } g  } x‘ | D]‰ } | | } y | j | ƒ Wq t k
 r§ | t j k re ‚  q¨ | t j k r„ | j | ƒ q¨ t j t j | ƒ ƒ | | | <q Xq Wx | D] } | | =q³ W| S(   N(	   R+   t	   unmarshalR    R*   RA   R@   R6   R0   R:   (	   R,   RE   RF   RG   R.   R/   RH   R3   RI   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR0     s    
(c         C   sÁ   t  j t j |  j ƒ ƒ } d j | j ƒ  ƒ } d |  j |  j | ƒ | f g } x_ |  j	 D]T } t
 |  | ƒ r\ | d k r | j | ƒ q° | j d | t |  | ƒ f ƒ q\ q\ Wd j | ƒ S(	   NR   s   %s=%s%sR   R   R   s   %s=%ss   ; (   s   secures   discards   httponly(   t   base64t   encodestringt   marshalt   dumpsR   R8   t   splitR   RM   R   R5   R6   R7   (   R   t   mR9   R   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR:     s    "'c         C   s–   |  j  | ƒ y t j |  j ƒ } Wn  t d |  j |  j f ‚ n Xy t j | ƒ |  _ Wn3 t t	 t
 f k
 r‘ t d |  j |  j f ‚ n Xd  S(   Ns"   Cannot base64 Decode Cookie: %s=%ss   Cannot Unmarshal Cookie: %s=%s(   RD   RU   t   decodestringR   R    R   RW   t   loadst   EOFErrorR   t	   TypeError(   R   RF   t   data(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyRT   .  s    (	   R   R   R=   R*   R?   R0   RB   R:   RT   (    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyRS   ô   s
   	sJ   (?x)[,\ ]*(?P<key>[^;\ =]+)\ *(=\ *)?(?P<val>"(?:[^\\"]|\\.)*"|[^;]*)\s*;?c         C   s‡   i  } t  j |  ƒ } xk | D]c } | j d ƒ | j d ƒ } } | d d k r] | d  k si | | k r | | | ƒ | | <q q W| S(   Nt   keyRP   i    t   $(   t   _cookiePatternt   finditert   groupRR   (   R-   R,   t   namesR9   t	   matchItert   matchR`   RP   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyR+   O  s    (R   c         K   si   t  | t ƒ s$ t | | |  } n  |  j j d ƒ sL |  j j d d ƒ n  |  j j d t | ƒ ƒ d S(   sq   
    Sets a cookie in outgoing headers and adds a cache
    directive so that caches don't cache the cookie.
    s
   Set-Cookies   Cache-Controls   no-cache="set-cookie"N(   t
   isinstanceR*   t   headers_outt   has_keyt   addR-   (   t   reqt   cookieR   R.   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt
   add_cookie`  s
    c         K   s]   |  j  j d ƒ s i  S|  j  d } t | ƒ t g  ƒ k rM d j | ƒ } n  | j | |  S(   sŽ   
    A shorthand for retrieveing and parsing cookies given
    a Cookie class. The class must be one of the classes from
    this module.
    Rm   s   ; (   t
   headers_inRj   R   R8   R0   (   Rl   R,   R.   t   cookies(    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   get_cookiesq  s    c         K   s6   t  |  | d | g | } | j | ƒ r2 | | Sd  S(   NRe   (   Rq   Rj   (   Rl   R   R,   R.   Rp   (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt
   get_cookie  s    (   R=   R   t   reRJ   RW   RU   t	   ExceptionR    R   R   t   objectR*   RC   RS   t   compileRb   RR   R+   Rn   Rq   Rr   (    (    (    s5   /usr/lib/python2.7/dist-packages/mod_python/Cookie.pyt   <module>*   s    /DJL	