@@ -68,14 +68,14 @@ def finalize(self) -> None: ...
6868 def close (self ) -> None : ...
6969
7070 class FieldProtocol (_FormProtocol , Protocol ):
71- def __init__ (self , name : bytes , headers : dict [str ,bytes ]) -> None :
72- ...
71+ def __init__ (self , name : bytes , headers : dict [str , bytes ]) -> None : ...
7372
7473 def set_none (self ) -> None : ...
7574
7675 class FileProtocol (_FormProtocol , Protocol ):
77- def __init__ (self , file_name : bytes | None , field_name : bytes | None , headers : dict [str ,bytes ], config : FileConfig ) -> None :
78- ...
76+ def __init__ (
77+ self , file_name : bytes | None , field_name : bytes | None , config : FileConfig , headers : dict [str , bytes ]
78+ ) -> None : ...
7979
8080 OnFieldCallback = Callable [[FieldProtocol ], None ]
8181 OnFileCallback = Callable [[FileProtocol ], None ]
@@ -225,10 +225,10 @@ class Field:
225225 name: The name of the form field.
226226 """
227227
228- def __init__ (self , name : bytes , headers : dict [str ,bytes ]= {}) -> None :
228+ def __init__ (self , name : bytes , headers : dict [str , bytes ] = {}) -> None :
229229 self ._name = name
230230 self ._value : list [bytes ] = []
231- self ._headers : dict [str ,bytes ] = headers
231+ self ._headers : dict [str , bytes ] = headers
232232
233233 # We cache the joined version of _value for speed.
234234 self ._cache = _missing
@@ -321,7 +321,7 @@ def value(self) -> bytes | None:
321321 return self ._cache
322322
323323 @property
324- def headers (self ) -> dict [str ,bytes ]:
324+ def headers (self ) -> dict [str , bytes ]:
325325 """This property returns the headers of the field."""
326326 return self ._headers
327327
@@ -365,7 +365,13 @@ class File:
365365 config: The configuration for this File. See above for valid configuration keys and their corresponding values.
366366 """ # noqa: E501
367367
368- def __init__ (self , file_name : bytes | None , field_name : bytes | None = None , headers : dict [str ,bytes ] = {}, config : FileConfig = {}) -> None :
368+ def __init__ (
369+ self ,
370+ file_name : bytes | None ,
371+ field_name : bytes | None = None ,
372+ headers : dict [str , bytes ] = {},
373+ config : FileConfig = {},
374+ ) -> None :
369375 # Save configuration, set other variables default.
370376 self .logger = logging .getLogger (__name__ )
371377 self ._config = config
@@ -430,11 +436,15 @@ def in_memory(self) -> bool:
430436 return self ._in_memory
431437
432438 @property
433- def headers (self ) -> dict [str ,bytes ]:
434- """The headers for this part.
435- """
439+ def headers (self ) -> dict [str , bytes ]:
440+ """The headers for this part."""
436441 return self ._headers
437-
442+
443+ @property
444+ def content_type (self ) -> bytes | None :
445+ """The Content-Type value for this part."""
446+ return self ._headers .get ("content-type" )
447+
438448 def flush_to_disk (self ) -> None :
439449 """If the file is already on-disk, do nothing. Otherwise, copy from
440450 the in-memory buffer to a disk file, and then reassign our internal
@@ -1555,7 +1565,7 @@ def __init__(
15551565
15561566 def on_start () -> None :
15571567 nonlocal file
1558- file = FileClass (file_name , None , config = cast ("FileConfig" , self .config ))
1568+ file = FileClass (file_name , None , headers = {}, config = cast ("FileConfig" , self .config ))
15591569
15601570 def on_data (data : bytes , start : int , end : int ) -> None :
15611571 nonlocal file
@@ -1594,7 +1604,7 @@ def on_field_name(data: bytes, start: int, end: int) -> None:
15941604 def on_field_data (data : bytes , start : int , end : int ) -> None :
15951605 nonlocal f
15961606 if f is None :
1597- f = FieldClass (b"" .join (name_buffer ))
1607+ f = FieldClass (b"" .join (name_buffer ), headers = {} )
15981608 del name_buffer [:]
15991609 f .write (data [start :end ])
16001610
@@ -1604,7 +1614,7 @@ def on_field_end() -> None:
16041614 if f is None :
16051615 # If we get here, it's because there was no field data.
16061616 # We create a field, set it to None, and then continue.
1607- f = FieldClass (b"" .join (name_buffer ))
1617+ f = FieldClass (b"" .join (name_buffer ), headers = {} )
16081618 del name_buffer [:]
16091619 f .set_none ()
16101620
@@ -1636,7 +1646,7 @@ def _on_end() -> None:
16361646
16371647 header_name : list [bytes ] = []
16381648 header_value : list [bytes ] = []
1639- headers : dict [bytes , bytes ] = {}
1649+ headers : dict [str , bytes ] = {}
16401650
16411651 f_multi : FileProtocol | FieldProtocol | None = None
16421652 writer = None
@@ -1671,7 +1681,7 @@ def on_header_value(data: bytes, start: int, end: int) -> None:
16711681 header_value .append (data [start :end ])
16721682
16731683 def on_header_end () -> None :
1674- headers [b"" .join (header_name )] = b"" .join (header_value )
1684+ headers [b"" .join (header_name ). decode (). lower () ] = b"" .join (header_value )
16751685 del header_name [:]
16761686 del header_value [:]
16771687
@@ -1681,26 +1691,25 @@ def on_headers_finished() -> None:
16811691 is_file = False
16821692
16831693 # Parse the content-disposition header.
1684- # TODO: handle mixed case
1685- content_disp = headers .get (b"Content-Disposition" )
1694+ content_disp = headers .get ("content-disposition" )
16861695 disp , options = parse_options_header (content_disp )
16871696
16881697 # Get the field and filename.
1689- field_name = options .get (b"name" )
1698+ field_name = options .get (b"name" , b"" )
16901699 file_name = options .get (b"filename" )
16911700 # TODO: check for errors
16921701
16931702 # Create the proper class.
16941703 if file_name is None :
1695- f_multi = FieldClass (field_name )
1704+ f_multi = FieldClass (field_name , headers = headers )
16961705 else :
1697- f_multi = FileClass (file_name , field_name , config = cast ("FileConfig" , self .config ))
1706+ f_multi = FileClass (file_name , field_name , config = cast ("FileConfig" , self .config ), headers = headers )
16981707 is_file = True
16991708
17001709 # Parse the given Content-Transfer-Encoding to determine what
17011710 # we need to do with the incoming data.
17021711 # TODO: check that we properly handle 8bit / 7bit encoding.
1703- transfer_encoding = headers .get (b"Content-Transfer-Encoding " , b"7bit" )
1712+ transfer_encoding = headers .get ("content-transfer-encoding " , b"7bit" )
17041713
17051714 if transfer_encoding in (b"binary" , b"8bit" , b"7bit" ):
17061715 writer = f_multi
0 commit comments