@@ -193,68 +193,64 @@ async def stream(self, timeout=None, raw=False):
193193 agen = super ().recv (timeout )
194194 paused = False
195195 bytes_unread = 0
196+ chunk_size = - 1
196197
197198 while True :
198199 if not paused :
199- try :
200- buf .extend (await agen .__anext__ ())
201- except StopAsyncIteration as exc :
202- if b'\r \n \r \n ' not in buf :
203- raise BadRequest (
204- 'bad chunked encoding: incomplete read'
205- ) from exc
200+ buf .extend (await agen .__anext__ ())
206201
207202 if bytes_unread > 2 :
208203 data = bytes (buf [:bytes_unread - 2 ])
209-
210204 yield data
211- del buf [:bytes_unread - 2 ]
212205
206+ del buf [:bytes_unread - 2 ]
213207 bytes_unread -= len (data )
214208
215- if bytes_unread > 2 :
216- continue
217-
218- paused = True
219- else :
220- # bytes_unread should only be either 0 or 2 at this point
221- i = buf .find (b'\r \n ' , bytes_unread )
222-
223- if i == - 1 :
224- if len (buf ) > 64 :
225- raise BadRequest (
226- 'bad chunked encoding: no chunk size'
227- )
209+ paused = False
210+ continue
228211
212+ if bytes_unread == 2 :
213+ if len (buf ) < 2 :
229214 paused = False
230215 continue
231216
232- try :
233- chunk_size = parse_int (
234- buf [bytes_unread :i ].split (b';' , 1 )[0 ], 16
235- )
236- except ValueError as exc :
237- raise BadRequest ('bad chunked encoding' ) from exc
217+ if not buf .startswith (b'\r \n ' ):
218+ raise BadRequest ('bad chunked encoding: '
219+ 'invalid chunk terminator' )
238220
239- data = bytes (buf [i + 2 :i + 2 + chunk_size ])
240- bytes_unread = chunk_size - len (data ) + 2
221+ if chunk_size == 0 :
222+ if self .server .options ['experimental' ]:
223+ self .server .queue [0 ].queue .appendleft (buf [2 :])
224+ else :
225+ self .http_keepalive = False
241226
242- if bytes_unread > 2 :
243- paused = False
244227 del buf [:]
245- else :
246- paused = True
247- del buf [:i + 2 + chunk_size ]
228+ break
248229
249- if bytes_unread == 2 and not b'\r \n ' .startswith (buf [:2 ]):
250- raise BadRequest (
251- 'bad chunked encoding: invalid chunk terminator'
252- )
230+ # bytes_unread should only be either 0 or 2 at this point
231+ i = buf .find (b'\r \n ' , bytes_unread )
253232
254- if chunk_size <= 0 :
255- break
233+ if i == - 1 :
234+ if len (buf ) > 64 :
235+ raise BadRequest ('bad chunked encoding: no chunk size' )
256236
257- yield data
237+ paused = False
238+ continue
239+
240+ try :
241+ chunk_size = parse_int (
242+ buf [bytes_unread :i ].split (b';' , 1 )[0 ], 16
243+ )
244+ except ValueError as exc :
245+ raise BadRequest ('bad chunked encoding' ) from exc
246+
247+ data = bytes (buf [i + 2 :i + 2 + chunk_size ])
248+ bytes_unread = chunk_size - len (data ) + 2
249+
250+ del buf [:i + 2 + chunk_size ]
251+
252+ yield data
253+ paused = True
258254 else :
259255 if (self .content_length >
260256 self .server .options ['client_max_body_size' ]):
0 commit comments