a
    .`&                     @   s   d Z ddlZddlZddlZddlZzddlZW n eyF   dZ	Y n0 ddl
mZmZ ddlZ
dZdZeeZddiZd	d
 Zdd ZdddZG dd dejZG dd deZdS )z3Implements file-like objects for reading from http.    NT)
bytebuffer	constantsi   )httphttpszAccept-Encodingidentityc                 C   sB   t j| }|jtv sJ |j|j }d|d }t|j|dS )N/)schemeuri_path)	urllibparseurlsplitr   SCHEMESnetlocpathlstripdict)Zuri_as_stringZ	split_urir	    r   .lib/python3.9/site-packages/smart_open/http.py	parse_uri&   s
    r   c                 C   s    t jt|}t| |fi |S N)
smart_openutilsZcheck_kwargsopen)urimodeZtransport_paramskwargsr   r   r   open_uri/   s    r   Fc              	   C   sL   |t jkr<t| ||||||d}tjtj| j|_	|S t
d| dS )aO  Implement streamed reader from a web site.

    Supports Kerberos and Basic HTTP authentication.

    Parameters
    ----------
    url: str
        The URL to open.
    mode: str
        The mode to open using.
    kerberos: boolean, optional
        If True, will attempt to use the local Kerberos credentials
    user: str, optional
        The username for authenticating over HTTP
    password: str, optional
        The password for authenticating over HTTP
    headers: dict, optional
        Any headers to send in the request. If ``None``, the default headers are sent:
        ``{'Accept-Encoding': 'identity'}``. To use no headers at all,
        set this variable to an empty dict, ``{}``.

    Note
    ----
    If neither kerberos or (user, password) are set, will connect
    unauthenticated, unless set separately in headers.

    )kerberosuserpasswordheaderstimeoutz(http support for mode %r not implementedN)r   ZREAD_BINARYSeekableBufferedInputBaseosr   basenamer
   r   urlparsenameNotImplementedError)r   r   r   r   r   r    r!   Zfobjr   r   r   r   4   s    
r   c                   @   s`   e Zd ZdedddddfddZdd Zdd	 Zd
d Zdd ZdddZ	dddZ
dd ZdS )BufferedInputBaserFNc	                 C   s   |rdd l }	|	 }
n|d ur0|d ur0||f}
nd }
|| _|| _|d u rTt | _n|| _|| _tj	||
d| j| jd| _
| j
js| j
  | j
| j| _t|| _d| _d | _d S )Nr   Tauthstreamr    r!   )requests_kerberosHTTPKerberosAuthbuffer_sizer   _HEADERScopyr    r!   requestsgetresponseokraise_for_statusiter_content
_read_iterr   
ByteBuffer_read_buffer_current_posraw)selfurlr   r/   r   r   r   r    r!   r-   r+   r   r   r   __init__\   s2    


zBufferedInputBase.__init__c                 C   s   t d d| _d| _dS )zFlush and close this stream.zclose: calledN)loggerdebugr4   r8   r=   r   r   r   close   s    
zBufferedInputBase.closec                 C   s   dS )z+Return True if the stream can be read from.Tr   rB   r   r   r   readable   s    zBufferedInputBase.readablec                 C   s   dS )NFr   rB   r   r   r   seekable   s    zBufferedInputBase.seekablec                 C   s
   t jdS zUnsupported.NioUnsupportedOperationrB   r   r   r   detach   s    zBufferedInputBase.detachc                 C   s   t d| | jdu rdS |dkr&dS |dk rJt| jdkrJ| jj }n|dk rj| j | jj  }nbt| j|k rt d| j| | j| j	}|dkrj| j }|  jt|7  _|S qj| j|}|  jt|7  _|S )z>
        Mimics the read call to a filehandle object.
        zreading with size: %dN    r   z:http reading more content at current_pos: %d with size: %d)
r@   rA   r4   lenr:   r<   readr;   fillr8   )r=   sizeZretvalZ
bytes_readr   r   r   rN      s,    

