o
    NK&hS                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	 er*d dl
mZ d dlmZ eed ed	 ed
 ed ed ed f Zd ZdZejej d Zed Zdd eedd D Zdd Zedee jZG dd dZG dd dZdS )    )annotationsN)datetime)TYPE_CHECKINGUnion)ServerError)Header)LiteralStrictLaxNonestrictlaxnone)r   r   r   z!#$%&'*+-.^_`|~:z ()/<=>?@[]{}c                 C  s   i | ]	}|d |dqS )\03o ).0chr   r   I/var/www/html/venv/lib/python3.10/site-packages/sanic/cookies/response.py
<dictcomp>    s    r       s   ";\c                 C  s&   | du st | r
| S d| t dS )zQuote a string for use in a cookie header.
    If the string does not need to be double-quoted, then just return the
    string.  Otherwise, surround the string in doublequotes and quote
    (with a \) special characters.
    N")_is_legal_key	translate
TRANSLATOR)strr   r   r   _quote#   s   r   z[%s]+c                   @  s   e Zd ZdZdZd2ddZdd Zed3ddZ				d4d5ddZ					d4d6ddZ
ddddddddddddd7d,d-Zdddddd.d8d0d1ZdS )9	CookieJaraO  A container to manipulate cookies.

    CookieJar dynamically writes headers as cookies are added and removed
    It gets around the limitation of one header per name by using the
    MultiHeader class to provide a unique key that encodes to Set-Cookie.

    Args:
        headers (Header): The headers object to write cookies to.
    z
Set-Cookieheadersr   c                 C  
   || _ d S N)r   )selfr   r   r   r   __init__?      
zCookieJar.__init__c                 C  s
   t | jS r    )lencookiesr!   r   r   r   __len__B   r#   zCookieJar.__len__returnlist[Cookie]c                 C  s   | j | jg S )z|A list of cookies in the CookieJar.

        Returns:
            List[Cookie]: A list of cookies in the CookieJar.
        )r   getall
HEADER_KEYr&   r   r   r   r%   E   s   zCookieJar.cookies/NFkeyr   pathdomain
str | Nonehost_prefixboolsecure_prefixCookie | Nonec                 C  s@   | j D ]}|jt|||kr|j|kr|j|kr|  S qdS )a  Fetch a cookie from the CookieJar.

        Args:
            key (str): The key of the cookie to fetch.
            path (str, optional): The path of the cookie. Defaults to `"/"`.
            domain (Optional[str], optional): The domain of the cookie.
                Defaults to `None`.
            host_prefix (bool, optional): Whether to add __Host- as a prefix to the key.
                This requires that path="/", domain=None, and secure=True.
                Defaults to `False`.
            secure_prefix (bool, optional): Whether to add __Secure- as a prefix to the key.
                This requires that secure=True. Defaults to `False`.

        Returns:
            Optional[Cookie]: The cookie if it exists, otherwise `None`.
        Nr%   r-   Cookiemake_keyr.   r/   r!   r-   r.   r/   r1   r3   cookier   r   r   
get_cookieN   s   


zCookieJar.get_cookiec                 C  s>   | j D ]}|jt|||kr|j|kr|j|kr dS qdS )a  Check if a cookie exists in the CookieJar.

        Args:
            key (str): The key of the cookie to check.
            path (str, optional): The path of the cookie. Defaults to `"/"`.
            domain (Optional[str], optional): The domain of the cookie.
                Defaults to `None`.
            host_prefix (bool, optional): Whether to add __Host- as a prefix to the key.
                This requires that path="/", domain=None, and secure=True.
                Defaults to `False`.
            secure_prefix (bool, optional): Whether to add __Secure- as a prefix to the key.
                This requires that secure=True. Defaults to `False`.

        Returns:
            bool: Whether the cookie exists.
        TFr5   r8   r   r   r   
has_cookieo   s   


zCookieJar.has_cookieTr
   r.   r/   securemax_ageexpireshttponlysamesitepartitionedcommentr1   r3   valuer=   r>   
