hyper_noise/
lib.rs

1pub mod client;
2pub mod server;
3
4mod errors;
5pub use errors::*;
6
7#[cfg(test)]
8mod tests {
9    use super::*;
10
11    use hyper::{Body, Request, Response};
12    use tokio::net::{TcpListener, TcpStream};
13    use tokio_noise::handshakes::nn_psk2::{Initiator, Responder};
14
15    use std::convert::Infallible;
16    use std::time::{Duration, Instant};
17
18    #[tokio::test]
19    async fn basic_get_request() {
20        let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
21        let listener_addr = listener.local_addr().unwrap();
22
23        const PSK: [u8; 32] = [0xFFu8; 32];
24
25        let handle = tokio::task::spawn(async move {
26            let make_responder = |_| {
27                Responder::new(|id| match std::str::from_utf8(id) {
28                    Ok("bob") => Some(PSK),
29                    _ => None,
30                })
31            };
32            let make_handle_request = |_| {
33                |peer_id: &[u8], _req: Request<Body>| async move {
34                    let _ = peer_id;
35                    let resp = Response::new(Body::empty());
36                    Ok::<_, Infallible>(resp)
37                }
38            };
39
40            server::accept_and_serve_http(
41                listener,
42                make_responder,
43                make_handle_request,
44                Some(Duration::from_millis(250)),
45            )
46            .await
47            .unwrap();
48        });
49
50        let initiator = Initiator {
51            identity: "bob".as_ref(),
52            psk: &PSK,
53        };
54
55        let request = Request::builder()
56            .uri(format!("http://{listener_addr}"))
57            .method("GET")
58            .body(Body::from(vec![]))
59            .unwrap();
60
61        let tcp_stream = TcpStream::connect(listener_addr).await.unwrap();
62        let response = client::send_request(tcp_stream, initiator, request, None)
63            .await
64            .unwrap();
65
66        assert_eq!(response.status(), hyper::StatusCode::OK);
67
68        handle.abort();
69        handle.await.ok();
70    }
71
72    #[tokio::test]
73    async fn server_handler_timeout() {
74        let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
75        let listener_addr = listener.local_addr().unwrap();
76
77        const PSK: [u8; 32] = [0xFFu8; 32];
78
79        let handle = tokio::task::spawn(async move {
80            let make_responder = |_| {
81                Responder::new(|id| match std::str::from_utf8(id) {
82                    Ok("bob") => Some(PSK),
83                    _ => None,
84                })
85            };
86
87            #[allow(unreachable_code)]
88            let make_handle_request = |_| {
89                |_peer_id: &[u8], _req: Request<Body>| async move {
90                    tokio::time::sleep(Duration::from_secs(1)).await;
91                    panic!("should never wait this long");
92                    let resp = Response::new(Body::empty());
93                    Ok::<_, Infallible>(resp)
94                }
95            };
96
97            server::accept_and_serve_http(
98                listener,
99                make_responder,
100                make_handle_request,
101                Some(Duration::from_millis(250)),
102            )
103            .await
104            .unwrap();
105        });
106
107        let initiator = Initiator {
108            identity: "bob".as_ref(),
109            psk: &PSK,
110        };
111
112        let request = Request::builder()
113            .uri(format!("http://{listener_addr}"))
114            .method("GET")
115            .body(Body::from(vec![]))
116            .unwrap();
117
118        let start = Instant::now();
119
120        let tcp_stream = TcpStream::connect(listener_addr).await.unwrap();
121
122        // client has no timeout
123        match client::send_request(tcp_stream, initiator, request, None).await {
124            Err(ClientError::Hyper(hyper_err)) => assert!(hyper_err.is_incomplete_message()),
125            Err(e) => panic!("unexpected error: {e}"),
126            Ok(_) => panic!("client request returned OK unexpectedly"),
127        };
128
129        handle.abort();
130        handle.await.ok();
131
132        assert!(start.elapsed().as_millis() < 350);
133    }
134
135    #[tokio::test]
136    async fn client_request_timeout() {
137        let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
138        let listener_addr = listener.local_addr().unwrap();
139
140        const PSK: [u8; 32] = [0xFFu8; 32];
141
142        let handle = tokio::task::spawn(async move {
143            let make_responder = |_| {
144                Responder::new(|id| match std::str::from_utf8(id) {
145                    Ok("bob") => Some(PSK),
146                    _ => None,
147                })
148            };
149
150            let make_handle_request = |_| {
151                |_peer_id: &[u8], _req: Request<Body>| async move {
152                    tokio::time::sleep(Duration::from_secs(1)).await;
153                    let resp = Response::new(Body::empty());
154                    Ok::<_, Infallible>(resp)
155                }
156            };
157
158            // Server has no timeout
159            server::accept_and_serve_http(listener, make_responder, make_handle_request, None)
160                .await
161                .unwrap();
162        });
163
164        let initiator = Initiator {
165            identity: "bob".as_ref(),
166            psk: &PSK,
167        };
168
169        let request = Request::builder()
170            .uri(format!("http://{listener_addr}"))
171            .method("GET")
172            .body(Body::from(vec![]))
173            .unwrap();
174
175        let start = Instant::now();
176
177        let tcp_stream = TcpStream::connect(listener_addr).await.unwrap();
178        match client::send_request(
179            tcp_stream,
180            initiator,
181            request,
182            Some(Duration::from_millis(250)),
183        )
184        .await
185        {
186            Err(ClientError::RequestTimeout) => { /* expected */ }
187            Err(e) => panic!("unexpected error: {e}"),
188            Ok(_) => panic!("client request returned OK unexpectedly"),
189        };
190
191        assert!(start.elapsed().as_millis() < 350);
192
193        handle.abort();
194        handle.await.ok();
195    }
196}