ignore trailers for some time on locally reset streams (#194)
This commit is contained in:
		| @@ -143,6 +143,15 @@ where | |||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let stream = me.store.resolve(key); |         let stream = me.store.resolve(key); | ||||||
|  |  | ||||||
|  |         if stream.state.is_local_reset() { | ||||||
|  |             // Locally reset streams must ignore frames "for some time". | ||||||
|  |             // This is because the remote may have sent trailers before | ||||||
|  |             // receiving the RST_STREAM frame. | ||||||
|  |             trace!("recv_headers; ignoring trailers on {:?}", stream.id); | ||||||
|  |             return Ok(()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         let actions = &mut me.actions; |         let actions = &mut me.actions; | ||||||
|         let mut send_buffer = self.send_buffer.inner.lock().unwrap(); |         let mut send_buffer = self.send_buffer.inner.lock().unwrap(); | ||||||
|         let send_buffer = &mut *send_buffer; |         let send_buffer = &mut *send_buffer; | ||||||
|   | |||||||
| @@ -467,7 +467,7 @@ fn skipped_stream_ids_are_implicitly_closed() { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
| fn send_rst_stream_allows_recv_frames() { | fn send_rst_stream_allows_recv_data() { | ||||||
|     let _ = ::env_logger::init(); |     let _ = ::env_logger::init(); | ||||||
|     let (io, srv) = mock::new(); |     let (io, srv) = mock::new(); | ||||||
|  |  | ||||||
| @@ -518,6 +518,55 @@ fn send_rst_stream_allows_recv_frames() { | |||||||
|     client.join(srv).wait().expect("wait"); |     client.join(srv).wait().expect("wait"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn send_rst_stream_allows_recv_trailers() { | ||||||
|  |     let _ = ::env_logger::init(); | ||||||
|  |     let (io, srv) = mock::new(); | ||||||
|  |  | ||||||
|  |     let srv = srv.assert_client_handshake() | ||||||
|  |         .unwrap() | ||||||
|  |         .recv_settings() | ||||||
|  |         .recv_frame( | ||||||
|  |             frames::headers(1) | ||||||
|  |                 .request("GET", "https://example.com/") | ||||||
|  |                 .eos(), | ||||||
|  |         ) | ||||||
|  |         .send_frame(frames::headers(1).response(200)) | ||||||
|  |         .send_frame(frames::data(1, vec![0; 16_384])) | ||||||
|  |         .recv_frame(frames::reset(1).cancel()) | ||||||
|  |         // sending frames after canceled! | ||||||
|  |         .send_frame(frames::headers(1).field("foo", "bar").eos()) | ||||||
|  |         // do a pingpong to ensure no other frames were sent | ||||||
|  |         .ping_pong([1; 8]) | ||||||
|  |         .close(); | ||||||
|  |  | ||||||
|  |     let client = Client::handshake(io) | ||||||
|  |         .expect("handshake") | ||||||
|  |         .and_then(|(mut client, conn)| { | ||||||
|  |             let request = Request::builder() | ||||||
|  |                 .method(Method::GET) | ||||||
|  |                 .uri("https://example.com/") | ||||||
|  |                 .body(()) | ||||||
|  |                 .unwrap(); | ||||||
|  |  | ||||||
|  |             let req = client.send_request(request, true) | ||||||
|  |                 .unwrap() | ||||||
|  |                 .0.expect("response") | ||||||
|  |                 .and_then(|resp| { | ||||||
|  |                     assert_eq!(resp.status(), StatusCode::OK); | ||||||
|  |                     // drop resp will send a reset | ||||||
|  |                     Ok(()) | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             conn.expect("client") | ||||||
|  |                 .drive(req) | ||||||
|  |                 .and_then(|(conn, _)| conn) | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     client.join(srv).wait().expect("wait"); | ||||||
|  | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
| fn rst_stream_expires() { | fn rst_stream_expires() { | ||||||
|     let _ = ::env_logger::init(); |     let _ = ::env_logger::init(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user