extern crate qiniu_multipart; extern crate tiny_http; use qiniu_multipart::mock::StdoutTee; use qiniu_multipart::server::{Entries, Multipart, SaveResult}; use std::io::{self, Cursor, Write}; use tiny_http::{Request, Response, StatusCode}; fn main() { // Starting a server on `localhost:80` let server = tiny_http::Server::http("localhost:80").expect("Could not bind localhost:80"); loop { // This blocks until the next request is received let mut request = server.recv().unwrap(); // Processes a request and returns response or an occured error 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", ) } }; // Answers with a response to a client request.respond(resp).unwrap(); } } type RespBody = Cursor>; /// Processes a request and returns response or an occured error. fn process_request(request: &mut Request) -> io::Result> { // Getting a multipart reader wrapper match Multipart::from_request(request) { Ok(mut multipart) => { // Fetching all data and processing it. // save().temp() reads the request fully, parsing all fields and saving all files // in a new temporary directory under the OS temporary directory. match multipart.save().temp() { SaveResult::Full(entries) => process_entries(entries), SaveResult::Partial(entries, reason) => { process_entries(entries.keep_partial())?; // We don't set limits Err(reason.unwrap_err()) } SaveResult::Error(error) => Err(error), } } Err(_) => Ok(build_response(400, "The request is not multipart")), } } /// Processes saved entries from multipart request. /// Returns an OK response or an error. fn process_entries(entries: Entries) -> io::Result> { let mut data = Vec::new(); { let stdout = io::stdout(); let tee = StdoutTee::new(&mut data, &stdout); entries.write_debug(tee)?; } writeln!(data, "Entries processed")?; Ok(build_response(200, data)) } fn build_response>>(status_code: u16, data: D) -> Response { let data = data.into(); let data_len = data.len(); Response::new( StatusCode(status_code), vec![], Cursor::new(data), Some(data_len), None, ) }