o
    eW                     @   s  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Zd dlm	Z	m
Z
 d dlmZ d dlmZmZmZmZ d dlZd dlmZ d dlmZ zd dlmZ W n eyc   G dd	 d	eZY nw d
dlmZmZ d
dlmZmZ e e!fZ"G dd deZ#G dd de#Z$G dd de#Z%G dd de#Z&G dd de'Z(G dd de'Z)G dd de)Z*G dd de'Z+G dd de+Z,G dd  d e+Z-dS )!    N)xrange	cStringIO)	urlencode)print_reraisestring_types	text_type)encode_multipart_formdata)RequestField)DNSErrorc                   @      e Zd ZdS )r   N__name__
__module____qualname__ r   r   JD:\Projects\ConvertPro\env\Lib\site-packages\geventhttpclient/useragent.pyr      s    r      )URLto_key_val_list)
HTTPClientHTTPClientPoolc                       s,   e Zd Zdd Zdd Z fddZ  ZS )ConnectionErrorc                 O   s   || _ | j| |r<t|d tr<z|d |dd   | _W n+ ty;   |r6|d d t|dd   nd| _Y nw t|dkrHt|d nd| _|rq|  j| jrUdnd7  _d	dd t
|D | _|  j| j7  _d S d| _d S )Nr   r   z:  , c                 s   s     | ]\}}d ||f V  qdS )z%s=%sNr   ).0keyvalr   r   r   	<genexpr>)   s    z+ConnectionError.__init__.<locals>.<genexpr>)url__dict__update
isinstancer   text	TypeErrorstrlenjoinsix	iteritemskwargs_text)selfr   argskwargsr   r   r   __init__   s   *
zConnectionError.__init__c                 C   s    | j rd| j| j f S d| j S )Nz
URL %s: %szURL %s)r#   r   r+   r   r   r   __str__.   s   
zConnectionError.__str__c                    s.   t   }| jr|ddd| jdgS |S )N)r   r   )super__repr__r*   replacer'   )r+   repr_str	__class__r   r   r3   4   s   
zConnectionError.__repr__)r   r   r   r.   r0   r3   __classcell__r   r   r6   r   r      s    r   c                   @   r   )RetriesExceededNr   r   r   r   r   r9   ;       r9   c                   @   r   )BadStatusCodeNr   r   r   r   r   r;   ?   r:   r;   c                   @   r   )EmptyResponseNr   r   r   r   r   r<   C   r:   r<   c                   @   s   e Zd ZdZd"ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
edd Zd#ddZdd Zdd Zdd Zdd Zdd Zd d! ZdS )$CompatRequestzr urllib / cookielib compatible request class.
        See also: http://docs.python.org/library/cookielib.html
    GETNc                 C   s0   || _ | | | jj| _|| _|| _|| _d S N)paramsset_url	url_splithostoriginal_hostmethodheaderspayload)r+   r   rE   rF   rG   r@   r   r   r   r.   L   s   


zCompatRequest.__init__c                 C   s:   t |trt|| _|| _d S || _t| j| jd| _d S )N)r@   )r"   r   r%   r   rB   r@   )r+   r   r   r   r   rA   T   s
   


zCompatRequest.set_urlc                 C      | j S r?   r   r/   r   r   r   get_full_url\      zCompatRequest.get_full_urlc                 C      | j jS r?   )rB   rC   r/   r   r   r   get_host_      zCompatRequest.get_hostc                 C   rL   r?   )rB   schemer/   r   r   r   get_typeb   rN   zCompatRequest.get_typec                 C   rH   r?   )rD   r/   r   r   r   get_origin_req_hoste   rK   z!CompatRequest.get_origin_req_hostc                 C      dS )zM See http://tools.ietf.org/html/rfc2965.html. Not fully implemented!
        Fr   r/   r   r   r   is_unverifiableh      zCompatRequest.is_unverifiablec                 C   s   |   S r?   )rS   r/   r   r   r   unverifiablem   s   zCompatRequest.unverifiablec                 C   s   | j ||S r?   )rF   get)r+   header_namedefaultr   r   r   
get_headerq      zCompatRequest.get_headerc                 C   s
   || j v S r?   rF   )r+   rW   r   r   r   
