Skip to content

Commit cb3f39c

Browse files
committed
feat(lib): update Tokio, bytes, http, h2, and http-body
1 parent 131962c commit cb3f39c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+991
-1311
lines changed

Cargo.toml

+16-23
Original file line numberDiff line numberDiff line change
@@ -20,45 +20,37 @@ include = [
2020
]
2121

2222
[dependencies]
23-
bytes = "0.4.6"
24-
futures-core = "0.3.1"
25-
futures-channel = "0.3.1"
26-
futures-util = "0.3.1"
27-
http = "0.1.15"
28-
http-body = "=0.2.0-alpha.3"
23+
bytes = "0.5"
24+
futures-core = { version = "0.3", default-features = false }
25+
futures-channel = "0.3"
26+
futures-util = { version = "0.3", default-features = false }
27+
http = "0.2"
28+
http-body = "0.2"
2929
httparse = "1.0"
30-
h2 = "=0.2.0-alpha.3"
31-
iovec = "0.1"
30+
h2 = "0.2"
3231
itoa = "0.4.1"
3332
log = "0.4"
3433
pin-project = "0.4"
3534
time = "0.1"
3635
tower-service = "=0.3.0-alpha.2"
37-
tokio-executor = "=0.2.0-alpha.6"
38-
tokio-io = "=0.2.0-alpha.6"
39-
tokio-sync = "=0.2.0-alpha.6"
36+
tokio = { version = "0.2", features = ["sync"] }
4037
want = "0.3"
4138

4239
# Optional
4340

4441
net2 = { version = "0.2.32", optional = true }
45-
tokio = { version = "=0.2.0-alpha.6", optional = true, default-features = false, features = ["rt-full"] }
46-
tokio-net = { version = "=0.2.0-alpha.6", optional = true, features = ["tcp"] }
47-
tokio-timer = { version = "=0.3.0-alpha.6", optional = true }
48-
4942

5043
[dev-dependencies]
51-
futures-util-a19 = { version = "=0.3.0-alpha.19", package = "futures-util-preview" }
44+
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
5245
matches = "0.1"
5346
num_cpus = "1.0"
5447
pretty_env_logger = "0.3"
5548
spmc = "0.3"
5649
serde = "1.0"
5750
serde_derive = "1.0"
5851
serde_json = "1.0"
59-
tokio = "=0.2.0-alpha.6" # using #[tokio::test] attributes
60-
tokio-fs = "=0.2.0-alpha.6"
61-
tokio-test = "=0.2.0-alpha.6"
52+
tokio = { version = "0.2.2", features = ["fs", "macros", "rt-util", "sync", "time", "test-util"] }
53+
tokio-test = "0.2"
6254
url = "1.0"
6355

6456
[features]
@@ -68,13 +60,13 @@ default = [
6860
]
6961
runtime = [
7062
"tcp",
71-
"tokio",
63+
"tokio/time",
7264
]
7365
tcp = [
7466
"net2",
75-
"tokio-executor/blocking",
76-
"tokio-net",
77-
"tokio-timer",
67+
"tokio/blocking",
68+
"tokio/tcp",
69+
"tokio/time",
7870
]
7971

8072
# unstable features
@@ -206,3 +198,4 @@ required-features = ["runtime", "unstable-stream"]
206198
name = "server"
207199
path = "tests/server.rs"
208200
required-features = ["runtime"]
201+

benches/connect.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33

44
extern crate test;
55

6+
use std::net::SocketAddr;
67
use tokio::net::TcpListener;
7-
use tokio::runtime::current_thread::Runtime;
88
use hyper::client::connect::{Destination, HttpConnector};
99
use hyper::service::Service;
1010
use http::Uri;
1111

1212
#[bench]
1313
fn http_connector(b: &mut test::Bencher) {
1414
let _ = pretty_env_logger::try_init();
15-
let mut rt = Runtime::new().unwrap();
16-
let mut listener = rt.block_on(TcpListener::bind("127.0.0.1:0")).expect("bind");
15+
let mut rt = tokio::runtime::Builder::new()
16+
.enable_all()
17+
.basic_scheduler()
18+
.build()
19+
.expect("rt build");
20+
let mut listener = rt.block_on(TcpListener::bind(&SocketAddr::from(([127, 0, 0, 1], 0)))).expect("bind");
1721
let addr = listener.local_addr().expect("local_addr");
1822
let uri: Uri = format!("http://{}/", addr).parse().expect("uri parse");
1923
let dst = Destination::try_from_uri(uri).expect("destination");

benches/end_to_end.rs

+21-16
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ extern crate test;
66
use std::net::SocketAddr;
77

88
use futures_util::future::join_all;
9-
use tokio::runtime::current_thread::Runtime;
109

11-
use hyper::{Body, Method, Request, Response, Server};
10+
use hyper::{body::HttpBody as _, Body, Method, Request, Response, Server};
1211
use hyper::client::HttpConnector;
1312

1413
// HTTP1
@@ -264,8 +263,12 @@ impl Opts {
264263
fn bench(self, b: &mut test::Bencher) {
265264
let _ = pretty_env_logger::try_init();
266265
// Create a runtime of current thread.
267-
let mut rt = Runtime::new().unwrap();
268-
let exec = rt.handle();
266+
let mut rt = tokio::runtime::Builder::new()
267+
.enable_all()
268+
.basic_scheduler()
269+
.build()
270+
.expect("rt build");
271+
let exec = rt.handle().clone();
269272

270273
let req_len = self.request_body.map(|b| b.len()).unwrap_or(0) as u64;
271274
let req_len = if self.request_chunks > 0 {
@@ -297,7 +300,7 @@ impl Opts {
297300
for _ in 0..chunk_cnt {
298301
tx.send_data(chunk.into()).await.expect("send_data");
299302
}
300-
}).expect("body tx spawn");
303+
});
301304
body
302305
} else {
303306
self
@@ -340,22 +343,24 @@ impl Opts {
340343
}
341344
}
342345

