1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
pub mod client;
pub mod server;

mod errors;
pub use errors::*;

#[cfg(test)]
mod tests {
    use super::*;

    use hyper::{Body, Request, Response};
    use tokio::net::{TcpListener, TcpStream};
    use tokio_noise::handshakes::nn_psk2::{Initiator, Responder};

    use std::convert::Infallible;

    #[tokio::test]
    async fn basic_get_request() {
        let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
        let listener_addr = listener.local_addr().unwrap();

        const PSK: [u8; 32] = [0xFFu8; 32];

        let handle = tokio::task::spawn(async move {
            let make_responder = |_| {
                Responder::new(|id| match std::str::from_utf8(id) {
                    Ok("bob") => Some(PSK),
                    _ => None,
                })
            };
            let make_handle_request = |_| {
                |peer_id: &[u8], _req: Request<Body>| async move {
                    let _ = peer_id;
                    let resp = Response::new(Body::empty());
                    Ok::<_, Infallible>(resp)
                }
            };

            server::accept_and_serve_http(listener, make_responder, make_handle_request)
                .await
                .unwrap();
        });

        let initiator = Initiator {
            identity: "bob".as_ref(),
            psk: &PSK,
        };

        let request = Request::builder()
            .uri(format!("http://{listener_addr}"))
            .method("GET")
            .body(Body::from(vec![]))
            .unwrap();

        let tcp_stream = TcpStream::connect(listener_addr).await.unwrap();
        let response = client::send_request(tcp_stream, initiator, request)
            .await
            .unwrap();

        assert_eq!(response.status(), hyper::StatusCode::OK);

        handle.abort();
        handle.await.ok();
    }
}