has_headert      
zCompatRequest.has_headerc                 C   
   | j  S r?   )rF   itemsr/   r   r   r   header_itemsw   r]   zCompatRequest.header_itemsc                 C   s   | j || d S r?   )rF   add)r+   r   r   r   r   r   add_unredirected_headerz   s   z%CompatRequest.add_unredirected_headerc                 C   s&   d| _ d | _dD ]}| j| qd S )Nr>   )content-lengthcontent-typecontent-encoding)rE   rG   rF   discardr+   itemr   r   r   _drop_payload}   s
   zCompatRequest._drop_payloadc                 C   s   dD ]}| j | qd S )N)cookieZcookie2)rF   rf   rg   r   r   r   _drop_cookies   s   zCompatRequest._drop_cookiesc                 C   s.   |  | j| |dv r|   |   dS )z9 Modify the request inplace to point to the new location ).  /  N)rA   rB   redirectri   rk   )r+   codelocationr   r   r   rn      s   zCompatRequest.redirect)r>   NNNr?   )r   r   r   __doc__r.   rA   rJ   rM   rP   rQ   rS   propertyrU   rY   r\   r`   rb   ri   rk   rn   r   r   r   r   r=   G   s$    


r=   c                   @   s   e Zd ZdZdZd$ddZedd Zedd	 Zed
d Z	d%ddZ
dd Zdd Zd&ddZedd Zdd Zdd Zdd Zdd Zd d! Zd"d# ZdS )'CompatResponsez7 Adapter for urllib responses with some extensions
    )rF   	_response_request_sent_request_cached_contentNc                 C   s    || _ || _|| _| j j| _d S r?   )rt   ru   rv   Z_headers_indexrF   )r+   Zghc_responserequestsent_requestr   r   r   r.      s   zCompatResponse.__init__c                 C   s
   t | jS )z" The returned http status
        )r%   status_coder/   r   r   r   status   s   
zCompatResponse.statusc                 C   r^   )z/ The http status code as plain integer
        )rt   get_coder/   r   r   r   rz      s   
zCompatResponse.status_codec                 C   rH   r?   rt   r/   r   r   r   stream      zCompatResponse.streamc                 C   s   | j |S )z- Read n bytes from the response body
        )rt   read)r+   nr   r   r   r      s   zCompatResponse.readc                 C   r^   r?   )rt   readliner/   r   r   r   r      r]   zCompatResponse.readlinec                 C   r^   r?   )rt   releaser/   r   r   r   r      r]   zCompatResponse.releaseTFc                 C   s`   | j  }|rt|dtj S |rt|S z	t|tj W S  tjy/   t| Y S w )N   )rt   r   zlib
decompress	MAX_WBITSbrotlierror)r+   gzipbrZbodystrr   r   r   unzipped   s   

zCompatResponse.unzippedc                 C   s,   z| j W S  ty   |  | _ | j  Y S w )zV Unzips if necessary and buffers the received body. Careful with large files!
        )rw   AttributeError_contentr/   r   r   r   content   s   

zCompatResponse.contentc                 C   s   z| j dd  }W n ty   d}Y nw |dkr#| jdd}n1|dkr.| jdd}n&|dkr8| j }n|d	krD| jddd
}n|dkrNtd| td| |   |S )Nre   r   identityr   T)r   deflateFr   )r   r   compressz"Compression type not supported: %szUnknown content encoding: %s)	rF   
getheaderslower
IndexErrorr   rt   r   
ValueErrorr   )r+   content_typeretr   r   r   r      s$   zCompatResponse._contentc              	   C   s8   zt | jdd W S  ttfy   t| j Y S w )zD The content lengths as should be returned from the headers
        rc   r   )intrF   r   r   r   r&   r   r/   r   r   r   __len__   s
   zCompatResponse.__len__c                 C   rR   )zU If we have an empty response body, we still don't want to evaluate as false
        Tr   r/   r   r   r   __nonzero__   rT   zCompatResponse.__nonzero__c                 C   rH   )z2 Adaption to cookielib: Alias for headers
        r[   r/   r   r   r   info   s   zCompatResponse.infoc                 C   s   | S r?   r   r/   r   r   r   	__enter__   s   zCompatResponse.__enter__c                 G      |    d S r?   )r   )r+   r,   r   r   r   __exit__      zCompatResponse.__exit__)NNr?   )TF)r   r   r   rq   	__slots__r.   rr   r{   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs      s,    






	rs   c                   @   s,   e Zd ZdZdd Zdd Zedd ZdS )	RestkitCompatResponsezI Some extra lines to also serve as a drop in replacement for restkit
    c                 C   rH   r?   )r   r/   r   r   r   body_string  rK   z!RestkitCompatResponse.body_stringc                 C   rH   r?   r}   r/   r   r   r   body_stream  rK   z!RestkitCompatResponse.body_streamc                 C   rH   r?   )rz   r/   r   r   r   
