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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Integration tests using `hyper` HTTP Client and the `warp` webserver (built on `hyper`).
/*
use std::{
thread,
str::FromStr,
convert::Infallible,
net::SocketAddr,
sync::mpsc,
};
use warp::Filter;
use bytes::Bytes;
use tokio::net::TcpListener;
use hyper::body::HttpBody;
use scl::salsa::{SalsaKey, Acceptor, StreamAcceptor, HttpSalsaConnector, Connector};
const KEY_B64: &str = include_str!("test.key");
fn api() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("api")
.and(warp::post())
.and(warp::body::content_length_limit(137438953472))
.and(warp::body::bytes())
.and_then(echo)
}
// Just reply with what was received.
async fn echo(raw: Bytes) -> Result<impl warp::Reply, Infallible> {
let body = warp::hyper::Body::from(raw);
Ok(warp::reply::Response::new(body))
}
fn spawn_localhost_server(key: SalsaKey) -> SocketAddr {
let (addr_send, addr_recv) = mpsc::channel();
thread::spawn(move || {
let mut rt = tokio::runtime::Builder::new()
.max_threads(1)
.threaded_scheduler()
.enable_io()
.build()
.unwrap();
let handle = rt.handle().clone();
let bound = rt.block_on(async move {
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let listener = TcpListener::bind(&addr)
.await
.expect("Cannot bind listen address.");
let listen_addr = listener
.local_addr()
.unwrap();
addr_send.send(listen_addr).unwrap();
listener
});
let server_fut = handle.enter(move || {
let acceptor = Acceptor::new(key);
let incoming = StreamAcceptor::new(acceptor, bound);
let server = warp::serve(api());
server.serve_incoming(incoming)
});
rt.block_on(server_fut);
});
addr_recv
.recv()
.unwrap()
}
#[tokio::test(core_threads = 1)]
async fn warp_salsa_cipher_works() -> Result<(), Box<dyn std::error::Error>> {
const FILE: &'static [u8] = include_bytes!("../README.md");
//let mut buffer: [u8; FILE.len()] = [0; FILE.len()];
let key = SalsaKey::from_str(KEY_B64)?;
let addr = spawn_localhost_server(key.clone());
let connector = Connector::new(key);
let uri_str = format!("http://localhost:{}/api", addr.port());
let uri: hyper::Uri = uri_str.parse()?;
let body = hyper::Body::from(FILE);
let req = hyper::Request::builder()
.uri(uri)
.method("POST")
.body(body)?;
let salsa_connector = HttpSalsaConnector::new_http(connector);
let client = hyper::client::Builder::default()
.build::<_, hyper::Body>(salsa_connector);
let mut response = client
.request(req)
.await?;
let mut buffer: Vec<u8> = Vec::new();
while let Some(chunk) = response.data().await {
buffer.extend(chunk?);
}
assert_eq!(buffer.as_slice(), FILE);
Ok(())
}
*/