11from typing import AsyncIterable , Iterable , List , Optional , Tuple , Type , TypeVar , Union
22
33from .datastructures import Headers
4+ from .exceptions import RequestEntityTooLarge
45from .multipart import (
56 Data ,
67 Epilogue ,
@@ -47,6 +48,8 @@ async def parse_async_stream(
4748 charset : str ,
4849 * ,
4950 file_factory : Type [_AsyncUploadFile ],
51+ max_form_parts : int = 324 ,
52+ max_form_memory_size : Union [int , None ] = None ,
5053) -> List [Tuple [str , Union [str , _AsyncUploadFile ]]]:
5154 """
5255 Parse an asynchronous stream in multipart format
@@ -60,6 +63,8 @@ async def parse_async_stream(
6063 field_name = ""
6164 data = bytearray ()
6265 file : Optional [_AsyncUploadFile ] = None
66+ form_parts_count = 0
67+ form_memory_size_count = 0
6368
6469 items : List [Tuple [str , Union [str , _AsyncUploadFile ]]] = []
6570
@@ -77,6 +82,14 @@ async def parse_async_stream(
7782 elif isinstance (event , Data ):
7883 if file is None :
7984 data .extend (event .data )
85+
86+ # Check if we have exceeded the maximum memory size
87+ form_memory_size_count += len (event .data )
88+ if (
89+ max_form_memory_size is not None
90+ and form_memory_size_count > max_form_memory_size
91+ ):
92+ raise RequestEntityTooLarge ()
8093 else :
8194 await file .awrite (event .data )
8295
@@ -88,6 +101,11 @@ async def parse_async_stream(
88101 await file .aseek (0 )
89102 items .append ((field_name , file ))
90103 file = None
104+
105+ # Check if we have exceeded the maximum number of form parts
106+ form_parts_count += 1
107+ if form_parts_count > max_form_parts :
108+ raise RequestEntityTooLarge ()
91109 return items
92110
93111
@@ -97,6 +115,8 @@ def parse_stream(
97115 charset : str ,
98116 * ,
99117 file_factory : Type [_SyncUploadFile ],
118+ max_form_parts : int = 324 ,
119+ max_form_memory_size : Union [int , None ] = None ,
100120) -> List [Tuple [str , Union [str , _SyncUploadFile ]]]:
101121 """
102122 Parse a synchronous stream in multipart format
@@ -110,6 +130,8 @@ def parse_stream(
110130 field_name = ""
111131 data = bytearray ()
112132 file : Optional [_SyncUploadFile ] = None
133+ form_parts_count = 0
134+ form_memory_size_count = 0
113135
114136 items : List [Tuple [str , Union [str , _SyncUploadFile ]]] = []
115137
@@ -127,6 +149,14 @@ def parse_stream(
127149 elif isinstance (event , Data ):
128150 if file is None :
129151 data .extend (event .data )
152+
153+ # Check if we have exceeded the maximum memory size
154+ form_memory_size_count += len (event .data )
155+ if (
156+ max_form_memory_size is not None
157+ and form_memory_size_count > max_form_memory_size
158+ ):
159+ raise RequestEntityTooLarge ()
130160 else :
131161 file .write (event .data )
132162
@@ -138,4 +168,9 @@ def parse_stream(
138168 file .seek (0 )
139169 items .append ((field_name , file ))
140170 file = None
171+
172+ # Check if we have exceeded the maximum number of form parts
173+ form_parts_count += 1
174+ if form_parts_count > max_form_parts :
175+ raise RequestEntityTooLarge ()
141176 return items
0 commit comments