o
    wvXj‘   ã                   @   s   d 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	 ddl
mZ ddl
m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 ddlmZ G dd„ dƒZG dd„ dƒ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 )zÅ
Parsers are used to parse the content of incoming HTTP requests.

They give us a generic way of being able to handle various media types
on the request, such as form content or json encoded data.
é    N)Úparse)Úsettings)ÚStopFutureHandlers)Ú	QueryDict)Ú	ChunkIter)ÚMultiPartParser)ÚMultiPartParserErrorÚparse_header)Ú	force_str)Ú	renderers)Ú
ParseError)Úapi_settings)Újsonc                   @   s   e Zd Zdd„ ZdS )ÚDataAndFilesc                 C   s   || _ || _d S )N)ÚdataÚfiles)Úselfr   r   © r   úS/var/www/html/myproject/venv/lib/python3.10/site-packages/rest_framework/parsers.pyÚ__init__   s   
zDataAndFiles.__init__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdZddd„ZdS )Ú
BaseParserz€
    All parsers should extend `BaseParser`, specifying a `media_type`
    attribute, and overriding the `.parse()` method.
    Nc                 C   s   t dƒ‚)z¿
        Given a stream to read from, return the parsed representation.
        Should return parsed data, or a `DataAndFiles` object consisting of the
        parsed data and files.
        z.parse() must be overridden.)ÚNotImplementedError)r   ÚstreamÚ
media_typeÚparser_contextr   r   r   r   &   s   zBaseParser.parse©NN©r   r   r   Ú__doc__r   r   r   r   r   r   r      s    r   c                   @   s*   e Zd ZdZdZejZej	Z
ddd„ZdS )Ú
JSONParserz&
    Parses JSON-serialized data.
    zapplication/jsonNc              
   C   sn   |pi }|  dtj¡}zt |¡|ƒ}| jrtjnd}tj||d�W S  t	y6 } zt
dt|ƒ ƒ‚d}~ww )zX
        Parses the incoming bytestream as JSON and returns the resulting data.
        ÚencodingN)Úparse_constantzJSON parse error - %s)Úgetr   ÚDEFAULT_CHARSETÚcodecsÚ	getreaderÚstrictr   Ústrict_constantÚloadÚ
ValueErrorr   Ústr)r   r   r   r   r"   Údecoded_streamr#   Úexcr   r   r   r   7   s   €ÿzJSONParser.parser   )r   r   r   r    r   r   ÚJSONRendererÚrenderer_classr   ÚSTRICT_JSONr(   r   r   r   r   r   r!   /   s    r!   c                   @   ó   e Zd ZdZdZddd„ZdS )Ú
FormParserz
    Parser for form data.
    z!application/x-www-form-urlencodedNc                 C   s&   |pi }|  dtj¡}t| ¡ |d�S )zt
        Parses the incoming bytestream as a URL encoded form,
        and returns the resulting QueryDict.
        r"   )r"   )r$   r   r%   r   Úread)r   r   r   r   r"   r   r   r   r   L   s   zFormParser.parser   r   r   r   r   r   r3   F   ó    r3   c                   @   r2   )r   zF
    Parser for multipart form data, which may include file data.
    zmultipart/form-dataNc              
   C   s†   |pi }|d }|  dtj¡}|j ¡ }||d< |j}zt||||ƒ}| ¡ \}	}
t|	|
ƒW S  t	yB } zt
dt|ƒ ƒ‚d}~ww )a	  
        Parses the incoming bytestream as a multipart encoded form,
        and returns a DataAndFiles object.

        `.data` will be a `QueryDict` containing all the form parameters.
        `.files` will be a `QueryDict` containing all the form files.
        Úrequestr"   ÚCONTENT_TYPEzMultipart form parse error - %sN)r$   r   r%   ÚMETAÚcopyÚupload_handlersÚDjangoMultiPartParserr   r   r   r   r,   )r   r   r   r   r6   r"   Úmetar:   Úparserr   r   r.   r   r   r   r   \   s   