status_int  r   z RestkitCompatResponse.status_intN)r   r   r   rq   r   r   rr   r   r   r   r   r   r      s    r   c                   @   s   e Zd ZeZeZeg dZeg dZ			d#ddZ
dd	 Zd
d Zd$ddZdd Zd%ddZdd Zd%ddZd%ddZdedddddfddZed%ddZedd Zd&d!d"ZdS )'	UserAgent)      -  rl   rm   3  )r   rl   rm   r      r   Nc                 K   sP   t || _t || _|| _tj | _|r| j| || _	t
di || _d S )Nr   )r   max_redirectsmax_retriesretry_delayr   ZDEFAULT_HEADERScopydefault_headersr!   	cookiejarr   
clientpool)r+   r   r   r   r   rF   r-   r   r   r   r.     s   

zUserAgent.__init__c                 C   s   | j   d S r?   )r   closer/   r   r   r   r     rZ   zUserAgent.closec                 C   r   r?   )r   r/   r   r   r   __del__!  r   zUserAgent.__del__r>   c           
      C   s   | j  }|r|| |s|rH|dd }|r&| ||\}	}|	}||d< t|tr6|s1d|d< t|}n|sBt|trBd|d< n|sHd|d< | j	|||||dS )Nrd   z0application/x-www-form-urlencoded; charset=utf-8ztext/plain; charset=utf-8zapplication/octet-stream)rE   rF   rG   r@   )
r   r   r!   rV   _encode_filesr"   dictr   r   request_type)
r+   r   rE   rF   rG   r@   filesZreq_headersr   bodyr   r   r   _make_request$  s$   




zUserAgent._make_requestc                 C   s<   | j |j}|j|j|jj|j|jd}| j|||j	dS )N)r   rF   )rx   ry   )
r   Z
get_clientrB   rx   rE   request_urirG   rF   response_typerv   )r+   rx   clientrespr   r   r   _urlopen9  s
   zUserAgent._urlopenc                 C   s   || j vrt||ddS ) Hook for subclassing
        )ro   N)valid_response_codesr;   )r+   rz   r   r   r   r   _verify_status?  s   
zUserAgent._verify_statusc                 C   s  |st dt|trt dg }t|pi }t|pi }|D ]>\}}t|ts-t|ds0|g}|D ]*}|dur\t|tsAt|}|t|trM|dn|t|trX|	dn|f q2q|D ]u\}}d}	d}
d}t|t
tfrt|dkr||\}}n*t|dkr|\}}}	nt|dkr|\}}}	}
n|\}}}	}
}n	| |p|}|}t|tttfr|}nt|d	r| }n|du rq`|}t||||
d
}|j|	d || q`t||\}}||fS )a0  
        Method taken from models in requests library , usage is the same. Only difference is that you can add custom
        boundary in 5-tuple version.

        Build the body for a multipart/form-data request.

        Will successfully encode files when passed as a dict or a list of
        tuples. Order is retained if data is a list of tuples but arbitrary
        if parameters are supplied as a dict.

        The tuples may be
        2-tuples (filename, fileobj),
        3-tuples (filename, fileobj, contentype),
        4-tuples (filename, fileobj, contentype, custom_headers) or
        5-tuples (filename, fileobj, contentype, custom_headers, custom boundary).

        example:
        files = {'file': ('report.xls', body, 'application/vnd.ms-excel', {'Expires': '0'}, 'custom_boundary')}

        zFiles must be provided.zData must not be a string.__iter__Nutf-8   r      r   )namedatafilenamerF   )r   )r   r"   
basestringr   hasattrbytesr%   appenddecodeencodetuplelistr&   guess_filename	bytearrayr   r
   make_multipartr	   )r+   r   r   
new_fieldsfieldsfieldr   vkftfhboundaryfnfpfdatarfr   r   r   r   r   r   E  sb   




zUserAgent._encode_filesc                 C   s   t |tjtjfr|S t |tjtfr$|jttj	tj
tjtjgv r$|S t |tjr2dt|v r2|S t |tr9|S tt||t d )a   Hook for subclassing. Raise the error to interrupt further retrying,
            return it to continue retries and save the error, when retries
            exceed the limit.
            Temporary errors should be swallowed here for automatic retries.
        zread operation timed outr   )r"   sockettimeoutgeventTimeoutr   r   errnosetZ	ETIMEDOUTZENOLINKENOENTEPIPEsslSSLErrorr%   r<   r   typesysexc_info)r+   er   r   r   r   _handle_error  s   
zUserAgent._handle_errorc                 C   s   t || j|d)r   )original)r9   r   )r+   r   
last_errorr   r   r   _handle_retries_exceeded  s   z"UserAgent._handle_retries_exceededFc	                 K   s  |	r|s|	}n
t |tr||	 |	dd}
nd}
| j||||||
d}t| jD ]B}|dkr:| jr:t	| j t| j
D ]}| jdurM| j| z| |}W n& tjy]     tyz } z||_| j||jd}W Y d}~ nd}~ww |dur|| j|j||jdd  z| j|j|jd W n0 ty } z$||_||_| j|j||jd|_|  | j||jd}W Y d}~ nd}~ww | jdur| j|| |jd}t |tjr| d	}|j| j!v r|r|  z	|"|j| W q? ty } z| j||jd}W Y d}~ nWd}~ww |s$|    S z|j#}W n tyE } z| j||jd}W Y d}~ n,d}~ww |sXt$|d
}| j||jd} n|    S t%|d| j
 }| j||d}q*| j&||dS )zJ Open an URL, do retries and redirects and verify the status code
        r   N)rE   rF   rG   r@   r   r   rI   )rG   

