mirror of https://github.com/rwf2/Rocket.git
parent
31cca896f4
commit
cd4af6836a
|
@ -105,7 +105,6 @@ impl RouteGenerateExt for RouteParams {
|
|||
let param = self.query_param.as_ref();
|
||||
let expr = quote_expr!(ecx,
|
||||
match _req.uri().query() {
|
||||
// FIXME: Don't reinterpret as UTF8 again.
|
||||
Some(query) => query,
|
||||
None => return ::rocket::Response::forward()
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
|
||||
register_decorators!(reg,
|
||||
"derive_FromForm" => from_form_derive,
|
||||
"error" => error_decorator,
|
||||
|
||||
"error" => error_decorator,
|
||||
"route" => route_decorator,
|
||||
"get" => get_decorator,
|
||||
"put" => put_decorator,
|
||||
|
|
|
@ -40,7 +40,7 @@ fn new(todo: Task) -> Result<Flash<Redirect>, Template> {
|
|||
}
|
||||
|
||||
// Should likely do something to simulate PUT.
|
||||
#[get("/<id>/toggle")]
|
||||
#[put("/<id>")]
|
||||
fn toggle(id: i32) -> Result<Redirect, Template> {
|
||||
if Task::toggle_with_id(id) {
|
||||
Ok(Redirect::to("/"))
|
||||
|
@ -50,7 +50,7 @@ fn toggle(id: i32) -> Result<Redirect, Template> {
|
|||
}
|
||||
|
||||
// Should likely do something to simulate DELETE.
|
||||
#[get("/<id>/delete")]
|
||||
#[delete("/<id>")]
|
||||
fn delete(id: i32) -> Result<Flash<Redirect>, Template> {
|
||||
if Task::delete_with_id(id) {
|
||||
Ok(Flash::success(Redirect::to("/"), "Todo was deleted."))
|
||||
|
|
|
@ -202,6 +202,7 @@ input[type="button"]:focus {
|
|||
outline: 0; }
|
||||
.button.button-primary,
|
||||
button.button-primary,
|
||||
button.primary,
|
||||
input[type="submit"].button-primary,
|
||||
input[type="reset"].button-primary,
|
||||
input[type="button"].button-primary {
|
||||
|
@ -210,11 +211,13 @@ input[type="button"].button-primary {
|
|||
border-color: #33C3F0; }
|
||||
.button.button-primary:hover,
|
||||
button.button-primary:hover,
|
||||
button.primary:hover,
|
||||
input[type="submit"].button-primary:hover,
|
||||
input[type="reset"].button-primary:hover,
|
||||
input[type="button"].button-primary:hover,
|
||||
.button.button-primary:focus,
|
||||
button.button-primary:focus,
|
||||
button.primary:focus,
|
||||
input[type="submit"].button-primary:focus,
|
||||
input[type="reset"].button-primary:focus,
|
||||
input[type="button"].button-primary:focus {
|
||||
|
|
|
@ -21,3 +21,38 @@
|
|||
span.completed {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
form.inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
form.link,
|
||||
button.link {
|
||||
display: inline;
|
||||
color: #1EAEDB;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0 0 0 0;
|
||||
height: inherit;
|
||||
text-decoration: underline;
|
||||
font-size: inherit;
|
||||
text-transform: none;
|
||||
font-weight: normal;
|
||||
line-height: inherit;
|
||||
letter-spacing: inherit;
|
||||
}
|
||||
|
||||
form.link:hover, button.link:hover {
|
||||
color: #0FA0CE;
|
||||
}
|
||||
|
||||
button.small {
|
||||
height: 20px;
|
||||
padding: 0 10px;
|
||||
font-size: 10px;
|
||||
line-height: 20px;
|
||||
margin: 0 2.5px;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<div class="row">
|
||||
<h4>Rocket Todo</h4>
|
||||
<form action="/todo" method="post" accept-charset="utf-8">
|
||||
<form action="/todo" method="post">
|
||||
<div class="ten columns">
|
||||
<input type="text" placeholder="enter a task description..."
|
||||
name="description" id="description" value="" autofocus
|
||||
|
@ -43,12 +43,21 @@
|
|||
{% if task.completed %}
|
||||
<li>
|
||||
<span class="completed">{{ task.description }}</span>
|
||||
<a href="/todo/{{ task.id }}/toggle">undo</a>
|
||||
<a href="/todo/{{ task.id }}/delete">delete</a>
|
||||
<form class="inline" action="/todo/{{task.id}}" method="post">
|
||||
<input type="hidden" name="_method" value="put" />
|
||||
<button class="small" type="submit">undo</button>
|
||||
</form>
|
||||
<form class="inline" action="/todo/{{task.id}}" method="post">
|
||||
<input type="hidden" name="_method" value="delete" />
|
||||
<button class="primary small" type="submit">delete</button>
|
||||
</form>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a href="/todo/{{ task.id }}/toggle">{{ task.description }}</a>
|
||||
<form class="link" action="/todo/{{task.id}}" method="post">
|
||||
<input type="hidden" name="_method" value="put" />
|
||||
<button class="link" type="submit">{{ task.description }}</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -49,6 +49,8 @@ impl ContentType {
|
|||
is_some!(is_xml: Application/Xml);
|
||||
is_some!(is_any: Star/Star);
|
||||
is_some!(is_html: Application/Html);
|
||||
is_some!(is_form: Application/WwwFormUrlEncoded);
|
||||
is_some!(is_data: Multipart/FormData);
|
||||
}
|
||||
|
||||
impl Default for ContentType {
|
||||
|
|
|
@ -48,15 +48,15 @@ impl FromStr for Method {
|
|||
|
||||
fn from_str(s: &str) -> Result<Method, Error> {
|
||||
match s {
|
||||
"GET" => Ok(Get),
|
||||
"PUT" => Ok(Put),
|
||||
"POST" => Ok(Post),
|
||||
"DELETE" => Ok(Delete),
|
||||
"OPTIONS" => Ok(Options),
|
||||
"HEAD" => Ok(Head),
|
||||
"TRACE" => Ok(Trace),
|
||||
"CONNECT" => Ok(Connect),
|
||||
"PATCH" => Ok(Patch),
|
||||
"GET" | "get" => Ok(Get),
|
||||
"PUT" | "put" => Ok(Put),
|
||||
"POST" | "post" => Ok(Post),
|
||||
"DELETE" | "delete" => Ok(Delete),
|
||||
"OPTIONS" | "options" => Ok(Options),
|
||||
"HEAD" | "head" => Ok(Head),
|
||||
"TRACE" | "trace" => Ok(Trace),
|
||||
"CONNECT" | "connect" => Ok(Connect),
|
||||
"PATCH" | "patch" => Ok(Patch),
|
||||
_ => Err(Error::BadMethod),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ use request::HyperRequest;
|
|||
use catcher;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::str::from_utf8_unchecked;
|
||||
use std::cmp::min;
|
||||
|
||||
use term_painter::Color::*;
|
||||
use term_painter::ToStyle;
|
||||
|
@ -36,7 +38,10 @@ impl Rocket {
|
|||
|
||||
// Try to create a Rocket request from the hyper request.
|
||||
let request = match Request::from_hyp(hyp_req) {
|
||||
Ok(req) => req,
|
||||
Ok(mut req) => {
|
||||
self.preprocess_request(&mut req);
|
||||
req
|
||||
},
|
||||
Err(ref reason) => {
|
||||
let mock_request = Request::mock(Method::Get, uri.as_str());
|
||||
debug_!("Bad request: {}", reason);
|
||||
|
@ -74,6 +79,27 @@ impl Rocket {
|
|||
self.handle_not_found(&request, res);
|
||||
}
|
||||
|
||||
/// Preprocess the request for Rocket-specific things. At this time, we're
|
||||
/// only checking for _method in forms.
|
||||
fn preprocess_request(&self, req: &mut Request) {
|
||||
// Check if this is a form and if the form contains the special _method
|
||||
// field which we use to reinterpret the request's method.
|
||||
let data_len = req.data.len();
|
||||
let (min_len, max_len) = ("_method=get".len(), "_method=delete".len());
|
||||
if req.content_type().is_form() && data_len >= min_len {
|
||||
let form = unsafe {
|
||||
from_utf8_unchecked(&req.data.as_slice()[..min(data_len, max_len)])
|
||||
};
|
||||
|
||||
let mut form_items = form::FormItems(form);
|
||||
if let Some(("_method", value)) = form_items.next() {
|
||||
if let Ok(method) = value.parse() {
|
||||
req.method = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call on internal server error.
|
||||
fn handle_internal_error<'r>(&self, request: &'r Request<'r>,
|
||||
response: FreshHyperResponse) {
|
||||
|
|
Loading…
Reference in New Issue