
    ,h*                   :   U 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
 d dlmZmZ d dlmZ d dlmZmZ dd	lmZmZ dd
lmZmZmZmZ erd dlmZmZmZmZmZ d dl m!Z!  G d de      Z" G d ded      Z# G d ded      Z$ G d ded      Z% G d de      Z& G d ded      Z' G d de      Z( G d de(e      Z) G d d e(e      Z*ee)gdf   Z+ee*gdf   Z,ed!   Z-d"e.d#<    e/       Z0 G d$ d%e
      Z1 G d& d'e
      Z2dZ3d(Z4d)Z5d*Z6d+Z7d,Z8d-Z9d.Z:d/Z;d0Z<d1Z=d Z> e?d2      Z@dDd3ZA G d4 d5      ZB G d6 d7      ZC G d8 d9      ZD G d: d;eD      ZE G d< d=eD      ZF G d> d?eD      ZG G d@ dA      ZHdi f	 	 	 	 	 	 	 	 	 	 	 dEdBZI	 dF	 	 	 	 	 	 	 	 	 	 	 dGdCZJy)H    )annotationsN)Message)IntEnum)BufferedRandomBytesIO)Number)TYPE_CHECKINGcast   )Base64DecoderQuotedPrintableDecoder)	FileErrorFormParserErrorMultipartParseErrorQuerystringParseError)AnyCallableLiteralProtocol	TypedDict)	TypeAliasc                      e Zd ZddZy)SupportsReadc                     y N )self_SupportsRead__ns     \/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/python_multipart/multipart.pyreadzSupportsRead.read           N)r   intreturnbytes)__name__
__module____qualname__r    r   r"   r   r   r      s    .r"   r   c                  @    e Zd ZU ded<   ded<   ded<   ded<   ded<   y)	QuerystringCallbacksCallable[[], None]on_field_start!Callable[[bytes, int, int], None]on_field_nameon_field_dataon_field_endon_endNr&   r'   r(   __annotations__r   r"   r   r*   r*      s     **8888((""r"   r*   F)totalc                  ,    e Zd ZU ded<   ded<   ded<   y)OctetStreamCallbacksr+   on_startr-   on_datar1   Nr2   r   r"   r   r6   r6       s    $$22""r"   r6   c                  h    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   y)MultipartCallbacksr+   on_part_beginr-   on_part_dataon_part_endon_header_beginon_header_fieldon_header_valueon_header_endon_headers_finishedr1   Nr2   r   r"   r   r:   r:   %   s8    ))77''++::::))//""r"   r:   c                  J    e Zd ZU ded<   ded<   ded<   ded<   ded<   d	ed
<   y)FormParserConfigz
str | None
UPLOAD_DIRboolUPLOAD_KEEP_FILENAMEUPLOAD_KEEP_EXTENSIONSUPLOAD_ERROR_ON_BAD_CTEr#   MAX_MEMORY_FILE_SIZEfloatMAX_BODY_SIZENr2   r   r"   r   rD   rD   0   s&    "" $$!%%!!r"   rD   c                  @    e Zd ZU ded<   ded<   ded<   ded<   ded<   y	)

FileConfigstr | bytes | NonerE   rF   UPLOAD_DELETE_TMPrG   rH   r#   rJ   Nr2   r   r"   r   rN   rN   8   s     &&"" $$!!r"   rN   c                  $    e Zd ZddZddZddZy)_FormProtocolc                     y r   r   r   datas     r   writez_FormProtocol.write@   r!   r"   c                     y r   r   r   s    r   finalizez_FormProtocol.finalizeB   r!   r"   c                     y r   r   rX   s    r   closez_FormProtocol.closeD   r!   r"   NrU   r%   r$   r#   r$   None)r&   r'   r(   rV   rY   r[   r   r"   r   rR   rR   ?   s    0'$r"   rR   c                      e Zd ZddZddZy)FieldProtocolc                     y r   r   r   names     r   __init__zFieldProtocol.__init__G   r!   r"   c                     y r   r   rX   s    r   set_nonezFieldProtocol.set_noneI   r!   r"   Nrc   bytes | Noner$   r^   r]   )r&   r'   r(   rd   rf   r   r"   r   r`   r`   F   s    ;'r"   r`   c                      e Zd ZddZy)FileProtocolc                     y r   r   )r   	file_name
field_nameconfigs       r   rd   zFileProtocol.__init__L   r!   r"   Nrl   rh   rm   rh   rn   rN   r$   r^   )r&   r'   r(   rd   r   r"   r   rj   rj   K   s    nr"   rj   )startrU   endfield_startrm   
field_data	field_end
part_begin	part_datapart_endheader_beginheader_fieldheader_value
header_endheaders_finishedr   CallbackNamec                      e Zd ZdZdZdZdZy)QuerystringStatezQuerystring parser states.

    These are used to keep track of the state of the parser, and are used to determine
    what to do when new data is encountered.
    r   r      N)r&   r'   r(   __doc__BEFORE_FIELD
FIELD_NAME
FIELD_DATAr   r"   r   r   r   g   s     LJJr"   r   c                  D    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZy)MultipartStatezMultipart parser states.

    These are used to keep track of the state of the parser, and are used to determine
    what to do when new data is encountered.
    r   r   r                     	   
         N)r&   r'   r(   r   STARTSTART_BOUNDARYHEADER_FIELD_STARTHEADER_FIELDHEADER_VALUE_STARTHEADER_VALUEHEADER_VALUE_ALMOST_DONEHEADERS_ALMOST_DONEPART_DATA_START	PART_DATAPART_DATA_ENDEND_BOUNDARYENDr   r"   r   r   r   s   sN     ENLL OIML
