
    i>                    ,   S SK 7  S SK7  SSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
Jr  \" 5       rSrS rSrSrS rSrSrSrS	rS
rSrSrSrSrSr/ SQrS rSrSr Sr!Sr"Sr#Sr$Sr%Sr&Sr'Sr(Sr)S r*S r+S r,\RZ                  " S5      r.Sr/S\.-   S-   \/-   S -   r0S!\.-   S"-   \0-   S -   r1\Rd                  " \15      r3S#r4S$ r5 " S% S&5      r6 " S' S(5      r7 " S) S*5      r8 " S+ S,\85      r9 " S- S.\85      r: " S/ S0\85      r; " S1 S25      r<S30 4S4 jr=S6S5 jr>g)7   )*    N)BytesIO)Number                     	   
      )STARTSTART_BOUNDARYHEADER_FIELD_STARTHEADER_FIELDHEADER_VALUE_STARTHEADER_VALUEHEADER_VALUE_ALMOST_DONEHEADRES_ALMOST_DONEPART_DATA_START	PART_DATAPART_DATA_ENDEND   :       -   &   ;   a   z   c                     U S-  $ )Nr    cs    ^/home/maestro/MAESTRO/maestro-backend/venv/lib/python3.13/site-packages/multipart/multipart.py<lambda>r*   @   s    q4x    c                     U $ Nr&   r'   s    r)   r*   r*   A   s    Qr+   c                 *    [        [        U 5      5      $ r-   )byteslist)bs    r)   r*   r*   B   s    uT!W~r+   s   ()<>@,;:\"/[]?={} 	s   "(?:\\.|[^"])*"s   (?:[^s   ]+|   )s   (?:;|^)\s*([^s   ]+)\s*=\s*("   c                 \   U (       d  S0 4$ [        U [        5      (       a  U R                  S5      n SU ;  a   U R                  5       R	                  5       0 4$ U R                  SS5      u  p0 n[        R                  U5       H  nUR                  S5      R                  5       nUR                  S5      n U S   [        :X  a4  U S   [        :X  a'  U SS n U R                  SS	5      R                  S
S5      n US:X  a&  U SS S:X  d	  U SS S:X  a  U R                  S	5      S   n XU'   M     X4$ )ze
Parses a Content-Type header into a value in the following format:
    (content_type, {parameters})
r+   latin-1   ;r   r   r   s   \\   \s   \"   "   filenamer   s   :\N)
isinstancestrencodelowerstripsplit	OPTION_REfinditergroupQUOTEreplace)valuectyperestoptionsmatchkeys         r)   parse_options_headerrL   O   s-   
 Ry %Y' 5##%r** ++dA&KEG ##D)kk!n""$A8ure!3!BKEMM'5199&$GE +QqzV#uRayG';E*2. *  >r+   c                   ~    \ rS rSrSrS r\S 5       rS rS r	S r
S rS	 rS
 r\S 5       r\S 5       rS rS rSrg)Fieldx   a  A Field object represents a (parsed) form field.  It represents a single
field with a corresponding name and value.

The name that a :class:`Field` will be instantiated with is the same name
that would be found in the following HTML::

    <input name="name_goes_here" type="text"/>

This class defines two methods, :meth:`on_data` and :meth:`on_end`, that
will be called when data is written to the Field, and when the Field is
finalized, respectively.

:param name: the name of the form field
c                 4    Xl         / U l        [        U l        g r-   )_name_value_missing_cache)selfnames     r)   __init__Field.__init__   s    
 r+   c                     U " U5      nUc  UR                  5         OUR                  U5        UR                  5         U$ )a  Create an instance of a :class:`Field`, and set the corresponding
value - either None or an actual value.  This method will also
finalize the Field itself.

:param name: the name of the form field
:param value: the value of the form field - either a bytestring or
              None
)set_nonewritefinalize)klassrV   rF   fs       r)   
from_valueField.from_value   s4     $K=JJLGGEN	

r+   c                 $    U R                  U5      $ )z@Write some data into the form field.

:param data: a bytestring
on_datarU   datas     r)   r[   Field.write       
 ||D!!r+   c                 d    U R                   R                  U5        [        U l        [	        U5      $ )zpThis method is a callback that will be called whenever data is
written to the Field.

:param data: a bytestring
)rR   appendrS   rT   lenrd   s     r)   rc   Field.on_data   s'     	4 4yr+   c                 l    U R                   [        L a!  SR                  U R                  5      U l         gg)?This method is called whenever the Field is finalized.
        r+   NrT   rS   joinrR   rU   s    r)   on_endField.on_end   s)     ;;("((4;;/DK #r+   c                 $    U R                  5         g)z!Finalize the form field.
        Nrq   rp   s    r)   r\   Field.finalize   s     	r+   c                 n    U R                   [        L a   SR                  U R                  5      U l         U ?g)zFClose the Field object.  This will free any underlying cache.
        r+   Nrn   rp   s    r)   closeField.close   s)     ;;("((4;;/DKKr+   c                     SU l         g)aZ  Some fields in a querystring can possibly have a value of None - for
example, the string "foo&bar=&baz=asdf" will have a field with the
name "foo" and value None, one with name "bar" and value "", and one
with name "baz" and value "asdf".  Since the write() interface doesn't
support writing None, this function will set the field value to None.
N)rT   rp   s    r)   rZ   Field.set_none   s     r+   c                     U R                   $ )z,This property returns the name of the field.)rQ   rp   s    r)   
field_nameField.field_name   s     zzr+   c                     U R                   [        L a   SR                  U R                  5      U l         U R                   $ )z2This property returns the value of the form field.r+   rn   rp   s    r)   rF   Field.value   s.     ;;("((4;;/DK{{r+   c                     [        U[        5      (       a9  U R                  UR                  :H  =(       a    U R                  UR                  :H  $ [        $ r-   )r;   rN   r|   rF   NotImplemented)rU   others     r)   __eq__Field.__eq__   sC    eU##5#3#33 *

ekk)
 "!r+   c                     [        U R                  5      S:  a  [        U R                  S S 5      S S S-   nO[        U R                  5      nSR                  U R                  R
                  U R                  U5      $ )Nr#   r7   z...'z{}(field_name={!r}, value={}))rj   rF   reprformat	__class____name__r|   )rU   vs     r)   __repr__Field.__repr__   sl    tzz?R TZZ_%cr*V3ATZZ A.55NN##OO
 	
