@@ -2041,6 +2041,89 @@ mod conn {
2041
2041
assert_eq ! ( vec, b"bar=foo" ) ;
2042
2042
}
2043
2043
2044
+ #[ tokio:: test]
2045
+ async fn test_try_send_request ( ) {
2046
+ use std:: future:: Future ;
2047
+ let ( listener, addr) = setup_tk_test_server ( ) . await ;
2048
+ let ( done_tx, done_rx) = tokio:: sync:: oneshot:: channel :: < ( ) > ( ) ;
2049
+
2050
+ tokio:: spawn ( async move {
2051
+ let mut sock = listener. accept ( ) . await . unwrap ( ) . 0 ;
2052
+ let mut buf = [ 0u8 ; 8192 ] ;
2053
+ sock. read ( & mut buf) . await . expect ( "read 1" ) ;
2054
+ sock. write_all ( b"HTTP/1.1 200 OK\r \n content-length: 0\r \n \r \n " )
2055
+ . await
2056
+ . expect ( "write 1" ) ;
2057
+ let _ = done_rx. await ;
2058
+ } ) ;
2059
+
2060
+ // make polling fair by putting both in spawns
2061
+ tokio:: spawn ( async move {
2062
+ let io = tcp_connect ( & addr) . await . expect ( "tcp connect" ) ;
2063
+ let ( mut client, mut conn) = conn:: http1:: Builder :: new ( )
2064
+ . handshake :: < _ , Empty < Bytes > > ( io)
2065
+ . await
2066
+ . expect ( "http handshake" ) ;
2067
+
2068
+ // get the conn ready
2069
+ assert ! ( future:: poll_fn( |cx| Poll :: Ready ( Pin :: new( & mut conn) . poll( cx) ) )
2070
+ . await
2071
+ . is_pending( ) ) ;
2072
+ assert ! ( client. is_ready( ) ) ;
2073
+
2074
+ // use the connection once
2075
+ let mut fut1 = std:: pin:: pin!( client. send_request( http:: Request :: new( Empty :: new( ) ) ) ) ;
2076
+ let _res1 = future:: poll_fn ( |cx| loop {
2077
+ if let Poll :: Ready ( res) = fut1. as_mut ( ) . poll ( cx) {
2078
+ return Poll :: Ready ( res) ;
2079
+ }
2080
+ return match Pin :: new ( & mut conn) . poll ( cx) {
2081
+ Poll :: Ready ( _) => panic ! ( "ruh roh" ) ,
2082
+ Poll :: Pending => Poll :: Pending ,
2083
+ } ;
2084
+ } )
2085
+ . await
2086
+ . expect ( "resp 1" ) ;
2087
+
2088
+ assert ! ( client. is_ready( ) ) ;
2089
+
2090
+ // simulate the server dropping the conn
2091
+ let _ = done_tx. send ( ( ) ) ;
2092
+ // let the server task die
2093
+ tokio:: task:: yield_now ( ) . await ;
2094
+
2095
+ let mut fut2 =
2096
+ std:: pin:: pin!( client. try_send_request( http:: Request :: new( Empty :: new( ) ) ) ) ;
2097
+ let poll1 = future:: poll_fn ( |cx| Poll :: Ready ( fut2. as_mut ( ) . poll ( cx) ) ) . await ;
2098
+ assert ! ( poll1. is_pending( ) , "not already known to error" ) ;
2099
+
2100
+ let mut conn_opt = Some ( conn) ;
2101
+ // wasn't a known error, req is in queue, and now the next poll, the
2102
+ // conn will be noticed as errored
2103
+ let mut err = future:: poll_fn ( |cx| {
2104
+ loop {
2105
+ if let Poll :: Ready ( res) = fut2. as_mut ( ) . poll ( cx) {
2106
+ return Poll :: Ready ( res) ;
2107
+ }
2108
+ if let Some ( ref mut conn) = conn_opt {
2109
+ match Pin :: new ( conn) . poll ( cx) {
2110
+ Poll :: Ready ( _) => {
2111
+ conn_opt = None ;
2112
+ } , // ok
2113
+ Poll :: Pending => return Poll :: Pending ,
2114
+ } ;
2115
+ }
2116
+ }
2117
+ } )
2118
+ . await
2119
+ . expect_err ( "resp 2" ) ;
2120
+
2121
+ assert ! ( err. take_message( ) . is_some( ) , "request was returned" ) ;
2122
+ } )
2123
+ . await
2124
+ . unwrap ( ) ;
2125
+ }
2126
+
2044
2127
#[ tokio:: test]
2045
2128
async fn http2_detect_conn_eof ( ) {
2046
2129
use futures_util:: future;
0 commit comments