@@ -130,7 +130,8 @@ class MultipartState(IntEnum):
130130 PART_DATA_START = 8
131131 PART_DATA = 9
132132 PART_DATA_END = 10
133- END = 11
133+ END_BOUNDARY = 11
134+ END = 12
134135
135136
136137# Flags for the multipart parser.
@@ -1119,7 +1120,10 @@ def data_callback(name: CallbackName, end_i: int, remaining: bool = False) -> No
11191120 # Check to ensure that the last 2 characters in our boundary
11201121 # are CRLF.
11211122 if index == len (boundary ) - 2 :
1122- if c != CR :
1123+ if c == HYPHEN :
1124+ # Potential empty message.
1125+ state = MultipartState .END_BOUNDARY
1126+ elif c != CR :
11231127 # Error!
11241128 msg = "Did not find CR at end of boundary (%d)" % (i ,)
11251129 self .logger .warning (msg )
@@ -1396,6 +1400,18 @@ def data_callback(name: CallbackName, end_i: int, remaining: bool = False) -> No
13961400 # the start of the boundary itself.
13971401 i -= 1
13981402
1403+ elif state == MultipartState .END_BOUNDARY :
1404+ if index == len (boundary ) - 2 + 1 :
1405+ if c != HYPHEN :
1406+ msg = "Did not find - at end of boundary (%d)" % (i ,)
1407+ self .logger .warning (msg )
1408+ e = MultipartParseError (msg )
1409+ e .offset = i
1410+ raise e
1411+ index += 1
1412+ self .callback ("end" )
1413+ state = MultipartState .END
1414+
13991415 elif state == MultipartState .END :
14001416 # Don't do anything if chunk ends with CRLF.
14011417 if c == CR and i + 1 < length and data [i + 1 ] == LF :
@@ -1707,8 +1723,8 @@ def on_headers_finished() -> None:
17071723
17081724 def _on_end () -> None :
17091725 nonlocal writer
1710- assert writer is not None
1711- writer .finalize ()
1726+ if writer is not None :
1727+ writer .finalize ()
17121728 if self .on_end is not None :
17131729 self .on_end ()
17141730
0 commit comments