extern crate argparse; extern crate env_logger; extern crate futures; extern crate tk_http; extern crate tokio_core; extern crate url; extern crate rustls; extern crate tokio_rustls; extern crate webpki; #[macro_use] extern crate log; use std::io::{self, Write, BufReader}; use std::env; use std::fs::File; use std::net::ToSocketAddrs; use std::sync::Arc; use futures::{Future, Sink}; use rustls::ClientConfig; use tokio_core::net::TcpStream; use tokio_rustls::ClientConfigExt; use tk_http::client::buffered::{Buffered}; use tk_http::client::{Proto, Config, Error}; use webpki::DNSNameRef; pub fn main() { if env::var("RUST_LOG").is_err() { env::set_var("RUST_LOG", "warn"); } env_logger::init().unwrap(); let host = "www.rust-lang.org"; let uri = ["https://", host, "/documentation.html"].join(""); let mut lp = tokio_core::reactor::Core::new().expect("loop created"); let handle = lp.handle(); let h2 = lp.handle(); let addr = (host, 443).to_socket_addrs() .expect("resolve address").next().expect("at least one IP"); let config = Arc::new({ let mut cfg = ClientConfig::new(); let mut pem = BufReader::new( File::open("/etc/ssl/certs/ca-certificates.crt") .expect("certificates exist")); cfg.root_store.add_pem_file(&mut pem).unwrap(); cfg }); let host = DNSNameRef::try_from_ascii_str(host).expect("host is valid"); let response = lp.run(futures::lazy(move || { TcpStream::connect(&addr, &handle) .and_then(move |sock| config.connect_async(host, sock)) .map_err(|e| error!("{}", e)) .and_then(move |sock| { let (codec, receiver) = Buffered::get( uri.parse().unwrap()); let proto = Proto::new(sock, &h2, &Arc::new(Config::new())); proto.send(codec) .join(receiver.map_err(|_| -> Error { unimplemented!() })) .map_err(|e| e) .and_then(|(_proto, result)| { result }) .map_err(|e| error!("{}", e)) }) })).expect("request failed"); io::stdout().write_all(response.body()).unwrap(); }