a
    còf%  ã                   @   sø   d Z ddl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 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)Úsettings)ÚStopFutureHandlers)Ú	QueryDict)Ú	ChunkIter)ÚMultiPartParser)ÚMultiPartParserError)Úparse_header_parameters)Ú	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/home/httpd/docs/test/DocsMgr/lib/python3.9/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ƒ‚dS )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.N)ÚNotImplementedError)r   ÚstreamÚ
media_typeÚparser_contextr   r   r   Úparse'   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   s~   |pi }|  dtj¡}z.t |¡|ƒ}| jr2tjnd}tj||d�W S  t	yx } zt
dt|ƒ ƒ‚W Y d}~n
d}~0 0 dS )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   Zstrict_constantÚloadÚ
ValueErrorr
   Ústr)r   r   r   r   r    Zdecoded_streamr!   Úexcr   r   r   r   8   s    zJSONParser.parse)NN)r   r   r   r   r   r	   ZJSONRendererZrenderer_classr   ZSTRICT_JSONr&   r   r   r   r   r   r   0   s
   r   c                   @   s   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   M   s    zFormParser.parse)NNr   r   r   r   r   r+   G   s   r+   c                   @   s   e Zd ZdZdZddd„ZdS )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	y� } zt
dt|ƒ ƒ‚W Y d}~n
d}~0 0 dS )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   r-   r    Úmetar1   Úparserr   r   r*   r   r   r   r   ]   s    
zMultiPartParser.parse)NNr   r   r   r   r   r   W   s   r   c                   @   s0   e Zd ZdZdZdddœZd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}|  |||¡}|sJt| jd ƒ‚|  d|  dd¡¡}	zt|  d|  dd	¡¡ƒ}
W n t	t
fy”   d
}
Y n0 |D ]4}| |||
d
|¡}|d
uršti d|d iƒ  S qšdd„ |D ƒ}tdg| ƒ}t||ƒ}d	gt|ƒ }t|ƒD ]N\}}z| d
||	|
|¡ W n, t�yV   |d
|d … }Y  �q\Y n0 �q|D ]R}t|ƒD ]B\}}t|ƒ}| ||| ¡}||  |7  < |d
u �rl �q`�ql�q`t|ƒD ]4\}}| || ¡}|d
u�r¼ti d|iƒ  S �q¼t| jd ƒ‚d
S )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.
        r-   r    r7   ZHTTP_CONTENT_TYPEr.   Ú ZHTTP_CONTENT_LENGTHÚCONTENT_LENGTHr   NÚfileé   c                 S   s   g | ]}|j r|j ‘qS r   )Ú
chunk_size)Ú.0Úxr   r   r   Ú
<listcomp>¥   ó    z*FileUploadParser.parse.<locals>.<listcomp>iüÿÿr6   )r"   r   r#   r/   r1   Úget_filenamer
   ÚerrorsÚintr(   Ú	TypeErrorZhandle_raw_inputr   Úminr   ÚlenÚ	enumerateÚnew_filer   Zreceive_data_chunkZfile_complete)r   r   r   r   r-   r    r3   r1   ÚfilenameÚcontent_typeÚcontent_lengthÚhandlerÚresultZpossible_sizesr<   ÚchunksZcountersÚindexÚchunkZchunk_lengthZfile_objr   r   r   r   ~   sd    
ÿ
ÿ

ü

ÿ

zFileUploadParser.parsec                 C   s¨   t  t¡� |d d W  d  ƒ S 1 s,0    Y  t  ttt¡�P |d j}t|d ƒ\}}d|v r~|d W  d  ƒ S |d W  d  ƒ S 1 sš0    Y  dS )z�
        Detects the uploaded file name. First searches a 'filename' url kwarg.
        Then tries to parse Content-Disposition header.
        ÚkwargsrI   Nr-   ZHTTP_CONTENT_DISPOSITIONz	filename*)Ú
contextlibÚsuppressÚKeyErrorÚAttributeErrorr(   r/   r   )r   r   r   r   r3   ÚdispositionÚparamsr   r   r   rA   Á   s    *
zFileUploadParser.get_filename)NN)r   r   r   r   r   rB   r   rA   r   r   r   r   r5   t   s   þ
Cr5   )r   r$   rR   Zdjango.confr   Zdjango.core.files.uploadhandlerr   Zdjango.httpr   Zdjango.http.multipartparserr   r   r2   r   Zdjango.utils.httpr   Zrest_frameworkr	   Zrest_framework.exceptionsr
   Zrest_framework.settingsr   Zrest_framework.utilsr   r   r   r   r+   r5   r   r   r   r   Ú<module>   s&   