Cr"   r   r      r   :       -   &   ;   a   z   sM   ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+-.^_`|~c                `   | sdi fS t        | t              r| j                  d      } t        | t              sJ d       d| vr/| j	                         j                         j                  d      i fS t               }| |d<   |j                         }|sJ d       |j                  d      d   j                  d      }i }|D ]h  }|\  }} t        | t              r| d   } |d	k(  r$| d
d dk(  s| dd dk(  r| j                  d      d   } | j                  d      ||j                  d      <   j ||fS )z`Parses a Content-Type header into a value in the following format: (content_type, {parameters}).r"   latin-1zValue should be a string by now;zcontent-typez1At least the content type value should be presentr   filenamer   r   z:\Nr   z\\\)
isinstancer%   decodestrlowerstripencoder   
get_paramspoptuplesplit)valuemessageparamsctypeoptionsparamkeys          r   parse_options_headerr      sM    Ry %Y' eS!D#DD %##%,,Y7<< iG#GN!FFFFJJqM!##I.E"$G A
U eU#"IE *QqzU"eBQi6&9D)"-).i)@

9%&A '>r"   c                      e Zd ZdZddZedd       ZddZddZddZ	ddZ
ddZdd	Zedd
       Zedd       ZddZddZy)Fielda  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.

    Args:
        name: The name of the form field.
    c                6    || _         g | _        t        | _        y r   )_name_value_missing_cacherb   s     r   rd   zField.__init__   s    
#% r"   c                ~     | |      }||j                          n|j                  |       |j                          |S )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.

        Args:
            name: the name of the form field.
            value: the value of the form field - either a bytestring or None.

        Returns:
            A new instance of a [`Field`][python_multipart.Field].
        )rf   rV   rY   )clsrc   r   fs       r   
from_valuezField.from_value   s4     I=JJLGGEN	

r"   c                $    | j                  |      S )zWrite some data into the form field.

        Args:
            data: The data to write to the field.

        Returns:
            The number of bytes written.
        r8   rT   s     r   rV   zField.write   s     ||D!!r"   c                d    | j                   j                  |       t        | _        t	        |      S )zThis method is a callback that will be called whenever data is
        written to the Field.

        Args:
            data: The data to write to the field.

        Returns:
            The number of bytes written.
        )r   appendr   r   lenrT   s     r   r8   zField.on_data  s'     	4 4yr"   c                j    | j                   t        u r!dj                  | j                        | _         yy)6This method is called whenever the Field is finalized.r"   Nr   r   joinr   rX   s    r   r1   zField.on_end  s'    ;;("((4;;/DK #r"   c                $    | j                          y)zFinalize the form field.Nr1   rX   s    r   rY   zField.finalize  s    r"   c                l    | j                   t        u r dj                  | j                        | _         | `y)z=Close the Field object.  This will free any underlying cache.r"   Nr   rX   s    r   r[   zField.close"  s)     ;;("((4;;/DKKr"   c                    d| _         y)a  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)r   rX   s    r   rf   zField.set_none*  s     r"   c                    | j                   S )z,This property returns the name of the field.)r   rX   s    r   rm   zField.field_name3  s     zzr"   c                    | j                   t        u r dj                  | j                        | _         t	        | j                   t
              s| j                   J | j                   S )z2This property returns the value of the form field.r"   )r   r   r   r   r   r%   rX   s    r   r   zField.value8  sH     ;;("((4;;/DK$++u-1DD{{r"   c                    t        |t              r4| j                  |j                  k(  xr | j                  |j                  k(  S t        S r   )r   r   rm   r   NotImplemented)r   others     r   __eq__zField.__eq__A  s9    eU#??e&6&66T4::;TT!!r"   c                   | j                   7t        | j                         dkD  rt        | j                   d d       d d dz   }nt        | j                         }dj                  | j                  j
                  | j                  |      S )Nr   r   z...'z{}(field_name={!r}, value={}))r   r   reprformat	__class__r&   rm   )r   vs     r   __repr__zField.__repr__G  so    ::!c$**o&: TZZ_%cr*V3ATZZ A.55dnn6M6Mt`abbr"   Nrg   )rc   r%   r   rh   r$   r   r\   r]   r$   rh   )r   objectr$   rF   r$   r   )r&   r'   r(   r   rd   classmethodr   rV   r8   r1   rY   r[   rf   propertyrm   r   r   r   r   r"   r   r   r      sq       *	"0
    "cr"   r   c                      e Zd ZdZdi fddZedd       Zedd       Zedd       Zedd       Z	edd       Z
edd	       Zdd
ZddZddZddZddZddZddZddZy)Filea[  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:

    | 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')`. |

    Args:
        file_name: The name of the file that this [`File`][python_multipart.File] represents.
        field_name: The name of the form field that this file was uploaded with.  This can be None, if, for example,
            the file was uploaded with Content-Type application/octet-stream.
        config: The configuration for this File.  See above for valid configuration keys and their corresponding values.
    Nc                   t        j                  t              | _        || _        d| _        d| _        t               | _        || _	        || _
        d | _        |1t        j                  j                  |      \  }}|| _        || _        y y )NTr   )logging	getLoggerr&   logger_config