r+   )rT   rQ   rR   N)r   
__module____qualname____firstlineno____doc__rW   classmethodr_   r[   rc   rq   r\   rw   rZ   propertyr|   rF   r   r   __static_attributes__r&   r+   r)   rN   rN   x   sp      $"0
    "
r+   rN   c                       \ rS rSrSrS0 4S jr\S 5       r\S 5       r\S 5       r	\S 5       r
\S	 5       r\S
 5       rS rS rS rS rS rS rS rS rSrg)File   a  This class represents an uploaded file.  It handles writing file data to
either an in-memory file or a temporary file on-disk, if the optional
threshold is passed.

There are some options that can be passed to the File to change behavior
of the class.  Valid options are as follows:

.. list-table::
   :widths: 15 5 5 30
   :header-rows: 1

   * - Name
     - Type
     - Default
     - Description
   * - UPLOAD_DIR
     - `str`
     - None
     - The directory to store uploaded files in.  If this is None, a
       temporary file will be created in the system's standard location.
   * - UPLOAD_DELETE_TMP
     - `bool`
     - True
     - Delete automatically created TMP file
   * - UPLOAD_KEEP_FILENAME
     - `bool`
     - False
     - Whether or not to keep the filename of the uploaded file.  If True,
       then the filename will be converted to a safe representation (e.g.
       by removing any invalid path segments), and then saved with the
       same name).  Otherwise, a temporary name will be used.
   * - UPLOAD_KEEP_EXTENSIONS
     - `bool`
     - False
     - Whether or not to keep the uploaded file's extension.  If False, the
       file will be saved with the default temporary extension (usually
       ".tmp").  Otherwise, the file's extension will be maintained.  Note
       that this will properly combine with the UPLOAD_KEEP_FILENAME
       setting.
   * - MAX_MEMORY_FILE_SIZE
     - `int`
     - 1 MiB
     - The maximum number of bytes of a File to keep in memory.  By
       default, the contents of a File are kept into memory until a certain
       limit is reached, after which the contents of the File are written
       to a temporary file.  This behavior can be disabled by setting this
       value to an appropriately large value (or, for example, infinity,
       such as `float('inf')`.

:param file_name: The name of the file that this :class:`File` represents

:param field_name: The field name that uploaded this file.  Note that this
                   can be None, if, for example, the file was uploaded
                   with Content-Type application/octet-stream

:param config: The configuration for this File.  See above for valid
               configuration keys and their corresponding values.
Nc                    [         R                  " [        5      U l        X0l        SU l        SU l        [        5       U l        X l	        Xl
        S U l        Ub.  [        R                  R                  U5      u  pEX@l        XPl        g g )NTr   )logging	getLoggerr   logger_config
_in_memory_bytes_writtenr   _fileobj_field_name
_file_name_actual_file_nameospathsplitext
_file_base_ext)rU   	file_namer|   configbaseexts         r)   rW   File.__init__/  su    ''1	 &# "&  ((3ID"OI !r+   c                     U R                   $ )zThe form field associated with this file.  May be None if there isn't
one, for example when we have an application/octet-stream upload.
)r   rp   s    r)   r|   File.field_nameE  s    
 r+   c                     U R                   $ )z3The file name given in the upload request.
        )r   rp   s    r)   r   File.file_nameL  s     r+   c                     U R                   $ )z]The file name that this file is saved as.  Will be None if it's not
currently saved on disk.
)r   rp   s    r)   actual_file_nameFile.actual_file_nameR  s    
 %%%r+   c                     U R                   $ )zThe file object that we're currently writing to.  Note that this
