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