
    ]<              	          d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddlmZ ddlmZ 	 ddlmZ g d	Zd
ZdZe	j.                  e	j0                  e	j2                  e	j4                  efZ ej8                  dg d      Zej<                  d d       Z G d de       Z! G d d ej8                  dg d            Z"d Z#d Z$d Z%d Z&ddde&e#fdZ'de#fdZ(g Z)d Z*d Z+y# e$ r	 ddlmZ Y w xY w)!zpHTTP wrapper for apitools.

This library wraps the underlying http library we use, which is
currently httplib2.
    N)http_client)parse)
exceptions)util)HttpAccessTokenRefreshError)AccessTokenRefreshError)CheckResponseGetHttp)HandleExceptionsAndRebuildHttpConnectionsMakeRequestRebuildHttpConnectionsRequestResponseRethrowExceptionHandler4  i  ExceptionRetryArgs)httphttp_requestexcnum_retriesmax_retry_waittotal_wait_secc              #     K   | j                   d yt        j                  }i }|t        _        |G|j                  j	                         D ]*  \  }}d|vr|j                  ||<   |j                  |       , d |t        _        |F|j	                         D ]2  \  }}||j                  v s|j                  |   j                  |       4 yyw)a  Temporarily change the value of httplib2.debuglevel, if necessary.

    If http_request has a `loggable_body` distinct from `body`, then we
    need to prevent httplib2 from logging the full body. This sets
    httplib2.debuglevel for the duration of the `with` block; however,
    that alone won't change the value of existing HTTP connections. If
    an httplib2.Http object is provided, we'll also change the level on
    any cached connections attached to it.

    Args:
      http_request: a Request we're logging.
      level: (int) the debuglevel for logging.
      http: (optional) an httplib2.Http whose connections we should
        set the debuglevel on.

    Yields:
      None.
    N:)loggable_bodyhttplib2
debuglevelconnectionsitemsset_debuglevel)r   levelr   	old_levelhttp_levelsconnection_key
connections          0lib/third_party/apitools/base/py/http_wrapper.py_Httplib2Debuglevelr'   K   s     ( !!)##IKH*.*:*:*@*@*B&NJ
 .(*4*?*?K'%%e, +C 
#H)4):):)<%NI!1!11  0??	J *= s   B-C0"Cc                       e Zd ZdZddZed        Zej                  d        Zed        Zej                  d        Zy)	r   z1Class encapsulating the data for an HTTP request.Nc                 `    || _         || _        |xs i | _        d | _        d | _        || _        y N)urlhttp_methodheaders_Request__body_Request__loggable_bodybody)selfr+   r,   r-   r0   s        r&   __init__zRequest.__init__{   s2    &}"#	    c                     | j                   S r*   )r/   r1   s    r&   r   zRequest.loggable_body   s    ###r3   c                 T    | j                   t        j                  d      || _        y )Nz0Cannot set loggable body on request with no body)r0   r   RequestErrorr/   )r1   values     r&   r   zRequest.loggable_body   s,    99))BD D$r3   c                     | j                   S r*   )r.   r5   s    r&   r0   zRequest.body   s    {{r3   c                 6   || _         |Gt        | j                   dd      xs t        | j                         }t        |      | j                  d<   n| j                  j                  dd       t        |t        d      t        j                  f      sd| _
        yy)z>Sets the request body; handles logging and length measurement.Nlengthcontent-lengthz<media body>)r.   getattrlenstrr-   pop
isinstancetypesixstring_typesr   )r1   r8   body_lengths      r&   r0   zRequest.body   s     !Xt- A03DKK0@ -0-=DLL)*LL-t4%$t*c.>.>!?@!/D Ar3   ) GETNrF   )	__name__
__module____qualname____doc__r2   propertyr   setterr0    r3   r&   r   r   w   sd    ; $ $ % %   
[[0 0r3   r   c                   Z    e Zd ZdZdZd Zed        Zed        Zed        Z	ed        Z
y)	r   z.Class encapsulating data for an HTTP response.rN   c                     | j                   S r*   )r;   r5   s    r&   __len__zResponse.__len__   s    {{r3   c                 >   d }d| j                   v r#d| j                   v r || j                   d         S d| j                   v r$t        | j                   j                  d            S d| j                   v r || j                   d         S t        | j                        S )zReturn the length of this response.

        We expose this as an attribute since using len() directly can fail
        for responses larger than sys.maxint.

        Returns:
          Response length (as int or long)
        c                     | j                  d      \  }}}|j                  d      \  }}}|j                  d      \  }}}t        |      t        |      z
  dz   S )N /-   )	partitionint)content_range_
