1 extern crate multipart;
2 extern crate iron;
3 
4 extern crate env_logger;
5 
6 use std::io::{self, Write};
7 use multipart::mock::StdoutTee;
8 use multipart::server::{Multipart, Entries, SaveResult};
9 use iron::prelude::*;
10 use iron::status;
11 
main()12 fn main() {
13     env_logger::init();
14 
15     Iron::new(process_request).http("localhost:80").expect("Could not bind localhost:80");
16 }
17 
18 /// Processes a request and returns response or an occured error.
process_request(request: &mut Request) -> IronResult<Response>19 fn process_request(request: &mut Request) -> IronResult<Response> {
20     // Getting a multipart reader wrapper
21     match Multipart::from_request(request) {
22         Ok(mut multipart) => {
23             // Fetching all data and processing it.
24             // save().temp() reads the request fully, parsing all fields and saving all files
25             // in a new temporary directory under the OS temporary directory.
26             match multipart.save().temp() {
27                 SaveResult::Full(entries) => process_entries(entries),
28                 SaveResult::Partial(entries, reason) => {
29                     process_entries(entries.keep_partial())?;
30                     Ok(Response::with((
31                         status::BadRequest,
32                         format!("error reading request: {}", reason.unwrap_err())
33                     )))
34                 }
35                 SaveResult::Error(error) => Ok(Response::with((
36                     status::BadRequest,
37                     format!("error reading request: {}", error)
38                 ))),
39             }
40         }
41         Err(_) => {
42             Ok(Response::with((status::BadRequest, "The request is not multipart")))
43         }
44     }
45 }
46 
47 /// Processes saved entries from multipart request.
48 /// Returns an OK response or an error.
process_entries(entries: Entries) -> IronResult<Response>49 fn process_entries(entries: Entries) -> IronResult<Response> {
50     let mut data = Vec::new();
51 
52     {
53         let stdout = io::stdout();
54         let tee = StdoutTee::new(&mut data, &stdout);
55         entries.write_debug(tee).map_err(|e| {
56             IronError::new(
57                 e,
58                 (status::InternalServerError, "Error printing request fields")
59             )
60         })?;
61     }
62 
63     let _ = writeln!(data, "Entries processed");
64 
65     Ok(Response::with((status::Ok, data)))
66 }
67