diff --git a/examples/client.rs b/examples/client.rs index 24f5880baa..40a3217d36 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -1,59 +1,62 @@ #![deny(warnings)] extern crate hyper; +extern crate tokio; + extern crate pretty_env_logger; use std::env; use std::io::{self, Write}; use hyper::Client; -use hyper::rt::{self, Future, Stream}; +use hyper::rt::{Future, Stream}; +use tokio::runtime::Runtime; fn main() { pretty_env_logger::init(); - // Some simple CLI args requirements... + // Pass URL as first argument, or use a default let url = match env::args().nth(1) { Some(url) => url, - None => { - println!("Usage: client "); - return; - } + None => "http://www.columbia.edu/~fdc/sample.html".to_owned() }; - // HTTPS requires picking a TLS implementation, so give a better - // warning if the user tries to request an 'https' URL. + // HTTPS requires picking a TLS implementation, so give a better warning + // if the user tries to request an 'https' URL. let url = url.parse::().unwrap(); if url.scheme_part().map(|s| s.as_ref()) != Some("http") { println!("This example only works with 'http' URLs."); return; } - rt::run(rt::lazy(move || { - let client = Client::new(); - - client - // Fetch the url... - .get(url) - // And then, if we get a response back... - .and_then(|res| { - println!("Response: {}", res.status()); - println!("Headers: {:#?}", res.headers()); - - // The body is a stream, and for_each returns a new Future - // when the stream is finished, and calls the closure on - // each chunk of the body... - res.into_body().for_each(|chunk| { - io::stdout().write_all(&chunk) - .map_err(|e| panic!("example expects stdout is open, error={}", e)) - }) - }) - // If all good, just tell the user... - .map(|_| { - println!("\n\nDone."); - }) - // If there was an error, let the user know... - .map_err(|err| { - eprintln!("Error {}", err); + let mut runtime = Runtime::new().unwrap(); + let client = Client::new(); + + let job = client.get(url) // HTTP GET request on URL + .and_then(|res| { // On successful (non-error) response + println!("Response: {}", res.status()); + println!("Headers: {:#?}", res.headers()); + + // The body is a stream, and for_each returns a new Future when + // the stream is finished, and calls the closure on each chunk of + // the body... + res.into_body().for_each(|chunk| { + io::stdout() + .write_all(&chunk) + .map_err(|e| { + panic!("example expects stdout is open, error={}", e) + }) }) - })); + }) + .map(|_| { // When done (success) + println!("\n\nDone."); + }) + .map_err(|err| { // When done (error) + eprintln!("Error {}", err); + }); + runtime.spawn(job); // non-blocking + + // Wait and shutdown sequence: drop `client` first, in order for "idle" + // to occur as soon as `job` completes. + drop(client); + runtime.shutdown_on_idle().wait().unwrap(); }