zBufferedInputBase.readc                 C   s   | j |dS )zThis is the same as read().)rP   )rN   r=   rP   r   r   r   read1   s    zBufferedInputBase.read1c                 C   s.   |  t|}|sdS ||dt|< t|S )zLRead up to len(b) bytes into b, and return the number of bytes
        read.r   N)rN   rM   )r=   bdatar   r   r   readinto   s
    zBufferedInputBase.readinto)rK   )rK   )__name__
__module____qualname__DEFAULT_BUFFER_SIZEr?   rC   rD   rE   rJ   rN   rR   rU   r   r   r   r   r(   [   s   

+
#
r(   c                   @   sV   e Zd ZdZdedddddfddZddd	Zd
d Zdd ZdddZ	dddZ
dS )r"   zr
    Implement seekable streamed reader from a web site.
    Supports Kerberos and Basic HTTP authentication.
    r)   FNc	           
      C   s  || _ |rddl}	|	 | _n"|dur:|dur:||f| _nd| _|du rTt | _n|| _|| _|| _|| _	| 
 | _| jjs| j  td| j| jj d| _t| jjdd| _| jdk rd| _| jjdd	 d
krd| _| j| j| _t|| _d| _d| _dS )z
        If Kerberos is True, will attempt to use the local Kerberos credentials.
        Otherwise, will try to use "basic" HTTP authentication via username/password.

        If none of those are set, will connect unauthenticated.
        r   Nzself.response: %r, raw: %rTzContent-LengthrK   FzAccept-RangesZnonebytes)r>   r-   r.   r+   r0   r1   r    r!   r/   r   _partial_requestr4   r5   r6   r@   rA   r<   	_seekableintr3   content_lengthlowerr7   r8   r   r9   r:   r;   )
r=   r>   r   r/   r   r   r   r    r!   r-   r   r   r   r?      s6    


z"SeekableBufferedInputBase.__init__r   c                 C   s  t d|| |tjvr&tdtj |  s2t|tjkrB|}n*|tjkrX| j	| }n|tj
krl| j| }tj|d| j}| j	|kr| j	S t d| j	| || _	|| jkrd| _d| _| j  n8| |}|jr|| _| j| j| _| j  nd| _| j	S )zSeek to the specified position.

        :param int offset: The offset in bytes.
        :param int whence: Where the offset is from.

        Returns the position after seeking.z seeking to offset: %r whence: %rz"invalid whence, expected one of %rr   z0http seeking from current_pos: %d to new_pos: %dN)r@   rA   r   ZWHENCE_CHOICES
ValueErrorrE   OSErrorZWHENCE_STARTZWHENCE_CURRENTr;   Z
WHENCE_ENDr^   r   r   Zclampr4   r8   r:   emptyr[   r5   r7   r/   )r=   offsetwhenceZnew_posr4   r   r   r   seek  s6    







zSeekableBufferedInputBase.seekc                 C   s   | j S r   )r;   rB   r   r   r   tell2  s    zSeekableBufferedInputBase.tellc                 O   s   | j S r   )r\   )r=   argsr   r   r   r   rE   5  s    z"SeekableBufferedInputBase.seekablec                 C   s
   t jdS rF   rG   rQ   r   r   r   truncate8  s    z"SeekableBufferedInputBase.truncatec                 C   s@   |d ur | j dtj|i tj| j| jd| j | j	d}|S )NrangeTr*   )
r    updater   r   Zmake_range_stringr2   r3   r>   r+   r!   )r=   Z	start_posr4   r   r   r   r[   <  s    z*SeekableBufferedInputBase._partial_request)r   )N)N)rV   rW   rX   __doc__rY   r?   re   rf   rE   rh   r[   r   r   r   r   r"      s   

3
-
r"   )FNNNN)rk   rH   loggingZos.pathr#   urllib.parser
   r2   ImportErrorZMISSING_DEPSr   r   r   Zsmart_open.utilsrY   r   Z	getLoggerrV   r@   r0   r   r   r   BufferedIOBaser(   r"   r   r   r   r   <module>   s&   

		
'q