Split the 'http' module into its own 'rocket_http' crate.

This commit is contained in:
Sergio Benitez 2018-06-07 15:34:47 +02:00
parent 900e716ea6
commit df7111143e
44 changed files with 432 additions and 203 deletions

View File

@ -6,6 +6,7 @@ members = [
"core/lib/",
"core/codegen/",
"core/codegen_next/",
"core/http/",
"contrib/lib",
"examples/cookies",
"examples/errors",

View File

@ -15,12 +15,12 @@ build = "build.rs"
plugin = true
[dependencies]
rocket = { version = "0.4.0-dev", path = "../lib/" }
rocket_http = { version = "0.4.0-dev", path = "../http" }
indexmap = "1.0"
log = "0.4"
[dev-dependencies]
compiletest_rs = "0.3.5"
rocket = { version = "0.4.0-dev", path = "../lib" }
[build-dependencies]
yansi = "0.4"

View File

@ -15,10 +15,10 @@ use syntax::parse::token;
use syntax::symbol::LocalInternedString;
use syntax::ptr::P;
use rocket::http::{Method, MediaType};
use rocket_http::{Method, MediaType};
fn method_to_path(ecx: &ExtCtxt, method: Method) -> Path {
quote_enum!(ecx, method => ::rocket::http::Method {
quote_enum!(ecx, method => ::rocket_http::Method -> ::rocket::http::Method {
Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch;
})
}

View File

@ -222,12 +222,11 @@
//! ```
#[macro_use] extern crate log;
extern crate syntax;
extern crate syntax_ext;
extern crate syntax_pos;
extern crate rustc_plugin;
extern crate rocket;
extern crate rocket_http;
extern crate indexmap;
#[macro_use] mod utils;
@ -235,7 +234,6 @@ mod parser;
mod macros;
mod decorators;
use std::env;
use rustc_plugin::Registry;
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
@ -279,11 +277,6 @@ macro_rules! register_macros {
/// Compiler hook for Rust to register plugins.
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
// Enable logging early if the DEBUG_ENV_VAR is set.
if env::var(DEBUG_ENV_VAR).is_ok() {
::rocket::logger::init(::rocket::config::LoggingLevel::Debug);
}
register_macros!(reg,
"routes" => routes,
"catchers" => catchers,

View File

@ -2,7 +2,7 @@ use syntax::ast::*;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::codemap::{Span, Spanned, dummy_spanned};
use rocket::http::Status;
use rocket_http::Status;
use utils::{span, MetaItemExt};
use super::Function;

View File

@ -9,8 +9,8 @@ use utils::{MetaItemExt, SpanExt, span, is_valid_ident};
use super::Function;
use super::keyvalue::KVSpanned;
use super::uri::validate_uri;
use rocket::http::{Method, MediaType};
use rocket::http::uri::Uri;
use rocket_http::{Method, MediaType};
use rocket_http::uri::Uri;
/// This structure represents the parsed `route` attribute.
///
@ -131,7 +131,7 @@ impl RouteParams {
}
fn is_valid_method(method: Method) -> bool {
use rocket::http::Method::*;
use rocket_http::Method::*;
match method {
Get | Put | Post | Delete | Head | Patch | Options => true,
Trace | Connect => false

View File

@ -2,7 +2,7 @@ use syntax::ast::*;
use syntax::codemap::{Span, Spanned, dummy_spanned};
use syntax::ext::base::ExtCtxt;
use rocket::http::uri::Uri;
use rocket_http::uri::Uri;
use super::route::param_to_ident;
use utils::{span, SpanExt, is_valid_ident};

View File

@ -27,6 +27,17 @@ use syntax::fold::Folder;
use syntax::attr::HasAttrs;
use syntax::ptr::P;
macro_rules! debug {
($($t:tt)*) => (
// Enable debug logs if the DEBUG_ENV_VAR is set.
if ::std::env::var(::DEBUG_ENV_VAR).is_ok() {
eprintln!("--> {}:{} ({})", file!(), line!(), module_path!());
eprintln!($($t)*);
eprintln!();
}
)
}
pub fn span<T>(t: T, span: Span) -> Spanned<T> {
Spanned { node: t, span: span }
}
@ -133,12 +144,12 @@ pub fn split_idents(path: &str) -> Vec<Ident> {
}
macro_rules! quote_enum {
($ecx:expr, $var:expr => $(::$root:ident)+
($ecx:expr, $var:expr => $(::$from_root:ident)+ -> $(::$to_root:ident)+
{ $($variant:ident),+ ; $($extra:pat => $result:expr),* }) => ({
use syntax::codemap::DUMMY_SP;
use syntax::ast::Ident;
use $(::$root)+::*;
let root_idents = vec![$(Ident::from_str(stringify!($root))),+];
use $(::$from_root)+::*;
let root_idents = vec![$(Ident::from_str(stringify!($to_root))),+];
match $var {
$($variant => {
let variant = Ident::from_str(stringify!($variant));

40
core/http/Cargo.toml Normal file
View File

@ -0,0 +1,40 @@
[package]
name = "rocket_http"
version = "0.4.0-dev"
authors = ["Sergio Benitez <sb@sergio.bz>"]
description = """
Types, traits, and parsers for HTTP requests, responses, and headers.
"""
documentation = "https://api.rocket.rs/rocket_http/"
homepage = "https://rocket.rs"
repository = "https://github.com/SergioBenitez/Rocket"
readme = "../../README.md"
keywords = ["rocket", "web", "framework", "http"]
license = "MIT/Apache-2.0"
categories = ["web-programming"]
[features]
tls = ["rustls", "hyper-sync-rustls"]
[dependencies]
pear = { git = "http://github.com/SergioBenitez/Pear", rev = "54667ae" }
smallvec = "0.6"
percent-encoding = "1"
hyper = { version = "0.10.13", default-features = false }
time = "0.1"
indexmap = "1.0"
rustls = { version = "0.12.0", optional = true }
[dependencies.cookie]
git = "https://github.com/alexcrichton/cookie-rs"
rev = "0365a18"
features = ["percent-encode", "secure"]
[dependencies.hyper-sync-rustls]
version = "=0.3.0-rc.2"
features = ["server"]
optional = true
[dev-dependencies]
rocket = { version = "0.4.0-dev", path = "../lib" }
rocket_codegen = { version = "0.4.0-dev", path = "../codegen" }

View File

@ -4,9 +4,9 @@ use std::fmt;
use smallvec::SmallVec;
use {Header, MediaType};
use ext::IntoCollection;
use http::{Header, MediaType};
use http::parse::parse_accept;
use parse::parse_accept;
/// A `MediaType` with an associated quality value.
#[derive(Debug, Clone, PartialEq)]
@ -18,6 +18,7 @@ impl QMediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{MediaType, QMediaType};
///
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
@ -33,6 +34,7 @@ impl QMediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{MediaType, QMediaType};
///
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
@ -51,6 +53,7 @@ impl QMediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{MediaType, QMediaType};
///
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
@ -139,6 +142,7 @@ impl PartialEq for AcceptParams {
/// Construct an `Accept` header with a single `application/json` media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Accept;
///
/// # #[allow(unused_variables)]
@ -151,6 +155,7 @@ impl PartialEq for AcceptParams {
/// where an `Into<Header>` is expected:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Accept;
/// use rocket::response::Response;
///
@ -193,6 +198,7 @@ impl Accept {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{QMediaType, MediaType, Accept};
///
/// // Construct an `Accept` via a `Vec<QMediaType>`.
@ -228,6 +234,7 @@ impl Accept {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{QMediaType, MediaType, Accept};
///
/// let media_types = vec![
@ -274,6 +281,7 @@ impl Accept {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{QMediaType, MediaType, Accept};
///
/// let accept = Accept::new(QMediaType(MediaType::XML, None));
@ -291,6 +299,7 @@ impl Accept {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{QMediaType, MediaType, Accept};
///
/// let qmedia_types = vec![
@ -321,6 +330,7 @@ impl Accept {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{QMediaType, MediaType, Accept};
///
/// let qmedia_types = vec![
@ -378,7 +388,7 @@ impl Into<Header<'static>> for Accept {
#[cfg(test)]
mod test {
use http::{Accept, MediaType};
use {Accept, MediaType};
macro_rules! assert_preference {
($string:expr, $expect:expr) => (

View File

@ -3,9 +3,9 @@ use std::ops::Deref;
use std::str::FromStr;
use std::fmt;
use {Header, MediaType, Source};
use ext::IntoCollection;
use http::{Header, MediaType, Source};
use http::hyper::mime::Mime;
use hyper::mime::Mime;
/// Representation of HTTP Content-Types.
///
@ -21,6 +21,7 @@ use http::hyper::mime::Mime;
/// `HTML` constant:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// # #[allow(unused_variables)]
@ -33,6 +34,7 @@ use http::hyper::mime::Mime;
/// context where an `Into<Header>` is expected:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
/// use rocket::response::Response;
///
@ -75,6 +77,7 @@ macro_rules! from_extension {
/// Recognized content types:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let xml = ContentType::from_extension("xml");
@ -87,6 +90,7 @@ macro_rules! from_extension {
/// An unrecognized content type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let foo = ContentType::from_extension("foo");
@ -118,6 +122,7 @@ macro_rules! parse_flexible {
/// Using a shorthand:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let html = ContentType::parse_flexible("html");
@ -130,6 +135,7 @@ macro_rules! parse_flexible {
/// Using the full content-type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let html = ContentType::parse_flexible("text/html; charset=utf-8");
@ -145,6 +151,7 @@ macro_rules! parse_flexible {
/// An unrecognized content-type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let foo = ContentType::parse_flexible("foo");
@ -170,6 +177,7 @@ impl ContentType {
/// Create a custom `application/x-person` content type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let custom = ContentType::new("application", "x-person");
@ -196,6 +204,7 @@ impl ContentType {
/// Create a custom `application/x-id; id=1` content type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let id = ContentType::with_params("application", "x-id", ("id", "1"));
@ -205,6 +214,7 @@ impl ContentType {
/// Create a custom `text/person; name=bob; weight=175` content type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let params = vec![("name", "bob"), ("ref", "2382")];
@ -225,6 +235,7 @@ impl ContentType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{ContentType, MediaType};
///
/// let http = ContentType::HTML;
@ -287,6 +298,7 @@ impl FromStr for ContentType {
/// Parsing an `application/json`:
///
/// ```rust
/// # extern crate rocket;
/// use std::str::FromStr;
/// use rocket::http::ContentType;
///
@ -298,6 +310,7 @@ impl FromStr for ContentType {
/// Parsing a content type extension:
///
/// ```rust
/// # extern crate rocket;
/// use std::str::FromStr;
/// use rocket::http::ContentType;
///
@ -310,6 +323,7 @@ impl FromStr for ContentType {
/// Parsing an invalid Content-Type value:
///
/// ```rust
/// # extern crate rocket;
/// use std::str::FromStr;
/// use rocket::http::ContentType;
///
@ -328,6 +342,7 @@ impl fmt::Display for ContentType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::ContentType;
///
/// let ct = format!("{}", ContentType::JSON);

View File

@ -4,7 +4,7 @@ use std::cell::RefMut;
pub use cookie::{Cookie, Key, CookieJar};
use cookie::{SameSite, Delta};
use http::Header;
use Header;
/// Collection of one or more HTTP cookies.
///
@ -117,23 +117,32 @@ pub enum Cookies<'a> {
}
impl<'a> Cookies<'a> {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[inline]
pub(crate) fn new(jar: RefMut<'a, CookieJar>, key: &'a Key) -> Cookies<'a> {
#[doc(hidden)]
pub fn new(jar: RefMut<'a, CookieJar>, key: &'a Key) -> Cookies<'a> {
Cookies::Jarred(jar, key)
}
#[inline]
pub(crate) fn empty() -> Cookies<'static> {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
#[inline(always)]
pub fn empty() -> Cookies<'static> {
Cookies::Empty(CookieJar::new())
}
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
#[inline(always)]
pub(crate) fn parse_cookie(cookie_str: &str) -> Option<Cookie<'static>> {
pub fn parse_cookie(cookie_str: &str) -> Option<Cookie<'static>> {
Cookie::parse_encoded(cookie_str).map(|c| c.into_owned()).ok()
}
/// Adds an original `cookie` to this collection.
pub(crate) fn add_original(&mut self, cookie: Cookie<'static>) {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[inline]
#[doc(hidden)]
pub fn add_original(&mut self, cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, _) = *self {
jar.add_original(cookie)
}
@ -145,6 +154,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Cookies;
///
/// fn handler(cookies: Cookies) {
@ -166,6 +176,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Cookies;
///
/// fn handler(mut cookies: Cookies) {
@ -184,6 +195,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Cookie, Cookies};
///
/// fn handler(mut cookies: Cookies) {
@ -223,6 +235,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Cookie, Cookies};
///
/// fn handler(mut cookies: Cookies) {
@ -237,7 +250,9 @@ impl<'a> Cookies<'a> {
}
/// Adds an original, private `cookie` to the collection.
pub(crate) fn add_original_private(&mut self, mut cookie: Cookie<'static>) {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
pub fn add_original_private(&mut self, mut cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, key) = *self {
Cookies::set_private_defaults(&mut cookie);
jar.private(key).add_original(cookie)
@ -284,6 +299,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Cookie, Cookies};
///
/// fn handler(mut cookies: Cookies) {
@ -305,6 +321,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Cookie, Cookies};
///
/// fn handler(mut cookies: Cookies) {
@ -326,6 +343,7 @@ impl<'a> Cookies<'a> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Cookies;
///
/// fn handler(cookies: Cookies) {
@ -341,7 +359,10 @@ impl<'a> Cookies<'a> {
}
}
pub(crate) fn delta(&self) -> Delta {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
#[inline]
pub fn delta(&self) -> Delta {
match *self {
Cookies::Jarred(ref jar, _) => jar.delta(),
Cookies::Empty(ref jar) => jar.delta()

62
core/http/src/ext.rs Normal file
View File

@ -0,0 +1,62 @@
use smallvec::{Array, SmallVec};
// TODO: It would be nice if we could somehow have one trait that could give us
// either SmallVec or Vec.
pub trait IntoCollection<T> {
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A>;
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, f: F) -> SmallVec<A>;
}
impl<T> IntoCollection<T> for T {
#[inline]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
let mut vec = SmallVec::new();
vec.push(self);
vec
}
#[inline(always)]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
f(self).into_collection()
}
}
impl<T> IntoCollection<T> for Vec<T> {
#[inline(always)]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
SmallVec::from_vec(self)
}
#[inline]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
self.into_iter().map(|item| f(item)).collect()
}
}
macro_rules! impl_for_slice {
($($size:tt)*) => (
impl<'a, T: Clone> IntoCollection<T> for &'a [T $($size)*] {
#[inline(always)]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
self.iter().cloned().collect()
}
#[inline]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
self.iter().cloned().map(|item| f(item)).collect()
}
}
)
}
impl_for_slice!();
impl_for_slice!(; 1);
impl_for_slice!(; 2);
impl_for_slice!(; 3);
impl_for_slice!(; 4);
impl_for_slice!(; 5);
impl_for_slice!(; 6);
impl_for_slice!(; 7);
impl_for_slice!(; 8);
impl_for_slice!(; 9);
impl_for_slice!(; 10);

View File

@ -3,7 +3,7 @@ use std::fmt;
use indexmap::IndexMap;
use http::uncased::{Uncased, UncasedStr};
use uncased::{Uncased, UncasedStr};
/// Simple representation of an HTTP header.
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
@ -27,6 +27,7 @@ impl<'h> Header<'h> {
/// value`.
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Header;
///
/// let header = Header::new("X-Custom-Header", "custom value");
@ -36,6 +37,7 @@ impl<'h> Header<'h> {
/// Use a `String` as a value to do the same.
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Header;
///
/// let value = format!("{} value", "custom");
@ -60,6 +62,7 @@ impl<'h> Header<'h> {
/// A case-sensitive equality check:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Header;
///
/// let value = format!("{} value", "custom");
@ -71,6 +74,7 @@ impl<'h> Header<'h> {
/// A case-insensitive equality check via `.name`:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Header;
///
/// let header = Header::new("X-Custom-Header", "custom value");
@ -89,6 +93,7 @@ impl<'h> Header<'h> {
/// A case-sensitive equality check:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Header;
///
/// let header = Header::new("X-Custom-Header", "custom value");
@ -126,6 +131,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let map = HeaderMap::new();
@ -140,6 +146,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, ContentType};
///
/// let mut map = HeaderMap::new();
@ -158,6 +165,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -183,6 +191,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let map = HeaderMap::new();
@ -199,6 +208,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -228,6 +238,7 @@ impl<'h> HeaderMap<'h> {
/// Retrieve the first value when one exists:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -243,6 +254,7 @@ impl<'h> HeaderMap<'h> {
/// Attempt to retrieve a value that doesn't exist:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -270,6 +282,7 @@ impl<'h> HeaderMap<'h> {
/// Replace a header that doesn't yet exist:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, ContentType};
///
/// let mut map = HeaderMap::new();
@ -281,6 +294,7 @@ impl<'h> HeaderMap<'h> {
/// Replace a header that already exists:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, ContentType};
///
/// let mut map = HeaderMap::new();
@ -296,6 +310,7 @@ impl<'h> HeaderMap<'h> {
/// An example of case-insensitivity.
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, Header, ContentType};
///
/// let mut map = HeaderMap::new();
@ -319,6 +334,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -344,6 +360,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -368,6 +385,7 @@ impl<'h> HeaderMap<'h> {
/// previously added, that header will have one more value.
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Cookie, HeaderMap};
///
/// let mut map = HeaderMap::new();
@ -390,6 +408,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -415,6 +434,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -446,6 +466,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::HeaderMap;
///
/// let mut map = HeaderMap::new();
@ -470,6 +491,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, Header};
/// use std::collections::HashSet;
///
@ -510,6 +532,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, Header};
///
/// // The headers we'll be storing.
@ -554,6 +577,7 @@ impl<'h> HeaderMap<'h> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{HeaderMap, Header};
///
/// // The headers we'll be storing.
@ -598,8 +622,10 @@ impl<'h> HeaderMap<'h> {
/// Consumes `self` and returns an iterator over all of the headers stored
/// in the map in the way they are stored. This is a low-level machinism and
/// should likely not be used.
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
#[inline]
pub(crate) fn into_iter_raw(self)
pub fn into_iter_raw(self)
-> impl Iterator<Item=(Uncased<'h>, Vec<Cow<'h, str>>)> {
self.headers.into_iter()
}

View File

@ -4,33 +4,35 @@
//! These types will, with certainty, be removed with time, but they reside here
//! while necessary.
pub(crate) use hyper::server::Request as Request;
pub(crate) use hyper::server::Response as Response;
pub(crate) use hyper::server::Server as Server;
pub(crate) use hyper::server::Handler as Handler;
extern crate hyper;
pub(crate) use hyper::net;
#[doc(hidden)] pub use self::hyper::server::Request as Request;
#[doc(hidden)] pub use self::hyper::server::Response as Response;
#[doc(hidden)] pub use self::hyper::server::Server as Server;
#[doc(hidden)] pub use self::hyper::server::Handler as Handler;
pub(crate) use hyper::method::Method;
pub(crate) use hyper::status::StatusCode;
pub(crate) use hyper::error::Error;
pub(crate) use hyper::uri::RequestUri;
pub(crate) use hyper::http::h1;
pub(crate) use hyper::buffer;
#[doc(hidden)] pub use self::hyper::net;
pub use hyper::mime;
#[doc(hidden)] pub use self::hyper::method::Method;
#[doc(hidden)] pub use self::hyper::status::StatusCode;
#[doc(hidden)] pub use self::hyper::error::Error;
#[doc(hidden)] pub use self::hyper::uri::RequestUri;
#[doc(hidden)] pub use self::hyper::http::h1;
#[doc(hidden)] pub use self::hyper::buffer;
/// Type alias to `hyper::Response<'a, hyper::net::Fresh>`.
pub(crate) type FreshResponse<'a> = self::Response<'a, self::net::Fresh>;
pub use self::hyper::mime;
/// Type alias to `self::hyper::Response<'a, self::hyper::net::Fresh>`.
#[doc(hidden)] pub type FreshResponse<'a> = self::Response<'a, self::net::Fresh>;
/// Reexported Hyper header types.
pub mod header {
use http::Header;
use Header;
use hyper::header::Header as HyperHeaderTrait;
use super::hyper::header::Header as HyperHeaderTrait;
macro_rules! import_hyper_items {
($($item:ident),*) => ($(pub use hyper::header::$item;)*)
($($item:ident),*) => ($(pub use super::hyper::header::$item;)*)
}
macro_rules! import_hyper_headers {

View File

@ -1,3 +1,9 @@
#![feature(specialization)]
#![feature(proc_macro)]
#![feature(proc_macro_non_items)]
#![feature(const_fn)]
#![recursion_limit="256"]
//! Types that map to concepts in HTTP.
//!
//! This module exports types that map to HTTP concepts or to the underlying
@ -5,9 +11,24 @@
//! change (see <a
//! href="https://github.com/SergioBenitez/Rocket/issues/17">#17</a>), types in
//! [hyper](hyper/index.html) should be considered unstable.
#[macro_use]
extern crate pear;
extern crate smallvec;
#[macro_use]
extern crate percent_encoding;
extern crate cookie;
extern crate time;
extern crate indexmap;
pub mod hyper;
pub mod uri;
#[cfg(feature = "tls")]
pub mod tls;
#[macro_use]
mod docify;
#[macro_use]
mod known_media_types;
mod cookies;
@ -18,6 +39,7 @@ mod status;
mod header;
mod accept;
mod raw_str;
mod ext;
pub(crate) mod parse;
@ -36,4 +58,6 @@ pub use self::raw_str::RawStr;
pub use self::media_type::MediaType;
pub use self::cookies::{Cookie, Cookies};
pub(crate) use self::cookies::{Key, CookieJar};
#[doc(hidden)]
pub use self::cookies::{Key, CookieJar};

View File

@ -4,8 +4,8 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use ext::IntoCollection;
use http::uncased::{uncased_eq, UncasedStr};
use http::parse::{Indexed, IndexedString, parse_media_type};
use uncased::{uncased_eq, UncasedStr};
use parse::{Indexed, IndexedString, parse_media_type};
use smallvec::SmallVec;
@ -77,6 +77,7 @@ impl Source {
/// constant:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let json = MediaType::JSON;
@ -180,6 +181,7 @@ macro_rules! from_extension {
/// Recognized media types:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let xml = MediaType::from_extension("xml");
@ -192,6 +194,7 @@ macro_rules! from_extension {
/// An unrecognized media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let foo = MediaType::from_extension("foo");
@ -225,6 +228,7 @@ macro_rules! parse_flexible {
/// Using a shorthand:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let html = MediaType::parse_flexible("html");
@ -237,6 +241,7 @@ macro_rules! parse_flexible {
/// Using the full media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let html = MediaType::parse_flexible("text/html; charset=utf-8");
@ -252,6 +257,7 @@ macro_rules! parse_flexible {
/// An unrecognized media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let foo = MediaType::parse_flexible("foo");
@ -279,6 +285,7 @@ impl MediaType {
/// Create a custom `application/x-person` media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let custom = MediaType::new("application", "x-person");
@ -306,6 +313,7 @@ impl MediaType {
/// Create a custom `application/x-id; id=1` media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let id = MediaType::with_params("application", "x-id", ("id", "1"));
@ -315,6 +323,7 @@ impl MediaType {
/// Create a custom `text/person; name=bob; weight=175` media type:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let params = vec![("name", "bob"), ("ref", "2382")];
@ -350,6 +359,7 @@ impl MediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let plain = MediaType::Plain;
@ -368,6 +378,7 @@ impl MediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let plain = MediaType::Plain;
@ -392,6 +403,7 @@ impl MediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let mt = MediaType::Plain;
@ -421,6 +433,7 @@ impl MediaType {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let plain = MediaType::Plain;
@ -461,6 +474,7 @@ impl MediaType {
/// The `MediaType::Plain` type has one parameter: `charset=utf-8`:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let plain = MediaType::Plain;
@ -471,6 +485,7 @@ impl MediaType {
/// The `MediaType::PNG` type has no parameters:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::MediaType;
///
/// let png = MediaType::PNG;

View File

@ -1,9 +1,7 @@
use std::fmt;
use std::str::FromStr;
use error::Error;
use http::hyper;
use http::uncased::uncased_eq;
use {hyper, uncased::uncased_eq};
use self::Method::*;
@ -24,7 +22,9 @@ pub enum Method {
}
impl Method {
pub(crate) fn from_hyp(method: &hyper::Method) -> Option<Method> {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
pub fn from_hyp(method: &hyper::Method) -> Option<Method> {
match *method {
hyper::Method::Get => Some(Get),
hyper::Method::Put => Some(Put),
@ -45,6 +45,7 @@ impl Method {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Method;
///
/// assert_eq!(Method::Get.supports_payload(), false);
@ -63,6 +64,7 @@ impl Method {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Method;
///
/// assert_eq!(Method::Get.as_str(), "GET");
@ -84,11 +86,11 @@ impl Method {
}
impl FromStr for Method {
type Err = Error;
type Err = ();
// According to the RFC, method names are case-sensitive. But some old
// clients don't follow this, so we just do a case-insensitive match here.
fn from_str(s: &str) -> Result<Method, Error> {
fn from_str(s: &str) -> Result<Method, ()> {
match s {
x if uncased_eq(x, Get.as_str()) => Ok(Get),
x if uncased_eq(x, Put.as_str()) => Ok(Put),
@ -99,7 +101,7 @@ impl FromStr for Method {
x if uncased_eq(x, Trace.as_str()) => Ok(Trace),
x if uncased_eq(x, Connect.as_str()) => Ok(Connect),
x if uncased_eq(x, Patch.as_str()) => Ok(Patch),
_ => Err(Error::BadMethod),
_ => Err(()),
}
}
}

View File

@ -1,10 +1,10 @@
use pear::parser;
use pear::parsers::*;
use http::parse::checkers::is_whitespace;
use http::parse::media_type::media_type;
use http::{Accept, QMediaType};
use http::parse::{Input, Result};
use {Accept, QMediaType};
use parse::{Input, Result};
use parse::checkers::is_whitespace;
use parse::media_type::media_type;
#[parser]
fn weighted_media_type<'a>(input: &mut Input<'a>) -> Result<'a, QMediaType> {
@ -33,7 +33,7 @@ pub fn parse_accept(input: &str) -> Result<Accept> {
#[cfg(test)]
mod test {
use http::MediaType;
use MediaType;
use super::parse_accept;
macro_rules! assert_parse {

View File

@ -3,9 +3,9 @@ use std::borrow::Cow;
use pear::{parser, switch};
use pear::parsers::*;
use http::{MediaType, Source};
use http::parse::checkers::{is_whitespace, is_valid_token};
use http::parse::{Input, Slice, Result};
use {MediaType, Source};
use parse::checkers::{is_whitespace, is_valid_token};
use parse::{Input, Slice, Result};
#[parser]
fn quoted_string<'a>(input: &mut Input<'a>) -> Result<'a, Slice<'a>> {
@ -58,7 +58,7 @@ pub fn parse_media_type(input: &str) -> Result<MediaType> {
#[cfg(test)]
mod test {
use http::MediaType;
use MediaType;
use super::parse_media_type;
macro_rules! assert_no_parse {

View File

@ -5,7 +5,7 @@ use std::cmp::Ordering;
use std::str::Utf8Error;
use std::fmt;
use http::uncased::UncasedStr;
use uncased::UncasedStr;
/// A reference to a string inside of a raw HTTP message.
///
@ -54,6 +54,7 @@ impl RawStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str = RawStr::from_str("Hello, world!");
@ -77,6 +78,7 @@ impl RawStr {
/// With a valid string:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str = RawStr::from_str("Hello%21");
@ -87,6 +89,7 @@ impl RawStr {
/// With an invalid string:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// // Note: Rocket should never hand you a bad `&RawStr`.
@ -108,6 +111,7 @@ impl RawStr {
/// With a valid string:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str = RawStr::from_str("Hello%21");
@ -118,6 +122,7 @@ impl RawStr {
/// With an invalid string:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// // Note: Rocket should never hand you a bad `&RawStr`.
@ -141,6 +146,7 @@ impl RawStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str: &RawStr = "Hello%2C+world%21".into();
@ -169,6 +175,7 @@ impl RawStr {
/// Strings with HTML sequences are escaped:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str: &RawStr = "<b>Hi!</b>".into();
@ -183,6 +190,7 @@ impl RawStr {
/// Strings without HTML sequences remain untouched:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str: &RawStr = "Hello!".into();
@ -239,6 +247,7 @@ impl RawStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str = RawStr::from_str("Hello, world!");
@ -257,6 +266,7 @@ impl RawStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::RawStr;
///
/// let raw_str = RawStr::from_str("Content-Type");

View File

@ -55,6 +55,7 @@ impl StatusClass {
/// A status of `200 OK` can be instantiated via the `Ok` constant:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// # #[allow(unused_variables)]
@ -64,6 +65,7 @@ impl StatusClass {
/// A status of `404 Not Found` can be instantiated via the `NotFound` constant:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// # #[allow(unused_variables)]
@ -73,6 +75,7 @@ impl StatusClass {
/// The code and phrase can be retrieved directly:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// let not_found = Status::NotFound;
@ -109,6 +112,7 @@ macro_rules! ctrs {
/// Create a `Status` from a known `code`:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// let not_found = Status::from_code(404);
@ -118,6 +122,7 @@ macro_rules! ctrs {
/// Create a `Status` from an unknown `code`:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// let not_found = Status::from_code(600);
@ -143,6 +148,7 @@ impl Status {
/// Create a custom `299 Somewhat Successful` status:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::Status;
///
/// let custom = Status::new(299, "Somewhat Successful");
@ -161,6 +167,7 @@ impl Status {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::{Status, StatusClass};
///
/// let processing = Status::Processing;

5
core/http/src/tls.rs Normal file
View File

@ -0,0 +1,5 @@
extern crate rustls;
extern crate hyper_sync_rustls;
pub use self::hyper_sync_rustls::{util, WrappedStream, ServerSession, TlsServer};
pub use self::rustls::{Certificate, PrivateKey};

View File

@ -14,6 +14,7 @@ use std::fmt;
/// created from an `&str` as follows:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::UncasedStr;
///
/// let ascii_ref: &UncasedStr = "Hello, world!".into();
@ -28,6 +29,7 @@ impl UncasedStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::UncasedStr;
///
/// let uncased_str = UncasedStr::new("Hello!");
@ -45,6 +47,7 @@ impl UncasedStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::UncasedStr;
///
/// let uncased_str = UncasedStr::new("Hello!");
@ -61,6 +64,7 @@ impl UncasedStr {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::Uncased;
///
/// let uncased = Uncased::new("Hello!");
@ -164,6 +168,7 @@ impl<'s> Uncased<'s> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::Uncased;
///
/// let uncased = Uncased::new("Content-Type");
@ -180,6 +185,7 @@ impl<'s> Uncased<'s> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::Uncased;
///
/// let uncased = Uncased::new("Content-Type");
@ -196,6 +202,7 @@ impl<'s> Uncased<'s> {
/// # Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uncased::Uncased;
///
/// let boxed = Uncased::new("Content-Type").into_boxed_uncased();

View File

@ -1,7 +1,6 @@
use std::path::{Path, PathBuf};
use http::RawStr;
use http::uri::UriDisplay;
use {RawStr, uri::UriDisplay};
/// Conversion trait for parameters used in `uri!` invocations.
///
@ -57,6 +56,7 @@ use http::uri::UriDisplay;
/// `uri!` invocation where a `User` type is expected.
///
/// ```rust
/// # extern crate rocket;
/// use std::fmt;
///
/// use rocket::http::RawStr;

View File

@ -59,6 +59,7 @@ impl<'a> Uri<'a> {
/// A valid URI with only non-empty segments:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c");
@ -68,6 +69,7 @@ impl<'a> Uri<'a> {
/// A URI with empty segments:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b//c/d///e");
@ -96,6 +98,7 @@ impl<'a> Uri<'a> {
/// A valid URI with only non-empty segments:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c?a=true#done");
@ -112,6 +115,7 @@ impl<'a> Uri<'a> {
/// A URI with empty segments:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("///a//b///c////d?#");
@ -137,6 +141,7 @@ impl<'a> Uri<'a> {
/// A URI with only a path:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c");
@ -146,6 +151,7 @@ impl<'a> Uri<'a> {
/// A URI with other components:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c?name=bob#done");
@ -165,6 +171,7 @@ impl<'a> Uri<'a> {
/// A URI with a query part:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c?alphabet=true");
@ -174,6 +181,7 @@ impl<'a> Uri<'a> {
/// A URI without the query part:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b/c");
@ -192,6 +200,7 @@ impl<'a> Uri<'a> {
/// A URI with a fragment part:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a?alphabet=true#end");
@ -201,6 +210,7 @@ impl<'a> Uri<'a> {
/// A URI without the fragment part:
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a?query=true");
@ -217,6 +227,7 @@ impl<'a> Uri<'a> {
/// # Examples
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/Hello%2C%20world%21");
@ -235,6 +246,7 @@ impl<'a> Uri<'a> {
/// # Examples
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/Hello%2C%20world%21");
@ -253,6 +265,7 @@ impl<'a> Uri<'a> {
/// # Examples
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let encoded = Uri::percent_encode("hello?a=<b>hi</b>");
@ -271,6 +284,7 @@ impl<'a> Uri<'a> {
/// ### Example
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/b///c/d/e//f?name=Mike#end");
@ -355,6 +369,7 @@ impl<'a> fmt::Display for Uri<'a> {
/// ### Examples
///
/// ```rust
/// # extern crate rocket;
/// use rocket::http::uri::Uri;
///
/// let uri = Uri::new("/a/////b/c////////d");
@ -424,11 +439,11 @@ mod tests {
fn seg_count(path: &str, expected: usize) -> bool {
let actual = Uri::new(path).segment_count();
if actual != expected {
trace_!("Count mismatch: expected {}, got {}.", expected, actual);
trace_!("{}", if actual != expected { "lifetime" } else { "buf" });
trace_!("Segments (for {}):", path);
eprintln!("Count mismatch: expected {}, got {}.", expected, actual);
eprintln!("{}", if actual != expected { "lifetime" } else { "buf" });
eprintln!("Segments (for {}):", path);
for (i, segment) in Uri::new(path).segments().enumerate() {
trace_!("{}: {}", i, segment);
eprintln!("{}: {}", i, segment);
}
}

View File

@ -2,8 +2,7 @@ use std::fmt;
use std::path::{Path, PathBuf};
use std::borrow::Cow;
use http::RawStr;
use http::uri::Uri;
use {RawStr, uri::Uri};
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};

View File

@ -15,37 +15,25 @@ build = "build.rs"
categories = ["web-programming::http-server"]
[features]
tls = ["rustls", "hyper-sync-rustls"]
tls = ["rocket_http/tls"]
[dependencies]
rocket_codegen_next = { version = "0.4.0-dev", path = "../codegen_next" }
rocket_http = { version = "0.4.0-dev", path = "../http" }
yansi = "0.4"
log = "0.4"
percent-encoding = "1"
toml = "0.4.2"
num_cpus = "1.0"
state = "0.4.1"
time = "0.1"
# TODO: Use pear instead.
memchr = "2"
base64 = "0.9"
smallvec = "0.6"
pear = { git = "http://github.com/SergioBenitez/Pear", rev = "54667ae" }
rustls = { version = "0.12.0", optional = true }
hyper = { version = "0.10.13", default-features = false }
indexmap = "1.0"
isatty = "0.1"
[dependencies.hyper-sync-rustls]
version = "=0.3.0-rc.2"
features = ["server"]
optional = true
[dependencies.cookie]
git = "https://github.com/alexcrichton/cookie-rs"
rev = "0365a18"
features = ["percent-encode", "secure"]
[dev-dependencies]
# TODO: Find a way to not depend on this.
lazy_static = "1.0"
rocket_codegen = { version = "0.4.0-dev", path = "../codegen" }

View File

@ -555,21 +555,21 @@ impl Config {
/// ```
#[cfg(feature = "tls")]
pub fn set_tls(&mut self, certs_path: &str, key_path: &str) -> Result<()> {
use hyper_sync_rustls::util as tls;
use hyper_sync_rustls::util::Error::Io;
use http::tls::util::{self, Error};
let pem_err = "malformed PEM file";
// Load the certificates.
let certs = tls::load_certs(self.root_relative(certs_path))
let certs = util::load_certs(self.root_relative(certs_path))
.map_err(|e| match e {
Io(e) => ConfigError::Io(e, "tls.certs"),
Error::Io(e) => ConfigError::Io(e, "tls.certs"),
_ => self.bad_type("tls", pem_err, "a valid certificates file")
})?;
// And now the private key.
let key = tls::load_private_key(self.root_relative(key_path))
let key = util::load_private_key(self.root_relative(key_path))
.map_err(|e| match e {
Io(e) => ConfigError::Io(e, "tls.key"),
Error::Io(e) => ConfigError::Io(e, "tls.key"),
_ => self.bad_type("tls", pem_err, "a valid private key file")
})?;

View File

@ -1,6 +1,6 @@
use std::fmt;
#[cfg(feature = "tls")] use rustls::{Certificate, PrivateKey};
#[cfg(feature = "tls")] use http::tls::{Certificate, PrivateKey};
use config::{Result, Config, Value, ConfigError, LoggingLevel};
use http::uncased::uncased_eq;

View File

@ -2,7 +2,7 @@ use std::io;
use std::net::{SocketAddr, Shutdown};
use std::time::Duration;
#[cfg(feature = "tls")] use hyper_sync_rustls::{WrappedStream, ServerSession};
#[cfg(feature = "tls")] use http::tls::{WrappedStream, ServerSession};
use http::hyper::net::{HttpStream, NetworkStream};
use self::NetStream::*;

View File

@ -1,5 +1,4 @@
use std::io;
use smallvec::{Array, SmallVec};
pub trait ReadExt: io::Read {
fn read_max(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
@ -18,64 +17,3 @@ pub trait ReadExt: io::Read {
}
impl<T: io::Read> ReadExt for T { }
// TODO: It would be nice if we could somehow have one trait that could give us
// either SmallVec or Vec.
pub trait IntoCollection<T> {
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A>;
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, f: F) -> SmallVec<A>;
}
impl<T> IntoCollection<T> for T {
#[inline]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
let mut vec = SmallVec::new();
vec.push(self);
vec
}
#[inline(always)]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
f(self).into_collection()
}
}
impl<T> IntoCollection<T> for Vec<T> {
#[inline(always)]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
SmallVec::from_vec(self)
}
#[inline]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
self.into_iter().map(|item| f(item)).collect()
}
}
macro_rules! impl_for_slice {
($($size:tt)*) => (
impl<'a, T: Clone> IntoCollection<T> for &'a [T $($size)*] {
#[inline(always)]
fn into_collection<A: Array<Item=T>>(self) -> SmallVec<A> {
self.iter().cloned().collect()
}
#[inline]
fn mapped<U, F: FnMut(T) -> U, A: Array<Item=U>>(self, mut f: F) -> SmallVec<A> {
self.iter().cloned().map(|item| f(item)).collect()
}
}
)
}
impl_for_slice!();
impl_for_slice!(; 1);
impl_for_slice!(; 2);
impl_for_slice!(; 3);
impl_for_slice!(; 4);
impl_for_slice!(; 5);
impl_for_slice!(; 6);
impl_for_slice!(; 7);
impl_for_slice!(; 8);
impl_for_slice!(; 9);
impl_for_slice!(; 10);

View File

@ -102,30 +102,22 @@
#[allow(unused_imports)] #[macro_use] extern crate rocket_codegen_next;
#[doc(hidden)] pub use rocket_codegen_next::*;
extern crate rocket_http;
#[macro_use] extern crate log;
#[macro_use] extern crate pear;
#[cfg(feature = "tls")] extern crate rustls;
#[cfg(feature = "tls")] extern crate hyper_sync_rustls;
#[macro_use] extern crate percent_encoding;
extern crate yansi;
extern crate hyper;
extern crate toml;
extern crate num_cpus;
extern crate state;
extern crate cookie;
extern crate time;
extern crate memchr;
extern crate base64;
extern crate smallvec;
extern crate indexmap;
extern crate isatty;
#[cfg(test)] #[macro_use] extern crate lazy_static;
#[doc(hidden)] #[macro_use] pub mod logger;
#[macro_use] mod docify;
pub mod local;
pub mod http;
pub mod request;
pub mod response;
pub mod outcome;
@ -135,6 +127,13 @@ pub mod handler;
pub mod fairing;
pub mod error;
// Reexport of HTTP everything.
pub mod http {
// FIXME: This unfortunately doesn't work! See rust-lang/rust#51252.
#[doc(inline)]
pub use rocket_http::*;
}
mod router;
mod rocket;
mod codegen;

View File

@ -8,8 +8,7 @@ use std::mem;
use yansi::Paint;
use state::Container;
#[cfg(feature = "tls")]
use hyper_sync_rustls::TlsServer;
#[cfg(feature = "tls")] use http::tls::TlsServer;
use {logger, handler};
use ext::ReadExt;

View File

@ -23,19 +23,41 @@ function relative() {
fi
}
ROOT_DIR=$(relative "") || exit $?
# Root of workspace-like directories.
PROJECT_ROOT=$(relative "") || exit $?
CORE_ROOT=$(relative "core") || exit $?
CONTRIB_ROOT=$(relative "contrib") || exit $?
# Root of project-like directories.
CORE_LIB_ROOT=$(relative "core/lib") || exit $?
CORE_CODEGEN_ROOT=$(relative "core/codegen") || exit $?
CORE_CODEGEN_NEXT_ROOT=$(relative "core/codegen_next") || exit $?
CORE_HTTP_ROOT=$(relative "core/http") || exit $?
CONTRIB_LIB_ROOT=$(relative "contrib/lib") || exit $?
# Root of infrastructure directories.
EXAMPLES_DIR=$(relative "examples") || exit $?
LIB_DIR=$(relative "core/lib") || exit $?
CODEGEN_DIR=$(relative "core/codegen") || exit $?
CONTRIB_DIR=$(relative "contrib/lib") || exit $?
DOC_DIR=$(relative "target/doc") || exit $?
ALL_PROJECT_DIRS=(
"${CORE_LIB_ROOT}"
"${CORE_CODEGEN_ROOT}"
"${CORE_CODEGEN_NEXT_ROOT}"
"${CORE_HTTP_ROOT}"
"${CONTRIB_LIB_ROOT}"
)
if [ "${1}" = "-p" ]; then
echo "${ROOT_DIR}"
echo "${SCRIPT_DIR}"
echo "${EXAMPLES_DIR}"
echo "${LIB_DIR}"
echo "${CODEGEN_DIR}"
echo "${CONTRIB_DIR}"
echo "${DOC_DIR}"
echo "SCRIPT_DIR: ${SCRIPT_DIR}"
echo "PROJECT_ROOT: ${PROJECT_ROOT}"
echo "CORE_ROOT: ${CORE_ROOT}"
echo "CONTRIB_ROOT: ${CONTRIB_ROOT}"
echo "CORE_LIB_ROOT: ${CORE_LIB_ROOT}"
echo "CORE_CODEGEN_ROOT: ${CORE_CODEGEN_ROOT}"
echo "CORE_CODEGEN_NEXT_ROOT: ${CORE_CODEGEN_NEXT_ROOT}"
echo "CORE_HTTP_ROOT: ${CORE_HTTP_ROOT}"
echo "CONTRIB_LIB_ROOT: ${CONTRIB_LIB_ROOT}"
echo "EXAMPLES_DIR: ${EXAMPLES_DIR}"
echo "DOC_DIR: ${DOC_DIR}"
echo "ALL_PROJECT_DIRECTORIES: ${ALL_PROJECT_DIRECTORIES[*]}"
fi

View File

@ -5,7 +5,7 @@ set -e
# Builds the rustdocs for all of the libraries.
#
# Brings in: ROOT_DIR, EXAMPLES_DIR, LIB_DIR, CODEGEN_DIR, CONTRIB_DIR, DOC_DIR
# Brings in: PROJECT_ROOT, EXAMPLES_DIR, LIB_DIR, CODEGEN_DIR, CONTRIB_DIR, DOC_DIR
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${SCRIPT_DIR}/config.sh"
@ -18,12 +18,14 @@ function mk_doc() {
}
# We need to clean-up beforehand so we don't get all of the dependencies.
echo ":::: Cleaning up before documenting..."
cargo clean
cargo update
mk_doc "${LIB_DIR}"
mk_doc "${CODEGEN_DIR}"
mk_doc "${CONTRIB_DIR}"
# Generate the rustdocs for all of the crates.
for dir in "${ALL_PROJECT_DIRS[@]}"; do
mk_doc "${dir}"
done
# Blank index, for redirection.
touch "${DOC_DIR}/index.html"

View File

@ -2,10 +2,12 @@
set -e
#
# Publishes the current versions of core, contrib, and codegen to crates.io.
# Publishes the current versions of all Rocket crates to crates.io.
#
# Brings in: ROOT_DIR, EXAMPLES_DIR, LIB_DIR, CODEGEN_DIR, CONTRIB_DIR, DOC_DIR
# FIXME: Check for FIXMEs before publishing!..?
# Brings in _ROOT, _DIR, _DIRS globals.
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${SCRIPT_DIR}/config.sh"
@ -14,17 +16,28 @@ if ! [ -z "$(git status --porcelain)" ]; then
exit 1
fi
function strip_dev_dependencies() {
perl -i.bak -p0e 's/\[dev-dependencies\][^\[]*//smg' "${1}/Cargo.toml"
}
function restore_dev_dependencies() {
mv "${1}/Cargo.toml.bak" "${1}/Cargo.toml"
}
# Ensure everything passes before trying to publish.
echo ":::: Running test suite..."
cargo clean
bash "${SCRIPT_DIR}/test.sh"
bash "${SCRIPT_DIR}/test.sh" --release
# Temporarily remove the dependency on codegen from core so crates.io verifies.
sed -i.bak 's/rocket_codegen.*//' "${LIB_DIR}/Cargo.toml"
# Temporarily remove dev-dependencies so crates.io verifies.
echo ":::: Stripping [dev-dependencies]..."
for dir in "${ALL_PROJECT_DIRS[@]}"; do
strip_dev_dependencies "${dir}"
done
# Publish all the things.
for dir in "${LIB_DIR}" "${CODEGEN_DIR}" "${CONTRIB_DIR}"; do
for dir in "${ALL_PROJECT_DIRS[@]}"; do
pushd "${dir}"
echo ":::: Publishing '${dir}..."
# We already checked things ourselves. Don't spend time reverifying.
@ -32,5 +45,8 @@ for dir in "${LIB_DIR}" "${CODEGEN_DIR}" "${CONTRIB_DIR}"; do
popd
done
# Restore the original core Cargo.toml.
mv "${LIB_DIR}/Cargo.toml.bak" "${LIB_DIR}/Cargo.toml"
# Restore dev-dependencies.
echo ":::: Restoring [dev-dependencies]..."
for dir in "${ALL_PROJECT_DIRS[@]}"; do
restore_dev_dependencies "${dir}"
done

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -e
# Brings in: ROOT_DIR, EXAMPLES_DIR, LIB_DIR, CODEGEN_DIR, CONTRIB_DIR, DOC_DIR
# Brings in _ROOT, _DIR, _DIRS globals.
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${SCRIPT_DIR}/config.sh"
@ -31,7 +31,7 @@ function check_versions_match() {
# Ensures there are no tabs in any file.
function ensure_tab_free() {
local tab=$(printf '\t')
local matches=$(git grep -E -I "${tab}" "${ROOT_DIR}" | grep -v 'LICENSE')
local matches=$(git grep -E -I "${tab}" "${PROJECT_ROOT}" | grep -v 'LICENSE')
if ! [ -z "${matches}" ]; then
echo "Tab characters were found in the following:"
echo "${matches}"
@ -41,7 +41,7 @@ function ensure_tab_free() {
# Ensures there are no files with trailing whitespace.
function ensure_trailing_whitespace_free() {
local matches=$(git grep -E -I "\s+$" "${ROOT_DIR}")
local matches=$(git grep -E -I "\s+$" "${PROJECT_ROOT}")
if ! [ -z "${matches}" ]; then
echo "Trailing whitespace was found in the following:"
echo "${matches}"
@ -68,7 +68,7 @@ function bootstrap_examples() {
}
echo ":: Ensuring all crate versions match..."
check_versions_match "${LIB_DIR}" "${CODEGEN_DIR}" "${CONTRIB_DIR}"
check_versions_match "${ALL_PROJECT_DIRS[@]}"
echo ":: Checking for tabs..."
ensure_tab_free