o
    	c;*                     @   s   d dl mZ z
d dlmZmZ W n ey!   d dlmZmZ Y nw zd dlmZ W n ey:   G dd dZY nw d dlm	Z	 ddl
mZ dd	lmZ dd
lmZmZ ddgZe ZG dd deZG dd deZdS )    )absolute_import)MappingMutableMapping)RLockc                   @   s   e Zd Zdd Zdd ZdS )r   c                 C      d S N selfr   r   A/opt/certbot/lib/python3.10/site-packages/urllib3/_collections.py	__enter__      zRLock.__enter__c                 C   r   r   r   )r
   exc_type	exc_value	tracebackr   r   r   __exit__   r   zRLock.__exit__N)__name__
__module____qualname__r   r   r   r   r   r   r      s    r   )OrderedDict   )InvalidHeader)six)iterkeys
itervaluesRecentlyUsedContainerHTTPHeaderDictc                   @   sV   e Zd ZdZeZdddZdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd ZdS )r   a  
    Provides a thread-safe dict-like container which maintains up to
    ``maxsize`` keys while throwing away the least-recently-used keys beyond
    ``maxsize``.

    :param maxsize:
        Maximum number of recent elements to retain.

    :param dispose_func:
        Every time an item is evicted from the container,
        ``dispose_func(value)`` is called.  Callback which will get called
    
   Nc                 C   s"   || _ || _|  | _t | _d S r   )_maxsizedispose_funcContainerCls
_containerr   lock)r
   maxsizer   r   r   r   __init__/   s   
zRecentlyUsedContainer.__init__c                 C   sD   | j  | j|}|| j|< |W  d    S 1 sw   Y  d S r   )r"   r!   pop)r
   keyitemr   r   r   __getitem__6   s
   
$z!RecentlyUsedContainer.__getitem__c                 C   s   t }| j% | j|t }|| j|< t| j| jkr#| jjdd\}}W d    n1 s-w   Y  | jr@|t urB| | d S d S d S )NF)last)_Nullr"   r!   getlenr   popitemr   )r
   r&   valueevicted_value_keyr   r   r   __setitem__=   s   

z!RecentlyUsedContainer.__setitem__c                 C   sJ   | j  | j|}W d    n1 sw   Y  | jr#| | d S d S r   )r"   r!   r%   r   )r
   r&   r.   r   r   r   __delitem__L   s   z!RecentlyUsedContainer.__delitem__c                 C   s4   | j  t| jW  d    S 1 sw   Y  d S r   )r"   r,   r!   r	   r   r   r   __len__S   s   $zRecentlyUsedContainer.__len__c                 C   s   t d)Nz7Iteration over this class is unlikely to be threadsafe.)NotImplementedErrorr	   r   r   r   __iter__W   s   zRecentlyUsedContainer.__iter__c                 C   s`   | j  tt| j}| j  W d    n1 sw   Y  | jr,|D ]	}| | q$d S d S r   )r"   listr   r!   clearr   )r
   valuesr.   r   r   r   r7   \   s   zRecentlyUsedContainer.clearc                 C   s8   | j  tt| jW  d    S 1 sw   Y  d S r   )r"   r6   r   r!   r	   r   r   r   keysf   s   $zRecentlyUsedContainer.keys)r   N)r   r   r   __doc__r   r    r$   r(   r1   r2   r3   r5   r7   r9   r   r   r   r   r      s    

c                       s   e Zd ZdZd- fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
ejr.ejZejZe Zdd Zdd ZefddZdd Zdd Zdd ZefddZeZeZeZeZdd  Zd!d" Zd#d$ Zd%d& Z d'd( Z!d)d* Z"e#d+d, Z$  Z%S ).r   ap  
    :param headers:
        An iterable of field-value pairs. Must not contain multiple field names
        when compared case-insensitively.

    :param kwargs:
        Additional field-value pairs to pass in to ``dict.update``.

    A ``dict`` like container for storing HTTP Headers.

    Field names are stored and compared case-insensitively in compliance with
    RFC 7230. Iteration provides the first case-sensitive key seen for each
    case-insensitive pair.

    Using ``__setitem__`` syntax overwrites fields that compare equal
    case-insensitively in order to maintain ``dict``'s api. For fields that
    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
    in a loop.

    If multiple fields that are equal case-insensitively are passed to the
    constructor or ``.update``, the behavior is undefined and some will be
    lost.

    >>> headers = HTTPHeaderDict()
    >>> headers.add('Set-Cookie', 'foo=bar')
    >>> headers.add('set-cookie', 'baz=quxx')
    >>> headers['content-length'] = '7'
    >>> headers['SET-cookie']
    'foo=bar, baz=quxx'
    >>> headers['Content-Length']
    '7'
    Nc                    sT   t t|   t | _|d urt|tr| | n| | |r(| | d S d S r   )superr   r$   r   r!   
isinstance
_copy_fromextend)r
   headerskwargs	__class__r   r   r$      s   