int | Noner?   datetime | Noner@   rA   SameSite | NonerB   rC   r6   c                C  s6   t ||||||||||	|
||d}| j| j| |S )a5
  Add a cookie to the CookieJar.

        Args:
            key (str): Key of the cookie.
            value (str): Value of the cookie.
            path (str, optional): Path of the cookie. Defaults to "/".
            domain (Optional[str], optional): Domain of the cookie. Defaults to None.
            secure (bool, optional): Whether to set it as a secure cookie. Defaults to True.
            max_age (Optional[int], optional): Max age of the cookie in seconds; if set to 0 a
                browser should delete it. Defaults to None.
            expires (Optional[datetime], optional): When the cookie expires; if set to None browsers
                should set it as a session cookie. Defaults to None.
            httponly (bool, optional): Whether to set it as HTTP only. Defaults to False.
            samesite (Optional[SameSite], optional): How to set the samesite property, should be
                strict, lax, or none (case insensitive). Defaults to "Lax".
            partitioned (bool, optional): Whether to set it as partitioned. Defaults to False.
            comment (Optional[str], optional): A cookie comment. Defaults to None.
            host_prefix (bool, optional): Whether to add __Host- as a prefix to the key.
                This requires that path="/", domain=None, and secure=True. Defaults to False.
            secure_prefix (bool, optional): Whether to add __Secure- as a prefix to the key.
                This requires that secure=True. Defaults to False.

        Returns:
            Cookie: The instance of the created cookie.

        Raises:
            ServerError: If host_prefix is set without secure=True.
            ServerError: If host_prefix is set without path="/" and domain=None.
            ServerError: If host_prefix is set with domain.
            ServerError: If secure_prefix is set without secure=True.
            ServerError: If partitioned is set without host_prefix=True.

        Examples:
            Basic usage
            ```python
            cookie = add_cookie('name', 'value')
            ```

            Adding a cookie with a custom path and domain
            ```python
            cookie = add_cookie('name', 'value', path='/custom', domain='example.com')
            ```

            Adding a secure, HTTP-only cookie with a comment
            ```python
            cookie = add_cookie('name', 'value', secure=True, httponly=True, comment='My Cookie')
            ```

            Adding a cookie with a max age of 60 seconds
            ```python
            cookie = add_cookie('name', 'value', max_age=60)
            ```
        )r.   r?   rC   r/   r>   r=   r@   rA   rB   r1   r3   )r6   r   addr+   )r!   r-   rD   r.   r/   r=   r>   r?   r@   rA   rB   rC   r1   r3   r9   r   r   r   
add_cookie   s"   FzCookieJar.add_cookie)r.   r/   r=   r1   r3   r   c          
      C  s   |r|r|dkr|du st d|r|st d| j| jg }d}|D ]%}	|	jt|||ks:|	j|ks:|	j|krC| j	| j|	 q$|du rI|	}q$|durf| j
|d|j|j|jd|j|j|j||d dS | j
|d|||dd||d	 dS )	a  
        Delete a cookie

        This will effectively set it as Max-Age: 0, which a browser should
        interpret it to mean: "delete the cookie".

        Since it is a browser/client implementation, your results may vary
        depending upon which client is being used.

        :param key: The key to be deleted
        :type key: str
        :param path: Path of the cookie, defaults to None
        :type path: Optional[str], optional
        :param domain: Domain of the cookie, defaults to None
        :type domain: Optional[str], optional
        :param secure: Whether to delete a secure cookie. Defaults to True.
        :param secure: bool
        :param host_prefix: Whether to add __Host- as a prefix to the key.
            This requires that path="/", domain=None, and secure=True,
            defaults to False
        :type host_prefix: bool
        :param secure_prefix: Whether to add __Secure- as a prefix to the key.
            This requires that secure=True, defaults to False
        :type secure_prefix: bool
        r,   NzQCannot set host_prefix on a cookie without path='/', domain=None, and secure=True8Cannot set secure_prefix on a cookie without secure=True r   )r-   rD   r.   r/   r=   r>   r@   rB   rA   r1   r3   )	r-   rD   r.   r/   r=   r>   rA   r1   r3   )r   r   popallr+   r-   r6   r7   r.   r/   rH   rI   r=   r@   rB   rA   )
r!   r-   r.   r/   r=   r1   r3   r%   existing_cookier9   r   r   r   delete_cookie   sV   #



zCookieJar.delete_cookie)r   r   )r(   r)   )r,   NFF)r-   r   r.   r   r/   r0   r1   r2   r3   r2   r(   r4   )r-   r   r.   r   r/   r0   r1   r2   r3   r2   r(   r2   )r-   r   rD   r   r.   r   r/   r0   r=   r2   r>   rE   r?   rF   r@   r2   rA   rG   rB   r2   rC   r0   r1   r2   r3   r2   r(   r6   )r-   r   r.   r   r/   r0   r=   r2   r1   r2   r3   r2   r(   r   )__name__
__module____qualname____doc__r+   r"   r'   propertyr%   r:   r;   rI   rN   r   r   r   r   r   2   sF    

