#![deny(warnings)] #[macro_use] extern crate futures; extern crate bytes; extern crate reqwest; extern crate tokio; extern crate tokio_threadpool; use std::io::{self, Cursor}; use std::mem; use std::path::Path; use bytes::Bytes; use futures::{Async, Future, Poll, Stream}; use reqwest::r#async::{Client, Decoder}; use tokio::fs::File; use tokio::io::AsyncRead; const CHUNK_SIZE: usize = 1024; struct FileSource { inner: File, } impl FileSource { fn new(file: File) -> FileSource { FileSource { inner: file } } } impl Stream for FileSource { type Item = Bytes; type Error = io::Error; fn poll(&mut self) -> Poll, Self::Error> { let mut buf = [0; CHUNK_SIZE]; let size = try_ready!(self.inner.poll_read(&mut buf)); if size > 0 { Ok(Async::Ready(Some(buf[0..size].into()))) } else { Ok(Async::Ready(None)) } } } fn post

(path: P) -> impl Future where P: AsRef, { File::open(path.as_ref().to_owned()) .map_err(|err| println!("request error: {}", err)) .and_then(|file| { let source: Box + Send> = Box::new(FileSource::new(file)); Client::new() .post("https://httpbin.org/post") .body(source) .send() .and_then(|mut res| { println!("{}", res.status()); let body = mem::replace(res.body_mut(), Decoder::empty()); body.concat2() }) .map_err(|err| println!("request error: {}", err)) .map(|body| { let mut body = Cursor::new(body); let _ = io::copy(&mut body, &mut io::stdout()).map_err(|err| { println!("stdout error: {}", err); }); }) }) } fn main() { let pool = tokio_threadpool::ThreadPool::new(); let path = concat!(env!("CARGO_MANIFEST_DIR"), "/LICENSE-APACHE"); tokio::run(pool.spawn_handle(post(path))); }