Added support for sending requests with streaming Body (#545)
This commit is contained in:
committed by
Sean McArthur
parent
9f256405e5
commit
e16aed5e3c
81
examples/async_stream.rs
Normal file
81
examples/async_stream.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
#![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::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<Option<Self::Item>, 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<P>(path: P) -> impl Future<Item = (), Error = ()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
File::open(path.as_ref().to_owned())
|
||||
.map_err(|err| println!("request error: {}", err))
|
||||
.and_then(|file| {
|
||||
let source: Box<Stream<Item = Bytes, Error = io::Error> + 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)));
|
||||
}
|
||||
Reference in New Issue
Block a user