When all Streams are dropped / finished, the Connection was held open until the peer hangs up. Instead, the Connection should hang up once it knows that nothing more will be sent. To fix this, we notify the Connection when a stream is no longer referenced. On the Connection poll(), we check that there are no active, held, reset streams or any references to the Streams and transition to sending a GOAWAY if that is case. The specific behavior depends on if running as a client or server.
		
			
				
	
	
		
			64 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| #[macro_use]
 | |
| pub mod support;
 | |
| use support::prelude::*;
 | |
| 
 | |
| #[test]
 | |
| fn write_continuation_frames() {
 | |
|     // An invalid dependency ID results in a stream level error. The hpack
 | |
|     // payload should still be decoded.
 | |
|     let _ = ::env_logger::init();
 | |
|     let (io, srv) = mock::new();
 | |
| 
 | |
|     let large = build_large_headers();
 | |
| 
 | |
|     // Build the large request frame
 | |
|     let frame = large.iter().fold(
 | |
|         frames::headers(1).request("GET", "https://http2.akamai.com/"),
 | |
|         |frame, &(name, ref value)| frame.field(name, &value[..]));
 | |
| 
 | |
|     let srv = srv.assert_client_handshake()
 | |
|         .unwrap()
 | |
|         .recv_settings()
 | |
|         .recv_frame(frame.eos())
 | |
|         .send_frame(
 | |
|             frames::headers(1)
 | |
|                 .response(204)
 | |
|                 .eos(),
 | |
|         )
 | |
|         .close();
 | |
| 
 | |
|     let client = client::handshake(io)
 | |
|         .expect("handshake")
 | |
|         .and_then(|(mut client, conn)| {
 | |
|             let mut request = Request::builder();
 | |
|             request.uri("https://http2.akamai.com/");
 | |
| 
 | |
|             for &(name, ref value) in &large {
 | |
|                 request.header(name, &value[..]);
 | |
|             }
 | |
| 
 | |
|             let request = request
 | |
|                 .body(())
 | |
|                 .unwrap();
 | |
| 
 | |
|             let req = client
 | |
|                 .send_request(request, true)
 | |
|                 .expect("send_request1")
 | |
|                 .0
 | |
|                 .then(|res| {
 | |
|                     let response = res.unwrap();
 | |
|                     assert_eq!(response.status(), StatusCode::NO_CONTENT);
 | |
|                     Ok::<_, ()>(())
 | |
|                 });
 | |
| 
 | |
|             conn.drive(req)
 | |
|                 .and_then(move |(h2, _)| {
 | |
|                     h2.unwrap()
 | |
|                 }).map(|c| {
 | |
|                     (c, client)
 | |
|                 })
 | |
|         });
 | |
| 
 | |
|     client.join(srv).wait().expect("wait");
 | |
| }
 |