3 ]r @sdZddlZddlZddlZddlmZddlmZddlm 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/ddl0m1Z1ddlm2Z2ej3dkrNy ej4Z5Wne6k rJej7Z5YnXnejZ5e fddZ8e fddZ9Gddde:Z;Gddde;ZIsz!merge_setting..) isinstancer rupdateitems)request_settingsession_setting dict_classmerged_setting none_keyskeyr'r'r+ merge_setting1s     r6cCs@|dks|jdgkr|S|dks0|jdgkr4|St|||S)zProperly merges both requests and session hooks. This is necessary because when request_hooks == {'response': []}, the merge breaks Session hooks entirely. Nresponse)getr6) request_hooks session_hooksr2r'r'r+ merge_hooksPs r;c@s>eZdZddZddZddd Zd d Zd d ZddZdS)SessionRedirectMixincCs,|jr(|jd}tr|jd}t|dSdS)z7Receives a Response. Returns a redirect URI or ``None``locationlatin1utf8N) is_redirectheadersrencoder)selfrespr=r'r'r+get_redirect_targetas    z(SessionRedirectMixin.get_redirect_targetcCst|}t|}|j|jkr dS|jdkrL|jdkrL|jdkrL|jd krLdS|j|jk}|j|jk}tj|jddf}| r|j|kr|j|krdS|p|S) zFDecide whether Authorization header should be removed when redirectingThttpPNhttpsF)rGN)rIN)r hostnameschemeportrr8)rCold_urlnew_url old_parsed new_parsedZ changed_portZchanged_scheme default_portr'r'r+should_strip_authvs    z&SessionRedirectMixin.should_strip_authFNTc ksdg} |j|} t|jj} xB| r^|j} | j|| dd|_y |jWn(tt t fk rv|j j ddYnXt |j|jkrtd|j|d|j| jdrt|j}dt|j| f} t| }|jd kr| r|j| d }n |jr|j} |j} |jst|jt| } nt| } t| | _|j| ||jtjtjfkrtd}x|D]}| jj|dqVWd| _ | j}y |d=Wnt!k rYnXt"| j#||j t$| j#|j%| j&| j#|j'| |}|j(| || j)dk od |kpd |k}|r t*| | }|r|Vq|j+|f|||||dd| }t"|j%| |j |j|} |VqWdS)zBReceives a Response. Returns a generator of Responses or Requests.rNF)decode_contentzExceeded %s redirects.)r7z//z%s:%s)fragmentContent-Length Content-TypeTransfer-EncodingCookie)streamtimeoutverifycertproxiesallow_redirects)rVrWrX),rEr urlrUcopyappendhistorycontentrr RuntimeErrorrawreadlen max_redirectsrclose startswithrrK_replacegeturlnetlocrrrebuild_method status_coder$temporary_redirectpermanent_redirectrApopbodyKeyErrorr _cookiesrcookiesprepare_cookiesrebuild_proxies rebuild_auth_body_positionr#send)rCrDreqrZr[r\r]r^yield_requestsadapter_kwargshistr`Zprevious_fragmentprepared_request parsed_rurlparsedpurged_headersheaderrA rewindabler'r'r+resolve_redirectss|                z&SessionRedirectMixin.resolve_redirectscCsR|j}|j}d|kr*|j|jj|r*|d=|jr8t|nd}|dk rN|j|dS)zWhen 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. AuthorizationN)rAr`rRrequest trust_envr prepare_auth)rCrr7rAr`new_authr'r'r+rzs z!SessionRedirectMixin.rebuild_authc Cs|dk r |ni}|j}|j}t|j}|j}|jd}t||d}|jr~| r~t||d} | j|| jd} | r~|j || d|kr|d=yt ||\} } Wnt k rd\} } YnX| r| rt | | |d<|S)aThis 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 Nno_proxy)rallzProxy-Authorization)NN) rAr`r rKrar8r!rr setdefaultr"rur) rCrr^rAr`rK new_proxiesr bypass_proxyenviron_proxiesproxyusernamepasswordr'r'r+rys*       z$SessionRedirectMixin.rebuild_proxiescCsX|j}|jtjkr|dkrd}|jtjkr6|dkr6d}|jtjkrN|dkrNd}||_dS)zWhen being redirected we may want to change the method of the request based on certain specs or browser behavior. HEADGETPOSTN)methodrpr$ see_otherfoundmoved)rCrr7rr'r'r+ro=sz#SessionRedirectMixin.rebuild_method)FNTNNF) __name__ __module__ __qualname__rErRrrzryror'r'r'r+r<_s p)r<c@seZdZdZdddddddd d d d d dg ZddZddZddZddZd7ddZ ddZ ddZ dd Z d8d!d"Z d9d#d$Zd:d%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6ZdS);SessionaA 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') rArwauthr^hooksparamsr\r]prefetchadaptersrZrricCsrt|_d|_i|_t|_i|_d|_d|_d|_ t |_ d|_ t i|_t|_|jdt|jdtdS)NFTzhttps://zhttp://)rrArr^rrrrZr\r]rrirr rwrrmountr)rCr'r'r+__init__ms zSession.__init__cCs|S)Nr')rCr'r'r+ __enter__szSession.__enter__cGs |jdS)N)rj)rCargsr'r'r+__exit__szSession.__exit__c Cs|jpi}t|tjst|}ttt|j|}|j}|jrV| rV|j rVt |j }t }|j |j j|j |j|j|jt|j|jtdt|j|jt||j|t|j|jd |S)aConstructs 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 )r2) rr`filesdatajsonrArrrwr)rwr-r CookieJarr rr rrr r`rpreparerupperrrrr6rArrr;r)rCrrwmerged_cookiesrpr'r'r+prepare_requests*     zSession.prepare_requestNTc Cstt|j||||pi||pi||| d }|j|}| p8i} |j|j| | ||}| | d}|j||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 ) rr`rArrrrrrwr)r[r_)rrrmerge_environment_settingsr`r.r|)rCrr`rrrArwrrr[r_r^rrZr\r]rr}prepsettings send_kwargsrDr'r'r+rs()  zSession.requestcKs|jdd|jd|f|S)zSends 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 r_Tr)rr)rCr`kwargsr'r'r+r8s z Session.getcKs|jdd|jd|f|S)zSends 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 r_TOPTIONS)rr)rCr`rr'r'r+options$s zSession.optionscKs|jdd|jd|f|S)zSends 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 r_Fr)rr)rCr`rr'r'r+head/s z Session.headcKs|jd|f||d|S)aSends 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 r)rr)r)rCr`rrrr'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 PUTr)r)rCr`rrr'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 PATCHr)r)rCr`rrr'r'r+patchSs z Session.patchcKs|jd|f|S)zSends 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 DELETE)r)rCr`rr'r'r+delete_szSession.deletec Ks~|jd|j|jd|j|jd|j|jd|jt|trJtd|jdd}|j d}|j }|j |j d}t }|j|f|}t |} t| d |_td ||f|}|jrx |jD]} t|j| j| jqWt|j||j|j||f|} |r d d | Dng} | r.| jd || j}| |_|sny"t|j||fddi||_Wntk rlYnX|sz|j|S)zISend a given PreparedRequest. :rtype: requests.Response rZr\r]r^z#You can only send PreparedRequests.r_T)r`)secondsr7cSsg|]}|qSr'r')r(rDr'r'r+r,sz Session.send..rr~)rrZr\r]r^r-r ValueErrorrsr8r get_adapterr`preferred_clockr|relapsedrrcr rwrrfrinsertnext_next StopIterationrd) rCrrr_rZradapterstartrrrDgenrcr'r'r+r|isB       "z Session.sendc Cs|jrr|dk r|jdnd}t||d}x |jD]\}} |j|| q2W|dksZ|dkrrtjjdpptjjd}t||j}t||j }t||j }t||j }||||dS)z^ Check the environment and merge it with some settings. :rtype: dict Nr)rTREQUESTS_CA_BUNDLECURL_CA_BUNDLE)r\r^rZr]) rr8rr/rosenvironr6r^rZr\r]) rCr`r^rZr\r]r env_proxiesr)r*r'r'r+rs       z"Session.merge_environment_settingscCs>x,|jjD]\}}|jj|jr |Sq Wtd|dS)z~ Returns the appropriate connection adapter for the given URL. :rtype: requests.adapters.BaseAdapter z*No connection adapters were found for '%s'N)rr/lowerrkr)rCr`prefixrr'r'r+rszSession.get_adaptercCs x|jjD] }|jq WdS)z+Closes all adapters and as such the sessionN)rvaluesrj)rCr*r'r'r+rjsz Session.closecsB||j<fdd|jD}x|D]}|jj||j|<q$WdS)zwRegisters a connection adapter to a prefix. Adapters are sorted in descending order by prefix length. cs g|]}t|tkr|qSr')rh)r(r))rr'r+r,sz!Session.mount..N)rrs)rCrr keys_to_mover5r')rr+rs  z Session.mountcsfddjD}|S)Ncsi|]}t|d|qS)N)getattr)r(attr)rCr'r+ sz(Session.__getstate__..) __attrs__)rCstater')rCr+ __getstate__szSession.__getstate__cCs&x |jD]\}}t|||q WdS)N)r/setattr)rCrrvaluer'r'r+ __setstate__szSession.__setstate__)NNNNNNNTNNNNNN)NN)N)N)rrr__doc__rrrrrrr8rrrrrrr|rrrjrrrr'r'r'r+rTs2 7) D    I rcCstS)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 )rr'r'r'r+sessions r)>rrsystimedatetimerrrcompatrrrrr r rwr r r rmodelsrrrrrr_internal_utilsrutilsrrr exceptionsrrrr structuresrrrrrr r!r"r# status_codesr$r%platform perf_counterrAttributeErrorclockr6r;objectr<rrr'r'r'r+ s@             v%