rp   r   zEmpty response body receivedzRedirection limit reached (%s)r   )'r"   r   r!   rV   r   r   r   r   r   sleepr   r   add_cookie_headerr   ZGreenletExitBaseExceptionrx   r   r   write_conversation_strrG   r   rz   	ExceptionresponseZhttp_logr   extract_cookiesrF   r(   binary_typer   redirect_resonse_codesrn   r   r<   r9   r   )r+   r   rE   Zresponse_codesrF   rG   	to_stringdebug_streamr@   r-   r   reqretry_r   r   r   Zredirectionr   r   r   r   urlopen  s   







zUserAgent.urlopenc                 C   sH  t jr@ddd |j D }d| d |j }|r&t|tr&||d 7 }|d|jj	 d t
|j d | d |j 7 }|S ddd |j D }d| d |j }|rt|t jrwz||d	d 7 }W n tyv   |d
7 }Y nw t|t jr||d 7 }|d|jj	 d t
|j d | d |jd d  d	 7 }|S )N
c                 s       | ]}d | V  qdS z%s: %sNr   r   rh   r   r   r   r         z.UserAgent._conversation_str.<locals>.<genexpr>z	REQUEST: r   z
RESPONSE:  c                 s   r  r  r   r  r   r   r   r     r	  r   zUnicodeDecodeError

)r(   PY2r'   rF   Ziteroriginalrv   r"   r   rt   versionr%   rz   r   r   r   UnicodeDecodeErrorr   )clsr   r   rG   Z
header_strr   r   r   r   r     sP   zUserAgent._conversation_strc                 C   sN   t |dd}|rt|tr!|d dkr#|d dkr%tj|S dS dS dS dS )z0Tries to guess the filename of the given object.r   Nr   <>)getattrr"   r   ospathbasename)r  filer   r   r   r   r     s   &zUserAgent.guess_filename @  c                 K   s  | dd  | di }d|d< |rtj|rtj|}nd}t| jD ]}|r`d| |d< | j|fd|i|}	|	j	d}
|	j
d	ksZ|
rZ|
d
rZ|
d dd t|s`|	  d}|ss| dd  | j|fd|i|}	t||rydndf}|r||tj z'|	|}|	 |r|| |	|}|sW d    n1 sw   Y  W n+ ty } z| j||d |	j	dd
kr| }W Y d }~W d    q&d }~ww W d     |	S 1 sw   Y   |	S | j||d |	S )Nr   rF   z
Keep-Alive
Connectionr   z	bytes=%d-RangezContent-Ranger   r   r   abwbrI   zaccept-rangesr   )popr  r  isfilegetsizer   r   r  rF   rV   rz   
startswithsplitr%   r   openseekSEEK_SETr   r   r   r   tellr   )r+   r   Zfpath
chunk_sizeresumer-   rF   offsetr  r   crfr   r   r   r   r   download%  sb   



	
zUserAgent.download)r   r   r   NN)r>   NNNNr?   )r  F)r   r   r   rs   r   r=   r   	frozensetr   r   r.   r   r   r   r   r   r   r   r   r  classmethodr   r   r*  r   r   r   r   r     s0    



T


U
r   c                   @   s   e Zd ZeZdS )RestkitCompatUserAgentN)r   r   r   r   r   r   r   r   r   r-  Q  s    r-  c                   @   s   e Zd ZdddZdS )XmlrpcCompatUserAgentFc                 C   sJ   |sd nt  }| j|| d|d|d}|d ur#|d t|  |S )NPOSTT)rG   r   r   r   )r   StringIOr  r"  r   r   )r+   rC   handlerrx   verboser   r   r   r   r   rx   V  s   
zXmlrpcCompatUserAgent.requestN)F)r   r   r   rx   r   r   r   r   r.  U  s    r.  ).r   r   r(   r   r   r   r  r   Z	six.movesr   r   Zsix.moves.urllib.parser   r   r   r   r   r   urllib3r	   Zurllib3.fieldsr
   Z
gevent.dnsr   ImportErrorr   r   r   r   r   r   r   r%   r   r   r   r9   r;   r<   objectr=   rs   r   r   r-  r.  r   r   r   r   <module>   sD    Ho  F