summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-06-05 18:47:09 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-06-05 18:47:09 +0200
commit5d2c20e2b5b93f5dd74b0faf016d67afc631b903 (patch)
tree5d8886077932770fd15afe92455f1acbd2151420 /net
parente475e149ec7d259bb57af24ad4b0b9b55e8116c4 (diff)
net: Bump hyper to "0.12", hyper-tls to "0.2".
Diffstat (limited to 'net')
-rw-r--r--net/Cargo.toml5
-rw-r--r--net/src/async.rs68
-rw-r--r--net/src/lib.rs26
-rw-r--r--net/tests/hkp.rs143
4 files changed, 124 insertions, 118 deletions
diff --git a/net/Cargo.toml b/net/Cargo.toml
index bd97084b..c48a7be9 100644
--- a/net/Cargo.toml
+++ b/net/Cargo.toml
@@ -11,8 +11,9 @@ capnp-rpc = "0.8"
failure = "0.1.1"
fs2 = "0.4.2"
futures = "0.1"
-hyper = "0.11"
-hyper-tls = "0.1.2"
+http = "0.1.5"
+hyper = "0.12"
+hyper-tls = "0.2"
libc = "0.2.33"
native-tls = "0.1.4"
percent-encoding = "1.0.1"
diff --git a/net/src/async.rs b/net/src/async.rs
index 9ee962e2..3095c3dc 100644
--- a/net/src/async.rs
+++ b/net/src/async.rs
@@ -5,9 +5,9 @@
use failure;
use futures::{future, Future, Stream};
-use hyper::client::{FutureResponse, HttpConnector};
-use hyper::header::{ContentLength, ContentType};
-use hyper::{self, Client, StatusCode, Request, Method};
+use hyper::client::{ResponseFuture, HttpConnector};
+use hyper::header::{CONTENT_LENGTH, CONTENT_TYPE, HeaderValue};
+use hyper::{self, Client, Body, StatusCode, Request};
use hyper_tls::HttpsConnector;
use native_tls::{Certificate, TlsConnector};
use percent_encoding::{percent_encode, DEFAULT_ENCODE_SET};
@@ -40,15 +40,14 @@ const DNS_WORKER: usize = 4;
impl KeyServer {
/// Returns a handle for the given URI.
- pub fn new(ctx: &Context, uri: &str, handle: &Handle) -> Result<Self> {
+ pub fn new(ctx: &Context, uri: &str, _handle: &Handle) -> Result<Self> {
let uri: Url = uri.parse()?;
let client: Box<AClient> = match uri.scheme() {
- "hkp" => Box::new(Client::new(handle)),
+ "hkp" => Box::new(Client::new()),
"hkps" => {
- Box::new(Client::configure()
- .connector(HttpsConnector::new(DNS_WORKER, handle)?)
- .build(handle))
+ Box::new(Client::builder()
+ .build(HttpsConnector::new(DNS_WORKER)?))
},
_ => return Err(Error::MalformedUri.into()),
};
@@ -60,7 +59,7 @@ impl KeyServer {
///
/// `cert` is used to authenticate the server.
pub fn with_cert(ctx: &Context, uri: &str, cert: Certificate,
- handle: &Handle) -> Result<Self> {
+ _handle: &Handle) -> Result<Self> {
let uri: Url = uri.parse()?;
let client: Box<AClient> = {
@@ -68,11 +67,10 @@ impl KeyServer {
ssl.add_root_certificate(cert)?;
let ssl = ssl.build()?;
- let mut http = HttpConnector::new(DNS_WORKER, handle);
+ let mut http = HttpConnector::new(DNS_WORKER);
http.enforce_http(false);
- Box::new(Client::configure()
- .connector(HttpsConnector::from((http, ssl)))
- .build(handle))
+ Box::new(Client::builder()
+ .build(HttpsConnector::from((http, ssl))))
};
Self::make(ctx, client, uri)
@@ -127,14 +125,16 @@ impl KeyServer {
.from_err()
.and_then(|res| {
let status = res.status();
- res.body().concat2().from_err()
+ res.into_body().concat2().from_err()
.and_then(move |body| match status {
- StatusCode::Ok => {
+ StatusCode::OK => {
let c = Cursor::new(body.as_ref());
- let r = armor::Reader::new(c, armor::Kind::PublicKey);
+ let r = armor::Reader::new(
+ c, armor::Kind::PublicKey);
future::done(TPK::from_reader(r))
},
- StatusCode::NotFound => future::err(Error::NotFound.into()),
+ StatusCode::NOT_FOUND =>
+ future::err(Error::NotFound.into()),
n => future::err(Error::HttpStatus(n).into()),
})
}))
@@ -165,18 +165,28 @@ impl KeyServer {
let mut post_data = b"keytext=".to_vec();
post_data.extend_from_slice(percent_encode(&armored_blob, KEYSERVER_ENCODE_SET)
.collect::<String>().as_bytes());
+ let length = post_data.len();
- let mut request = Request::new(Method::Post, url2uri(uri));
- request.headers_mut().set(ContentType::form_url_encoded());
- request.headers_mut().set(ContentLength(post_data.len() as u64));
- request.set_body(post_data);
+ let mut request = match Request::post(url2uri(uri))
+ .body(Body::from(post_data))
+ {
+ Ok(r) => r,
+ Err(e) => return Box::new(future::err(Error::from(e).into())),
+ };
+ request.headers_mut().insert(
+ CONTENT_TYPE,
+ HeaderValue::from_static("application/x-www-form-urlencoded"));
+ request.headers_mut().insert(
+ CONTENT_LENGTH,
+ HeaderValue::from_str(&format!("{}", length))
+ .expect("cannot fail: only ASCII characters"));
Box::new(self.client.do_request(request)
.from_err()
.and_then(|res| {
match res.status() {
- StatusCode::Ok => future::ok(()),
- StatusCode::NotFound => future::err(Error::ProtocolViolation.into()),
+ StatusCode::OK => future::ok(()),
+ StatusCode::NOT_FOUND => future::err(Error::ProtocolViolation.into()),
n => future::err(Error::HttpStatus(n).into()),
}
}))
@@ -184,24 +194,24 @@ impl KeyServer {
}
trait AClient {
- fn do_get(&mut self, uri: Url) -> FutureResponse;
- fn do_request(&mut self, request: Request) -> FutureResponse;
+ fn do_get(&mut self, uri: Url) -> ResponseFuture;
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture;
}
impl AClient for Client<HttpConnector> {
- fn do_get(&mut self, uri: Url) -> FutureResponse {
+ fn do_get(&mut self, uri: Url) -> ResponseFuture {
self.get(url2uri(uri))
}
- fn do_request(&mut self, request: Request) -> FutureResponse {
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture {
self.request(request)
}
}
impl AClient for Client<HttpsConnector<HttpConnector>> {
- fn do_get(&mut self, uri: Url) -> FutureResponse {
+ fn do_get(&mut self, uri: Url) -> ResponseFuture {
self.get(url2uri(uri))
}
- fn do_request(&mut self, request: Request) -> FutureResponse {
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture {
self.request(request)
}
}
diff --git a/net/src/lib.rs b/net/src/lib.rs
index d01aa93d..bb9c0bf4 100644
--- a/net/src/lib.rs
+++ b/net/src/lib.rs
@@ -36,6 +36,7 @@ extern crate sequoia_core;
#[macro_use]
extern crate failure;
extern crate futures;
+extern crate http;
extern crate hyper;
extern crate hyper_tls;
extern crate native_tls;
@@ -47,8 +48,8 @@ extern crate url;
extern crate capnp_rpc;
-use hyper::client::{FutureResponse, HttpConnector};
-use hyper::{Client, Request};
+use hyper::client::{ResponseFuture, HttpConnector};
+use hyper::{Client, Request, Body};
use hyper_tls::HttpsConnector;
use native_tls::Certificate;
use std::convert::From;
@@ -114,24 +115,24 @@ impl KeyServer {
}
trait AClient {
- fn do_get(&mut self, uri: Url) -> FutureResponse;
- fn do_request(&mut self, request: Request) -> FutureResponse;
+ fn do_get(&mut self, uri: Url) -> ResponseFuture;
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture;
}
impl AClient for Client<HttpConnector> {
- fn do_get(&mut self, uri: Url) -> FutureResponse {
+ fn do_get(&mut self, uri: Url) -> ResponseFuture {
self.get(url2uri(uri))
}
- fn do_request(&mut self, request: Request) -> FutureResponse {
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture {
self.request(request)
}
}
impl AClient for Client<HttpsConnector<HttpConnector>> {
- fn do_get(&mut self, uri: Url) -> FutureResponse {
+ fn do_get(&mut self, uri: Url) -> ResponseFuture {
self.get(url2uri(uri))
}
- fn do_request(&mut self, request: Request) -> FutureResponse {
+ fn do_request(&mut self, request: Request<Body>) -> ResponseFuture {
self.request(request)
}
}
@@ -160,6 +161,9 @@ pub enum Error {
/// A `hyper::error::UriError` occurred.
#[fail(display = "URI Error")]
UriError(url::ParseError),
+ /// A `http::Error` occurred.
+ #[fail(display = "http Error")]
+ HttpError(http::Error),
/// A `hyper::Error` occurred.
#[fail(display = "Hyper Error")]
HyperError(hyper::Error),
@@ -168,6 +172,12 @@ pub enum Error {
TlsError(native_tls::Error),
}
+impl From<http::Error> for Error {
+ fn from(e: http::Error) -> Error {
+ Error::HttpError(e)
+ }
+}
+
impl From<hyper::Error> for Error {
fn from(e: hyper::Error) -> Error {
Error::HyperError(e)
diff --git a/net/tests/hkp.rs b/net/tests/hkp.rs
index d3da0f93..b2d68bb0 100644
--- a/net/tests/hkp.rs
+++ b/net/tests/hkp.rs
@@ -1,4 +1,5 @@
extern crate futures;
+extern crate http;
extern crate hyper;
extern crate rand;
extern crate url;
@@ -7,8 +8,9 @@ use futures::Stream;
use futures::future::Future;
use futures::sync::oneshot;
-use hyper::header::ContentLength;
-use hyper::server::{Http, Request, Response, Service};
+use http::{Request, Response};
+use hyper::{Server, Body};
+use hyper::service::service_fn;
use hyper::{Method, StatusCode};
use rand::Rng;
use rand::os::OsRng;
@@ -26,8 +28,6 @@ use openpgp::{Fingerprint, KeyID};
use sequoia_core::{Context, NetworkPolicy};
use sequoia_net::KeyServer;
-struct HKPServer;
-
const RESPONSE: &'static str = "-----BEGIN PGP PUBLIC KEY BLOCK-----
xsBNBFoVcvoBCACykTKOJddF8SSUAfCDHk86cNTaYnjCoy72rMgWJsrMLnz/V16B
@@ -63,61 +63,53 @@ Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g=
const FP: &'static str = "3E8877C877274692975189F5D03F6F865226FE8B";
const ID: &'static str = "D03F6F865226FE8B";
-impl Service for HKPServer {
- type Request = Request;
- type Response = Response;
- type Error = hyper::Error;
- type Future = Box<Future<Item=Self::Response, Error=Self::Error>>;
-
- fn call(&self, req: Request) -> Self::Future {
- match (req.method(), req.path()) {
- (&Method::Get, "/pks/lookup") => {
- if let Some(args) = req.query() {
- for (key, value) in url::form_urlencoded::parse(args.as_bytes()) {
- match key.clone().into_owned().as_ref() {
- "op" => assert_eq!(value, "get"),
- "options" => assert_eq!(value, "mr"),
- "search" => assert_eq!(value, "0xD03F6F865226FE8B"),
- _ => panic!("Bad query: {}:{}", key, value),
- }
+fn service(req: Request<Body>)
+ -> Box<Future<Item=Response<Body>, Error=hyper::Error> + Send> {
+ let (parts, body) = req.into_parts();
+ match (parts.method, parts.uri.path()) {
+ (Method::GET, "/pks/lookup") => {
+ if let Some(args) = parts.uri.query() {
+ for (key, value) in url::form_urlencoded::parse(args.as_bytes()) {
+ match key.clone().into_owned().as_ref() {
+ "op" => assert_eq!(value, "get"),
+ "options" => assert_eq!(value, "mr"),
+ "search" => assert_eq!(value, "0xD03F6F865226FE8B"),
+ _ => panic!("Bad query: {}:{}", key, value),
}
- } else {
- panic!("Expected query string");
}
+ } else {
+ panic!("Expected query string");
+ }
- Box::new(futures::future::ok(Response::new()
- .with_header(ContentLength(RESPONSE.len() as u64))
- .with_body(RESPONSE)))
- },
- (&Method::Post, "/pks/add") => {
- Box::new(
- req.body().concat2()
- .map(|b| {
- for (key, value) in url::form_urlencoded::parse(b.as_ref()) {
- match key.clone().into_owned().as_ref() {
- "keytext" => {
- let key = TPK::from_reader(
- Reader::new(Cursor::new(value.into_owned()),
- Kind::Any)).unwrap();
- assert_eq!(
- key.fingerprint(),
- Fingerprint::from_hex(FP)
- .unwrap());
- },
- _ => panic!("Bad post: {}:{}", key, value),
- }
- }
-
- Response::new()
- .with_header(ContentLength("Ok".len() as u64))
- .with_body("Ok")
- }))
- },
- _ => {
- Box::new(futures::future::ok(Response::new()
- .with_status(StatusCode::NotFound)))
- },
- }
+ Box::new(futures::future::ok(Response::new(Body::from(RESPONSE))))
+ },
+ (Method::POST, "/pks/add") => {
+ Box::new(
+ body.concat2()
+ .map(|b| {
+ for (key, value) in url::form_urlencoded::parse(b.as_ref()) {
+ match key.clone().into_owned().as_ref() {
+ "keytext" => {
+ let key = TPK::from_reader(
+ Reader::new(Cursor::new(value.into_owned()),
+ Kind::Any)).unwrap();
+ assert_eq!(
+ key.fingerprint(),
+ Fingerprint::from_hex(FP)
+ .unwrap());
+ },
+ _ => panic!("Bad post: {}:{}", key, value),
+ }
+ }
+
+ Response::new(Body::from("Ok"))
+ }))
+ },
+ _ => {
+ Box::new(futures::future::ok(Response::builder()
+ .status(StatusCode::NOT_FOUND)
+ .body(Body::from("Not found")).unwrap()))
+ },
}
}
@@ -125,25 +117,26 @@ impl Service for HKPServer {
///
/// Returns the address, a channel to drop() to kill the server, and
/// the thread handle to join the server thread.
-fn start_server() -> (SocketAddr, oneshot::Sender<()>, thread::JoinHandle<()>) {
- let (keep_going, done) = oneshot::channel::<()>();
+fn start_server() -> SocketAddr {
let (tx, rx) = oneshot::channel::<SocketAddr>();
- let t = thread::spawn(move || {
- let server = loop {
+ thread::spawn(move || {
+ let (addr, server) = loop {
let port = OsRng::new().unwrap().next_u32() as u16;
- if let Ok(s) = Http::new().bind(
- &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port),
- || Ok(HKPServer)) {
- break s;
+ let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
+ port);
+ if let Ok(s) = Server::try_bind(&addr) {
+ break (addr, s);
}
};
- tx.send(server.local_addr().unwrap()).unwrap();
- server.run_until(done.map_err(|_| ())).unwrap();
+
+ tx.send(addr).unwrap();
+ hyper::rt::run(server
+ .serve(|| service_fn(service))
+ .map_err(|e| panic!(e)));
});
let addr = rx.wait().unwrap();
-
- (addr, keep_going, t)
+ addr
}
#[test]
@@ -154,7 +147,7 @@ fn get() {
.build().unwrap();
// Start server.
- let (addr, keep_going, t) = start_server();
+ let addr = start_server();
let mut keyserver =
KeyServer::new(&ctx, &format!("hkp://{}", addr)).unwrap();
@@ -163,10 +156,6 @@ fn get() {
assert_eq!(key.fingerprint(),
Fingerprint::from_hex(FP).unwrap());
-
- // Kill server, join.
- drop(keep_going);
- t.join().unwrap();
}
#[test]
@@ -177,15 +166,11 @@ fn send() {
.build().unwrap();
// Start server.
- let (addr, keep_going, t) = start_server();
-
+ let addr = start_server();
+ eprintln!("{}", format!("hkp://{}", addr));
let mut keyserver =
KeyServer::new(&ctx, &format!("hkp://{}", addr)).unwrap();
let key = TPK::from_reader(Reader::new(Cursor::new(RESPONSE),
Kind::Any)).unwrap();
keyserver.send(&key).unwrap();
-
- // Kill server, join.
- drop(keep_going);
- t.join().unwrap();
}