€ÿzMultiPartParser.parser   r   r   r   r   r   r   V   r5   r   c                   @   s8   e Zd ZdZdZdddœZddd„Zd	d
„ Zdd„ ZdS )ÚFileUploadParserz&
    Parser for file upload data.
    z*/*zFFileUpload parse error - none of upload handlers can handle the streamz`Missing filename. Request should include a Content-Disposition header with a filename parameter.)Ú	unhandledÚno_filenameNc              	   C   sè  |pi }|d }|  dtj¡}|j}|j}|  |||¡}|s%t| jd ƒ‚|  d|  dd¡¡}	zt|  d|  dd	¡¡ƒ}
W n t	t
fyJ   d
}
Y nw |D ]}| |||
d
|¡}|d
urgti d|d iƒ  S qMdd„ |D ƒ}tdg| ƒ}t||ƒ}d	gt|ƒ }t|ƒD ]!\}}z| d
||	|
|¡ W q† ty§   |d
|d … }Y  nw |D ]%}t|ƒD ]\}}t|ƒ}| ||| ¡}||  |7  < |d
u rÎ nq°qªt|ƒD ]\}}| || ¡}|d
urìti d|iƒ  S qÔt| jd ƒ‚)a  
        Treats the incoming bytestream as a raw file upload and returns
        a `DataAndFiles` object.

        `.data` will be None (we expect request body to be a file content).
        `.files` will be a `QueryDict` containing one 'file' element.
        r6   r"   r@   ÚHTTP_CONTENT_TYPEr7   Ú ÚHTTP_CONTENT_LENGTHÚCONTENT_LENGTHr   NÚfileé   c                 S   s   g | ]}|j r|j ‘qS r   )Ú
chunk_size)Ú.0Úxr   r   r   Ú
<listcomp>¤   s    z*FileUploadParser.parse.<locals>.<listcomp>iüÿÿr?   )r$   r   r%   r8   r:   Úget_filenamer   ÚerrorsÚintr+   Ú	TypeErrorÚhandle_raw_inputr   Úminr   ÚlenÚ	enumerateÚnew_filer   Úreceive_data_chunkÚfile_complete)r   r   r   r   r6   r"   r<   r:   ÚfilenameÚcontent_typeÚcontent_lengthÚhandlerÚresultÚpossible_sizesrG   ÚchunksÚcountersÚindexÚchunkÚchunk_lengthÚfile_objr   r   r   r   }   sp   
ÿ

ÿÿüÿ

ÿþÿ€ÿzFileUploadParser.parsec              
   C   s‚   z|d d W S  t y   Y nw z"|d j}t|d  ¡ ƒ}|d }d|v r-|  |¡W S t|d ƒW S  tt tfy@   Y dS w )z�
        Detects the uploaded file name. First searches a 'filename' url kwarg.
        Then tries to parse Content-Disposition header.
        ÚkwargsrV   r6   ÚHTTP_CONTENT_DISPOSITIONrF   ú	filename*N)ÚKeyErrorr8   r	   ÚencodeÚget_encoded_filenamer
   ÚAttributeErrorr+   )r   r   r   r   r<   ÚdispositionÚfilename_parmr   r   r   rK   À   s   ÿ
ÿzFileUploadParser.get_filenamec              	   C   sT   t |d ƒ}z| dd¡\}}}t |¡}W |S  ttfy)   t |d ƒ}Y |S w )zw
        Handle encoded filenames per RFC6266. See also:
        https://tools.ietf.org/html/rfc2231#section-4
        rd   ú'é   rV   )r
   Úsplitr   Úunquoter+   ÚLookupError)r   rj   Úencoded_filenameÚcharsetÚlangrV   r   r   r   rg   Ô   s   þþz%FileUploadParser.get_encoded_filenamer   )	r   r   r   r    r   rL   r   rK   rg   r   r   r   r   r>   s   s    þ
Cr>   )r    r&   Úurllibr   Údjango.confr   Údjango.core.files.uploadhandlerr   Údjango.httpr   Údjango.http.multipartparserr   r   r;   r   r	   Údjango.utils.encodingr
   Úrest_frameworkr   Úrest_framework.exceptionsr   Úrest_framework.settingsr   Úrest_framework.utilsr   r   r   r!   r3   r>   r   r   r   r   Ú<module>   s(    