o
     d(                     @   s   d dl Z d dlmZmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZmZmZ zd dlZd dlmZ W n eyA   dZdZY nw G dd	 d	eZeG d
d dZdededefddZG dd deZG dd dZG dd dZdS )    N)	dataclassfield)Enum)SpooledTemporaryFile)unquote_plus)FormDataHeaders
UploadFile)parse_options_headerc                   @   s    e Zd ZdZdZdZdZdZdS )FormMessage               N)__name__
__module____qualname__FIELD_START
FIELD_NAME
FIELD_DATA	FIELD_ENDEND r   r   @/usr/local/lib/python3.10/dist-packages/starlette/formparsers.pyr      s    r   c                   @   sl   e Zd ZU dZeje ed< dZe	ed< dZ
eed< dZeje ed< eedZejejeef  ed	< dS )
MultipartPartNcontent_disposition 
field_name    datafile)default_factoryitem_headers)r   r   r   r   typingOptionalbytes__annotations__r   strr    r!   r	   r   listr#   ListTupler   r   r   r   r      s   
 &r   srccodecreturnc              	   C   s.   z|  |W S  ttfy   |  d Y S w )Nlatin-1)decodeUnicodeDecodeErrorLookupError)r,   r-   r   r   r   _user_safe_decode"   s
   r3   c                   @   s   e Zd ZdeddfddZdS )MultiPartExceptionmessager.   Nc                 C   s
   || _ d S N)r5   selfr5   r   r   r   __init__*   s   
zMultiPartException.__init__)r   r   r   r(   r9   r   r   r   r   r4   )   s    r4   c                   @   s   e Zd Zdedejedf ddfddZdddZd	ed
e	de	ddfddZ
d	ed
e	de	ddfddZdddZdddZdefddZdS )
FormParserheadersstreamNr.   c                 C   s&   t d usJ d|| _|| _g | _d S )NEThe `python-multipart` library must be installed to use form parsing.)	multipartr;   r<   messages)r8   r;   r<   r   r   r   r9   /   s   
zFormParser.__init__c                 C      t jdf}| j| d S Nr   )r   r   r?   appendr7   r   r   r   on_field_start9      
zFormParser.on_field_startr    startendc                 C   "   t j||| f}| j| d S r6   )r   r   r?   rB   r8   r    rE   rF   r5   r   r   r   on_field_name=      zFormParser.on_field_namec                 C   rG   r6   )r   r   r?   rB   rH   r   r   r   on_field_dataA   rJ   zFormParser.on_field_datac                 C   r@   rA   )r   r   r?   rB   r7   r   r   r   on_field_endE   rD   zFormParser.on_field_endc                 C   r@   rA   )r   r   r?   rB   r7   r   r   r   on_endI   rD   zFormParser.on_endc                    s   | j | j| j| j| jd}t|}d}d}g }| j2 z[3 d H W }|r*|| n|	  t
| j}| j  |D ]<\}}	|tjkrHd}d}q:|tjkrR||	7 }q:|tjkr\||	7 }q:|tjkrvt|d}
t|d}||
|f q:q6 t|S )N)rC   rI   rK   rL   rM   r   r/   )rC   rI   rK   rL   rM   r>   QuerystringParserr<   writefinalizer)   r?   clearr   r   r   r   r   r   r0   rB   r   )r8   	callbacksparserr   field_valueitemschunkr?   message_typemessage_bytesnamevaluer   r   r   parseM   sB   
	







