extern crate tiny_http;
extern crate multipart;
use std::fs::File;
use std::io::{Error, Read};
use multipart::server::{Multipart, Entries, SaveResult};
use tiny_http::{Response, StatusCode, Request};
fn main() {
let server = tiny_http::Server::http("localhost:80").expect("Could not bind localhost:80");
loop {
let mut request = server.recv().unwrap();
let result = process_request(&mut request);
let resp = match result {
Ok(resp) => resp,
Err(e) => {
println!("An error has occured during request proccessing: {:?}", e);
build_response(500, "The received data was not correctly proccessed on the server")
}
};
request.respond(resp).unwrap();
}
}
fn process_request<'a, 'b>(request: &'a mut Request) -> Result<Response<&'b [u8]>, Error> {
match Multipart::from_request(request) {
Ok(mut multipart) => {
match multipart.save_all() {
SaveResult::Full(entries) => process_entries(entries),
SaveResult::Partial(entries, error) => {
try!(process_entries(entries));
Err(error)
}
SaveResult::Error(error) => Err(error),
}
}
Err(_) => Ok(build_response(400, "The request is not multipart")),
}
}
fn process_entries<'a>(entries: Entries) -> Result<Response<&'a [u8]>, Error> {
for (name, field) in entries.fields {
println!(r#"Field "{}": "{}""#, name, field);
}
for (name, savedfile) in entries.files {
let filename = match savedfile.filename {
Some(s) => s,
None => "None".into(),
};
let mut file = try!(File::open(savedfile.path));
let mut contents = String::new();
try!(file.read_to_string(&mut contents));
println!(r#"Field "{}" is file "{}":"#, name, filename);
println!("{}", contents);
}
Ok(build_response(200, "Multipart data is received!".into()))
}
fn build_response(status_code: u16, response: &str) -> Response<&[u8]> {
let bytes = response.as_bytes();
Response::new(StatusCode(status_code),
vec![],
bytes,
Some(bytes.len()),
None)
}