1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use rocket::{Data, State}; use formdata::{read_formdata, FilePart}; use routing::request::ConvertedHeaders; use hyper::header::{Headers, ContentDisposition, DispositionParam}; use rocket::request::FromRequest; use std::io::{Read, Write, copy}; use std::io::{BufReader, BufWriter}; use std::fs::{OpenOptions, File, create_dir}; use cli::{HandlerMethod, SwerveConfig}; use std::path::{Path, PathBuf}; use std::collections::HashMap; use rand::{Rng, StdRng}; #[post(path = "/", data = "<upload>")] pub fn to_file(headers: ConvertedHeaders, conf: State<SwerveConfig>, upload: Data) -> Result<String, String> { let formdata = read_formdata(&mut upload.open(), &headers.as_hyper()); if let Ok(data) = formdata { let fields = collect_fields(data.fields); match conf.field_handling { HandlerMethod::Log => println!("{:?}", fields), HandlerMethod::File => println!("{:?}", fields), } create_dir("uploads"); for file in data.files { match conf.file_handling { HandlerMethod::Log => log_file(file), HandlerMethod::File => upload_file(file), } } Ok(String::from("Complete")) } else { Err(String::from("Failed")) } } fn collect_fields(fields: Vec<(String, String)>) -> HashMap<String, String> { let mut map = HashMap::with_capacity(fields.len()); 'collector: for (key, value) in fields { if value == String::from("undefined") { continue 'collector }; map.insert(key.clone(), value.clone()); } map } type Upload = (String, FilePart); fn upload_file(file: Upload) { let (name, value) = file; let content_disposition = value.headers.get::<ContentDisposition>().unwrap(); let file_name = filename_from_disposition(content_disposition); let mut input = File::open(value.path.clone()).unwrap(); let mut output = OpenOptions::new() .write(true) .create(true) .open(PathBuf::from("uploads").join(file_name.clone().unwrap_or(String::from("upload_data")))) .unwrap(); copy(&mut input, &mut output).unwrap(); println!("File written to {}", file_name.unwrap()); } fn log_file(file: Upload) { let (name, value) = file; println!("[UPLOAD] From field: {}. Size: {}", name, value.size.unwrap_or(0)); for header in value.headers.iter() { println!("[UPLOAD] :: {}; {}", header.name(), header.value_string()); } } fn filename_from_disposition(dispo: &ContentDisposition) -> Option<String> { for param in dispo.parameters.iter() { if let &DispositionParam::Filename(_, _, ref name_vec) = param { return Some(String::from_utf8(name_vec.to_vec()).unwrap_or(String::from("bad_filename.bin"))); } } None }