U
    nËjs&  ã                   @  s  d dl m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
mZmZmZmZmZ ddlmZmZmZ ddd	œZe d
d„ edƒD ƒ¡ e d dd„ e ¡ D ƒ¡¡Zddddœdd„Zdddœdd„Zdddœdd„ZG dd„ dƒZG dd „ d ƒZG d!d"„ d"ee
ƒZ dS )#é    )ÚannotationsN)ÚPathé   )ÚAsyncByteStreamÚFileContentÚ	FileTypesÚRequestDataÚRequestFilesÚSyncByteStream)Úpeek_filelike_lengthÚprimitive_value_to_strÚto_bytesz%22z\\)ú"ú\c                 C  s$   i | ]}|d krt |ƒd |¡“qS )é   z%{:02X})ÚchrÚformat©Ú.0Úc© r   ú4/tmp/pip-unpacked-wheel-7ig9zwdf/httpx/_multipart.pyÚ
<dictcomp>   s       r   é    ú|c                 C  s   g | ]}t  |¡‘qS r   )ÚreÚescaper   r   r   r   Ú
<listcomp>   s     r   ÚstrÚbytes©ÚnameÚvalueÚreturnc                 C  s0   dddœdd„}t  ||¡}| › d|› d� ¡ S )z;
    Encode a name/value pair within a multipart form.
    ztyping.Match[str]r   )Úmatchr#   c                 S  s   t |  d¡ S )Nr   )Ú!_HTML5_FORM_ENCODING_REPLACEMENTSÚgroup)r$   r   r   r   Úreplacer&   s    z$_format_form_param.<locals>.replacerz="r   )Ú_HTML5_FORM_ENCODING_REÚsubÚencode)r!   r"   r'   r   r   r   Ú_format_form_param!   s    r+   z
str | None)Úfilenamer#   c                 C  s   | rt  | ¡d pdS dS )z‘
    Guesses the mimetype based on a filename. Defaults to `application/octet-stream`.

    Returns `None` if `filename` is `None` or empty.
    r   zapplication/octet-streamN)Ú	mimetypesÚ
guess_type)r,   r   r   r   Ú_guess_content_type-   s    r/   úbytes | None)Úcontent_typer#   c                 C  s^   | r|   d¡sd S d| krZ|  d¡D ]4}| ¡  ¡   d¡r$| ¡ tdƒd …  d¡  S q$d S )Ns   multipart/form-dataó   ;s	   boundary=ó   ")Ú
startswithÚsplitÚstripÚlowerÚlen)r1   Úsectionr   r   r   Ú(get_multipart_boundary_from_content_type8   s     r:   c                   @  sZ   e Zd ZdZddddœdd„Zdd	œd
d„Zdd	œdd„Zdd	œdd„Zdd	œdd„ZdS )Ú	DataFieldzB
    A single form field item, within a multipart form field.
    r   z str | bytes | int | float | NoneÚNoner    c                 C  sv   t |tƒs"tdt|ƒ› d|›�ƒ‚|d k	rTt |ttttfƒsTtdt|ƒ› d|›�ƒ‚|| _t |tƒrh|nt|ƒ| _	d S )Nz)Invalid type for name. Expected str, got ú: z5Invalid type for value. Expected primitive type, got )
Ú
isinstancer   Ú	TypeErrorÚtyper   ÚintÚfloatr!   r   r"   )Úselfr!   r"   r   r   r   Ú__init__K   s    
ÿÿÿzDataField.__init__r   ©r#   c                 C  s.   t | dƒs(td| jƒ}d d|dg¡| _| jS )NÚ_headersr!   ó    ó    Content-Disposition: form-data; ó   

)Úhasattrr+   r!   ÚjoinrF   )rC   r!   r   r   r   Úrender_headersZ   s    
ÿzDataField.render_headersc                 C  s   t | dƒst| jƒ| _| jS )NÚ_data)rJ   r   r"   rM   ©rC   r   r   r   Úrender_datac   s    
zDataField.render_datarA   c                 C  s    |   ¡ }|  ¡ }t|ƒt|ƒ S ©N)rL   rO   r8   )rC   ÚheadersÚdatar   r   r   Ú
get_lengthi   s    zDataField.get_lengthútyping.Iterator[bytes]c                 c  s   |   ¡ V  |  ¡ V  d S rP   ©rL   rO   rN   r   r   r   Úrendern   s    
zDataField.renderN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__rD   rL   rO   rS   rV   r   r   r   r   r;   F   s   	r;   c                   @  s^   e Zd ZdZdZddddœdd„Zd	d
œdd„Zdd
œdd„Zdd
œdd„Zdd
œdd„Z	dS )Ú	FileFieldzB
    A single file field item, within a multipart form field.
    i   r   r   r<   r    c                 C  sâ   || _ i }d }t|tƒrTt|ƒdkr.|\}}qnt|ƒdkrF|\}}}qn|\}}}}nttt|ddƒƒƒj }|}|d kr~t|ƒ}tdd„ |D ƒƒ}|d k	r¤|s¤||d< t|t	j
