U ��.e�r�@s�dZddlZddlZddlZddlmZddlmZddlm Z m Z m Z m Z m Z mZddlmZmZmZmZddlmZmZmZdd lmZmZdd lmZdd lmZmZm Z dd l!m"Z"m#Z#m$Z$m%Z%dd l&m'Z'ddl(m)Z)ddlm*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ddl0m1Z1ddlm2Z2ej3dk�rNz ej4Z5Wne6k �rJej7Z5YnXnejZ5e fdd�Z8e fdd�Z9Gdd�de:�Z;Gdd�de;�ZIsz!merge_setting..)� isinstancer r�update�items)Zrequest_settingZsession_setting� dict_classZmerged_settingZ none_keys�keyr'r'r+� merge_setting1s�� r2cCs@|dks|�d�gkr|S|dks0|�d�gkr4|St|||�S)z�Properly merges both requests and session hooks. This is necessary because when request_hooks == {'response': []}, the merge breaks Session hooks entirely. N�response)�getr2)Z request_hooksZ session_hooksr0r'r'r+� merge_hooksPs r5c@s>eZdZdd�Zdd�Zddd �Zd d �Zd d �Zdd�ZdS)�SessionRedirectMixincCs,|jr(|jd}tr|�d�}t|d�SdS)z7Receives a Response. Returns a redirect URI or ``None``�location�latin1�utf8N)Z is_redirect�headersr�encoder)�self�respr7r'r'r+�get_redirect_targetas    z(SessionRedirectMixin.get_redirect_targetcCs�t|�}t|�}|j|jkr dS|jdkrL|jdkrL|jdkrL|jdkrLdS|j|jk}|j|jk}t�|jd�df}|s�|j|kr�|j|kr�dS|p�|S)zFDecide whether Authorization header should be removed when redirectingTZhttp)�PNZhttps)i�NFN)r Zhostname�schemeZportrr4)r<Zold_urlZnew_urlZ old_parsedZ new_parsedZ changed_portZchanged_schemeZ default_portr'r'r+�should_strip_authvs$ ��  �z&SessionRedirectMixin.should_strip_authFNTc  ksZg} |�|�} t|j�j} | �rV|��} | �|�| dd�|_z |jWn(tt t fk rr|j j dd�YnXt |j�|jkr�td|j|d��|��| �d�r�t|j�}dt|j�| f} t| �}|jd kr�| r�|j| d �}n |jr�|j} |��} |j�st|jt| ��} nt| �} t| �| _|�| |�|jtjtjfk�rld }|D]}| j�|d��qPd| _ | j}z |d =Wnt!k �r�YnXt"| j#||j �t$| j#|j%�| �&| j#�|�'| |�}|�(| |�| j)dk �o�d |k�p�d|k}|�rt*| �| }|�r|Vq|j+|f|||||dd�| ��}t"|j%| |j �|�|�} |VqdS)zBReceives a Response. Returns a generator of Responses or Requests.rNF)Zdecode_contentzExceeded %s redirects.)r3z//z%s:%s�)�fragment)�Content-Lengthz Content-Type�Transfer-EncodingZCookierDrE)�stream�timeout�verify�cert�proxies�allow_redirects),r>r �urlrC�copy�append�history�contentrr� RuntimeError�raw�read�len� max_redirectsr�close� startswithrr@�_replaceZgeturlZnetlocrr�rebuild_method� status_coder$Ztemporary_redirectZpermanent_redirectr:�popZbody�KeyErrorr Z_cookiesr�cookiesZprepare_cookies�rebuild_proxies� rebuild_authZ_body_positionr#�send)r<r=�reqrFrGrHrIrJ�yield_requestsZadapter_kwargsZhistrLZprevious_fragment�prepared_requestZ parsed_rurlZparsedZpurged_headers�headerr:Z rewindabler'r'r+�resolve_redirects�s�             ����  z&SessionRedirectMixin.resolve_redirectscCsR|j}|j}d|kr*|�|jj|�r*|d=|jr8t|�nd}|dk rN|�|�dS)z�When being redirected we may want to strip authentication from the request to avoid leaking credentials. This method intelligently removes and reapplies authentication where possible to avoid credential loss. Z AuthorizationN)r:rLrA�request� trust_envr Z prepare_auth)r<rcr3r:rLZnew_authr'r'r+r_s z!SessionRedirectMixin.rebuild_authc Cs�|dk r |ni}|j}|j}t|�j}|��}|�d�}t||d�}|jr||s|t||d�} | �|| �d��} | r||� || �d|kr�|d=zt ||�\} } Wnt k r�d\} } YnX| r�| r�t | | �|d<|S)a�This method re-evaluates the proxy configuration by considering the environment variables. If we are redirected to a URL covered by NO_PROXY, we strip the proxy configuration. Otherwise, we set missing proxy keys for this URL (in case they were stripped by a previous redirect). This method also replaces the Proxy-Authorization header where necessary. :rtype: dict N�no_proxy�rh�allzProxy-Authorization)NN) r:rLr r@rMr4r!rgr� setdefaultr"r\r) r<rcrJr:rLr@Z new_proxiesrhZ bypass_proxyZenviron_proxies�proxyZusernameZpasswordr'r'r+r^s*       z$SessionRedirectMixin.rebuild_proxiescCsX|j}|jtjkr|dkrd}|jtjkr6|dkr6d}|jtjkrN|dkrNd}||_dS)z�When being redirected we may want to change the method of the request based on certain specs or browser behavior. �HEAD�GET�POSTN)�methodrZr$Z see_other�foundZmoved)r<rcr3rpr'r'r+rY=sz#SessionRedirectMixin.rebuild_method)FNTNNF) �__name__� __module__� __qualname__r>rArer_r^rYr'r'r'r+r6_s� q)r6c@s�eZdZdZdddddddd d d d d dg Zdd�Zdd�Zdd�Zdd�Zd7dd�Z dd�Z dd�Z dd �Z d8d!d"�Z d9d#d$�Zd:d%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�ZdS);�Sessiona�A Requests session. Provides cookie persistence, connection-pooling, and configuration. Basic Usage:: >>> import requests >>> s = requests.Session() >>> s.get('https://httpbin.org/get') Or as a context manager:: >>> with requests.Session() as s: >>> s.get('https://httpbin.org/get') r:r]�authrJ�hooks�paramsrHrIZprefetch�adaptersrFrgrUcCsrt�|_d|_i|_t�|_i|_d|_d|_d|_ t |_ d|_ t i�|_t�|_|�dt��|�dt��dS)NFTzhttps://zhttp://)rr:rvrJrrwrxrFrHrIrrUrgr r]rry�mountr�r<r'r'r+�__init__ms zSession.__init__cCs|Sr&r'r{r'r'r+� __enter__�szSession.__enter__cGs |��dSr&)rV)r<�argsr'r'r+�__exit__�szSession.__exit__c Cs�|jpi}t|tj�st|�}ttt�|j�|�}|j}|jrR|sR|jsRt |j �}t �}|j |j ��|j |j|j|jt|j|jtd�t|j|j�t||j�|t|j|j�d� |S)a�Constructs a :class:`PreparedRequest ` for transmission and returns it. The :class:`PreparedRequest` has settings merged from the :class:`Request ` instance and those of the :class:`Session`. :param request: :class:`Request` instance to prepare with this session's settings. :rtype: requests.PreparedRequest )r0) rprL�files�data�jsonr:rxrvr]rw)r]r-rZ CookieJarr rr rvrgr rLrZpreparerp�upperr�r�r�r2r:rrxr5rw)r<rfr]Zmerged_cookiesrv�pr'r'r+�prepare_request�s0   �    � zSession.prepare_requestNTc Cstt|��||||pi||pi||| d� }|�|�}| p8i} |�|j| | ||�}| | d�}|�|�|j|f|�}|S)aConstructs a :class:`Request `, prepares it and sends it. Returns :class:`Response ` object. :param method: method for the new :class:`Request` object. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json to send in the body of the :class:`Request`. :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. :param files: (optional) Dictionary of ``'filename': file-like-objects`` for multipart encoding upload. :param auth: (optional) Auth tuple or callable to enable Basic/Digest/Custom HTTP Auth. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple :param allow_redirects: (optional) Set to True by default. :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol or protocol and hostname to the URL of the proxy. :param stream: (optional) whether to immediately download the response content. Defaults to ``False``. :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to ``True``. :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. :rtype: requests.Response ) rprLr:r�r�r�rxrvr]rw)rGrK)rr�r��merge_environment_settingsrLr.r`)r<rprLrxr�r:r]r�rvrGrKrJrwrFrHrIr�raZprepZsettingsZ send_kwargsr=r'r'r+rf�s6)� �� zSession.requestcKs|�dd�|jd|f|�S)z�Sends a GET request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response rKTrn�rkrf�r<rL�kwargsr'r'r+r4s z Session.getcKs|�dd�|jd|f|�S)z�Sends a OPTIONS request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response rKTZOPTIONSr�r�r'r'r+�options$s zSession.optionscKs|�dd�|jd|f|�S)z�Sends a HEAD request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response rKFrmr�r�r'r'r+�head/s z Session.headcKs|jd|f||d�|��S)a�Sends a POST request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response ro)r�r��rf)r<rLr�r�r�r'r'r+�post:s z Session.postcKs|jd|fd|i|��S)auSends a PUT request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response ZPUTr�r��r<rLr�r�r'r'r+�putGs z Session.putcKs|jd|fd|i|��S)awSends a PATCH request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response ZPATCHr�r�r�r'r'r+�patchSs z Session.patchcKs|jd|f|�S)z�Sends a DELETE request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response ZDELETEr�r�r'r'r+�delete_szSession.deletec Ksz|�d|j�|�d|j�|�d|j�|�d|j�t|t�rJtd��|�dd�}|� d�}|j }|j |j d�}t �}|j|f|�}t �|} t| d �|_td ||f|�}|jr�|jD]} t|j| j| j�q�t|j||j�|j||f|�} |�rd d �| D�ng} | �r*| �d |�| ��}| |_|�sjz"t|j||fddi|���|_Wntk �rhYnX|�sv|j|S)zISend a given PreparedRequest. :rtype: requests.Response rFrHrIrJz#You can only send PreparedRequests.rKT)rL)Zsecondsr3cSsg|]}|�qSr'r')r(r=r'r'r+r,�sz Session.send..rrb)rkrFrHrIrJr-r� ValueErrorr[r4rw� get_adapterrL�preferred_clockr`r�elapsedrrOr r]rfrRre�insert�nextZ_next� StopIterationrP) r<rfr�rKrFrw�adapter�start�rr�r=�genrOr'r'r+r`isB       "z Session.sendc Cs�|jrn|dk r|�d�nd}t||d�}|��D]\}} |�|| �q0|dksV|dkrntj�d�pltj�d�}t||j�}t||j �}t||j �}t||j �}||||d�S)z^ Check the environment and merge it with some settings. :rtype: dict NrhriTZREQUESTS_CA_BUNDLEZCURL_CA_BUNDLE)rHrJrFrI) rgr4rr/rk�os�environr2rJrFrHrI) r<rLrJrFrHrIrhZ env_proxiesr)r*r'r'r+r��s    �    �z"Session.merge_environment_settingscCs>|j��D]"\}}|���|���r |Sq td|��dS)z~ Returns the appropriate connection adapter for the given URL. :rtype: requests.adapters.BaseAdapter z*No connection adapters were found for '%s'N)ryr/�lowerrWr)r<rL�prefixr�r'r'r+r��s zSession.get_adaptercCs|j��D] }|��q dS)z+Closes all adapters and as such the sessionN)ry�valuesrV)r<r*r'r'r+rV�sz Session.closecs>||j�<�fdd�|jD�}|D]}|j�|�|j|<q"dS)zwRegisters a connection adapter to a prefix. Adapters are sorted in descending order by prefix length. cs g|]}t|�t��kr|�qSr')rT)r(r)�r�r'r+r,�sz!Session.mount..N)ryr[)r<r�r�Z keys_to_mover1r'r�r+rz�s z Session.mountcs�fdd��jD�}|S)Ncsi|]}|t�|d��qSr&)�getattr)r(�attrr{r'r+� �sz(Session.__getstate__..)� __attrs__)r<�stater'r{r+� __getstate__�szSession.__getstate__cCs"|��D]\}}t|||�qdSr&)r/�setattr)r<r�r��valuer'r'r+� __setstate__�szSession.__setstate__)NNNNNNNTNNNNNN)NN)N)N)rrrsrt�__doc__r�r|r}rr�rfr4r�r�r�r�r�r�r`r�r�rVrzr�r�r'r'r'r+ruTs`�7)� G    I rucCst�S)aZ Returns a :class:`Session` for context-management. .. deprecated:: 1.0.0 This method has been deprecated since version 1.0.0 and is only kept for backwards compatibility. New code should use :class:`~requests.sessions.Session` to create a session. This may be removed at a future date. :rtype: Session )rur'r'r'r+�session�s r�)>r�r��sys�timeZdatetimerrvr�compatrrrrr r r]r r r rZmodelsrrrrwrrZ_internal_utilsrZutilsrrr� exceptionsrrrrZ structuresrryrrrr r!r"r#Z status_codesr$r%�platform� perf_counterr��AttributeErrorZclockr2r5�objectr6rur�r'r'r'r+�s@             v%