Merge branch 'master' of https://github.com/SergioBenitez/Rocket into fix-64

This commit is contained in:
Jacob Brown 2017-07-27 09:26:46 -05:00
commit 8d93b9f30b
7 changed files with 57 additions and 16 deletions

View File

@ -77,6 +77,7 @@ impl RouteGenerateExt for RouteParams {
let $name: $ty = { let $name: $ty = {
let mut items = ::rocket::request::FormItems::from($form_string); let mut items = ::rocket::request::FormItems::from($form_string);
let form = ::rocket::request::FromForm::from_form(items.by_ref(), true); let form = ::rocket::request::FromForm::from_form(items.by_ref(), true);
#[allow(unreachable_patterns)]
let obj = match form { let obj = match form {
Ok(v) => v, Ok(v) => v,
Err(_) => return ::rocket::Outcome::Forward(__data) Err(_) => return ::rocket::Outcome::Forward(__data)
@ -162,6 +163,7 @@ impl RouteGenerateExt for RouteParams {
let original_ident = param.ident(); let original_ident = param.ident();
fn_param_statements.push(quote_stmt!(ecx, fn_param_statements.push(quote_stmt!(ecx,
#[allow(unreachable_patterns)]
let $ident: $ty = match $expr { let $ident: $ty = match $expr {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {

View File

@ -41,8 +41,8 @@ impl Engine for Tera {
Ok(string) => Some(string), Ok(string) => Some(string),
Err(e) => { Err(e) => {
error_!("Error rendering Tera template '{}'.", name); error_!("Error rendering Tera template '{}'.", name);
for error in e.iter().skip(1) { for error in e.iter() {
error_!("{}.", error); error_!("{}", error);
} }
None None

View File

@ -18,7 +18,7 @@ categories = ["web-programming::http-server"]
tls = ["rustls", "hyper-sync-rustls"] tls = ["rustls", "hyper-sync-rustls"]
[dependencies] [dependencies]
yansi = { version = "0.3", features = ["nightly"] } yansi = { version = "0.3.1", features = ["nightly"] }
log = "0.3" log = "0.3"
url = "1" url = "1"
toml = "0.4.2" toml = "0.4.2"

View File

@ -1,25 +1,29 @@
//! Borrowed and owned string types for absolute URIs. //! Borrowed and owned string types for absolute URIs.
use std::cell::Cell;
use std::convert::From; use std::convert::From;
use std::fmt; use std::fmt;
use std::borrow::Cow; use std::borrow::Cow;
use std::str::Utf8Error; use std::str::Utf8Error;
use std::sync::atomic::{AtomicIsize, Ordering};
use url; use url;
/// Index (start, end) into a string, to prevent borrowing. /// Index (start, end) into a string, to prevent borrowing.
type Index = (usize, usize); type Index = (usize, usize);
/// Representation of an empty segment count.
const EMPTY: isize = -1;
// TODO: Reconsider deriving PartialEq and Eq to make "//a/b" == "/a/b". // TODO: Reconsider deriving PartialEq and Eq to make "//a/b" == "/a/b".
/// Borrowed string type for absolute URIs. /// Borrowed string type for absolute URIs.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug)]
pub struct URI<'a> { pub struct URI<'a> {
uri: Cow<'a, str>, uri: Cow<'a, str>,
path: Index, path: Index,
query: Option<Index>, query: Option<Index>,
fragment: Option<Index>, fragment: Option<Index>,
segment_count: Cell<Option<usize>>, // The cached segment count. `EMPTY` is used to represent no segment count.
segment_count: AtomicIsize,
} }
impl<'a> URI<'a> { impl<'a> URI<'a> {
@ -43,7 +47,7 @@ impl<'a> URI<'a> {
path: path, path: path,
query: query, query: query,
fragment: fragment, fragment: fragment,
segment_count: Cell::new(None), segment_count: AtomicIsize::new(EMPTY),
} }
} }
@ -74,11 +78,17 @@ impl<'a> URI<'a> {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn segment_count(&self) -> usize { pub fn segment_count(&self) -> usize {
self.segment_count.get().unwrap_or_else(|| { let count = self.segment_count.load(Ordering::Relaxed);
let count = self.segments().count(); if count == EMPTY {
self.segment_count.set(Some(count)); let real_count = self.segments().count();
count if real_count <= isize::max_value() as usize {
}) self.segment_count.store(real_count as isize, Ordering::Relaxed);
}
real_count
} else {
count as usize
}
} }
/// Returns an iterator over the segments of the path in this URI. Skips /// Returns an iterator over the segments of the path in this URI. Skips
@ -275,6 +285,30 @@ impl<'a> URI<'a> {
} }
} }
impl<'a> Clone for URI<'a> {
#[inline(always)]
fn clone(&self) -> URI<'a> {
URI {
uri: self.uri.clone(),
path: self.path,
query: self.query,
fragment: self.fragment,
segment_count: AtomicIsize::new(EMPTY),
}
}
}
impl<'a, 'b> PartialEq<URI<'b>> for URI<'a> {
#[inline]
fn eq(&self, other: &URI<'b>) -> bool {
self.path() == other.path() &&
self.query() == other.query() &&
self.fragment() == other.fragment()
}
}
impl<'a> Eq for URI<'a> {}
impl<'a> From<&'a str> for URI<'a> { impl<'a> From<&'a str> for URI<'a> {
#[inline(always)] #[inline(always)]
fn from(uri: &'a str) -> URI<'a> { fn from(uri: &'a str) -> URI<'a> {
@ -312,8 +346,6 @@ impl<'a> fmt::Display for URI<'a> {
} }
} }
unsafe impl<'a> Sync for URI<'a> { /* It's safe! */ }
/// Iterator over the segments of an absolute URI path. Skips empty segments. /// Iterator over the segments of an absolute URI path. Skips empty segments.
/// ///
/// ### Examples /// ### Examples
@ -405,6 +437,12 @@ mod tests {
actual == expected actual == expected
} }
#[test]
fn send_and_sync() {
fn assert<T: Send + Sync>() {};
assert::<URI>();
}
#[test] #[test]
fn simple_segment_count() { fn simple_segment_count() {
assert!(seg_count("", 0)); assert!(seg_count("", 0));

View File

@ -143,6 +143,8 @@ impl Log for RocketLogger {
pub fn try_init(level: LoggingLevel, verbose: bool) { pub fn try_init(level: LoggingLevel, verbose: bool) {
if !::isatty::stdout_isatty() { if !::isatty::stdout_isatty() {
Paint::disable(); Paint::disable();
} else if cfg!(windows) {
Paint::enable_windows_ascii();
} }
let result = log::set_logger(|max_log_level| { let result = log::set_logger(|max_log_level| {

View File

@ -1,4 +1,4 @@
//! Contains types that set the status code and correspoding headers of a //! Contains types that set the status code and corresponding headers of a
//! response. //! response.
//! //!
//! These types are designed to make it easier to respond correctly with a given //! These types are designed to make it easier to respond correctly with a given

View File

@ -72,7 +72,6 @@ impl hyper::Handler for Rocket {
}; };
// Dispatch the request to get a response, then write that response out. // Dispatch the request to get a response, then write that response out.
// let req = UnsafeCell::new(req);
let response = self.dispatch(&mut req, data); let response = self.dispatch(&mut req, data);
self.issue_response(response, res) self.issue_response(response, res)
} }