$&]r   c                   @  s  e Zd ZdZdZdZdZddddd	d
dddd	Zh dZdddddddddddddMd(d)Z	d*d+ Z
edNd-d.ZejdOd0d.ZedPd1d2ZejdQd4d2ZedRd5d6ZejdOd7d6ZedRd8d9ZejdOd:d9ZedSd;d<ZejdTd>d<ZedUd?d@ZejdVdAd@ZedUdBdCZejdVdDdCZedWdEdFZejdXdGdFZedUdHdIZejdVdJdIZe	dYdZdKdLZdS )[r6   a'  A representation of a HTTP cookie, providing an interface to manipulate cookie attributes intended for a response.

    This class is a simplified representation of a cookie, similar to the Morsel SimpleCookie in Python's standard library.
    It allows the manipulation of various cookie attributes including path, domain, security settings, and others.

    Several "smart defaults" are provided to make it easier to create cookies that are secure by default. These include:

    - Setting the `secure` flag to `True` by default
    - Setting the `samesite` flag to `Lax` by default

    Args:
        key (str): The key (name) of the cookie.
        value (str): The value of the cookie.
        path (str, optional): The path for the cookie. Defaults to "/".
        domain (Optional[str], optional): The domain for the cookie.
            Defaults to `None`.
        secure (bool, optional): Whether the cookie is secure.
            Defaults to `True`.
        max_age (Optional[int], optional): The maximum age of the cookie
            in seconds. Defaults to `None`.
        expires (Optional[datetime], optional): The expiration date of the
            cookie. Defaults to `None`.
        httponly (bool, optional): HttpOnly flag for the cookie.
            Defaults to `False`.
        samesite (Optional[SameSite], optional): The SameSite attribute for
            the cookie. Defaults to `"Lax"`.
        partitioned (bool, optional): Whether the cookie is partitioned.
            Defaults to `False`.
        comment (Optional[str], optional): A comment for the cookie.
            Defaults to `None`.
        host_prefix (bool, optional): Whether to use the host prefix.
            Defaults to `False`.
        secure_prefix (bool, optional): Whether to use the secure prefix.
            Defaults to `False`.
    z__Host-z	__Secure-)r-   rD   _path_comment_domain_secure	_httponly_partitioned_expires_max_age	_samesitePathCommentDomainzMax-Ager?   SameSiteSecureHttpOnlyPartitioned)	r.   rC   r/   max-ager?   rA   r=   r@   rB   >   r=   r@   rB   r,   NTFr
   r<   r-   r   rD   r.   r/   r0   r=   r2   r>   rE   rF   r@   rA   rG   rB   rC   r1   r3   c                C  s   || j v r	tdt|std|r(|std|dkr!td|r'tdn|r0|s0td|
r8|s8td| |||| _|| _|| _|| _|| _	|| _
|| _|
| _d | _d | _d | _|d ure|| _|d url|| _|	d uru|	| _d S d S )	NzCookie name is a reserved wordz&Cookie key contains illegal charactersz6Cannot set host_prefix on a cookie without secure=Truer,   z2Cannot set host_prefix on a cookie unless path='/'z8Cannot set host_prefix on a cookie with a defined domainrJ   zHCannot create a partitioned cookie without also setting host_prefix=True)_keysKeyErrorr   r   r7   r-   rD   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r?   r>   rA   )r!   r-   rD   r.   r/   r=   r>   r?   r@   rA   rB   rC   r1   r3   r   r   r   r"     sX   

zCookie.__init__c              
     s  d | jt| jg}t| j  t| j  fdddD ]i}t| |	dd}|dur|dur|d	krZz|
d
| j| |f  W q tyY   |
d | j| | Y qw |dkrn|
d| j| |df  q|| jv r||
| j|  q|
d | j| | qd|S )z$Format as a Set-Cookie header value.z{}={}c                   s
     | S r    )index)kordered_keysr   r   <lambda>  s   
 z Cookie.__str__.<locals>.<lambda>)r-   -_NFrd   z%s=%dr?   z%s=%sz%a, %d-%b-%Y %T GMTz; )formatr-   r   rD   listre   keyssortedgetattrreplaceappend	TypeErrorstrftime_flagsjoin)r!   outputr-   rD   r   ri   r   __str__  s4   