343-
fn spawn_server(rt: &mut Runtime, opts: &Opts) -> SocketAddr {
346+
fn spawn_server(rt: &mut tokio::runtime::Runtime, opts: &Opts) -> SocketAddr {
344347
use hyper::service::{make_service_fn, service_fn};
345348
let addr = "127.0.0.1:0".parse().unwrap();
346349

347350
let body = opts.response_body;
348-
let srv = Server::bind(&addr)
349-
.http2_only(opts.http2)
350-
.http2_initial_stream_window_size(opts.http2_stream_window)
351-
.http2_initial_connection_window_size(opts.http2_conn_window)
352-
.serve(make_service_fn( move |_| async move {
353-
Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| async move {
354-
let mut req_body = req.into_body();
355-
while let Some(_chunk) = req_body.next().await {}
356-
Ok::<_, hyper::Error>(Response::new(Body::from(body)))
351+
let srv = rt.block_on(async move {
352+
Server::bind(&addr)
353+
.http2_only(opts.http2)
354+
.http2_initial_stream_window_size(opts.http2_stream_window)
355+
.http2_initial_connection_window_size(opts.http2_conn_window)
356+
.serve(make_service_fn( move |_| async move {
357+
Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| async move {
358+
let mut req_body = req.into_body();
359+
while let Some(_chunk) = req_body.next().await {}
360+
Ok::<_, hyper::Error>(Response::new(Body::from(body)))
361+
}))
357362
}))
358-
}));
363+
});
359364
let addr = srv.local_addr();
360365
rt.spawn(async {
361366
if let Err(err) = srv.await {

benches/pipeline.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::net::{TcpStream};
88
use std::sync::mpsc;
99
use std::time::Duration;
1010

11-
use tokio::runtime::current_thread;
1211
use tokio::sync::oneshot;
1312

1413
use hyper::{Body, Response, Server};
@@ -31,9 +30,17 @@ fn hello_world(b: &mut test::Bencher) {
3130
Ok::<_, hyper::Error>(Response::new(Body::from("Hello, World!")))
3231
}))
3332
});
34-
let srv = Server::bind(&addr)
35-
.http1_pipeline_flush(true)
36-
.serve(make_svc);
33+
34+
let mut rt = tokio::runtime::Builder::new()
35+
.enable_all()
36+
.basic_scheduler()
37+
.build()
38+
.expect("rt build");
39+
let srv = rt.block_on(async move {
40+
Server::bind(&addr)
41+
.http1_pipeline_flush(true)
42+
.serve(make_svc)
43+
});
3744

3845
addr_tx.send(srv.local_addr()).unwrap();
3946

@@ -42,13 +49,11 @@ fn hello_world(b: &mut test::Bencher) {
4249
until_rx.await.ok();
4350
});
4451

45-
let mut rt = current_thread::Runtime::new().unwrap();
46-
rt.spawn(async {
52+
rt.block_on(async {
4753
if let Err(e) = graceful.await {
4854
panic!("server error: {}", e);
4955
}
5056
});
51-
rt.run().unwrap();
5257
});
5358

5459
addr_rx.recv().unwrap()

benches/server.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::sync::mpsc;
99
use std::time::Duration;
1010

1111
use futures_util::{stream, StreamExt};
12-
use tokio::runtime::current_thread;
1312
use tokio::sync::oneshot;
1413

1514
use hyper::{Body, Response, Server};
@@ -33,22 +32,29 @@ macro_rules! bench_server {
3332
)
3433
}))
3534
});
36-
let srv = Server::bind(&addr)
37-
.serve(make_svc);
35+
36+
let mut rt = tokio::runtime::Builder::new()
37+
.enable_all()
38+
.basic_scheduler()
39+
.build()
40+
.expect("rt build");
41+
42+
let srv = rt.block_on(async move {
43+
Server::bind(&addr)
44+
.serve(make_svc)
45+
});
3846

3947
addr_tx.send(srv.local_addr()).unwrap();
4048

4149
let graceful = srv
4250
.with_graceful_shutdown(async {
4351
until_rx.await.ok();
4452
});
45-
let mut rt = current_thread::Runtime::new().unwrap();
46-
rt.spawn(async {
53+
rt.block_on(async move {
4754
if let Err(e) = graceful.await {
4855
panic!("server error: {}", e);
4956
}
5057
});
51-
rt.run().unwrap();
5258
});
5359

