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 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::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) => { }
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}