@@ -74,7 +74,8 @@ def set_none(self) -> None:
74
74
...
75
75
76
76
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 :
78
79
...
79
80
80
81
OnFieldCallback = Callable [[FieldProtocol ], None ]
@@ -353,7 +354,8 @@ class File:
353
354
config: The configuration for this File. See above for valid configuration keys and their corresponding values.
354
355
""" # noqa: E501
355
356
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 :
357
359
# Save configuration, set other variables default.
358
360
self .logger = logging .getLogger (__name__ )
359
361
self ._config = config
@@ -423,6 +425,14 @@ def headers(self) -> dict[str,bytes]:
423
425
"""
424
426
return self ._headers
425
427
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
+
426
436
def flush_to_disk (self ) -> None :
427
437
"""If the file is already on-disk, do nothing. Otherwise, copy from
428
438
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:
1651
1661
header_value .append (data [start :end ])
1652
1662
1653
1663
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 )
1655
1665
del header_name [:]
1656
1666
del header_value [:]
1657
1667
@@ -1661,8 +1671,7 @@ def on_headers_finished() -> None:
1661
1671
is_file = False
1662
1672
1663
1673
# 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" )
1666
1675
disp , options = parse_options_header (content_disp )
1667
1676
1668
1677
# Get the field and filename.
@@ -1672,15 +1681,15 @@ def on_headers_finished() -> None:
1672
1681
1673
1682
# Create the proper class.
1674
1683
if file_name is None :
1675
- f = FieldClass (field_name )
1684
+ f = FieldClass (field_name , headers = headers )
1676
1685
else :
1677
- f = FileClass (file_name , field_name , config = self .config )
1686
+ f = FileClass (file_name , field_name , config = self .config , headers = headers )
1678
1687
is_file = True
1679
1688
1680
1689
# Parse the given Content-Transfer-Encoding to determine what
1681
1690
# we need to do with the incoming data.
1682
1691
# 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" )
1684
1693
1685
1694
if transfer_encoding in (b"binary" , b"8bit" , b"7bit" ):
1686
1695
writer = f
0 commit comments