mirror of https://github.com/rwf2/Rocket.git
Add support for flash cookie. Revamp cookie support.
This commit is contained in:
parent
9a9d07f044
commit
e8e85f09cd
|
@ -7,8 +7,8 @@ extern crate rocket;
|
||||||
extern crate tera;
|
extern crate tera;
|
||||||
|
|
||||||
use rocket::Rocket;
|
use rocket::Rocket;
|
||||||
use rocket::response::{Cookied, Redirect};
|
use rocket::response::Redirect;
|
||||||
use rocket::request::Cookies;
|
use rocket::request::{Cookie, Cookies};
|
||||||
|
|
||||||
lazy_static!(static ref TERA: tera::Tera = tera::Tera::new("templates/**/*"););
|
lazy_static!(static ref TERA: tera::Tera = tera::Tera::new("templates/**/*"););
|
||||||
|
|
||||||
|
@ -25,12 +25,13 @@ struct Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/submit", form = "<message>")]
|
#[post("/submit", form = "<message>")]
|
||||||
fn submit(message: Message) -> Cookied<Redirect> {
|
fn submit(cookies: &Cookies, message: Message) -> Redirect {
|
||||||
Cookied::new(Redirect::to("/")).add("message", &message.message)
|
cookies.add(Cookie::new("message".into(), message.message));
|
||||||
|
Redirect::to("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn index(cookies: Cookies) -> tera::TeraResult<String> {
|
fn index(cookies: &Cookies) -> tera::TeraResult<String> {
|
||||||
let message = cookies.find("message").map(|msg| msg.value);
|
let message = cookies.find("message").map(|msg| msg.value);
|
||||||
TERA.render("index.html", ctxt(message))
|
TERA.render("index.html", ctxt(message))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,28 +11,30 @@ mod static_files;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
use rocket::Rocket;
|
use rocket::Rocket;
|
||||||
use rocket::response::Redirect;
|
use rocket::response::{Flash, Redirect};
|
||||||
use task::Task;
|
use task::Task;
|
||||||
|
|
||||||
lazy_static!(static ref TERA: tera::Tera = tera::Tera::new("templates/**/*"););
|
lazy_static!(static ref TERA: tera::Tera = tera::Tera::new("static/*.html"););
|
||||||
|
|
||||||
fn ctxt(error: Option<&str>) -> tera::Context {
|
fn ctxt(msg: Option<(&str, &str)>) -> tera::Context {
|
||||||
|
let unwrapped_msg = msg.unwrap_or(("", ""));
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
context.add("error", &error.is_some());
|
context.add("has_msg", &msg.is_some());
|
||||||
context.add("msg", &error.unwrap_or("").to_string());
|
context.add("msg_type", &unwrapped_msg.0.to_string());
|
||||||
|
context.add("msg", &unwrapped_msg.1.to_string());
|
||||||
context.add("tasks", &Task::all());
|
context.add("tasks", &Task::all());
|
||||||
context
|
context
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/", form = "<todo>")]
|
#[post("/", form = "<todo>")]
|
||||||
fn new(todo: Task) -> Result<Redirect, tera::TeraResult<String>> {
|
fn new(todo: Task) -> Result<Flash<Redirect>, tera::TeraResult<String>> {
|
||||||
if todo.description.is_empty() {
|
if todo.description.is_empty() {
|
||||||
let context = ctxt(Some("Description cannot be empty."));
|
let context = ctxt(Some(("error", "Description cannot be empty.")));
|
||||||
Err(TERA.render("index.html", context))
|
Err(TERA.render("index.html", context))
|
||||||
} else if todo.insert() {
|
} else if todo.insert() {
|
||||||
Ok(Redirect::to("/")) // Say that it was added...somehow.
|
Ok(Flash::success(Redirect::to("/"), "Todo successfully added."))
|
||||||
} else {
|
} else {
|
||||||
let context = ctxt(Some("Whoops! The server failed."));
|
let context = ctxt(Some(("error", "Whoops! The server failed.")));
|
||||||
Err(TERA.render("index.html", context))
|
Err(TERA.render("index.html", context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,32 +43,32 @@ fn new(todo: Task) -> Result<Redirect, tera::TeraResult<String>> {
|
||||||
#[get("/<id>/toggle")]
|
#[get("/<id>/toggle")]
|
||||||
fn toggle(id: i32) -> Result<Redirect, tera::TeraResult<String>> {
|
fn toggle(id: i32) -> Result<Redirect, tera::TeraResult<String>> {
|
||||||
if Task::toggle_with_id(id) {
|
if Task::toggle_with_id(id) {
|
||||||
Ok(Redirect::to("/")) // Say that it was added...somehow.
|
Ok(Redirect::to("/"))
|
||||||
} else {
|
} else {
|
||||||
let context = ctxt(Some("Could not toggle that task."));
|
let context = ctxt(Some(("error", "Could not toggle that task.")));
|
||||||
Err(TERA.render("index.html", context))
|
Err(TERA.render("index.html", context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should likely do something to simulate DELETE.
|
// Should likely do something to simulate DELETE.
|
||||||
#[get("/<id>/delete")]
|
#[get("/<id>/delete")]
|
||||||
fn delete(id: i32) -> Result<Redirect, tera::TeraResult<String>> {
|
fn delete(id: i32) -> Result<Flash<Redirect>, tera::TeraResult<String>> {
|
||||||
if Task::delete_with_id(id) {
|
if Task::delete_with_id(id) {
|
||||||
Ok(Redirect::to("/")) // Say that it was added...somehow.
|
Ok(Flash::success(Redirect::to("/"), "Todo was deleted."))
|
||||||
} else {
|
} else {
|
||||||
let context = ctxt(Some("Could not delete that task."));
|
let context = ctxt(Some(("error", "Could not delete that task.")));
|
||||||
Err(TERA.render("index.html", context))
|
Err(TERA.render("index.html", context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn index() -> tera::TeraResult<String> {
|
fn index(msg: Option<Flash<()>>) -> tera::TeraResult<String> {
|
||||||
TERA.render("index.html", ctxt(None))
|
TERA.render("index.html", ctxt(msg.as_ref().map(|m| (m.name(), m.msg()))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut rocket = Rocket::new("127.0.0.1", 8000);
|
let mut rocket = Rocket::new("127.0.0.1", 8000);
|
||||||
rocket.mount("/", routes![index, static_files::all, static_files::all_level_one]);
|
rocket.mount("/", routes![index, static_files::all])
|
||||||
rocket.mount("/todo/", routes![new, delete, toggle]);
|
.mount("/todo/", routes![new, delete, toggle]);
|
||||||
rocket.launch();
|
rocket.launch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[get("/<top>/<file>")]
|
#[get("/<path..>", rank = 5)]
|
||||||
fn all_level_one(top: &str, file: &str) -> io::Result<File> {
|
fn all(path: PathBuf) -> io::Result<File> {
|
||||||
let file = format!("static/{}/{}", top, file);
|
File::open(Path::new("static/").join(path))
|
||||||
File::open(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/<file>")]
|
|
||||||
fn all(file: &str) -> io::Result<File> {
|
|
||||||
let file = format!("static/{}", file);
|
|
||||||
File::open(file)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,9 @@ impl Task {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::update_with_id(id, !task.unwrap().completed.unwrap())
|
let new_status = !task.unwrap().completed.unwrap();
|
||||||
}
|
let updated_task = diesel::update(all_tasks.find(id));
|
||||||
|
updated_task.set(task_completed.eq(new_status)).execute(&db()).is_ok()
|
||||||
pub fn update_with_id(id: i32, completed: bool) -> bool {
|
|
||||||
let task = diesel::update(all_tasks.find(id));
|
|
||||||
task.set(task_completed.eq(completed)).execute(&db()).is_ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_with_id(id: i32) -> bool {
|
pub fn delete_with_id(id: i32) -> bool {
|
||||||
|
|
|
@ -8,6 +8,16 @@
|
||||||
margin: -10px 0 10px 0;
|
margin: -10px 0 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-success {
|
||||||
|
border: 1px solid #5AB953 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-success-msg {
|
||||||
|
color: #5AB953;
|
||||||
|
display: block;
|
||||||
|
margin: -10px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
span.completed {
|
span.completed {
|
||||||
text-decoration: line-through;
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
<div class="ten columns">
|
<div class="ten columns">
|
||||||
<input type="text" placeholder="enter a task description..."
|
<input type="text" placeholder="enter a task description..."
|
||||||
name="description" id="description" value="" autofocus
|
name="description" id="description" value="" autofocus
|
||||||
class="u-full-width {% if error %}field-error{% endif %}" />
|
class="u-full-width {% if has_msg %}field-{{msg_type}}{% endif %}" />
|
||||||
{% if error %}
|
{% if has_msg %}
|
||||||
<small class="field-error-msg">
|
<small class="field-{{msg_type}}-msg">
|
||||||
{{ msg }}
|
{{ msg }}
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
|
@ -9,7 +9,3 @@ log = "*"
|
||||||
hyper = "*"
|
hyper = "*"
|
||||||
url = "*"
|
url = "*"
|
||||||
mime = "*"
|
mime = "*"
|
||||||
|
|
||||||
# [dependencies.hyper]
|
|
||||||
# git = "https://github.com/hyperium/hyper.git"
|
|
||||||
# branch = "mio"
|
|
||||||
|
|
|
@ -25,15 +25,10 @@ impl<'r, 'c> FromRequest<'r, 'c> for Method {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r, 'c> FromRequest<'r, 'c> for Cookies {
|
impl<'r, 'c> FromRequest<'r, 'c> for &'r Cookies {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(request: &'r Request<'c>) -> Result<Self, Self::Error> {
|
fn from_request(request: &'r Request<'c>) -> Result<Self, Self::Error> {
|
||||||
match request.headers().get::<HyperCookie>() {
|
Ok(request.cookies())
|
||||||
// TODO: What to do about key?
|
|
||||||
Some(cookie) => Ok(cookie.to_cookie_jar(&[])),
|
|
||||||
None => Ok(Cookies::new(&[]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,5 @@ pub use hyper::header::Headers as HyperHeaders;
|
||||||
pub use hyper::header::Cookie as HyperCookie;
|
pub use hyper::header::Cookie as HyperCookie;
|
||||||
use hyper::header::CookieJar;
|
use hyper::header::CookieJar;
|
||||||
|
|
||||||
|
pub use hyper::header::CookiePair as Cookie;
|
||||||
pub type Cookies = CookieJar<'static>;
|
pub type Cookies = CookieJar<'static>;
|
||||||
|
|
|
@ -17,18 +17,19 @@ use router::URI;
|
||||||
use router::Route;
|
use router::Route;
|
||||||
|
|
||||||
// Hyper stuff.
|
// Hyper stuff.
|
||||||
use request::{HyperHeaders, HyperRequest};
|
use request::{Cookies, HyperCookie, HyperHeaders, HyperRequest};
|
||||||
|
|
||||||
pub struct Request<'a> {
|
pub struct Request<'a> {
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
pub uri: URIBuf, // FIXME: Should be URI (without Hyper).
|
pub uri: URIBuf, // FIXME: Should be URI (without Hyper).
|
||||||
pub data: Vec<u8>, // FIXME: Don't read this! (bad Hyper.)
|
pub data: Vec<u8>, // FIXME: Don't read this! (bad Hyper.)
|
||||||
params: RefCell<Option<Vec<&'a str>>>, // This also sucks.
|
cookies: Cookies,
|
||||||
headers: HyperHeaders, // This sucks.
|
headers: HyperHeaders, // This sucks.
|
||||||
|
params: RefCell<Option<Vec<&'a str>>>, // This also sucks.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Request<'a> {
|
impl<'a> Request<'a> {
|
||||||
// FIXME: Don't do the parsing here. I think. Not sure. Decide.
|
// FIXME: Don't do the from_param parsing here. I think. Not sure. Decide.
|
||||||
pub fn get_param<T: FromParam<'a>>(&self, n: usize) -> Result<T, Error> {
|
pub fn get_param<T: FromParam<'a>>(&self, n: usize) -> Result<T, Error> {
|
||||||
let params = self.params.borrow();
|
let params = self.params.borrow();
|
||||||
if params.is_none() || n >= params.as_ref().unwrap().len() {
|
if params.is_none() || n >= params.as_ref().unwrap().len() {
|
||||||
|
@ -39,6 +40,10 @@ impl<'a> Request<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cookies<'r>(&'r self) -> &'r Cookies {
|
||||||
|
&self.cookies
|
||||||
|
}
|
||||||
|
|
||||||
/// i is the index of the first segment to consider
|
/// i is the index of the first segment to consider
|
||||||
pub fn get_segments<'r: 'a, T: FromSegments<'a>>(&'r self, i: usize)
|
pub fn get_segments<'r: 'a, T: FromSegments<'a>>(&'r self, i: usize)
|
||||||
-> Result<T, Error> {
|
-> Result<T, Error> {
|
||||||
|
@ -58,6 +63,7 @@ impl<'a> Request<'a> {
|
||||||
Request {
|
Request {
|
||||||
params: RefCell::new(None),
|
params: RefCell::new(None),
|
||||||
method: method,
|
method: method,
|
||||||
|
cookies: Cookies::new(&[]),
|
||||||
uri: URIBuf::from(uri),
|
uri: URIBuf::from(uri),
|
||||||
data: vec![],
|
data: vec![],
|
||||||
headers: HyperHeaders::new()
|
headers: HyperHeaders::new()
|
||||||
|
@ -118,6 +124,12 @@ impl<'a> Request<'a> {
|
||||||
_ => return Err(format!("Bad method: {}", h_method))
|
_ => return Err(format!("Bad method: {}", h_method))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cookies = match h_headers.get::<HyperCookie>() {
|
||||||
|
// TODO: What to do about key?
|
||||||
|
Some(cookie) => cookie.to_cookie_jar(&[]),
|
||||||
|
None => Cookies::new(&[])
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME: GRRR.
|
// FIXME: GRRR.
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
h_body.read_to_end(&mut data).unwrap();
|
h_body.read_to_end(&mut data).unwrap();
|
||||||
|
@ -125,6 +137,7 @@ impl<'a> Request<'a> {
|
||||||
let request = Request {
|
let request = Request {
|
||||||
params: RefCell::new(None),
|
params: RefCell::new(None),
|
||||||
method: method,
|
method: method,
|
||||||
|
cookies: cookies,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
data: data,
|
data: data,
|
||||||
headers: h_headers,
|
headers: h_headers,
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
use response::*;
|
|
||||||
use std::string::ToString;
|
|
||||||
use hyper::header::{SetCookie, CookiePair};
|
|
||||||
|
|
||||||
pub struct Cookied<R: Responder> {
|
|
||||||
cookies: Option<Vec<CookiePair>>,
|
|
||||||
responder: R
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Responder> Cookied<R> {
|
|
||||||
pub fn new(responder: R) -> Cookied<R> {
|
|
||||||
Cookied {
|
|
||||||
cookies: None,
|
|
||||||
responder: responder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pairs(responder: R, pairs: &[(&ToString, &ToString)]) -> Cookied<R> {
|
|
||||||
Cookied {
|
|
||||||
cookies: Some(
|
|
||||||
pairs.iter()
|
|
||||||
.map(|p| CookiePair::new(p.0.to_string(), p.1.to_string()))
|
|
||||||
.collect()
|
|
||||||
),
|
|
||||||
responder: responder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn add<A: ToString, B: ToString>(mut self, a: A, b: B) -> Self {
|
|
||||||
let new_pair = CookiePair::new(a.to_string(), b.to_string());
|
|
||||||
match self.cookies {
|
|
||||||
Some(ref mut pairs) => pairs.push(new_pair),
|
|
||||||
None => self.cookies = Some(vec![new_pair])
|
|
||||||
};
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Responder> Responder for Cookied<R> {
|
|
||||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
|
||||||
if let Some(pairs) = self.cookies.take() {
|
|
||||||
res.headers_mut().set(SetCookie(pairs));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.responder.respond(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
use response::*;
|
||||||
|
use std::convert::AsRef;
|
||||||
|
use hyper::header::{SetCookie, CookiePair};
|
||||||
|
use request::{Request, FromRequest};
|
||||||
|
|
||||||
|
pub struct Flash<R> {
|
||||||
|
name: String,
|
||||||
|
message: String,
|
||||||
|
responder: R
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Responder> Flash<R> {
|
||||||
|
pub fn new<N: AsRef<str>, M: AsRef<str>>(res: R, name: N, msg: M) -> Flash<R> {
|
||||||
|
Flash {
|
||||||
|
name: name.as_ref().to_string(),
|
||||||
|
message: msg.as_ref().to_string(),
|
||||||
|
responder: res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn warning<S: AsRef<str>>(responder: R, msg: S) -> Flash<R> {
|
||||||
|
Flash::new(responder, "warning", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn success<S: AsRef<str>>(responder: R, msg: S) -> Flash<R> {
|
||||||
|
Flash::new(responder, "success", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn error<S: AsRef<str>>(responder: R, msg: S) -> Flash<R> {
|
||||||
|
Flash::new(responder, "error", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cookie_pair(&self) -> CookiePair {
|
||||||
|
let content = format!("{}{}{}", self.name.len(), self.name, self.message);
|
||||||
|
let mut pair = CookiePair::new("flash".to_string(), content);
|
||||||
|
pair.path = Some("/".to_string());
|
||||||
|
pair.max_age = Some(300);
|
||||||
|
pair
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Responder> Responder for Flash<R> {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
trace_!("Flash: setting message: {}:{}", self.name, self.message);
|
||||||
|
res.headers_mut().set(SetCookie(vec![self.cookie_pair()]));
|
||||||
|
self.responder.respond(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flash<()> {
|
||||||
|
fn named(name: &str, msg: &str) -> Flash<()> {
|
||||||
|
Flash {
|
||||||
|
name: name.to_string(),
|
||||||
|
message: msg.to_string(),
|
||||||
|
responder: (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn msg(&self) -> &str {
|
||||||
|
self.message.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Using Flash<()> is ugly. Either create a type FlashMessage = Flash<()>
|
||||||
|
// or create a Flash under request that does this.
|
||||||
|
// TODO: Consider not removing the 'flash' cookie until after this thing is
|
||||||
|
// dropped. This is because, at the moment, if Flash is including as a
|
||||||
|
// from_request param, and some other param fails, then the flash message will
|
||||||
|
// be dropped needlessly. This may or may not be the intended behavior.
|
||||||
|
// Alternatively, provide a guarantee about the order that from_request params
|
||||||
|
// will be evaluated and recommend that Flash is last.
|
||||||
|
impl<'r, 'c> FromRequest<'r, 'c> for Flash<()> {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn from_request(request: &'r Request<'c>) -> Result<Self, Self::Error> {
|
||||||
|
trace_!("Flash: attemping to retrieve message.");
|
||||||
|
request.cookies().find("flash").ok_or(()).and_then(|cookie| {
|
||||||
|
// Clear the flash message.
|
||||||
|
trace_!("Flash: retrieving message: {:?}", cookie);
|
||||||
|
request.cookies().remove("flash");
|
||||||
|
|
||||||
|
// Parse the flash.
|
||||||
|
let content = cookie.pair().1;
|
||||||
|
let (len_str, rest) = match content.find(|c: char| !c.is_digit(10)) {
|
||||||
|
Some(i) => (&content[..i], &content[i..]),
|
||||||
|
None => (content, "")
|
||||||
|
};
|
||||||
|
|
||||||
|
let name_len: usize = len_str.parse().map_err(|_| ())?;
|
||||||
|
let (name, msg) = (&rest[..name_len], &rest[name_len..]);
|
||||||
|
Ok(Flash::named(name, msg))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ mod responder;
|
||||||
mod redirect;
|
mod redirect;
|
||||||
mod with_status;
|
mod with_status;
|
||||||
mod outcome;
|
mod outcome;
|
||||||
mod cookied;
|
mod flash;
|
||||||
mod data_type;
|
mod data_type;
|
||||||
|
|
||||||
pub use hyper::server::Response as HyperResponse;
|
pub use hyper::server::Response as HyperResponse;
|
||||||
|
@ -18,7 +18,7 @@ pub use self::empty::{Empty, Forward};
|
||||||
pub use self::redirect::Redirect;
|
pub use self::redirect::Redirect;
|
||||||
pub use self::with_status::StatusResponse;
|
pub use self::with_status::StatusResponse;
|
||||||
pub use self::outcome::Outcome;
|
pub use self::outcome::Outcome;
|
||||||
pub use self::cookied::Cookied;
|
pub use self::flash::Flash;
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ use term_painter::ToStyle;
|
||||||
|
|
||||||
use hyper::server::Server as HyperServer;
|
use hyper::server::Server as HyperServer;
|
||||||
use hyper::server::Handler as HyperHandler;
|
use hyper::server::Handler as HyperHandler;
|
||||||
|
use hyper::header::SetCookie;
|
||||||
|
|
||||||
pub struct Rocket {
|
pub struct Rocket {
|
||||||
address: String,
|
address: String,
|
||||||
|
@ -49,8 +50,12 @@ impl Rocket {
|
||||||
info_!("Matched: {}", route);
|
info_!("Matched: {}", route);
|
||||||
request.set_params(route);
|
request.set_params(route);
|
||||||
|
|
||||||
// Here's the magic: dispatch the request to the handler.
|
// Dispatch the request to the handler and update the cookies.
|
||||||
let outcome = (route.handler)(&request).respond(res);
|
let mut responder = (route.handler)(&request);
|
||||||
|
res.headers_mut().set(SetCookie(request.cookies().delta()));
|
||||||
|
|
||||||
|
// Get the response.
|
||||||
|
let outcome = responder.respond(res);
|
||||||
info_!("{} {}", White.paint("Outcome:"), outcome);
|
info_!("{} {}", White.paint("Outcome:"), outcome);
|
||||||
|
|
||||||
// Get the result if we failed so we can try again.
|
// Get the result if we failed so we can try again.
|
||||||
|
|
|
@ -39,12 +39,12 @@ impl Router {
|
||||||
// let num_segments = req.uri.segment_count();
|
// let num_segments = req.uri.segment_count();
|
||||||
// self.routes.get(&(req.method, num_segments)).map_or(vec![], |routes| {
|
// self.routes.get(&(req.method, num_segments)).map_or(vec![], |routes| {
|
||||||
self.routes.get(&req.method).map_or(vec![], |routes| {
|
self.routes.get(&req.method).map_or(vec![], |routes| {
|
||||||
trace_!("All possible matches: {:?}", routes);
|
|
||||||
let mut matches: Vec<_> = routes.iter().filter(|r| {
|
let mut matches: Vec<_> = routes.iter().filter(|r| {
|
||||||
r.collides_with(req)
|
r.collides_with(req)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
matches.sort_by(|a, b| a.rank.cmp(&b.rank));
|
matches.sort_by(|a, b| a.rank.cmp(&b.rank));
|
||||||
|
trace_!("All matches: {:?}", matches);
|
||||||
matches
|
matches
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue