@@ -74,7 +74,8 @@ def set_none(self) -> None:
7474 ...
7575
7676 class FileProtocol (_FormProtocol , Protocol ):
77- def __init__ (self , file_name : bytes | None , field_name : bytes | None , headers : dict [str ,bytes ], config : FileConfig ) -> None :
77+ def __init__ (self , file_name : bytes | None , field_name : bytes | None , config : FileConfig ,
78+ headers : dict [str ,bytes ]) -> None :
7879 ...
7980
8081 OnFieldCallback = Callable [[FieldProtocol ], None ]
@@ -353,7 +354,8 @@ class File:
353354 config: The configuration for this File. See above for valid configuration keys and their corresponding values.
354355 """ # noqa: E501
355356
356- def __init__ (self , file_name : bytes | None , field_name : bytes | None = None , headers : dict [str ,bytes ] = {}, config : FileConfig = {}) -> None :
357+ def __init__ (self , file_name : bytes | None , field_name : bytes | None = None ,
358+ headers : dict [str ,bytes ] = {}, config : FileConfig = {}) -> None :
357359 # Save configuration, set other variables default.
358360 self .logger = logging .getLogger (__name__ )
359361 self ._config = config
@@ -423,6 +425,14 @@ def headers(self) -> dict[str,bytes]:
423425 """
424426 return self ._headers
425427
428+ @property
429+ def content_type (self ) -> bytes :
430+ """The Content-Type value for this part.
431+ """
432+ if self ._headers is None :
433+ return None
434+ return self ._headers .get ("content-type" , None )
435+
426436 def flush_to_disk (self ) -> None :
427437 """If the file is already on-disk, do nothing. Otherwise, copy from
428438 the in-memory buffer to a disk file, and then reassign our internal
@@ -1651,7 +1661,7 @@ def on_header_value(data: bytes, start: int, end: int) -> None:
16511661 header_value .append (data [start :end ])
16521662
16531663 def on_header_end () -> None :
1654- headers [b"" .join (header_name )] = b"" .join (header_value )
1664+ headers [b"" .join (header_name ). decode (). lower () ] = b"" .join (header_value )
16551665 del header_name [:]
16561666 del header_value [:]
16571667
@@ -1661,8 +1671,7 @@ def on_headers_finished() -> None:
16611671 is_file = False
16621672
16631673 # Parse the content-disposition header.
1664- # TODO: handle mixed case
1665- content_disp = headers .get (b"Content-Disposition" )
1674+ content_disp = headers .get ("content-disposition" )
16661675 disp , options = parse_options_header (content_disp )
16671676
16681677 # Get the field and filename.
@@ -1672,15 +1681,15 @@ def on_headers_finished() -> None:
16721681
16731682 # Create the proper class.
16741683 if file_name is None :
1675- f = FieldClass (field_name )
1684+ f = FieldClass (field_name , headers = headers )
16761685 else :
1677- f = FileClass (file_name , field_name , config = self .config )
1686+ f = FileClass (file_name , field_name , config = self .config , headers = headers )
16781687 is_file = True
16791688
16801689 # Parse the given Content-Transfer-Encoding to determine what
16811690 # we need to do with the incoming data.
16821691 # TODO: check that we properly handle 8bit / 7bit encoding.
1683- transfer_encoding = headers .get (b"Content-Transfer-Encoding " , b"7bit" )
1692+ transfer_encoding = headers .get ("content-transfer-encoding " , b"7bit" )
16841693
16851694 if transfer_encoding in (b"binary" , b"8bit" , b"7bit" ):
16861695 writer = f
0 commit comments