o
    ]<                     @   sh  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 zddlmZ W n eyM   ddlmZ Y nw g d	Zd
ZdZe	je	je	je	jefZedg dZejd)ddZG dd de Z!G dd dedg dZ"dd Z#dd Z$dd Z%dd Z&ddd e&e#fd!d"Z'd e#fd#d$Z(g Z)d%d& Z*d'd( Z+dS )*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                 c   s    | j du rdV  dS tj}i }|t_|dur0|j D ]\}}d|vr%q|j||< || qdV  |t_|durP| D ]\}}||jv rO|j| | q>dS dS )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
connection r$   F/tmp/google-cloud-sdk/lib/third_party/apitools/base/py/http_wrapper.py_Httplib2DebuglevelK   s,   


r&   c                   @   sN   e Zd ZdZdddZedd Zejd	d Zed
d Zejdd ZdS )r   z1Class encapsulating the data for an HTTP request. GETNc                 C   s,   || _ || _|p	i | _d | _d | _|| _d S N)urlhttp_methodheaders_Request__body_Request__loggable_bodybody)selfr*   r+   r,   r/   r$   r$   r%   __init__{   s   

zRequest.__init__c                 C      | j S r)   )r.   r0   r$   r$   r%   r         zRequest.loggable_bodyc                 C   s   | j d u r
td|| _d S )Nz0Cannot set loggable body on request with no body)r/   r   RequestErrorr.   )r0   valuer$   r$   r%   r      s
   

c                 C   r2   r)   )r-   r3   r$   r$   r%   r/      r4   zRequest.bodyc                 C   sf   || _ |durt| j ddpt| j }t|| jd< n| jdd t|tdtj	fs1d| _
dS dS )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   )r0   r6   body_lengthr$   r$   r%   r/      s   
)r'   r(   Nr'   )	__name__
__module____qualname____doc__r1   propertyr   setterr/   r$   r$   r$   r%   r   w   s    



r   c                   @   sL   e Zd ZdZdZdd Zedd Zedd Zed	d
 Z	edd Z
dS )r   z.Class encapsulating data for an HTTP response.r$   c                 C   r2   r)   )r7   r3   r$   r$   r%   __len__   s   zResponse.__len__c                 C   sf   dd }d| j v rd| j v r|| j d S d| j v r"t| 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                 S   sD   |  d\}}}| d\}}}| d\}}}t|t| d S )N /-   )	partitionint)content_range_
range_spec
byte_rangestartendr$   r$   r%   ProcessContentRange   s   z,Response.length.<locals>.ProcessContentRangez-content-encodingzcontent-ranger8   )inforN   getr:   content)r0   rU   r$   r$   r%   r7      s   



zResponse.lengthc                 C   s   t | jd S )Nstatus)rN   rV   r3   r$   r$   r%   status_code   s   zResponse.status_codec                 C   s   d| j v rt| j d S d S )Nzretry-after)rV   rN   r3   r$   r$   r%   retry_after   s   
zResponse.retry_afterc                 C   s   | j tv o	d| jv S )Nlocation)rZ   _REDIRECT_STATUS_CODESrV   r3   r$   r$   r%   is_redirect   s   
zResponse.is_redirectN)rB   rC   rD   rE   	__slots__rH   rF   r7   rZ   r[   r^   r$   r$   r$   r%   r      s    


r   HttpResponse)rV   rX   request_urlc                 C   sN   | d u rt d| j | jdks| jtkrt j| | jr%t j| d S )Nz,Request to url %s did not return a response.  )	r   r5   ra   rZ   TOO_MANY_REQUESTSBadStatusCodeErrorFromResponser[   RetryAfterError)responser$   r$   r%   r      s   

r   c                 C   s8   t | ddrt| j D ]}d|v r| j|= qdS dS )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   )r9   listr   keys)r   conn_keyr$   r$   r%   r      s   r   c                   G   s    r)   r$   )unused_argsr$   r$   r%   r      s   r   c                 C   s  d}t | jtjtjtjfrtdt| jj	| j nt | jt
jr*td| j nt | jt
jr9td| j n}t | jt
jrHtd| j nnt | jtjrWtd| j n_t | jtretd| j nQt | jtrt| jdr| jjtks}| jjd	krtd
| j n1t | jtjrtd n$t | jtjrtd| jj nt | jtjrtd | jj}n| jt| j td| jj| j t |pt!j"| j#| j$d dS )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), retryingrY   rb   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)%r=   r   r   BadStatusLineIncompleteReadResponseNotReadyloggingdebugr>   rB   socketerrorgaierrortimeoutr   ServerNotFoundError
ValueErrorTokenRefreshErrorhasattrrY   rc   r   r5   rd   rZ   rf   r[   r   r   r   r*   timesleepr   CalculateWaitForRetryr   r   )
retry_argsr[   r$   r$   r%   r
      sl   






r
      <      c                 C   s   d}t   }t| drt| jdh | _	 z	t| |||dW S  tyJ }	 z |d7 }||kr/ t   | }
|t| ||	|||
 W Y d}	~	nd}	~	ww q)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   T)redirectionscheck_response_funcrL   N)rz   ry   setr   _MakeRequestNoRetry	Exceptionr   )r   r   retriesr   r   
retry_funcr   retryfirst_req_timeer   r$   r$   r%   r   9  s*   
r   c           
   	   C   s   d}t | ddrt|jj}|r|| jv r| j| }tjdkr"dnd}t||| d | j	t
|jt
|j|j|j||d\}}W d   n1 sKw   Y  |du rXt t|||j}	||	 |	S )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   )methodr/   r,   r   connection_type)r9   r   urlsplitr*   schemer   r   r   r&   requestr;   r+   r/   r,   r   r5   r   )
r   r   r   r   r   
url_schemenew_debuglevelrV   rX   rg   r$   r$   r%   r   k  s$   
r   c                 C   s   t |  d S r)   )_HTTP_FACTORIESappend)factoryr$   r$   r%   _RegisterHttpFactory  s   r   c                  K   s8   t D ]}|di | }|d ur|  S qtjdi | S )Nr$   )r   r   Http)kwdsr   r   r$   r$   r%   r	     s   r	   r)   ),rE   collections
contextlibrp   rr   rz   r   r?   	six.movesr   six.moves.urllibr   apitools.base.pyr   r   oauth2client.clientr   rx   ImportErrorr   __all__RESUME_INCOMPLETErc   MOVED_PERMANENTLYFOUND	SEE_OTHERTEMPORARY_REDIRECTr]   
namedtupler   contextmanagerr&   objectr   r   r   r   r   r
   r   r   r   r   r	   r$   r$   r$   r%   <module>   sd   +-3=
2
/