zHTTPHeaderDict.__init__c                 C   s    ||g| j | < | j |  S r   r!   lowerr
   r&   valr   r   r   r1      s   zHTTPHeaderDict.__setitem__c                 C   s    | j |  }d|dd  S )N, r   r!   rD   joinrE   r   r   r   r(      s   zHTTPHeaderDict.__getitem__c                 C   s   | j | = d S r   rC   r
   r&   r   r   r   r2      s   zHTTPHeaderDict.__delitem__c                 C   s   |  | jv S r   )rD   r!   rJ   r   r   r   __contains__   s   zHTTPHeaderDict.__contains__c                 C   s^   t |tst|dsdS t |t| st| |}tdd |  D tdd | D kS )Nr9   Fc                 s   s     | ]\}}|  |fV  qd S r   )rD   ).0kvr   r   r   	<genexpr>   s    z(HTTPHeaderDict.__eq__.<locals>.<genexpr>)r<   r   hasattrtypedict
itermergedr
   otherr   r   r   __eq__   s   
zHTTPHeaderDict.__eq__c                 C   s   |  | S r   )rV   rT   r   r   r   __ne__      zHTTPHeaderDict.__ne__c                 C   s
   t | jS r   )r,   r!   r	   r   r   r   r3      s   
zHTTPHeaderDict.__len__c                 c   s     | j  D ]}|d V  qd S )Nr   )r!   r8   )r
   valsr   r   r   r5      s   zHTTPHeaderDict.__iter__c                 C   s:   z| | }W n t y   || ju r | Y S w | |= |S )zD.pop(k[,d]) -> v, remove specified key and return the corresponding value.
        If key is not found, d is returned if given, otherwise KeyError is raised.
        )KeyError_HTTPHeaderDict__marker)r
   r&   defaultr.   r   r   r   r%      s   
zHTTPHeaderDict.popc                 C   s"   z| |= W d S  t y   Y d S w r   )rZ   rJ   r   r   r   discard   s
   zHTTPHeaderDict.discardc                 C   s8   |  }||g}| j||}||ur|| dS dS )zAdds a (name, value) pair, doesn't overwrite the value if it already
        exists.

        >>> headers = HTTPHeaderDict(foo='bar')
        >>> headers.add('Foo', 'baz')
        >>> headers['foo']
        'bar, baz'
        N)rD   r!   
setdefaultappend)r
   r&   rF   	key_lowernew_valsrY   r   r   r   add   s   	zHTTPHeaderDict.addc                 O   s   t |dkrtdt |t |dkr|d nd}t|tr0| D ]
\}}| || q$n5t|trC|D ]
}| |||  q7n"t|drX|	 D ]
}| |||  qLn|D ]
\}}| || qZ|
 D ]
\}}| || qidS )zGeneric import function for any type of header-like object.
        Adapted version of MutableMapping.update in order to insert items
        with self.add instead of self.__setitem__
        r   z9extend() takes at most 1 positional arguments ({0} given)r   r   r9   N)r,   	TypeErrorformatr<   r   	iteritemsrb   r   rP   r9   items)r
   argsr@   rU   r&   rF   r.   r   r   r   r>      s.   



zHTTPHeaderDict.extendc                 C   sH   z	| j |  }W n ty   || ju rg  Y S | Y S w |dd S )zmReturns a list of all the values for the named field. Returns an
        empty list if the key doesn't exist.r   N)r!   rD   rZ   r[   )r
   r&   r\   rY   r   r   r   getlist  s   
zHTTPHeaderDict.getlistc                 C   s   dt | jt|  f S )Nz%s(%s))rQ   r   rR   rS   r	   r   r   r   __repr__  s   zHTTPHeaderDict.__repr__c                 C   s>   |D ]}| |}t|trt|}|g| | j| < qd S r   )rh   r<   r6   r!   rD   )r
   rU   r&   rF   r   r   r   r=     s   

zHTTPHeaderDict._copy_fromc                 C   s   t |  }||  |S r   )rQ   r=   )r
   cloner   r   r   copy"  s   

zHTTPHeaderDict.copyc                 c   s>    | D ]}| j |  }|dd D ]	}|d |fV  qqdS )z8Iterate over all header lines, including duplicate ones.r   Nr   rC   )r
   r&   rY   rF   r   r   r   re   '  s   zHTTPHeaderDict.iteritemsc                 c   s:    | D ]}| j |  }|d d|dd fV  qdS )z:Iterate over all headers, merging duplicate ones together.r   rG   r   NrH   rE   r   r   r   rS   .  s
   zHTTPHeaderDict.itermergedc                 C   s   t |  S r   )r6   re   r	   r   r   r   rf   4  rX   zHTTPHeaderDict.itemsc                 C   s~   d}g }|j D ]3}||r)|std| |d \}}||d |  f|d< q|dd\}}||| f q| |S )z4Read headers from a Python 2 httplib message object.) 	z/Header continuation with no previous header: %srl   :r   )r?   
startswithr   stripsplitr_   )clsmessageobs_fold_continued_leadersr?   liner&   r.   r   r   r   from_httplib7  s   

zHTTPHeaderDict.from_httplibr   )&r   r   r   r:   r$   r1   r(   r2   rK   rV   rW   r   PY2r   r   r   objectr[   r3   r5   r%   r]   rb   r>   rh   
getheadersgetallmatchingheadersigetget_allri   r=   rk   re   rS   rf   classmethodrw   __classcell__r   r   rA   r   r   k   s@    !	N)
__future__r   collections.abcr   r   ImportErrorcollections	threadingr   r   
exceptionsr   packagesr   packages.sixr   r   __all__ry   r*   r   r   r   r   r   r   <module>   s&    
L