ƒr¸tdƒ‚t|t	jƒrÌtd	ƒ‚|| _|| _|| _d S )
Né   é   r!   Úuploadc                 s  s   | ]}d |  ¡ kV  qdS )zcontent-typeN)r7   )r   Úkeyr   r   r   Ú	<genexpr>—   s     z%FileField.__init__.<locals>.<genexpr>úContent-Typez?Multipart file uploads require 'io.BytesIO', not 'io.StringIO'.zDMultipart file uploads must be opened in binary mode, not text mode.)r!   r>   Útupler8   r   r   Úgetattrr/   ÚanyÚioÚStringIOr?   Ú
TextIOBaser,   ÚfilerQ   )rC   r!   r"   rQ   r1   r,   ÚfileobjZhas_content_type_headerr   r   r   rD   z   s6    

ÿÿzFileField.__init__ú
int | NonerE   c                 C  sP   |   ¡ }t| jttfƒr.t|ƒtt| jƒƒ S t| jƒ}|d krDd S t|ƒ| S rP   )rL   r>   rh   r   r   r8   r   r   )rC   rQ   Zfile_lengthr   r   r   rS   «   s    
zFileField.get_lengthr   c                 C  s’   t | dƒsŒdtd| jƒg}| jr:td| jƒ}| d|g¡ | j ¡ D ]0\}}d|› d� ¡ | ¡  }}| ||g¡ qD| d¡ d	 	|¡| _
| j
S )
NrF   rH   r!   r,   s   ; z
r=   rI   rG   )rJ   r+   r!   r,   ÚextendrQ   Úitemsr*   ÚappendrK   rF   )rC   Úpartsr,   Úheader_nameÚheader_valuer_   Úvalr   r   r   rL   º   s    

þ
zFileField.render_headersrT   c                 c  s„   t | jttfƒr t| jƒV  d S t| jdƒrTz| j d¡ W n tjk
rR   Y nX | j 	| j
¡}|r€t|ƒV  | j 	| j
¡}qbd S )NÚseekr   )r>   rh   r   r   r   rJ   rr   re   ÚUnsupportedOperationÚreadÚ
CHUNK_SIZE©rC   Úchunkr   r   r   rO   Ë   s    
zFileField.render_datac                 c  s   |   ¡ V  |  ¡ E d H  d S rP   rU   rN   r   r   r   rV   Û   s    
zFileField.renderN)
rW   rX   rY   rZ   ru   rD   rS   rL   rO   rV   r   r   r   r   r[   s   s   1r[   c                   @  s~   e Zd ZdZddddddœdd	„Zddd
dœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Z	ddœdd„Z
dS )ÚMultipartStreamzC
    Request content as streaming multipart encoded form data.
    Nr   r	   r0   r<   )rR   ÚfilesÚboundaryr#   c                 C  sH   |d krt  d¡ ¡  d¡}|| _d| d¡ | _t|  ||¡ƒ| _	d S )Né   Úasciiz multipart/form-data; boundary=%s)
ÚosÚurandomÚhexr*   rz   Údecoder1   ÚlistÚ_iter_fieldsÚfields)rC   rR   ry   rz   r   r   r   rD   å   s    ÿzMultipartStream.__init__z&typing.Iterator[FileField | DataField])rR   ry   r#   c                 c  s€   |  ¡ D ]>\}}t|ttfƒr8|D ]}t||d�V  q"qt||d�V  qt|tjƒr\|  ¡ n|}|D ]\}}t||d�V  qdd S )N)r!   r"   )rl   r>   rb   r�   r;   ÚtypingÚMappingr[   )rC   rR   ry   r!   r"   ÚitemZ
file_itemsr   r   r   r‚   ô   s    zMultipartStream._iter_fieldsrT   rE   c                 c  s<   | j D ]$}d| j V  | ¡ E d H  dV  qd| j V  d S )Ns   --%s
s   
s   --%s--
)rƒ   rz   rV   )rC   Úfieldr   r   r   Úiter_chunks  s
    
zMultipartStream.iter_chunksrj   c                 C  sd   t | jƒ}d}| jD ]:}| ¡ }|dkr. dS |d| d 7 }||7 }|d7 }q|d| d 7 }|S )zœ
        Return the length of the multipart encoded content, or `None` if
        any of the files have a length that cannot be determined upfront.
        r   Nr\   é   )r8   rz   rƒ   rS   )rC   Zboundary_lengthÚlengthr‡   Zfield_lengthr   r   r   Úget_content_length	  s    


z"MultipartStream.get_content_lengthzdict[str, str]c                 C  s.   |   ¡ }| j}|d kr d|dœS t|ƒ|dœS )NÚchunked)zTransfer-Encodingra   )zContent-Lengthra   )r‹   r1   r   )rC   Úcontent_lengthr1   r   r   r   Úget_headers  s
    
zMultipartStream.get_headersc                 c  s   |   ¡ D ]
}|V  qd S rP   ©rˆ   rv   r   r   r   Ú__iter__&  s    zMultipartStream.__iter__ztyping.AsyncIterator[bytes]c                 C s   |   ¡ D ]
}|V  qd S rP   r�   rv   r   r   r   Ú	__aiter__*  s    zMultipartStream.__aiter__)N)rW   rX   rY   rZ   rD   r‚   rˆ   r‹   rŽ   r�   r‘   r   r   r   r   rx   à   s    ürx   )!Ú
__future__r   re   r-   r}   r   r„   Úpathlibr   Ú_typesr   r   r   r   r	   r
   Ú_utilsr   r   r   r%   ÚupdateÚrangeÚcompilerK   Úkeysr(   r+   r/   r:   r;   r[   rx   r   r   r   r   Ú<module>   s*    
ÿÿ-m