_in_memory_bytes_writtenr   _fileobj_field_name
_file_name_actual_file_nameospathsplitext
_file_base_ext)r   rl   rm   rn   baseexts         r   rd   zFile.__init__i  s    ''129) &# 04  ((3ID#"DODI !r"   c                    | j                   S )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   rX   s    r   rm   zFile.field_name  s    
 r"   c                    | j                   S )z*The file name given in the upload request.)r   rX   s    r   rl   zFile.file_name  s     r"   c                    | j                   S )zmThe file name that this file is saved as.  Will be None if it's not
        currently saved on disk.
        )r   rX   s    r   actual_file_namezFile.actual_file_name  s    
 %%%r"   c                    | j                   S )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   rX   s    r   file_objectzFile.file_object  s     }}r"   c                    | j                   S )zzThe total size of this file, counted as the number of bytes that
        currently have been written to the file.
        )r   rX   s    r   sizez	File.size  s    
 """r"   c                    | j                   S )zqA boolean representing whether or not this file object is currently
        stored in-memory or on-disk.
        )r   rX   s    r   	in_memoryzFile.in_memory  s    
 r"   c                t   | j                   s| j                  j                  d       y| j                  j	                  d       | j                         }t        j                  | j                  |       |j	                  | j                         | j                  }|| _        d| _         |j                          y)aF  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   r[   )r   new_fileold_fileobjs      r   flush_to_diskzFile.flush_to_disk  s     KK RS 	1 &&( 	4==(3 	d))* mm    	r"   c                X   | j                   j                  d       | j                  j                  d      }| j                  j                  dd      }| j                  j                  dd      }| j                  j                  dd      }d}||r| j                   j                  d	|       |r| j                  | j
                  z   n| j                  }t        j                  j                  ||      }	 | j                   j                  d
|       t        |d      }n|r-| j
                  j                  t        j                               nd}|d}	n6t!        |t"              r$|j                  t        j                               }	n|}	| j                   j                  d|||	d       	 t%        t&        t)        j*                  |||	            }|J t!        |j,                  t.              r.|j,                  j1                  t        j                               }nt%        t"        |j,                        }|| _        |S # t        $ r, d}| j                   j                  d       t        d|z        w xY w# t        $ r' | j                   j                  d       t        d      w xY w)zFThis function is responsible for getting a file object on-disk for us.zOpening a file on diskrE   rG   FrH   rP   TNzSaving with filename in: %rzOpening file: %rzw+bzError opening temporary filez Error opening temporary file: %rz*Creating a temporary file with options: %r)suffixdeletedirz#Error creating named temporary file)r   infor   getr   r   r   r   r   openOSError	exceptionr   r   sysgetfilesystemencodingr   r%   r
   r   tempfileNamedTemporaryFilerc   r   r   r   )
r   file_dirkeep_filenamekeep_extensions
delete_tmptmp_filefnamer   r  r  s
             r   r  zFile._get_disk_file  sH   12<<##L1(()?G,,**+CUK\\%%&94@
*. MKK:HE 4CDOOdii/E77<<%0DK  !3T:e, GVTYY%%c&?&?&AB[_FHe,ooc&?&?&AB KK<[enq>rG0K0KSYblru0vw
 ''(--- ,,S-F-F-HIUHMM2!&I  K%%&DE BT IJJ	K0  G%%&KL EFFGs   5(I ,&I9 5I690J)c                $    | j                  |      S )zHWrite some data to the File.

        :param data: a bytestring
        r   rT   s     r   rV   z
File.write  s    
 ||D!!r"   c                   | j                   j                  |      }|t        |      k7  r(| j                  j	                  d|t        |             |S | xj
                  |z  c_        | j                  j                  d      }| j                  r<|:| j
                  |kD  r+| j                  j                  d       | j                          |S )zThis method is a callback that will be called whenever data is
        written to the File.

        Args:
            data: The data to write to the file.

        Returns:
            The number of bytes written.
        z bwritten != len(data) (%d != %d)rJ   zFlushing to disk)r   rV   r   r   r  r   r   r  r   r  r  )r   rU   bwrittenmax_memory_file_sizes       r   r8   zFile.on_data  s     ==&&t, s4y KK BHcRViXO 	x'  $||//0FG??3?TEXEX[oEoKK/0  r"   c                8    | j                   j                          y)r   N)r   flushrX   s    r   r1   zFile.on_end*  s     	r"   c                $    | j                          y)zFinalize the form file.  This will not close the underlying file,
        but simply signal that we are finished writing to the File.
        Nr   rX   s    r   rY   zFile.finalize/  s     	r"   c                8    | j                   j                          y)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   r[   rX   s    r   r[   z
File.close5  s    
 	r"   c                x    dj                  | j                  j                  | j                  | j                        S )Nz#{}(file_name={!r}, field_name={!r}))r   r   r&   rl   rm   rX   s    r   r   zFile.__repr__<  s/    4;;DNN<S<SUYUcUceietetuur"   ro   r   )r$   zBytesIO | BufferedRandom)r$   r#   )r$   rF   r]   )r$   r   r\   r   )r&   r'   r(   r   rd   r   rm   rl   r   r   r  r  r  r  rV   r8   r1   rY   r[   r   r   r"   r   r   r   R  s    , LPfh ,       & &   # #   D:x":
vr"   r   c                  V    e Zd ZdZd	dZ	 d
	 	 	 	 	 	 	 	 	 ddZddZd	dZd	dZddZ	y)
BaseParsera  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                N    t        j                  t              | _        i | _        y r   )r   r   r&   r   	callbacksrX   s    r   rd   zBaseParser.__init__U  s    ''1[]r"   Nc                   d|z   }| j                   j                  |      }|yt        d|      }|1|||k(  ry| j                  j	                  d|||        ||||       y| j                  j	                  d|        |        y)a  This function calls a provided callback with some data.  If the
        callback is not set, will do nothing.

        Args:
            name: The name of the callback to call (as a string).
            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.
            end: An integer that is passed to the data callback.
            start: An integer that is passed to the data callback.
        on_NzCallable[..., Any]zCalling %s with data[%d:%d]zCalling %s with no data)r-  r  r
   r   debug)r   rc   rU   rp   rq   on_namefuncs          r   callbackzBaseParser.callbackY  s     $,~~!!'*<($/ Uc\KK;WeSQuc"KK7AFr"   c                l    | | j                   j                  d|z   d       y|| j                   d|z   <   y)aq  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-  r   )r   rc   new_funcs      r   set_callbackzBaseParser.set_callbackw  s4     NNut|T2+3DNN54<(r"   c                     y r   r   rX   s    r   r[   zBaseParser.close      r"   c                     y r   r   rX   s    r   rY   zBaseParser.finalize  r8  r"   c                4    d| j                   j                  z  S Nz%s()r   r&   rX   s    r   r   zBaseParser.__repr__      ////r"   r]   )NNN)
rc   r}   rU   rh   rp   
int | Nonerq   r>  r$   r^   )rc   r}   r5  zCallable[..., Any] | Noner$   r^   r   )
r&   r'   r(   r   rd   r3  r6  r[   rY   r   r   r"   r   r+  r+  @  sU    (^
 jn (4DN\f	<40r"   r+  c                  N     e Zd ZdZi  ed      fd fdZddZd	dZd
dZ xZ	S )OctetStreamParseraB  This parser parses an octet-stream request body and calls callbacks when
    incoming data is received.  Callbacks are as follows:

    | 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.|

    Args:
        callbacks: A dictionary of callbacks.  See the documentation for [`BaseParser`][python_multipart.BaseParser].
        max_size: The maximum size of body to parse.  Defaults to infinity - i.e. unbounded.
    infc                    t         |           || _        d| _        t	        |t
              r|dk  rt        d|z        || _        d| _        y NFr   *max_size must be a positive number, not %rr   )	superrd   r-  _startedr   r   
ValueErrormax_size_current_size)r   r-  rH  r   s      r   rd   zOctetStreamParser.__init__  sL    "(F+x!|IHTUU%-r"   c                   | j                   s| j                  d       d| _         t        |      }| j                  |z   | j                  kD  rWt        | j                  | j                  z
        }| j                  j                  d| j                  | j                  ||       |}| xj                  |z  c_        | j                  d|d|       |S )a  Write some data to the parser, which will perform size verification,
        and then pass the data to the underlying callback.

        Args:
            data: The data to write to the parser.

        Returns:
            The number of bytes written.
        rp   TDCurrent size is %d (max %d), so truncating data length from %d to %drU   r   )rF  r3  r   rI  rH  r#   r   r  )r   rU   data_lennew_sizes       r   rV   zOctetStreamParser.write  s     }}MM'" DM t9)T]]:4==4+=+==>HKKV""  H 	h&fdAx0r"   c                &    | j                  d       y)ztFinalize this parser, which signals to that we are finished parsing,
        and sends the on_end callback.
        rq   N)r3  rX   s    r   rY   zOctetStreamParser.finalize  s     	er"   c                4    d| j                   j                  z  S r;  r<  rX   s    r   r   zOctetStreamParser.__repr__  r=  r"   )r-  r6   rH  rK   r\   r]   r   )
r&   r'   r(   r   rK   rd   rV   rY   r   __classcell__r   s   @r   r@  r@    s)     :<uUZ| B0r"   r@  c                  r     e Zd ZU dZded<   i d ed      f	 	 	 	 	 	 	 d fdZddZddZdd	Z	dd
Z
 xZS )QuerystringParsera5  This is a streaming querystring parser.  It will consume data, and call
    the callbacks given when it has data.

    | 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.|

    Args:
        callbacks: A dictionary of callbacks.  See the documentation for [`BaseParser`][python_multipart.BaseParser].
        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 [`QuerystringParseError`][python_multipart.exceptions.QuerystringParseError] will be raised.
        max_size: The maximum size of body to parse.  Defaults to infinity - i.e. unbounded.
    r   stateFrA  c                    t         |           t        j                  | _        d| _        || _        t        |t              r|dk  rt        d|z        || _
        d| _        || _        y rC  )rE  rd   r   r   rT  
_found_sepr-  r   r   rG  rH  rI  strict_parsing)r   r-  rW  rH  r   s       r   rd   zQuerystringParser.__init__  sg     	%22
" (F+x!|IHTUU%- -r"   c                   t        |      }| j                  |z   | j                  kD  rWt        | j                  | j                  z
        }| j                  j                  d| j                  | j                  ||       |}d}	 | j                  ||      }| xj                  |z  c_        |S # | xj                  |z  c_        w xY w)aA  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.

        Args:
            data: The data to write to the parser.

        Returns:
            The number of bytes written.
        rK  r   r   rI  rH  r#   r   r  _internal_writer   rU   rL  rM  ls        r   rV   zQuerystringParser.write       t9)T]]:4==4+=+==>HKKV""  H	$$$T84A!# !#   B+ +Cc                   | j                   }| j                  }| j                  }d}||k  r||   }|t        j                  k(  ry|t
        k(  s	|t        k(  r=|r7|rt        d|z        }||_        || j                  j                  d|       nd}n| j                  d       |dz  }t        j                  }d}n|t        j                  k(  r|j                  d|      }	|	dk(  r|j                  d	|      }	|	dk7  r|j                  d
||	      }
n|j                  d
|      }
|
dk7  r(| j                  d|||
       |
}t        j                  }nW|sX|	dk7  r<| j                  d|||	       | j                  d       |	dz
  }t        j                  }n| j                  d|||       |}n|	dk7  rt        d|fz        }||_        || j                  d|||       |}n|t        j                  k(  r|j                  d|      }	|	dk(  r|j                  d	|      }	|	dk7  r;| j                  d|||	       | j                  d       |	dz
  }t        j                  }nM| j                  d|||       |}n6d||fz  }| j                  j                  |       t        |      }||_        ||dz  }||k  r|| _         || _        t!        |      S )Nr   z,Skipping duplicate ampersand/semicolon at %dTrr   r   F   &r      ;   =rm   rt   z{When strict_parsing is True, we require an equals sign in all field chunks. Did not find one in the chunk that starts at %drs   !Reached an unknown state %d at %d)rT  rW  rV  r   r   	AMPERSAND	SEMICOLONr   offsetr   r0  r3  r   findr   r  r   )r   rU   lengthrT  rW  	found_sepichesep_pos
equals_posmsgs               r   rZ  z!QuerystringParser._internal_write"  s   

,,OO	&jaB (555 ?bIo ) 56dgh6h iA'(AH"#G KK--.\^_`
 %)	
 MM-0FA,77E %I*555 ))D!,b="iia0G
 b=!%4G!<J!%4!3J#MM,aD
 #A,77E *
 #b= MM,aI MM+6 '!A$4$A$AE !MM,aH &A
 #b= 5!JMND!Q!A
 ()AH"#G lD!VD"*555 ))D!,b="iia0G b=MM,aAMM+.  !A,99E MM,a@A :UAJF##C()#.FA} &j@ 
#4yr"   c                    | j                   t        j                  k(  r| j                  d       | j                  d       y)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.
        rt   rq   N)rT  r   r   r3  rX   s    r   rY   zQuerystringParser.finalize  s/     ::)444MM+&er"   c                x    dj                  | j                  j                  | j                  | j                        S )Nz&{}(strict_parsing={!r}, max_size={!r}))r   r   r&   rW  rH  rX   s    r   r   zQuerystringParser.__repr__  s0    7>>NN##T%8%8$--
 	
r"   )r-  r*   rW  rF   rH  rK   r$   r^   r\   rU   r%   rh  r#   r$   r#   r]   r   )r&   r'   r(   r   r3   rK   rd   rV   rZ  rY   r   rP  rQ  s   @r   rS  rS    s\    *  135dijodp---DH-\a-	-$"HHT
r"   rS  c                  d     e Zd ZdZi  ed      f	 	 	 	 	 	 	 d fdZd	dZd
dZddZddZ	 xZ
S )MultipartParseraE  This class is a streaming multipart/form-data parser.

    | 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. |

    Args:
        boundary: The multipart boundary.  This is required, and must match what is given in the HTTP request - usually in the Content-Type header.
        callbacks: A dictionary of callbacks.  See the documentation for [`BaseParser`][python_multipart.BaseParser].
        max_size: The maximum size of body to parse.  Defaults to infinity - i.e. unbounded.
    rA  c                <   t         |           t        j                  | _        dx| _        | _        || _        t        |t              r|dk  rt        d|z        || _        d| _        i | _        t        |t              r|j                  d      }d|z   | _        y )Nr   r   rD  r   s   
--)rE  rd   r   r   rT  indexflagsr-  r   r   rG  rH  rI  marksr   r   boundary)r   ry  r-  rH  r   s       r   rd   zMultipartParser.__init__  s     	#))
"##
TZ"(F+x!|IHTUU  &(
 h$y1H!H,r"   c                   t        |      }| j                  |z   | j                  kD  rWt        | j                  | j                  z
        }| j                  j                  d| j                  | j                  ||       |}d}	 | j                  ||      }| xj                  |z  c_        |S # | xj                  |z  c_        w xY w)a3  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.

        Args:
            data: The data to write to the parser.

        Returns:
            The number of bytes written.
        rK  r   rY  r[  s        r   rV   zMultipartParser.write  r]  r^  c                     j                    j                  } j                  } j                  }dd fd}dd fd}dd fd}k  r8   }	|t        j
                  k(  r1|	t        k(  s	|	t        k(  rdz  6d}t        j                  }dz  n|t        j                  k(  r9|t              dz
  k(  r_|	t        k(  rt        j                  }n>|	t        k7  r5dfz  }
 j                  j                  |
       t        |
      }|_        ||dz  }n_|t              dz
  dz   k(  rc|	t        k7  r5dfz  }
 j                  j                  |
       t        |
      }|_        |d} j!                  d	       t        j"                  }n|	|dz      k7  r@d
|dz      |	|dz   fz  }
 j                  j                  |
       t        |
      }|_        ||dz  }n|t        j"                  k(  r;d} |d       |	t        k7  r j!                  d       t        j$                  }dz  nH|t        j$                  k(  r|	t        k(  r$|dk(  r |d       t        j&                  }dz  *|dz  }|	t(        k(  rU|dk(  r5dfz  }
 j                  j                  |
       t        |
      }|_        | |d       t        j*                  }n|	t,        vrd|	fz  }
 j                  j                  |
       t        |
      }|_        ||t        j*                  k(  r/|	t.        k(  rdz   |d       t        j0                  }dz  n$|t        j0                  k(  r6|	t        k(  r |d        j!                  d       t        j2                  }n|t        j2                  k(  rP|	t        k7  r5d|	d}
 j                  j                  |
       t        |
      }|_        |t        j"                  }nx|t        j&                  k(  ra|	t        k7  r5d|	d}
 j                  j                  |
       t        |
      }|_        | j!                  d       t        j4                  }n|t        j4                  k(  r |d       t        j6                  }dz  n|t        j6                  k(  r|}t              }}|dk(  rfj9                  |      }|dk\  r|dz
  }||z   dz
  n;t;        ||z
        |dz
  k  r$   d   k7  rdz  |dz
  k  r   d   k7  r   }	||k  r|   |	k(  r|dz  }nd}n||k(  r.|dz  }|	t        k(  r
|t<        z  }n|	t        k(  r
|t>        z  }nd}n||dz   k(  r|t<        z  rg|	t        k(  rQ|t<         z  } |d|z
          j!                  d        j!                  d	       d}t        j"                  }dz  d}|t<         z  }nS|t>        z  rJ|	t        k(  r? |d|z
          j!                  d        j!                  d       t        j@                  }nd}|dk(  r)|dkD  r#d}dz  n|t        j                  k(  ry|t              dz
  dz   k(  r|	t        k7  r5dfz  }
 j                  j                  |
       t        |
      }|_        ||dz  } j!                  d       t        j@                  }n|t        j@                  k(  rE|	t        k(  rdz   k  rdz      t        k(  rdz  މ j                  j                  d       nBd|fz  }
 j                  j                  |
       t        |
      }|_        |dz  k  r8 |dd        |dd        |d|z
  d       | _        | _        | _        S ) Nr   c                $    j                   | <   y r   )rx  )rc   rj  r   s    r   set_markz1MultipartParser._internal_write.<locals>.set_mark  s     DJJtr"   c                >    j                   j                  | d        y r   )rx  r   )rc   resetr   s     r   delete_markz4MultipartParser._internal_write.<locals>.delete_mark  s    JJNN4&r"   c                L   	j                   j                  |       }|y ||k  rn|dk\  r	j                  | ||       n| }|t              k  r	j                  | d|       nu	j                  t
        z  rdz   }	j                  | |d|       nH	j                  t        z  rdz   }	j                  | |d|       n	j                  j                  d       |dkD  r	j                  | d|       |r|z
  	j                   | <   y 	j                   j                  | d        y )Nr   s   
s   --
zLook-back buffer error)
rx  r  r3  r   rw  FLAG_PART_BOUNDARYFLAG_LAST_BOUNDARYr   r  r   )
rc   end_i	remainingmarked_indexlookbehind_lenlookbackry  rU   rh  r   s
         r   data_callbackz6MultipartParser._internal_write.<locals>.data_callback&  s   ::>>$/L# $"dD,> #/!S]2MM$!^DZZ"44''1HMM$!^DZZ"44')3HMM$!^DKK''(@A19MM$a7 #(6>

4 

tT*r"   r   r   z'Did not find CR at end of boundary (%d)z'Did not find LF at end of boundary (%d)ru   z2Expected boundary character %r, got %r at index %dry   rx   zFound 0-length header at %dz*Found invalid character %r in header at %drz   r{   z2Did not find LF character at end of header (found )z)Did not find LF at end of headers (found r|   rv   rw   rq   z&Did not find - at end of boundary (%d)z!Skipping data after last boundaryrc  T)rc   r   r$   r^   )F)rc   r   r  rF   r$   r^   )rc   r}   r  r#   r  rF   r$   r^   )!ry  rT  rv  rw  r   r   CRLFr   r   HYPHENr   r   r  r   rf  r3  r   r   r   COLONr   TOKEN_CHARS_SETSPACEr   r   r   r   rg  maxr  r  r   )r   rU   rh  rT  rv  rw  r}  r  r  cro  rl  
prev_indexboundary_lengthdata_lengthi0ry  rj  s   ```             @@r   rZ  zMultipartParser._internal_write  s   == 





 	!	'%	+ %	+P &jQA,,,7a2gFA  '55Q.777 CMA--F{ . ; ;bG1$N++C0/4#$QJEc(ma/!33BwG1$N++C0/4#$ E MM,/ +==E HUQY//RV^_dgh_hViklnsvwnwUxx++C0/4#$ QJE.;;;  ( 7MM.1 '33Q.555 7uz/*>>EFA 
 :z;qdB++C0/4#$ ".!4 +==Eo-F!QOCKK'',+C0A AHG.;;;:FA ( '33Q.555 7!.!4MM,/*CCE.AAA7XY[CKK'',+C0A AHG
 '99.<<< 7EaU!LCKK'',+C0A AHG01&66.888% '00Q.222 #
 #&h-$ A: 8Q<BQw /! 3014  ;#@A  +/1d1g!6LFA  +/1d1g!6L QA ?*!+
 ! o-QJE Bw!33 f!33
 !" o11 117!&8%88E *+q5yA !MM*5 MM,7 %&E$2$E$EEFA$ !""4!44 !33;)+q5yA !MM*5 MM%0$2$6$6E %&E A:*q.!"J FA.555CMA-11F{F!M++C0/4#$QJEMM%(*..E.,,,7q1uv~$q1u+2CFA##$GH :UAJF##C(', FAY
 &jl
 	nfd3nfd3k6E>48 


 r"   c                     y)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   rX   s    r   rY   zMultipartParser.finalize  s     	r"   c                N    | j                   j                   d| j                  dS )Nz
(boundary=r  )r   r&   ry  rX   s    r   r   zMultipartParser.__repr__  s%    ..))**T]]4EQGGr"   )ry  zbytes | strr-  r:   rH  rK   r$   r^   r\   rr  r]   r   )r&   r'   r(   r   rK   rd   rV   rZ  rY   r   rP  rQ  s   @r   rt  rt    sU    * FH[`af[g-#-0B-SX-	-."HcJ	Hr"   rt  c                      e Zd ZU dZ ed      ddddddZded<   dddeei f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd	Z	dd
Z
ddZddZddZy)
FormParsera 	  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.

    Args:
        content_type: The Content-Type of the incoming request.  This is used to select the appropriate parser.
        on_field: The callback to call when a field has been parsed and is ready for usage.  See above for parameters.
        on_file: The callback to call when a file has been parsed and is ready for usage.  See above for parameters.
        on_end: An optional callback to call when all fields and files in a request has been parsed.  Can be None.
        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.
        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.
        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()
        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()
                - field_instance.set_none()
        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.
    rA     NF)rL   rJ   rE   rG   rH   rI   rD   DEFAULT_CONFIGc
                F    ! t        j                  t               _        | _        | _        d _        d  _         _         _	        | _
        t         _        t         _         j                  j!                          _         j"                  j%                  |	       d }
|dk(  r?d d fd}d fd}d fd}t'        |||d j"                  d         }
|
 _        y |d	k(  s|d
k(  rMg  d dd}d  fd}d  fd}d fd}d fd}t)        |||||d j"                  d         }
|
 _        y |dk(  r|& j                  j+                  d       t-        d      g g i d d !ddfd}d !fd}dfd}d fd}d fd}dfd}d !fd}d !fd}t/        |||||||||d j"                  d         }
|
 _        y  j                  j1                  d|       t-        dj3                  |            )!Nr   zapplication/octet-streamc                 D      d t        dj                              y )NrN   rn   )r
   rn   )	FileClassfilerl   r   s   r   r7   z%FormParser.__init__.<locals>.on_start  s     DlDKK9XYr"   c                .    j                  | ||        y r   rV   )rU   rp   rq   r  s      r   r8   z$FormParser.__init__.<locals>.on_data  s    

4c?+r"   c                 t     j                          r         j                  j                          y y r   rY   r1   )r  on_filer   s   r   _on_endz$FormParser.__init__.<locals>._on_end  s4      DM ;;*KKM +r"   )r7   r8   r1   rL   )r-  rH  z!application/x-www-form-urlencodedzapplication/x-url-encodedc                      y r   r   r   r"   r   r,   z+FormParser.__init__.<locals>.on_field_start5  s    r"   c                .    j                  | ||        y r   r   )rU   rp   rq   name_buffers      r   r.   z*FormParser.__init__.<locals>.on_field_name8      ""4c?3r"   c                j     dj                              d d = j                  | ||        y Nr"   )r   rV   )rU   rp   rq   
FieldClassr   r  s      r   r/   z*FormParser.__init__.<locals>.on_field_data;  s4    9"388K#89A#AU3(r"   c                     ,  dj                              d d = j                          j                          r        d y r  )r   rf   rY   )r  r   r  on_fields   r   r0   z)FormParser.__init__.<locals>.on_field_endB  sG     9 #388K#89A#AJJL

QKr"   c                 @     j                    j                          y y r   r   rX   s   r   r  z$FormParser.__init__.<locals>._on_endQ  s    ;;*KKM +r"   )r,   r.   r/   r0   r1   zmultipart/form-datazNo boundary givenFc                 
    i  y r   r   )headerss   r   r;   z*FormParser.__init__.<locals>.on_part_beginn  s
     r"   c                6    J j                  | ||        y r   r  )rU   rp   rq   writers      r   r<   z)FormParser.__init__.<locals>.on_part_datas  s    ))T%_-r"   c                 t     J  j                          rr	         y y r t        d              y y )Nr`   )rY   r
   )f_multiis_filer  r  s   r   r=   z(FormParser.__init__.<locals>.on_part_endy  sD    **  "(    ow!?@  r"   c                .    j                  | ||        y r   r  )rU   rp   rq   header_names      r   r?   z,FormParser.__init__.<locals>.on_header_field  r  r"   c                .    j                  | ||        y r   r  )rU   rp   rq   rz   s      r   r@   z,FormParser.__init__.<locals>.on_header_value  s    ##DsO4r"   c                 `    dj                        dj                         <    d d = d d = y r  )r   )r  rz   r  s   r   rA   z*FormParser.__init__.<locals>.on_header_end  s-    14,1G-.N Or"   c                    d
	j                  d      } t        |       \  }}|j                  d      }|j                  d      }|	 |      n! ||t        dj                              d
	j                  dd	      }|d
v ry |dk(  rt	              y |dk(  rt              y j                  j                  d|       j                  d   rt        dj                  |            y )NFs   Content-Dispositions   names   filenamerN   r  Ts   Content-Transfer-Encoding   7bit)s   binarys   8bitr  s   base64s   quoted-printablez%Unknown Content-Transfer-Encoding: %rrI   z(Unknown Content-Transfer-Encoding "{!r}")
r  r   r
   rn   r   r   r   r  r   r   )content_dispdispr   rm   rl   transfer_encodingr  r  r  r  r  r   r  s         r   rB   z0FormParser.__init__.<locals>.on_headers_finished  s       '{{+AB 4\ Bg %[[1
#KK4	 $(4G'	:d<Y]YdYdFefG"G
 %,KK0Lg$V!$(EE$F&)3*73F&*==3G<F KK''(OQbc{{#<=-.X._._`q.rss ")r"   c                 d    j                           j                   j                          y y r   r  )r   r  s   r   r  z$FormParser.__init__.<locals>._on_end  s+    %OO%;;*KKM +r"   )r;   r<   r=   r?   r@   rA   rB   r1   zUnknown Content-Type: %rzUnknown Content-Type: {}r]   )rU   r%   rp   r#   rq   r#   r$   r^   )r   r   r&   r   content_typery  bytes_receivedparserr  r  r1   r   r  r   r  r  copyrn   updater@  rS  errorr   rt  r  r   )"r   r  r  r  r1   ry  rl   r  r  rn   r  r7   r8   r  r,   r.   r/   r0   r;   r<   r=   r?   r@   rA   rB   r   r  r  r  rz   r  r  r  r  s"   ` ``  ```                @@@@@@@@@r   rd   zFormParser.__init__  sI    ''1 )  !  )-(;(;(@(@(B6"QU 55!%DZ Z," ''/GwW_5FX O @@LToDo')K&*A4) "
 '&4%2%2$0% _5	FB m 22!!"56%&9::')K(*L*,G;?GFG
.	A 	A45$
+) +)Z" %%2$0#.'6'6%2+>%	 _5F&  KK :LI!"<"C"CL"QRRr"   c                    | xj                   t        |      z  c_         | j                  J | j                  j                  |      S )zWrite some data.  The parser will forward this to the appropriate
        underlying parser.

        Args:
            data: The data to write.

        Returns:
            The number of bytes processed.
        )r  r   r  rV   rT   s     r   rV   zFormParser.write  s;     	s4y({{&&{{  &&r"   c                    | j                   2t        | j                   d      r| j                   j                          yyy)zFinalize the parser.NrY   )r  hasattrrY   rX   s    r   rY   zFormParser.finalize  s2    ;;"wt{{J'GKK  " (H"r"   c                    | j                   2t        | j                   d      r| j                   j                          yyy)zClose the parser.Nr[   )r  r  r[   rX   s    r   r[   zFormParser.close  s2    ;;"wt{{G'DKK (E"r"   c                x    dj                  | j                  j                  | j                  | j                        S )Nz"{}(content_type={!r}, parser={!r}))r   r   r&   r  r  rX   s    r   r   zFormParser.__repr__  s/    3::4>>;R;RTXTeTegkgrgrssr"   )r  r   r  OnFieldCallback | Noner  OnFileCallback | Noner1   zCallable[[], None] | Nonery  zbytes | str | Nonerl   rh   r  ztype[FileProtocol]r  ztype[FieldProtocol]rn   dict[Any, Any]r$   r^   r\   r]   r   )r&   r'   r(   r   rK   r  r3   r   r   rd   rV   rY   r[   r   r   r"   r   r  r    s    H u / %"'#((N$  -1'+"&(,*/!#ii )i '	i
 *i %i  i &i (i i 
iV'#
 
tr"   r  c                6   | j                  d      }|3t        j                  t              j	                  d       t        d      t        |      \  }}|j                  d      }|j                  d      }| j                  d      }t        ||||||      }	|	S )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.

    Args:
        headers: A dictionary-like object of HTTP headers.  The only required header is Content-Type.
        on_field: Callback to call with each parsed field.
        on_file: Callback to call with each parsed file.
        trust_x_headers: Whether or not to trust information received from certain X-Headers - for example, the file
            name from X-File-Name.
        config: Configuration variables to pass to the FormParser.
    zContent-TypezNo Content-Type header givenzNo Content-Type header given!s   boundaryr   zX-File-Name)ry  rl   rn   )	r  r   r   r&   r  rG  r   r   r  )
r  r  r  trust_x_headersrn   r  r   ry  rl   form_parsers
             r   create_form_parserr    s    * (/{{>'BL(#++,JK899 0=L&zz+&H  &&y1L M*I \8Wx[dmstK r"   c                R   t        | ||      }| j                  d      }|t        |      }nt        d      }d}	 t        t	        ||z
  |            }|j                  |      }	|j                  |	       |t        |	      z  }t        |	      |k7  s||k(  rn]|j                          y)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.

    Args:
        headers: A dictionary-like object of HTTP headers.  The only required header is Content-Type.
        input_stream: A file-like object that represents the request body. The read() method must return bytestrings.
        on_field: Callback to call with each parsed field.
        on_file: Callback to call with each parsed file.
        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-LengthNrA  r   )	r  r  r#   rK   minr    rV   r   rY   )
r  input_streamr  r  
chunk_sizer  content_length
bytes_readmax_readablebuffs
             r   
parse_formr  "  s    *  7;F 29=M1NN!^,uJ
3~
:JGH  . 	Tc$i
 t9$
n(D  OOr"   )r   rO   r$   z tuple[bytes, dict[bytes, bytes]])r  dict[str, bytes]r  r  r  r  r  rF   rn   r  r$   r  )r  )r  r  r  r   r  r  r  r  r  r#   r$   r^   )K
__future__r   r   r   r	  r  r  email.messager   enumr   ior   r   numbersr   typingr	   r
   decodersr   r   
exceptionsr   r   r   r   r   r   r   r   r   typing_extensionsr   r   r*   r6   r:   rD   rN   rR   r`   rj   OnFieldCallbackOnFileCallbackr}   r3   r   r   r   r   r  r  r  r  r  r  r  rd  re  LOWER_ALOWER_ZNULL	frozensetr  r   r   r   r+  r@  rS  rt  r  r  r  r   r"   r   <module>r     sZ   "  	  
  !  &  & ; ^ ^BB+/x /#y ##y #
	#Ye 	#9 "Ye "% %(x (
o}h o 45O|nd23N%	L) & 8	w 	W .   
 			

 (V}c }c@kv kv\M0 M0`A0
 A0He

 e
PAHj AHHst stt	 "))$) #) 	)
 ) )b /// %/ #	/
 / 
/r"   