zCookie.__str__r(   c                 C     | j S )z*The path of the cookie. Defaults to `"/"`.rT   r&   r   r   r   r.        zCookie.pathr   c                 C  r   r    r|   r!   rD   r   r   r   r.        
c                 C  r{   )z6The expiration date of the cookie. Defaults to `None`.)rZ   r&   r   r   r   r?     r}   zCookie.expiresr   c                 C  s   t |ts	td|| _d S )Nz,Cookie 'expires' property must be a datetime)
isinstancer   ru   rZ   r~   r   r   r   r?     s   

c                 C  r{   )z-A comment for the cookie. Defaults to `None`.rU   r&   r   r   r   rC     r}   zCookie.commentc                 C  r   r    r   r~   r   r   r   rC     r   c                 C  r{   )z-The domain of the cookie. Defaults to `None`.rV   r&   r   r   r   r/      r}   zCookie.domainc                 C  r   r    r   r~   r   r   r   r/     r   c                 C  r{   )z=The maximum age of the cookie in seconds. Defaults to `None`.)r[   r&   r   r   r   r>   	  r}   zCookie.max_ageintc                 C  s   t | s
td|| _d S )Nz!Cookie max-age must be an integer)r   isdigit
ValueErrorr[   r~   r   r   r   r>     s   
c                 C  r{   )z1Whether the cookie is secure. Defaults to `True`.rW   r&   r   r   r   r=     r}   zCookie.securec                 C  r   r    r   r~   r   r   r   r=     r   c                 C  r{   )z5Whether the cookie is HTTP only. Defaults to `False`.rX   r&   r   r   r   r@     r}   zCookie.httponlyc                 C  r   r    r   r~   r   r   r   r@   "  r   c                 C  r{   )z;The SameSite attribute for the cookie. Defaults to `"Lax"`.)r\   r&   r   r   r   rA   &  r}   zCookie.samesitec                 C  s.   |  tvrtddt | | _d S )Nz+Cookie 'samesite' property must be one of: ,)lowerSAMESITE_VALUESru   rx   titler\   r~   r   r   r   rA   +  s   c                 C  r{   )z7Whether the cookie is partitioned. Defaults to `False`.rY   r&   r   r   r   rB   4  r}   zCookie.partitionedc                 C  r   r    r   r~   r   r   r   rB   9  r   c                 C  s4   |r|rt d|r| j| }|S |r| j| }|S )a  Create a cookie key with the appropriate prefix.

        Cookies can have one ow two prefixes. The first is `__Host-` which
        requires that the cookie be set with `path="/", domain=None, and
        secure=True`. The second is `__Secure-` which requires that
        `secure=True`.

        They cannot be combined.

        Args:
            key (str): The key (name) of the cookie.
            host_prefix (bool, optional): Whether to add __Host- as a prefix to the key.
                This requires that path="/", domain=None, and secure=True.
                Defaults to `False`.
            secure_prefix (bool, optional): Whether to add __Secure- as a prefix to the key.
                This requires that secure=True. Defaults to `False`.

        Raises:
            ServerError: If both host_prefix and secure_prefix are set.

        Returns:
            str: The key with the appropriate prefix.
        zXBoth host_prefix and secure_prefix were requested. A cookie should have only one prefix.)r   HOST_PREFIXSECURE_PREFIX)clsr-   r1   r3   r   r   r   r7   =  s   

zCookie.make_key)r-   r   rD   r   r.   r   r/   r0   r=   r2   r>   rE   r?   rF   r@   r2   rA   rG   rB   r2   rC   r0   r1   r2   r3   r2   )r(   r   )rD   r   r(   r   )r(   rF   )rD   r   r(   r   )r(   r0   )r(   rE   )rD   r   r(   r   )r(   r2   )rD   r2   r(   r   )r(   rG   )rD   r`   r(   r   )FF)r-   r   r1   r2   r3   r2   r(   r   )rO   rP   rQ   rR   r   r   	__slots__re   rw   r"   rz   rS   r.   setterr?   rC   r/   r>   r=   r@   rA   rB   classmethodr7   r   r   r   r   r6   @  s    $Br6   )
__future__r   restringr   typingr   r   sanic.exceptionsr   sanic.compatr   r   r`   DEFAULT_MAX_AGEr   ascii_lettersdigitsLEGAL_CHARSUNESCAPED_CHARSbytesranger   r   compileescape	fullmatchr   r   r6   r   r   r   r   <module>   s:    	  