qiniu_multipart/client/
sized.rs1use client::{HttpRequest, HttpStream};
10
11use std::io;
12use std::io::prelude::*;
13
14pub struct SizedRequest<R> {
28 inner: R,
29 buffer: Vec<u8>,
30 boundary: String,
31}
32
33impl<R: HttpRequest> SizedRequest<R> {
34 #[doc(hidden)]
35 pub fn from_request(req: R) -> SizedRequest<R> {
36 SizedRequest {
37 inner: req,
38 buffer: Vec::new(),
39 boundary: String::new(),
40 }
41 }
42}
43
44impl<R> Write for SizedRequest<R> {
45 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
46 self.buffer.write(data)
47 }
48
49 fn flush(&mut self) -> io::Result<()> { Ok(()) }
50}
51
52impl<R: HttpRequest> HttpRequest for SizedRequest<R>
53where <R::Stream as HttpStream>::Error: From<R::Error> {
54 type Stream = Self;
55 type Error = R::Error;
56
57 fn apply_headers(&mut self, boundary: &str, _content_len: Option<u64>) -> bool {
59 self.boundary.clear();
60 self.boundary.push_str(boundary);
61 true
62 }
63
64 fn open_stream(mut self) -> Result<Self, Self::Error> {
65 self.buffer.clear();
66 Ok(self)
67 }
68}
69
70impl<R: HttpRequest> HttpStream for SizedRequest<R>
71where <R::Stream as HttpStream>::Error: From<R::Error> {
72 type Request = Self;
73 type Response = <<R as HttpRequest>::Stream as HttpStream>::Response;
74 type Error = <<R as HttpRequest>::Stream as HttpStream>::Error;
75
76 fn finish(mut self) -> Result<Self::Response, Self::Error> {
77 let content_len = self.buffer.len() as u64;
78
79 if !self.inner.apply_headers(&self.boundary, Some(content_len)) {
80 return Err(io::Error::new(
81 io::ErrorKind::Other,
82 "SizedRequest failed to apply headers to wrapped request."
83 ).into());
84 }
85
86 let mut req = self.inner.open_stream()?;
87 io::copy(&mut &self.buffer[..], &mut req)?;
88 req.finish()
89 }
90}