rust-bucket/src/mpu.rs

64 lines
1.8 KiB
Rust
Raw Normal View History

2018-08-07 23:23:15 -04:00
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::io;
use std::io::{Read, Cursor};
use rocket::data::{self, FromData};
use rocket::Data;
use rocket::Outcome;
use rocket::request::Request;
use rocket::http::Status;
use multipart::server::Multipart;
pub struct MultipartUpload {
file: Vec<u8>,
}
impl MultipartUpload {
pub fn stream_to_file(&self, path: &Path) -> io::Result<()> {
let mut f = File::create(path)?;
f.write_all(&self.file)
}
}
fn get_multipart(request: &Request, data: Data) -> Option<Multipart<Cursor<Vec<u8>>>> {
// All of these errors should be reported
let ct = request.headers().get_one("Content-Type")?;
let idx = ct.find("boundary=")?;
let boundary = &ct[(idx + "boundary=".len())..];
let mut d = Vec::new();
data.stream_to(&mut d).ok()?;
Some(Multipart::with_body(Cursor::new(d), boundary))
}
impl FromData for MultipartUpload {
type Error = ();
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
let mut mp = match get_multipart(&request, data) {
Some(m) => m,
None => return Outcome::Failure((Status::raw(421), ())),
};
// Custom implementation parts
let mut file = None;
mp.foreach_entry(|mut entry| match entry.headers.name.as_str() {
"file" => {
panic!("filename: {:?}", entry.headers.filename);
let mut d = Vec::new();
entry.data.read_to_end(&mut d).expect("cant read");
file = Some(d);
}
other => panic!("No known key {}", other),
}).expect("Unable to iterate");
Outcome::Success(MultipartUpload {
file: file.expect("file not set"),
})
}
}