range_spec
byte_rangestartends         r&   ProcessContentRangez,Response.length.<locals>.ProcessContentRange   s^    ,66s;Aq*)33C8J1&005ME1cs8c%j(1,,r3   z-content-encodingzcontent-ranger<   )inforY   getr>   content)r1   r`   s     r&   r;   zResponse.length   s    	- $))+4990L 'tyy'ABB*tyy}}%5677		)&tyy'ABB4<<  r3   c                 2    t        | j                  d         S )Nstatus)rY   ra   r5   s    r&   status_codezResponse.status_code   s    499X&''r3   c                 P    d| j                   v rt        | j                   d         S y )Nzretry-after)ra   rY   r5   s    r&   retry_afterzResponse.retry_after   s'    DII%tyy/00 &r3   c                 F    | j                   t        v xr d| j                  v S )Nlocation)rf   _REDIRECT_STATUS_CODESra   r5   s    r&   is_redirectzResponse.is_redirect   s'      $:: (dii'	)r3   N)rH   rI   rJ   rK   	__slots__rQ   rL   r;   rf   rh   rl   rN   r3   r&   r   r      sa     9I ! !4 ( ( 1 1 ) )r3   r   HttpResponse)ra   rc   request_urlc                 $   | "t        j                  d| j                  z        | j                  dk\  s| j                  t        k(  rt         j
                  j                  |       | j                  rt         j                  j                  |       y )Nz,Request to url %s did not return a response.  )	r   r7   ro   rf   TOO_MANY_REQUESTSBadStatusCodeErrorFromResponserh   RetryAfterError)responses    r&   r	   r	      s    %%:  !" 	" 

#
%


"3
3++88BB			((55h?? 
r3   c                     t        | dd      r;t        | j                  j                               D ]  }d|v s| j                  |=  yy)a  Rebuilds all http connections in the httplib2.Http instance.

    httplib2 overloads the map in http.connections to contain two different
    types of values:
    { scheme string:  connection class } and
    { scheme + authority string : actual http connection }
    Here we remove all of the entries for actual connections so that on the
    next request httplib2 will rebuild them from the connection types.

    Args:
      http: An httplib2.Http instance.
    r   Nr   )r=   listr   keys)r   conn_keys     r&   r   r      sH     t]D)T--2245Hh$$X. 6 *r3   c                        r*   rN   )unused_argss    r&   r   r      s    	r3   c                    d}t        | j                  t        j                  t        j                  t        j
                  f      r@t        j                  dt        | j                        j                  | j                         nt        | j                  t        j                        r"t        j                  d| j                         nzt        | j                  t        j                        r"t        j                  d| j                         n4t        | j                  t        j                        r"t        j                  d| j                         nt        | j                  t        j                        r"t        j                  d| j                         nt        | j                  t               r"t        j                  d| j                         nlt        | j                  t"              rmt%        | j                  d      rW| j                  j&                  t(        k(  s| j                  j&                  d	k\  r!t        j                  d
| j                         nt        | j                  t*        j,                        rt        j                  d       nt        | j                  t*        j.                        r+t        j                  d| j                  j0                         n\t        | j                  t*        j2                        r,t        j                  d       | j                  j4                  }n| j                  t7        | j8                         t        j                  d| j:                  j<                  | j                         t?        j@                  |xs+ tC        jD                  | jF                  | jH                               y)zException handler for http failures.

    This catches known failures and rebuilds the underlying HTTP connections.

    Args:
      retry_args: An ExceptionRetryArgs tuple.
    Nz"Caught HTTP error %s, retrying: %sz!Caught socket error, retrying: %sz)Caught socket address error, retrying: %sz)Caught socket timeout error, retrying: %sz+Caught server not found error, retrying: %sz+Response content was invalid (%s), retryingre   rq   z8Caught transient credential refresh error (%s), retryingz&Request returned no response, retryingz%Response returned status %s, retryingz0Response returned a retry-after header, retryingz-Retrying request to url %s after exception %s)max_wait)%rA   r   r   BadStatusLineIncompleteReadResponseNotReadyloggingdebugrB   rH   socketerrorgaierrortimeoutr   ServerNotFoundError
ValueErrorTokenRefreshErrorhasattrre   rr   r   r7   rs   rf   ru   rh   r   r   r   r+   timesleepr   CalculateWaitForRetryr   r   )
retry_argsrh   s     r&   r   r      ss    K *..;#<#<#.#=#=#.#?#?#A B 	::>>*33Z^^	E	JNNFLL	19:>>J	JNNFOO	47	I	JNNFNN	37	I	JNNH$@$@	A9:>>	K	JNNJ	/ 	C nn	&
Z^^%6
7
*..(
+>>  $55>>  C'FNN	 
JNNJ$;$;	<>?	JNNJ$A$A	B= nn00	2	JNNJ$>$>	?HI nn00nn:??+MMA))--z~~?JJ 	Ht11""Z-F-FHIr3      <      c                 B   d}t        j                          }t        | d      rt        | j                        dhz
  | _        	 	 t	        | |||      S # t
        $ rB}	|dz  }||k\  r t        j                          |z
  }
 |t        | ||	|||
             Y d}	~	nd}	~	ww xY w_)a  Send http_request via the given http, performing error/retry handling.

    Args:
      http: An httplib2.Http instance, or a http multiplexer that delegates to
          an underlying http, for example, HTTPMultiplexer.
      http_request: A Request to send.
      retries: (int, default 7) Number of retries to attempt on retryable
          replies (such as 429 or 5XX).
      max_retry_wait: (int, default 60) Maximum number of seconds to wait
          when retrying.
      redirections: (int, default 5) Number of redirects to follow.
      retry_func: Function to handle retries on exceptions. Argument is an
          ExceptionRetryArgs tuple.
      check_response_func: Function to validate the HTTP response.
          Arguments are (Response, response content, url).

    Raises:
      InvalidDataFromServerError: if there is no response after retries.

    Returns:
      A Response object.

    r   redirect_codesr   )redirectionscheck_response_funcrW   N)r   r   setr   _MakeRequestNoRetry	Exceptionr   )r   r   retriesr   r   
retry_funcr   retryfirst_req_timeer   s              r&   r   r   9  s    6 EYY[N t%&!$"5"56#>
	O&l$79 9
  	OQJE!%~!=-dL!U.<nN O O	O s   A 	B8BBc           	      :   d}t        | dd      rHt        j                  |j                        j                  }|r|| j
                  v r| j
                  |   }t        j                  dk(  rdnd}t        |||       5  | j                  t        |j                        t        |j                        |j                  |j                  ||      \  }}ddd       t        j                         t!        ||j                        }	 ||	       |	S # 1 sw Y   @xY w)a  Send http_request via the given http.

    This wrapper exists to handle translation between the plain httplib2
    request/response types and the Request and Response types above.

    Args:
      http: An httplib2.Http instance, or a http multiplexer that delegates to
          an underlying http, for example, HTTPMultiplexer.
      http_request: A Request to send.
      redirections: (int, default 5) Number of redirects to follow.
      check_response_func: Function to validate the HTTP response.
          Arguments are (Response, response content, url).

    Returns:
      A Response object.

    Raises:
      RequestError if no response could be parsed.

    Nr      r   )r   )methodr0   r-   r   connection_type)r=   r   urlsplitr+   schemer   r   r   r'   requestr?   r,   r0   r-   r   r7   r   )
r   r   r   r   r   
url_schemenew_debuglevelra   rc   rv   s
             r&   r   r   k  s   , O t]D)^^L$4$45<<
*(8(88"..z:O #--2QN	\>	E  !#l.F.F*G""L,@,@% % Hg 
F |%%''g|'7'78H!O 
F	Es   =ADDc                 .    t         j                  |        y r*   )_HTTP_FACTORIESappend)factorys    r&   _RegisterHttpFactoryr     s    7#r3   c                  ^    t         D ]  } |di | }||c S  t        j                  di | S )NrN   )r   r   Http)kwdsr   r   s      r&   r
   r
     s6    "K # == 4  r3   r*   ),rK   collections
contextlibr   r   r   r   rC   	six.movesr   six.moves.urllibr   apitools.base.pyr   r   oauth2client.clientr   r   ImportErrorr   __all__RESUME_INCOMPLETErr   MOVED_PERMANENTLYFOUND	SEE_OTHERTEMPORARY_REDIRECTrk   
namedtupler   contextmanagerr'   objectr   r   r	   r   r   r   r   r   r   r   r
   rN   r3   r&   <module>r      sG  "       
 ! " ' !QT	   !!""  ,[++ ?@ 
 (K (KV(0f (0Z0)%{%%:< 0)f
@/&

:Iz -.bD$1/Od :;,9,^ $!s  QPQs   C* *C87C8