@@ -159,27 +159,52 @@ impl Stream {
159
159
let headers_frame = framing:: headers:: HeaderFrame :: new ( & frame. header , & mut frame. payload . into_iter ( ) ) ;
160
160
self . temp_header_block . extend ( headers_frame. get_header_block_fragment ( ) ) ;
161
161
162
+ let mut process_error = None ;
163
+
162
164
// If the headers block is complete then unpack it immediately.
163
165
if headers_frame. is_end_headers ( ) {
164
- self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
166
+ process_error = self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
165
167
166
168
// TODO this only removes values from the vector, it doesn't change the allocated capacity.
167
169
self . temp_header_block . clear ( ) ;
168
170
}
169
171
170
- if headers_frame. is_end_stream ( ) {
172
+ if process_error. is_some ( ) {
173
+ if let state:: StreamStateName :: Open ( ref state) = new_state {
174
+ (
175
+ Some (
176
+ state:: StreamStateName :: Closed (
177
+ (
178
+ state,
179
+ state:: StreamClosedInfo {
180
+ reason : state:: StreamClosedReason :: ResetLocal
181
+ }
182
+ ) . into ( )
183
+ )
184
+ ) ,
185
+ process_error
186
+ )
187
+ }
188
+ else {
189
+ unreachable ! ( "enum decomposition failed. How?" ) ;
190
+ }
191
+ }
192
+ else if headers_frame. is_end_stream ( ) {
171
193
// This is an interesting consequence of using enums for wrapping states.
172
194
// This can never fail, because we have explicitly changed state to open above.
173
195
// But we still have to destructure.
174
196
new_state = if let state:: StreamStateName :: Open ( ref state) = new_state {
175
- state:: StreamStateName :: HalfClosedRemote ( state. into ( ) )
197
+ state:: StreamStateName :: HalfClosedRemote ( state. into ( ) )
176
198
}
177
199
else {
178
200
unreachable ! ( "enum decomposition failed. How?" ) ;
179
201
} ;
180
- }
181
202
182
- ( Some ( new_state) , None )
203
+ ( Some ( new_state) , None )
204
+ }
205
+ else {
206
+ ( Some ( new_state) , None )
207
+ }
183
208
} ,
184
209
framing:: FrameType :: PushPromise => {
185
210
// (8.2) A client cannot push. Thus, servers MUST treat the receipt of a
@@ -240,17 +265,35 @@ impl Stream {
240
265
// it is this header frame which needs to be checked for end stream rather than the next one.
241
266
let should_end_stream = self . should_headers_frame_end_stream ( ) ;
242
267
268
+ let mut process_error = None ;
269
+
243
270
if headers_frame. is_end_headers ( ) {
244
- self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
271
+ process_error = self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
245
272
246
273
// TODO this only removes values from the vector, it doesn't change the allocated capacity.
247
274
self . temp_header_block . clear ( ) ;
248
275
}
249
276
250
- // (8.1) An endpoint that receives a HEADERS frame without the END_STREAM
251
- // flag set after receiving a final (non-informational) status code MUST
252
- // treat the corresponding request or response as malformed (Section 8.1.2.6).
253
- if should_end_stream {
277
+ if process_error. is_some ( ) {
278
+ (
279
+ Some (
280
+ state:: StreamStateName :: Closed (
281
+ (
282
+ state,
283
+ state:: StreamClosedInfo {
284
+ reason : state:: StreamClosedReason :: ResetLocal
285
+ }
286
+ ) . into ( )
287
+ )
288
+ ) ,
289
+ process_error
290
+ )
291
+ }
292
+ else if should_end_stream {
293
+ // (8.1) An endpoint that receives a HEADERS frame without the END_STREAM
294
+ // flag set after receiving a final (non-informational) status code MUST
295
+ // treat the corresponding request or response as malformed (Section 8.1.2.6).
296
+
254
297
if headers_frame. is_end_stream ( ) {
255
298
(
256
299
Some (
@@ -386,16 +429,34 @@ impl Stream {
386
429
else {
387
430
let continuation_frame = framing:: continuation:: ContinuationFrame :: new ( & frame. header , & mut frame. payload . into_iter ( ) ) ;
388
431
self . temp_header_block . extend ( continuation_frame. get_header_block_fragment ( ) ) ;
389
-
432
+
433
+ let mut process_error = None ;
390
434
if continuation_frame. is_end_headers ( ) {
391
- self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
435
+ process_error = self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
392
436
393
437
// TODO this only removes values from the vector, it doesn't change the allocated capacity.
394
438
self . temp_header_block . clear ( ) ;
395
439
}
396
440
397
441
// TODO handle continuation frame decode error.
398
- ( None , None )
442
+ if process_error. is_some ( ) {
443
+ (
444
+ Some (
445
+ state:: StreamStateName :: Closed (
446
+ (
447
+ state,
448
+ state:: StreamClosedInfo {
449
+ reason : state:: StreamClosedReason :: ResetLocal
450
+ }
451
+ ) . into ( )
452
+ )
453
+ ) ,
454
+ process_error
455
+ )
456
+ }
457
+ else {
458
+ ( None , None )
459
+ }
399
460
}
400
461
} ,
401
462
_ => {
@@ -444,15 +505,33 @@ impl Stream {
444
505
let continuation_frame = framing:: continuation:: ContinuationFrame :: new ( & frame. header , & mut frame. payload . into_iter ( ) ) ;
445
506
self . temp_header_block . extend ( continuation_frame. get_header_block_fragment ( ) ) ;
446
507
508
+ let mut process_error = None ;
447
509
if continuation_frame. is_end_headers ( ) {
448
- self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
510
+ process_error = self . request . process_temp_header_block ( self . temp_header_block . as_slice ( ) , hpack_recv_context) ;
449
511
450
512
// TODO this only removes values from the vector, it doesn't change the allocated capacity.
451
513
self . temp_header_block . clear ( ) ;
452
514
}
453
515
454
516
// TODO handle continuation frame decode error.
455
- ( None , None )
517
+ if process_error. is_some ( ) {
518
+ (
519
+ Some (
520
+ state:: StreamStateName :: Closed (
521
+ (
522
+ state,
523
+ state:: StreamClosedInfo {
524
+ reason : state:: StreamClosedReason :: ResetLocal
525
+ }
526
+ ) . into ( )
527
+ )
528
+ ) ,
529
+ process_error
530
+ )
531
+ }
532
+ else {
533
+ ( None , None )
534
+ }
456
535
}
457
536
} ,
458
537
framing:: FrameType :: WindowUpdate => {
0 commit comments