will either be an instance of a :class:`io.BytesIO`, or a regular file
object.
)r   rp   s    r)   file_objectFile.file_objectY  s     }}r+   c                     U R                   $ )zjThe total size of this file, counted as the number of bytes that
currently have been written to the file.
)r   rp   s    r)   size	File.sizea  s    
 """r+   c                     U R                   $ )zaA boolean representing whether or not this file object is currently
stored in-memory or on-disk.
)r   rp   s    r)   	in_memoryFile.in_memoryh  s    
 r+   c                 ~   U R                   (       d  U R                  R                  S5        gU R                  R	                  S5        U R                  5       n[        R                  " U R                  U5        UR	                  U R                  5        U R                  nXl        SU l         UR                  5         g)a  If the file is already on-disk, do nothing.  Otherwise, copy from
the in-memory buffer to a disk file, and then reassign our internal
file object to this new disk file.

Note that if you attempt to flush a file that is already on-disk, a
warning will be logged to this module's logger.
z0Trying to flush to disk when we're not in memoryNr   F)
r   r   warningr   seek_get_disk_fileshutilcopyfileobjr   rw   )rU   new_fileold_fileobjs      r)   flush_to_diskFile.flush_to_disko  s     KKB  	1 &&( 	4==(3 	d))* mm    	r+   c                 J   U R                   R                  S5        U R                  R                  S5      nU R                  R                  SS5      nU R                  R                  SS5      nU R                  R                  SS5      nUb  U(       a  U R                   R                  S	U5        U R                  nU(       a  XPR
                  -   n[        R                  R                  X5      n U R                   R                  S
U5        [        US5      nGO0 n	U(       aI  U R
                  n
[        U
[        5      (       a$  U
R                  [         R"                  " 5       5      n
XS'   Ub?  Un[        U[        5      (       a$  UR                  [         R"                  " 5       5      nXS'   XIS'   U R                   R                  SU	5         [$        R&                  " S0 U	D6nUR(                  n[        U[*        5      (       a$  UR-                  [         R"                  " 5       5      nXPl        U$ ! [         a0  nSnU R                   R                  S5        [        SU-  5      eSnAff = f! [         a'    U R                   R                  S5        [        S5      ef = f)zOThis function is responsible for getting a file object on-disk for us.
        zOpening a file on disk
UPLOAD_DIRUPLOAD_KEEP_FILENAMEFUPLOAD_KEEP_EXTENSIONSUPLOAD_DELETE_TMPTNzSaving with filename in: %rzOpening file: %rzw+bzError opening temporary filez Error opening temporary file: %rsuffixdirdeletez*Creating a temporary file with options: %rz#Error creating named temporary filer&   )r   infor   getr   r   r   r   ro   openOSError	exception	FileErrorr;   r/   decodesysgetfilesystemencodingtempfileNamedTemporaryFilerV   r<   r=   r   )rU   file_dirkeep_filenamekeep_extensions
delete_tmpfnamer   tmp_fileerI   r   ds               r)   r   File._get_disk_file  s=    	12<<##L1(()?G,,**+CUK\\%%&94@
 MKK:HE OOE		)77<<0DK  !3T:e, Giic5))**S%>%>%@AC$'!#a''!:!:!<=A!" *H KKI$&G#66AA
 MME %%%S%>%>%@A!&Q  K%%&DE BT IJJ	K:  G%%&KL EFFGs$   2(H4 I1 4
I.>+I))I.11J"c                 $    U R                  U5      $ )z8Write some data to the File.

:param data: a bytestring
rb   rd   s     r)   r[   
File.write  rg   r+   c                 J   U R                   R                  5       nU R                   R                  U5      nUc  U R                   R                  5       U-
  nU[        U5      :w  a(  U R                  R                  SU[        U5      5        U$ U =R                  U-  sl        U R                  (       ap  U R                  R                  S5      bT  U R                  U R                  R                  S5      :  a+  U R                  R                  S5        U R                  5         U$ )zoThis method is a callback that will be called whenever data is
written to the File.

:param data: a bytestring
z bwritten != len(data) (%d != %d)MAX_MEMORY_FILE_SIZEzFlushing to disk)r   tellr[   rj   r   r   r   r   r   r   r   r   )rU   re   posbwrittens       r)   rc   File.on_data  s     mm  "==&&t,}}))+c1H s4y KK BH #D	+O 	x' OO  !78D$$!!"89:KK/0  r+   c                 8    U R                   R                  5         g)rm   N)r   flushrp   s    r)   rq   File.on_end  s     	r+   c                 $    U R                  5         g)z~Finalize the form file.  This will not close the underlying file,
but simply signal that we are finished writing to the File.
Nrt   rp   s    r)   r\   File.finalize  s     	r+   c                 8    U R                   R                  5         g)zClose the File object.  This will actually close the underlying
file object (whether it's a :class:`io.BytesIO` or an actual file
object).
N)r   rw   rp   s    r)   rw   
File.close  s    
 	r+   c                 x    SR                  U R                  R                  U R                  U R                  5      $ )Nz#{}(file_name={!r}, field_name={!r}))r   r   r   r   r|   rp   s    r)   r   File.__repr__  s0    4;;NN##NNOO
 	
r+   )
r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   rW   r   r|   r   r   r   r   r   r   r   r[   rc   rq   r\   rw   r   r   r&   r+   r)   r   r      s    9t .2" ,      
 & &   # #  "H@D"@
r+   r   c                   @    \ rS rSrSrS rSS jrS rS rS r	S	 r
S
rg)
BaseParseri  a  This class is the base class for all parsers.  It contains the logic for
calling and adding callbacks.

A callback can be one of two different forms.  "Notification callbacks" are
callbacks that are called when something happens - for example, when a new
part of a multipart message is encountered by the parser.  "Data callbacks"
are called when we get some sort of data - for example, part of the body of
a multipart chunk.  Notification callbacks are called with no parameters,
whereas data callbacks are called with three, as follows::

    data_callback(data, start, end)

The "data" parameter is a bytestring (i.e. "foo" on Python 2, or b"foo" on
Python 3).  "start" and "end" are integer indexes into the "data" string
that represent the data of interest.  Thus, in a data callback, the slice
`data[start:end]` represents the data that the callback is "interested in".
The callback is not passed a copy of the data, since copying severely hurts
performance.
c                 B    [         R                  " [        5      U l        g r-   )r   r   r   r   rp   s    r)   rW   BaseParser.__init__+  s    ''1r+   Nc                     SU-   nU R                   R                  U5      nUc  gUb0  Ub  X4:X  a  gU R                  R                  SXU5        U" X#U5        gU R                  R                  SU5        U" 5         g)a  This function calls a provided callback with some data.  If the
callback is not set, will do nothing.

:param name: The name of the callback to call (as a string).

:param data: Data to pass to the callback.  If None, then it is
             assumed that the callback is a notification callback,
             and no parameters are given.

:param end: An integer that is passed to the data callback.

:param start: An integer that is passed to the data callback.
on_NzCalling %s with data[%d:%d]zCalling %s with no data)	callbacksr   r   debug)rU   rV   re   startendfuncs         r)   callbackBaseParser.callback.  sy     t|~~!!$'<  U\KK;T#Nc"KK7>Fr+   c                 l    Uc   U R                   R                  SU-   S5        gX R                   SU-   '   g)aA  Update the function for a callback.  Removes from the callbacks dict
if new_func is None.

:param name: The name of the callback to call (as a string).

:param new_func: The new function for the callback.  If None, then the
                 callback will be removed (with no error if it does not
                 exist).
Nr   )r   pop)rU   rV   new_funcs      r)   set_callbackBaseParser.set_callbackM  s2     NNut|T2+3NN54<(r+   c                     g r-   r&   rp   s    r)   rw   BaseParser.close\      r+   c                     g r-   r&   rp   s    r)   r\   BaseParser.finalize_  r  r+   c                 4    SU R                   R                  -  $ Nz%s()r   r   rp   s    r)   r   BaseParser.__repr__b      ////r+   )r   )NNN)r   r   r   r   r   rW   r   r  rw   r\   r   r   r&   r+   r)   r   r     s%    &2>40r+   r   c                   R   ^  \ rS rSrSr0 \" S5      4U 4S jjrS rS rS r	Sr
U =r$ )	OctetStreamParserif  a  This parser parses an octet-stream request body and calls callbacks when
incoming data is received.  Callbacks are as follows:

.. list-table::
   :widths: 15 10 30
   :header-rows: 1

   * - Callback Name
     - Parameters
     - Description
   * - on_start
     - None
     - Called when the first data is parsed.
   * - on_data
     - data, start, end
     - Called for each data chunk that is parsed.
   * - on_end
     - None
     - Called when the parser is finished parsing all data.

:param callbacks: A dictionary of callbacks.  See the documentation for
                  :class:`BaseParser`.

:param max_size: The maximum size of body to parse.  Defaults to infinity -
                 i.e. unbounded.
infc                    > [         TU ]  5         Xl        SU l        [	        U[
        5      (       a  US:  a  [        SU-  5      eX l        SU l        g NFr   *max_size must be a positive number, not %rr   )	superrW   r   _startedr;   r   
ValueErrormax_size_current_size)rU   r   r  r   s      r)   rW   OctetStreamParser.__init__  sR    "(F++x!|I%& ' ' r+   c                    U R                   (       d  U R                  S5        SU l         [        U5      nU R                  U-   U R                  :  aW  [        U R                  U R                  -
  5      nU R                  R                  SU R                  U R                  UU5        UnU =R                  U-  sl        U R                  SUSU5        U$ )zWrite some data to the parser, which will perform size verification,
and then pass the data to the underlying callback.

:param data: a bytestring
r   TDCurrent size is %d (max %d), so truncating data length from %d to %dre   r   )r  r   rj   r  r  intr   r   )rU   re   data_lennew_sizes       r)   r[   OctetStreamParser.write  s     }}MM'" DM t9)T]]:4==4+=+==>HKK !< $ 2 2DMM8 (*  H 	h&fdAx0r+   c                 &    U R                  S5        g)zdFinalize this parser, which signals to that we are finished parsing,
and sends the on_end callback.
r   N)r   rp   s    r)   r\   OctetStreamParser.finalize  s     	er+   c                 4    SU R                   R                  -  $ r  r  rp   s    r)   r   OctetStreamParser.__repr__  r  r+   )r  r  r   r  )r   r   r   r   r   floatrW   r[   r\   r   r   __classcell__r   s   @r)   r  r  f  s,    4 "$eEl 	40 0r+   r  c                   Z   ^  \ rS rSrSr0 S\" S5      4U 4S jjrS rS rS r	S	 r
S
rU =r$ )QuerystringParseri  aq  This is a streaming querystring parser.  It will consume data, and call
the callbacks given when it has data.

.. list-table::
   :widths: 15 10 30
   :header-rows: 1

   * - Callback Name
     - Parameters
     - Description
   * - on_field_start
     - None
     - Called when a new field is encountered.
   * - on_field_name
     - data, start, end
     - Called when a portion of a field's name is encountered.
   * - on_field_data
     - data, start, end
     - Called when a portion of a field's data is encountered.
   * - on_field_end
     - None
     - Called when the end of a field is encountered.
   * - on_end
     - None
     - Called when the parser is finished parsing all data.

:param callbacks: A dictionary of callbacks.  See the documentation for
                  :class:`BaseParser`.

:param strict_parsing: Whether or not to parse the body strictly.  Defaults
                       to False.  If this is set to True, then the behavior
                       of the parser changes as the following: if a field
                       has a value with an equal sign (e.g. "foo=bar", or
                       "foo="), it is always included.  If a field has no
                       equals sign (e.g. "...&name&..."), it will be
                       treated as an error if 'strict_parsing' is True,
                       otherwise included.  If an error is encountered,
                       then a
                       :class:`multipart.exceptions.QuerystringParseError`
                       will be raised.

:param max_size: The maximum size of body to parse.  Defaults to infinity -
                 i.e. unbounded.
Fr  c                    > [         TU ]  5         [        U l        SU l        Xl        [        U[        5      (       a  US:  a  [        SU-  5      eX0l	        SU l
        X l        g r  )r  rW   STATE_BEFORE_FIELDstate
_found_sepr   r;   r   r  r  r  strict_parsing)rU   r   r.  r  r   s       r)   rW   QuerystringParser.__init__  sc    '
" (F++x!|I%& ' '  -r+   c                    [        U5      nU R                  U-   U R                  :  aW  [        U R                  U R                  -
  5      nU R                  R                  SU R                  U R                  UU5        UnSn U R                  X5      nU =R                  U-  sl        U$ ! U =R                  U-  sl        f = f)a  Write some data to the parser, which will perform size verification,
parse into either a field name or value, and then pass the
corresponding data to the underlying callback.  If an error is
encountered while parsing, a QuerystringParseError will be raised.  The
"offset" attribute of the raised exception will be set to the offset in
the input data chunk (NOT the overall stream) that caused the error.

:param data: a bytestring
r  r   rj   r  r  r  r   r   _internal_writerU   re   r  r  ls        r)   r[   QuerystringParser.write       t9)T]]:4==4+=+==>HKK !< $ 2 2DMM8 (*  H	$$$T4A!# !#   B+ +Cc                 *   U R                   nU R                  nU R                  nSnXb:  GaQ  X   nU[        :X  az  U[        :X  d
  U[
        :X  aF  U(       a;  U(       a  [        SU-  5      nXhl        UeU R                  R                  SU5        GOSnGOU R                  S5        US-  n[        nSnGOU[        :X  a  UR                  SU5      n	U	S:X  a  UR                  S	U5      n	U	S:w  a  UR                  S
Xi5      n
OUR                  S
U5      n
U
S:w  a  U R                  SXU
5        U
n[        nGO:U(       dL  U	S:w  a0  U R                  SXU	5        U R                  S5        U	S-
  n[        nOU R                  SXU5        UnOU	S:w  a  [        SU4-  5      nXhl        UeU R                  SXU5        UnOU[        :X  av  UR                  SU5      n	U	S:X  a  UR                  S	U5      n	U	S:w  a0  U R                  SXU	5        U R                  S5        U	S-
  n[        nOJU R                  SXU5        UnO4SX64-  nU R                  R                  U5        [        U5      nXhl        UeUS-  nXb:  a  GMQ  X0l         XPl        [        U5      $ )Nr   z,Skipping duplicate ampersand/semicolon at %dTfield_startr   F   &r7   r6      =r|   	field_endz{When strict_parsing is True, we require an equals sign in all field chunks. Did not find one in the chunk that starts at %d
field_data!Reached an unknown state %d at %d)r,  r.  r-  r+  	AMPERSAND	SEMICOLONQuerystringParseErroroffsetr   r   r   STATE_FIELD_NAMEfindSTATE_FIELD_DATAr   rj   )rU   re   lengthr,  r.  	found_sepichr   sep_pos
equals_posmsgs               r)   r2  !QuerystringParser._internal_write  s   

,,OO	jB ** ?bIo ) 5!%'(!)!A ()H"#G KK-- /;<=? %)	
 MM-0FA,E %I** ))D!,b="iia0G
 b=!%4!<J!%4!3J#MM,D
 #A,E *
 #b= MM,I MM+6 '!A$6E !MM,H &A
 #b=!6!J "#!%"A ()H"#G lDVD"** ))D!,b="iia0G b=MM,AMM+.  !A.E MM,@A :UJF##C()#.FAG jJ 
#4yr+   c                 p    U R                   [        :X  a  U R                  S5        U R                  S5        g)zFinalize this parser, which signals to that we are finished parsing,
if we're still in the middle of a field, an on_field_end callback, and
then the on_end callback.
r<  r   N)r,  rE  r   rp   s    r)   r\   QuerystringParser.finalize  s)     ::))MM+&er+   c                 x    SR                  U R                  R                  U R                  U R                  5      $ )Nz&{}(strict_parsing={!r}, max_size={!r}))r   r   r   r.  r  rp   s    r)   r   QuerystringParser.__repr__  s1    7>>NN##
 	
r+   )r  r-  r   r  r,  r.  r   r   r   r   r   r%  rW   r[   r2  r\   r   r   r&  r'  s   @r)   r)  r)    s7    +X "$E,-$:M^
 
r+   r)  c                   X   ^  \ rS rSrSr0 \" S5      4U 4S jjrS rS rS r	S r
S	rU =r$ )
MultipartParseri  ak  This class is a streaming multipart/form-data parser.

.. list-table::
   :widths: 15 10 30
   :header-rows: 1

   * - Callback Name
     - Parameters
     - Description
   * - on_part_begin
     - None
     - Called when a new part of the multipart message is encountered.
   * - on_part_data
     - data, start, end
     - Called when a portion of a part's data is encountered.
   * - on_part_end
     - None
     - Called when the end of a part is reached.
   * - on_header_begin
     - None
     - Called when we've found a new header in a part of a multipart
       message
   * - on_header_field
     - data, start, end
     - Called each time an additional portion of a header is read (i.e. the
       part of the header that is before the colon; the "Foo" in
       "Foo: Bar").
   * - on_header_value
     - data, start, end
     - Called when we get data for a header.
   * - on_header_end
     - None
     - Called when the current header is finished - i.e. we've reached the
       newline at the end of the header.
   * - on_headers_finished
     - None
     - Called when all headers are finished, and before the part data
       starts.
   * - on_end
     - None
     - Called when the parser is finished parsing all data.


:param boundary: The multipart boundary.  This is required, and must match
                 what is given in the HTTP request - usually in the
                 Content-Type header.

:param callbacks: A dictionary of callbacks.  See the documentation for
                  :class:`BaseParser`.

:param max_size: The maximum size of body to parse.  Defaults to infinity -
                 i.e. unbounded.
r  c                   > [         TU ]  5         [        U l        S=U l        U l        X l        [        U[        5      (       a  US:  a  [        SU-  5      eX0l
        SU l        0 U l        [        U[        5      (       a  UR                  S5      nSU-   U l        [!        U R                  5      U l        [%        ['        U5      S-   5       Vs/ s H	  n[(        PM     snU l        g s  snf )Nr   r   r  r5   s   
--r   )r  rW   STATE_STARTr,  indexflagsr   r;   r   r  r  r  marksr<   r=   boundary	frozensetboundary_charsrangerj   NULL
lookbehind)rU   rZ  r   r  xr   s        r)   rW   MultipartParser.__init__  s     
"##
TZ"(F++x!|I%& ' '  
 h$$y1H!H, (6 */s8}q/@)AB)AA4)ABBs   C(c                    [        U5      nU R                  U-   U R                  :  aW  [        U R                  U R                  -
  5      nU R                  R                  SU R                  U R                  UU5        UnSn U R                  X5      nU =R                  U-  sl        U$ ! U =R                  U-  sl        f = f)a  Write some data to the parser, which will perform size verification,
and then parse the data into the appropriate location (e.g. header,
data, etc.), and pass this on to the underlying callback.  If an error
is encountered, a MultipartParseError will be raised.  The "offset"
attribute on the raised exception will be set to the offset of the byte
in the input chunk that caused the error.

:param data: a bytestring
r  r   r1  r3  s        r)   r[   MultipartParser.write  r6  r7  c                    ^ ^^^ T R                   nT R                  nT R                  nT R                  nSmUU 4S jnSU 4S jjnSUUUU 4S jjn	TT:  Ga  TT   n
U[        :X  aF  U
[
        :X  d
  U
[        :X  a#  TS-  mT R                  R                  ST5        MM  Sn[        nTS-  mGOU[        :X  Ga  U[        U5      S-
  :X  aF  U
[
        :w  a5  ST4-  nT R                  R                  U5        [        U5      nTUl        UeUS-  nGO0U[        U5      S-
  S-   :X  aZ  U
[        :w  a5  S	T4-  nT R                  R                  U5        [        U5      nTUl        UeSnT R                  S
5        [        nGOXUS-      :w  a8  SXS-   4-  nT R                  R                  U5        [        U5      nTUl        UeUS-  nGOwU[        :X  a  SnU" S5        [         nTS-  mGOVU[         :X  a  U
[
        :X  a  U" S5        ["        nTS-  mGM  US-  nU
[$        :X  a  GOU
[&        :X  aK  US:X  a5  ST4-  nT R                  R                  U5        [        U5      nTUl        UeU	" S5        [(        nGO[+        U
5      nU[,        :  d
  U[.        :  a6  SU
T4-  nT R                  R                  U5        [        U5      nTUl        UeGOoU[(        :X  a'  U
[0        :X  a  TS-  mGM  U" S5        [2        nTS-  mGO>U[2        :X  a+  U
[
        :X  a  U	" S5        T R                  S5        [4        nGO	U[4        :X  aH  U
[        :w  a6  SU
< S3nT R                  R                  U5        [        U5      nTUl        Ue[        nGOU["        :X  aY  U
[        :w  a6  SU
< S3nT R                  R                  U5        [        U5      nTUl        UeT R                  S5        [6        nGOTU[6        :X  a  U" S5        [8        nTS-  mGO5U[8        :X  Ga  Un[        U5      nUS-
  nTnT R:                  nUS:X  a:  TU-  mTUS-
  :  a"  TT   U;  a  TU-  mTUS-
  :  a  TT   U;  a  M  TU-  mTT   n
X_:  a  X5   U
:X  a  US:X  a  U	" S5        US-  nOSnOX_:X  a0  US-  nU
[
        :X  a
  U[<        -  nOU
[$        :X  a
  U[>        -  nOSnOX_S-   :X  a  U[<        -  (       aS  U
[        :X  a<  U[<        ) -  nT R                  S5        T R                  S
5        Sn[        nTS-  mGM  SnU[<        ) -  nOCU[>        -  (       a5  U
[$        :X  a)  T R                  S5        T R                  S5        [@        nOSnUS:  a  U
T RB                  US-
  '   OUS:  a8  [E        T RB                  5      nT R                  SUSU5        SnU" S5        TS-  mOmU[@        :X  a-  U
[
        [        4;  a  T R                  R                  SU
5        O6SUT4-  nT R                  R                  U5        [        U5      nTUl        UeTS-  mTT:  a  GM  U	" SS5        U	" SS5        U	" SS5        UT l        UT l        UT l        T$ )Nr   c                 $   > TTR                   U '   g r-   )rY  )rV   rH  rU   s    r)   set_mark1MultipartParser._internal_write.<locals>.set_mark6  s     DJJtr+   c                 >   > TR                   R                  U S 5        g r-   )rY  r  )rV   resetrU   s     r)   delete_mark4MultipartParser._internal_write.<locals>.delete_mark:  s    JJNN4&r+   c                    > TR                   R                  U 5      nUc  g U(       a$  TR                  U TUT5        STR                   U '   g TR                  U TUT5        TR                   R                  U S 5        g )Nr   )rY  r   r   r  )rV   	remainingmarked_indexre   rH  rF  rU   s      r)   data_callback6MultipartParser._internal_write.<locals>.data_callbackB  si    ::>>$/L# dD,?#$

4 
 dD,:

tT*r+   r   zSkipping leading CR/LF at %dr   z'Did not find CR at end of boundary (%d)z'Did not find LF at end of boundary (%d)
part_beginz.Did not find boundary character %r at index %dheader_fieldzFound 0-length header at %dz3Found non-alphanumeric character %r in header at %dheader_value
header_endz2Did not find LF character at end of header (found )z)Did not find LF at end of headers (found headers_finished	part_datapart_endr   z(Consuming a byte '0x%x' in the end stater>  T)F)#rZ  r,  rW  rX  rV  CRLFr   r   STATE_START_BOUNDARYrj   r   MultipartParseErrorrB  r   STATE_HEADER_FIELD_STARTSTATE_HEADER_FIELDSTATE_HEADERS_ALMOST_DONEHYPHENCOLONSTATE_HEADER_VALUE_START
lower_charLOWER_ALOWER_ZSPACESTATE_HEADER_VALUESTATE_HEADER_VALUE_ALMOST_DONESTATE_PART_DATA_STARTSTATE_PART_DATAr\  FLAG_PART_BOUNDARYFLAG_LAST_BOUNDARY	STATE_ENDr_  
join_bytes)rU   re   rF  rZ  r,  rW  rX  rf  rj  ro  r(   rL  r   cl
prev_indexboundary_lengthboundary_enddata_lengthr\  lb_datarH  s   ```                 @r)   r2  MultipartParser._internal_write(  s   == 





 	!	'	+ 	+$ &jQA#7a2gFAKK%%&DaH  -Q.. CMA--BwG1$N++C0/4#$QJEc(ma/!33BwG1$N++C0/4#$ E MM,/ 5E UQY//#&'^4++C0/4#$ QJE22  ( +Q,, 7/5EFA 
 ; %Zz;qdB++C0/4#$ ".1 5E
 $ABG|rG|-011v6++C0/4#$ (4 22:FA ( +Q,, 7!.1MM,/:E887*+.CKK'',+C0A AHG
 133 7EaU!LCKK'',+C0A AHG01-//% (Q/) #
 #&h-.2$!%!4!4 A: %AkAo-$q'2O_, kAo-$q'2O %AQA *!+ !A:)+6 
 ! -QJE Bw!33 f!33
 !" 11 117!'9&9:E !MM*5 MM,7 %&E$<EFA$ !"#5"56 !33; !MM*5 MM%0$-E %&E 1912DOOEAI.  !^(9GMM+w:F "#J [) FA)#RH$KK''(RTUV :UAJF##C(', FAK
 &j^
 	nd+nd+k4( 


 r+   c                     g)a  Finalize this parser, which signals to that we are finished parsing.

Note: It does not currently, but in the future, it will verify that we
are in the final state of the parser (i.e. the end of the multipart
message is well-formed), and, if not, throw an error.
Nr&   rp   s    r)   r\   MultipartParser.finalize  s     	r+   c                 P    U R                   R                   SU R                  < S3$ )Nz
(boundary=ru  )r   r   rZ  rp   s    r)   r   MultipartParser.__repr__  s%    ..))**T]]4EQGGr+   )
r  rZ  r\  r   rX  rW  r_  rY  r  r,  rR  r'  s   @r)   rT  rT    s8    4l ,.e &CP:FP	H Hr+   rT  c                   d    \ rS rSrSr\" S5      SSSSSS.rSSS\\0 4S jr	S	 r
S
 rS rS rSrg)
FormParseri  a	  This class is the all-in-one form parser.  Given all the information
necessary to parse a form, it will instantiate the correct parser, create
the proper :class:`Field` and :class:`File` classes to store the data that
is parsed, and call the two given callbacks with each field and file as
they become available.

:param content_type: The Content-Type of the incoming request.  This is
                     used to select the appropriate parser.

:param on_field: The callback to call when a field has been parsed and is
                 ready for usage.  See above for parameters.

:param on_file: The callback to call when a file has been parsed and is
                ready for usage.  See above for parameters.

:param on_end: An optional callback to call when all fields and files in a
               request has been parsed.  Can be None.

:param boundary: If the request is a multipart/form-data request, this
                 should be the boundary of the request, as given in the
                 Content-Type header, as a bytestring.

:param file_name: If the request is of type application/octet-stream, then
                  the body of the request will not contain any information
                  about the uploaded file.  In such cases, you can provide
                  the file name of the uploaded file manually.

:param FileClass: The class to use for uploaded files.  Defaults to
                  :class:`File`, but you can provide your own class if you
                  wish to customize behaviour.  The class will be
                  instantiated as FileClass(file_name, field_name), and it
                  must provide the following functions::
                      file_instance.write(data)
                      file_instance.finalize()
                      file_instance.close()

:param FieldClass: The class to use for uploaded fields.  Defaults to
                   :class:`Field`, but you can provide your own class if
                   you wish to customize behaviour.  The class will be
                   instantiated as FieldClass(field_name), and it must
                   provide the following functions::
                       field_instance.write(data)
                       field_instance.finalize()
                       field_instance.close()

:param config: Configuration to use for this FormParser.  The default
               values are taken from the DEFAULT_CONFIG value, and then
               any keys present in this dictionary will overwrite the
               default values.

r     NF)MAX_BODY_SIZEr   r   r   r   UPLOAD_ERROR_ON_BAD_CTEc
           	      @  ^ ^^^^^^^^^^ [         R                  " [        5      T l        UT l        UT l        ST l        S T l        TT l        TT l	        UT l
        [        T l        [        T l        T R                  R!                  5       T l        T R"                  R%                  U	5        US:X  a@   " S S5      mUUU U4S jn
U4S jnUU U4S jnU
UUS.n['        UT R"                  S	   S
9nGO&US:X  d  US:X  aL  / m " S S5      mS nU4S jnUUU4S jnUUUU4S jnU 4S jnUUUUUS.n[)        UT R"                  S	   S9nOUS:X  a  Uc&  T R                  R+                  S5        [-        S5      e/ m/ m0 m " S S5      mS nU4S jnUUU4S jnU4S jnU4S jnUUU4S jnUUUU U4S jnU U4S jnUUUUUUUUS .n[/        X\T R"                  S	   S
9nO6T R                  R1                  S!U5        [-        S"R3                  U5      5      eUT l        g )#Nr   zapplication/octet-streamc                       \ rS rSrSrSrg)!FormParser.__init__.<locals>.varsi  Nr&   r   r   r   r   r^   r   r&   r+   r)   varsr        r+   r  c                  4   > T " TS TR                   S9Tl        g )Nr   )r   r^   )	FileClassr   rU   r  s   r)   on_start%FormParser.__init__.<locals>.on_start  s    "9d4;;Gr+   c                 @   > TR                   R                  XU 5        g r-   )r^   r[   )re   r   r   r  s      r)   rc   $FormParser.__init__.<locals>.on_data"  s    T_-r+   c                     > TR                   R                  5         T " TR                   5        TR                  b  TR                  5         g g r-   )r^   r\   rq   )on_filerU   r  s   r)   rq   #FormParser.__init__.<locals>.on_end%  s8    !  ;;*KKM +r+   )r  rc   rq   r  )r  z!application/x-www-form-urlencodedzapplication/x-url-encodedc                       \ rS rSrSrSrg)r  i?  Nr&   r  r&   r+   r)   r  r  ?  r  r+   c                      g r-   r&   r&   r+   r)   on_field_start+FormParser.__init__.<locals>.on_field_startB      r+   c                 ,   > TR                  XU 5        g r-   ri   )re   r   r   name_buffers      r)   on_field_name*FormParser.__init__.<locals>.on_field_nameE      ""4c?3r+   c                    > TR                   c!  T" SR                  T5      5      Tl         TS S 2	 TR                   R                  XU 5        g Nr+   )r^   ro   r[   )re   r   r   
FieldClassr  r  s      r)   on_field_data*FormParser.__init__.<locals>.on_field_dataH  s<    66>'(=>DF#AT_-r+   c                     > TR                   c;  T " SR                  T5      5      Tl         TS S 2	 TR                   R                  5         TR                   R                  5         T" TR                   5        S Tl         g r  )r^   ro   rZ   r\   )r  r  on_fieldr  s   r)   on_field_end)FormParser.__init__.<locals>.on_field_endN  sY    66> ((=>DF#AFFOO%! r+   c                  B   > T R                   b  T R                  5         g g r-   rt   rp   s   r)   rq   r  [  s    ;;*KKM +r+   )r  r  r  r  rq   )r   r  zmultipart/form-datazNo boundary givenc                        \ rS rSrSrSrSrSrg)r  ix  NFr&   )r   r   r   r   r^   writeris_filer   r&   r+   r)   r  r  x  s    r+   c                      g r-   r&   r&   r+   r)   on_part_begin*FormParser.__init__.<locals>.on_part_begin}  r  r+   c                 B   > TR                   R                  XU 5      nU$ r-   )r  r[   )re   r   r   bytes_processedr  s       r)   on_part_data)FormParser.__init__.<locals>.on_part_data  s!    "&++"3"3DsO"D&&r+   c                     > TR                   R                  5         TR                  (       a  T" TR                   5        g T " TR                   5        g r-   )r^   r\   r  )r  r  r  s   r)   on_part_end(FormParser.__init__.<locals>.on_part_end  s/    !<<DFFOTVV$r+   c                 ,   > TR                  XU 5        g r-   r  )re   r   r   header_names      r)   on_header_field,FormParser.__init__.<locals>.on_header_field  r  r+   c                 ,   > TR                  XU 5        g r-   r  )re   r   r   rs  s      r)   on_header_value,FormParser.__init__.<locals>.on_header_value  s    ##DsO4r+   c                  `   > SR                  T5      TSR                  T 5      '   T S S 2	 TS S 2	 g r  )ro   )r  rs  headerss   r)   on_header_end*FormParser.__init__.<locals>.on_header_end  s-    14,1G-.N Or+   c                    > ST
l         TR                  S5      n [        U 5      u  pUR                  S5      nUR                  S5      nUc  T" U5      T
l        OT" XCT	R                  S9T
l        ST
l         TR                  SS5      nUS	:X  d  US
:X  d  US:X  a  T
R                  T
l        g US:X  a  [        T
R                  5      T
l        g US:X  a  [        T
R                  5      T
l        g T	R                  R                  SU5        T	R                  S   (       a  [        SR                  U5      5      eT
R                  T
l        g )NFs   Content-Dispositions   namer:   r  Ts   Content-Transfer-Encodings   7bits   binarys   8bits   base64s   quoted-printablez%Unknown Content-Transfer-Encoding: %rr  z&Unknown Content-Transfer-Encoding "{}")r  r   rL   r^   r   r  Base64DecoderQuotedPrintableDecoderr   r   FormParserErrorr   )content_dispdisprI   r|   r   transfer_encodingr  r  r  rU   r  s         r)   on_headers_finished0FormParser.__init__.<locals>.on_headers_finished  s4   $  '{{+AB 4\ B %[[1
#KK4	 $'
3DF&yT[[QDF#'DL
 %,KK0L07%9! &2)W4)W4"&&&DK&)3"/"7DK&*=="8"@DK KK'' )-.?A{{#<=-DKK 1  '+ffr+   c                  v   > TR                   R                  5         T R                  b  T R                  5         g g r-   )r  r\   rq   )rU   r  s   r)   rq   r    s+    $$&;;*KKM +r+   )r  r  r  r  r  r  r  rq   zUnknown Content-Type: %rzUnknown Content-Type: {})r   r   r   r   content_typerZ  bytes_receivedparserr  r  rq   r   r  rN   r  DEFAULT_CONFIGcopyr   updater  r)  errorr  rT  r   r   )rU   r  r  r  rq   rZ  r   r  r  r   r  rc   r   r  r  r  r  r  r  r  r  r  r  r  r  r  rs  r  r  r  s   ` ``  ```                @@@@@r)   rW   FormParser.__init__   sF    ''1 )  !  ))..06" 55 H H.	" %" I 'y04O0LNF AA99K 4. " #1!.!. , I '#_5F
 22!!"56%&9::KLG   
'
%45$
2- 2-h" "/ ,*#2#2!.': 	I %X.2kk/.JLF KK :LI!"<"C"C#   r+   c                 t    U =R                   [        U5      -  sl         U R                  R                  U5      $ )zpWrite some data.  The parser will forward this to the appropriate
underlying parser.

:param data: a bytestring
)r  rj   r  r[   rd   s     r)   r[   FormParser.write  s.     	s4y({{  &&r+   c                     U R                   b7  [        U R                   S5      (       a  U R                   R                  5         ggg)zFinalize the parser.Nr\   )r  hasattrr\   rp   s    r)   r\   FormParser.finalize  s5    ;;"wt{{J'G'GKK  " (H"r+   c                     U R                   b7  [        U R                   S5      (       a  U R                   R                  5         ggg)zClose the parser.Nrw   )r  r  rw   rp   s    r)   rw   FormParser.close  s5    ;;"wt{{G'D'DKK (E"r+   c                 x    SR                  U R                  R                  U R                  U R                  5      $ )Nz"{}(content_type={!r}, parser={!r}))r   r   r   r  r  rp   s    r)   r   FormParser.__repr__  s2    3::NN##KK
 	
r+   )r  r  rZ  r  r   r  r   rq   r  r  r  )r   r   r   r   r   r%  r  r   rN   rW   r[   r\   rw   r   r   r&   r+   r)   r  r    sW    2l u / %"' $)	N @D$$!"fP'#
 

r+   r  Fc           	      2   U R                  S5      nUc4  [        R                  " [        5      R	                  S5        [        S5      e[        U5      u  pVUR                  S5      nUR                  S5      nU R                  S5      n[        UUUUUUS9n	U	$ )a  This function is a helper function to aid in creating a FormParser
instances.  Given a dictionary-like headers object, it will determine
the correct information needed, instantiate a FormParser with the
appropriate values and given callbacks, and then return the corresponding
parser.

:param headers: A dictionary-like object of HTTP headers.  The only
                required header is Content-Type.

:param on_field: Callback to call with each parsed field.

:param on_file: Callback to call with each parsed file.

:param trust_x_headers: Whether or not to trust information received from
                        certain X-Headers - for example, the file name from
                        X-File-Name.

:param config: Configuration variables to pass to the FormParser.
zContent-TypezNo Content-Type header givenzNo Content-Type header given!s   boundaryr5   zX-File-Name)rZ  r   r   )	r   r   r   r   r   r  rL   r   r  )
r  r  r  trust_x_headersr   r  paramsrZ  r   form_parsers
             r)   create_form_parserr    s    * ;;~.L(#++,JK899 0=Lzz+&H  &&y1L M*I \%$&.'0$*,K r+   c                 B   [        XU5      nU R                  S5      nUb  [        U5      nO[        S5      nSn [	        Xx-
  S5      n	UR                  U	5      n
UR                  U
5        U[        U
5      -  n[        U
5      U	:w  d  X:X  a  OMU  UR                  5         g)a  This function is useful if you just want to parse a request body,
without too much work.  Pass it a dictionary-like object of the request's
headers, and a file-like object for the input stream, along with two
callbacks that will get called whenever a field or file is parsed.

:param headers: A dictionary-like object of HTTP headers.  The only
                required header is Content-Type.

:param input_stream: A file-like object that represents the request body.
                     The read() method must return bytestrings.

:param on_field: Callback to call with each parsed field.

:param on_file: Callback to call with each parsed file.

:param chunk_size: The maximum size to read from the input stream and write
                   to the parser at one time.  Defaults to 1 MiB.
zContent-LengthNr  r   r  )	r  r   r  r%  minreadr[   rj   r\   )r  input_streamr  r  
chunk_sizekwargsr  content_length
bytes_readmax_readablebuffs              r)   
parse_formr  5  s    ,  7;F [[!12N!^,uJ
>6@  . 	Tc$i
 t9$
(D  OOr+   )r  )?decoders
exceptionsr   rer   r   r   r   ior   numbersr   objectrS   r+  rC  rE  rV  r{  r}  r~  r  r  r  r  r  r  STATE_PART_DATA_ENDr  STATESr  r  ry  rz  r  r  r  r?  r@  r  r  r^  r  ord_charr  escapeSPECIAL_CHARS
QUOTED_STR	VALUE_STROPTION_RE_STRcompilerA   rD   rL   rN   r   r   r  r)  rT  r  r  r  r&   r+   r)   <module>r     s     	 	 
      8     #$"# "# "# "# "# "# "# "# "#"$ "$	
 #$ "# 
 			

  
%
 		23 
%/*<uD	%7)CeK  JJ}%	&Ry
 y
x`
 `
F	L0 L0^G0
 G0Ty

 y
xPHj PHfB
 B
J
 DI .b0r+   