zFormParser.parser.   N)r   r   r   r   r$   AsyncGeneratorr&   r9   rC   intrI   rK   rL   rM   r   r[   r   r   r   r   r:   .   s    




r:   c                   @   s   e Zd ZdZddddedejedf deje	e
f deje	e
f d	df
d
dZd!ddZdede	de	d	dfddZd!ddZdede	de	d	dfddZdede	de	d	dfddZd!ddZd!ddZd!ddZd	efdd ZdS )"MultiPartParseri   i  )	max_files
max_fieldsr;   r<   Nr`   ra   r.   c                C   sj   t d usJ d|| _|| _|| _|| _g | _d| _d| _d| _d| _	t
 | _d| _g | _g | _g | _d S )Nr=   r   r   r   )r>   r;   r<   r`   ra   rU   _current_files_current_fields_current_partial_header_name_current_partial_header_valuer   _current_part_charset_file_parts_to_write_file_parts_to_finish_files_to_close_on_error)r8   r;   r<   r`   ra   r   r   r   r9   y   s$   	
zMultiPartParser.__init__c                 C   s   t  | _d S r6   )r   rf   r8   r   r   r   on_part_begin   s   zMultiPartParser.on_part_beginr    rE   rF   c                 C   sB   ||| }| j jd u r| j  j|7  _d S | j| j |f d S r6   )rf   r!   r    rh   rB   )r8   r    rE   rF   rX   r   r   r   on_part_data   s   zMultiPartParser.on_part_datac                 C   sZ   | j jd u r| j| j jt| j j| jf d S | j| j  | j| j j| j jf d S r6   )	rf   r!   rU   rB   r   r3   r    rg   ri   rk   r   r   r   on_part_end   s   zMultiPartParser.on_part_endc                 C      |  j ||| 7  _ d S r6   )rd   r8   r    rE   rF   r   r   r   on_header_field      zMultiPartParser.on_header_fieldc                 C   ro   r6   )re   rp   r   r   r   on_header_value   rr   zMultiPartParser.on_header_valuec                 C   s@   | j  }|dkr| j| j_| jj|| jf d| _ d| _d S )Ns   content-dispositionr   )rd   lowerre   rf   r   r#   rB   )r8   r   r   r   r   on_header_end   s   


zMultiPartParser.on_header_endc                 C   s   t | jj\}}zt|d | j| j_W n ty   tdw d|v r_|  jd7  _| j| j	kr:td| j	 dt|d | j}t
| jd}| j| t|d|t| jjd	d
| j_d S |  jd7  _| j| jkrutd| j dd | j_d S )Ns   namez=The Content-Disposition header field "name" must be provided.s   filenamer   z+Too many files. Maximum number of files is .)max_sizer   )raw)r!   sizefilenamer;   z-Too many fields. Maximum number of fields is )r
   rf   r   r3   rg   r   KeyErrorr4   rb   r`   r   max_file_sizerj   rB   r	   r   r#   r!   rc   ra   )r8   dispositionoptionsrz   tempfiler   r   r   on_headers_finished   sB   
z#MultiPartParser.on_headers_finishedc                 C   s   d S r6   r   rk   r   r   r   rM      s   zMultiPartParser.on_endc              
      sb  t | jd \}}|dd}t|tkr|d}|| _z|d }W n ty/   tdw | j	| j
| j| j| j| j| j| jd}t||}zF| j2 z?3 d H W }|| | jD ]\}}	|jsdJ |j|	I d H  q[| jD ]}|jsxJ |jdI d H  qq| j  | j  qM6 W n ty }
 z| jD ]}|  q|
d }
~
ww |  t| jS )	NzContent-Types   charsetzutf-8r/   s   boundaryzMissing boundary in multipart.)rl   rm   rn   rq   rs   ru   r   rM   r   )r
   r;   gettyper&   r0   rg   r{   r4   rl   rm   rn   rq   rs   ru   r   rM   r>   MultipartParserr<   rO   rh   r!   ri   seekrQ   rj   closerP   r   rU   )r8   _paramscharsetboundaryrR   rS   rV   partr    excr!   r   r   r   r[      sR   








zMultiPartParser.parser\   )r   r   r   r|   r   r$   r]   r&   Unionr^   floatr9   rl   rm   rn   rq   rs   ru   r   rM   r   r[   r   r   r   r   r_   v   s0    






#r_   )r$   dataclassesr   r   enumr   r   r   urllib.parser   starlette.datastructuresr   r   r	   r>   multipart.multipartr
   ImportErrorr   r   r&   r(   r3   	Exceptionr4   r:   r_   r   r   r   r   <module>   s(    H