5460
addr_rx.recv().unwrap()

examples/client.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::env;
44
use std::io::{self, Write};
55

66
use hyper::Client;
7+
use futures_util::StreamExt;
78

89
// A simple type alias so as to DRY.
910
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
@@ -24,7 +25,7 @@ async fn main() -> Result<()> {
2425
// HTTPS requires picking a TLS implementation, so give a better
2526
// warning if the user tries to request an 'https' URL.
2627
let url = url.parse::<hyper::Uri>().unwrap();
27-
if url.scheme_part().map(|s| s.as_ref()) != Some("http") {
28+
if url.scheme_str() != Some("http") {
2829
println!("This example only works with 'http' URLs.");
2930
return Ok(());
3031
}

examples/client_json.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
extern crate serde_derive;
66

77
use hyper::Client;
8-
use futures_util::TryStreamExt;
8+
use futures_util::StreamExt;
99

1010
// A simple type alias so as to DRY.
1111
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
@@ -27,9 +27,12 @@ async fn fetch_json(url: hyper::Uri) -> Result<Vec<User>> {
2727
let client = Client::new();
2828

2929
// Fetch the url...
30-
let res = client.get(url).await?;
30+
let mut res = client.get(url).await?;
3131
// asynchronously concatenate chunks of the body
32-
let body = res.into_body().try_concat().await?;
32+
let mut body = Vec::new();
33+
while let Some(chunk) = res.body_mut().next().await {
34+
body.extend_from_slice(&chunk?);
35+
}
3336
// try to parse as json with serde_json
3437
let users = serde_json::from_slice(&body)?;
3538

examples/echo.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
use hyper::{Body, Method, Request, Response, Server, StatusCode};
44
use hyper::service::{make_service_fn, service_fn};
5-
use futures_util::TryStreamExt;
5+
use futures_util::{StreamExt, TryStreamExt};
66

77
/// This is our service handler. It receives a Request, routes on its
88
/// path, and returns a Future of a Response.
9-
async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
10-
9+
async fn echo(mut req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
1110
match (req.method(), req.uri().path()) {
1211
// Serve some instructions at /
1312
(&Method::GET, "/") => {
@@ -37,13 +36,17 @@ async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
3736
// So here we do `.await` on the future, waiting on concatenating the full body,
3837
// then afterwards the content can be reversed. Only then can we return a `Response`.
3938
(&Method::POST, "/echo/reversed") => {
40-
let whole_chunk = req.into_body().try_concat().await;
41-
42-
let reversed_chunk = whole_chunk.map(move |chunk| {
43-
chunk.iter().rev().cloned().collect::<Vec<u8>>()
44-
45-
})?;
46-
Ok(Response::new(Body::from(reversed_chunk)))
39+
let mut whole_body = Vec::new();
40+
while let Some(chunk) = req.body_mut().next().await {
41+
whole_body.extend_from_slice(&chunk?);
42+
}
43+
44+
let reversed_body = whole_body
45+
.iter()
46+
.rev()
47+
.cloned()
48+
.collect::<Vec<u8>>();
49+
Ok(Response::new(Body::from(reversed_body)))
4750
}
4851

4952
// Return the 404 Not Found for other routes.

examples/params.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,24 @@ use hyper::service::{service_fn, make_service_fn};
66

77
use std::collections::HashMap;
88
use url::form_urlencoded;
9-
use futures_util::TryStreamExt;
9+
use futures_util::StreamExt;
1010

1111
static INDEX: &[u8] = b"<html><body><form action=\"post\" method=\"post\">Name: <input type=\"text\" name=\"name\"><br>Number: <input type=\"text\" name=\"number\"><br><input type=\"submit\"></body></html>";
1212
static MISSING: &[u8] = b"Missing field";
1313
static NOTNUMERIC: &[u8] = b"Number field is not numeric";
1414

1515
// Using service_fn, we can turn this function into a `Service`.
16-
async fn param_example(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
16+
async fn param_example(mut req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
1717
match (req.method(), req.uri().path()) {
1818
(&Method::GET, "/") | (&Method::GET, "/post") => {
1919
Ok(Response::new(INDEX.into()))
2020
},
2121
(&Method::POST, "/post") => {
22-
let b = req.into_body().try_concat().await?;
22+
// Concatenate the body...
23+
let mut b = Vec::new();
24+
while let Some(chunk) = req.body_mut().next().await {
25+
b.extend_from_slice(&chunk?);
26+
}
2327
// Parse the request body. form_urlencoded::parse
2428
// always succeeds, but in general parsing may
2529
// fail (for example, an invalid post of json), so

examples/send_file.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![deny(warnings)]
22

33
use tokio::io::AsyncReadExt;
4-
use tokio_fs::File;
4+
use tokio::fs::File;
55

66
use hyper::{Body, Method, Result, Request, Response, Server, StatusCode};
77
use hyper::service::{make_service_fn, service_fn};

0 commit comments

Comments
 (0)