I'm working on a small API in Rust and am not sure how to access a Request
from Iron in two places.
The Authentication
middleware reads the Request
once for a token and the actual route tries to read it again if the path is allowed (currently there is no check). This gives me an EOF error as the request has already been read.
I can't seem to easily clone the request and I believe it must be mutable in order to read the body.
extern crate iron;
extern crate router;
extern crate rustc_serialize;
use iron::prelude::*;
use iron::{BeforeMiddleware, status};
use router::Router;
use rustc_serialize::json;
use rustc_serialize::json::Json;
use std::io::Read;
#[derive(RustcEncodable, RustcDecodable)]
struct Greeting {
msg: String
}
struct Authentication;
fn main() {
let mut request_body = String::new();
impl BeforeMiddleware for Authentication {
fn before(&self, request: &mut Request) -> IronResult<()> {
let mut payload = String::new();
request.body.read_to_string(&mut payload).unwrap();
let json = Json::from_str(&payload).unwrap();
println!("json: {}", json);
let token = json.as_object()
.and_then(|obj| obj.get("token"))
.and_then(|token| token.as_string())
.unwrap_or_else(|| {
panic!("Unable to get token");
});
println!("token: {}", token);
Ok(())
}
}
fn attr(input: String, attribute: &str) -> String {
let json = Json::from_str(&input).unwrap();
let output = json.as_object()
.and_then(|obj| obj.get(attribute))
.and_then(|a| a.as_string())
.unwrap_or_else(|| {
panic!("Unable to get attribute {}", attribute);
});
String::from(output)
}
fn hello_world(_: &mut Request) -> IronResult<Response> {
let greeting = Greeting { msg: "Hello, world!".to_string() };
let payload = json::encode(&greeting).unwrap();
Ok(Response::with((status::Ok, payload)))
}
// Receive a message by POST and play it back if auth-key is correct.
fn set_greeting(request: &mut Request) -> IronResult<Response> {
let mut payload = String::new();
request.body.read_to_string(&mut payload).unwrap();
let json = Json::from_str(&payload).unwrap();
println!("json: {}", json);
let msg = attr(payload, "msg");
println!("msg: {}", msg);
let greeting = Greeting { msg: String::from(msg) };
let payload = json::encode(&greeting).unwrap();
Ok(Response::with((status::Ok, payload)))
}
let mut router = Router::new();
router.get("/", hello_world);
router.post("/set", set_greeting);
let mut chain = Chain::new(router);
chain.link_before(Authentication);
Iron::new(chain).http("localhost:3000").unwrap();
}