mirror of https://github.com/rwf2/Rocket.git
Update to Hyper 0.10. Use cookie crate directly.
A few interesting notes on this breakage: * `Cookie` how has a lifetime. It should be `'static'` everywhere. * The `SetCookie` header is no longer reexported. * Instead, `Cookie` implements `Into<Header>` for Set-Cookie.
This commit is contained in:
parent
8fd19cce4f
commit
06a7317fd9
|
@ -6,7 +6,6 @@ workspace = "../../"
|
|||
[dependencies]
|
||||
rocket = { path = "../../lib" }
|
||||
rocket_codegen = { path = "../../codegen" }
|
||||
lazy_static = "*"
|
||||
|
||||
[dependencies.rocket_contrib]
|
||||
path = "../../contrib"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#![feature(plugin, custom_derive, custom_attribute)]
|
||||
#![plugin(rocket_codegen)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate rocket_contrib;
|
||||
extern crate rocket;
|
||||
|
||||
|
@ -23,15 +21,16 @@ struct Message {
|
|||
|
||||
#[post("/submit", data = "<message>")]
|
||||
fn submit(cookies: &Cookies, message: Form<Message>) -> Redirect {
|
||||
cookies.add(Cookie::new("message".into(), message.into_inner().message));
|
||||
cookies.add(Cookie::new("message", message.into_inner().message));
|
||||
Redirect::to("/")
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
fn index(cookies: &Cookies) -> Template {
|
||||
let cookie = cookies.find("message");
|
||||
let mut context = HashMap::new();
|
||||
if let Some(msg) = cookies.find("message").map(|msg| msg.value) {
|
||||
context.insert("message", msg);
|
||||
if let Some(ref cookie) = cookie {
|
||||
context.insert("message", cookie.value());
|
||||
}
|
||||
|
||||
Template::render("index", &context)
|
||||
|
|
|
@ -20,7 +20,7 @@ fn test_submit() {
|
|||
assert_eq!(location_headers, vec!["/".to_string()]);
|
||||
}
|
||||
|
||||
fn test_body(optional_cookie: Option<Cookie>, expected_body: String) {
|
||||
fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
|
||||
let rocket = rocket::ignite().mount("/", routes![super::index]);
|
||||
let mut request = MockRequest::new(Method::Get, "/");
|
||||
|
||||
|
@ -47,7 +47,7 @@ fn test_index() {
|
|||
context.insert("message", "Hello from Rocket!");
|
||||
|
||||
// Test the route with the "message" cookie.
|
||||
let cookie = Cookie::new("message".into(), "Hello from Rocket!".into());
|
||||
let cookie = Cookie::new("message", "Hello from Rocket!");
|
||||
let template = Template::render("index", &context);
|
||||
test_body(Some(cookie), template.to_string());
|
||||
}
|
||||
|
|
|
@ -18,11 +18,16 @@ build = "build.rs"
|
|||
term-painter = "^0.2"
|
||||
log = "^0.3"
|
||||
url = "^1"
|
||||
hyper = { version = "=0.9.14", default-features = false }
|
||||
hyper = { version = "0.10", default-features = false }
|
||||
toml = { version = "^0.2", default-features = false }
|
||||
num_cpus = "1"
|
||||
state = "^0.2"
|
||||
# cookie = "^0.3"
|
||||
time = "^0.1"
|
||||
|
||||
[dependencies.cookie]
|
||||
version = "^0.6"
|
||||
default-features = false
|
||||
features = ["percent-encode"]
|
||||
|
||||
[dev-dependencies]
|
||||
lazy_static = "0.2"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
//! * **port**: _[integer]_ a port number to listen on
|
||||
//! * examples: `"8000"`, `"80"`, `"4242"`
|
||||
//! * **workers**: _[integer]_ the number of concurrent workers to use
|
||||
//! * examples: `"12"`, `"1"`, `"4"`
|
||||
//! * examples: `12`, `1`, `4`
|
||||
//! * **log**: _[string]_ how much information to log; one of `"normal"`,
|
||||
//! `"debug"`, or `"critical"`
|
||||
//! * **session_key**: _[string]_ a 192-bit base64 encoded string (32
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
use http;
|
||||
use http::Header;
|
||||
|
||||
pub use http::hyper::header::CookiePair as Cookie;
|
||||
pub use cookie::Cookie;
|
||||
pub use cookie::CookieJar;
|
||||
pub use cookie::CookieBuilder;
|
||||
|
||||
pub type Cookies = http::hyper::header::CookieJar<'static>;
|
||||
/// Type alias to a `'static` CookieJar.
|
||||
///
|
||||
/// A `CookieJar` should never be used without a `'static` lifetime. As a
|
||||
/// result, you should always use this alias.
|
||||
pub type Cookies = self::CookieJar<'static>;
|
||||
|
||||
impl<'c> From<Cookie<'c>> for Header<'static> {
|
||||
fn from(cookie: Cookie) -> Header<'static> {
|
||||
Header::new("Set-Cookie", cookie.encoded().to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ use std::collections::HashMap;
|
|||
use std::borrow::{Borrow, Cow};
|
||||
use std::fmt;
|
||||
|
||||
use http::hyper::header as hyper;
|
||||
use http::ascii::{UncasedAscii, UncasedAsciiRef};
|
||||
|
||||
/// Simple representation of an HTTP header.
|
||||
|
@ -107,13 +106,6 @@ impl<'h> fmt::Display for Header<'h> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Header<'static> where T: hyper::Header + hyper::HeaderFormat {
|
||||
fn from(hyper_header: T) -> Header<'static> {
|
||||
let formatter = hyper::HeaderFormatter(&hyper_header);
|
||||
Header::new(T::header_name(), format!("{}", formatter))
|
||||
}
|
||||
}
|
||||
|
||||
/// A collection of headers, mapping a header name to its many ordered values.
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
pub struct HeaderMap<'h> {
|
||||
|
@ -345,16 +337,13 @@ impl<'h> HeaderMap<'h> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use rocket::http::{Cookie, HeaderMap};
|
||||
/// use rocket::http::hyper::header;
|
||||
///
|
||||
/// let mut map = HeaderMap::new();
|
||||
///
|
||||
/// let cookie = vec![Cookie::new("a".to_string(), "b".to_string())];
|
||||
/// map.add(header::SetCookie(cookie));
|
||||
/// map.add(Cookie::new("a", "b"));
|
||||
/// assert_eq!(map.get("Set-Cookie").count(), 1);
|
||||
///
|
||||
/// let cookie = vec![Cookie::new("c".to_string(), "d".to_string())];
|
||||
/// map.add(header::SetCookie(cookie));
|
||||
/// map.add(Cookie::new("c", "d"));
|
||||
/// assert_eq!(map.get("Set-Cookie").count(), 2);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
|
|
@ -1,25 +1,79 @@
|
|||
//! Re-exported hyper HTTP library types.
|
||||
//!
|
||||
//! ## Hyper
|
||||
//!
|
||||
//! All types that are re-exported from Hyper resides inside of this module.
|
||||
//! All types that are re-exported from Hyper reside inside of this module.
|
||||
//! These types will, with certainty, be removed with time, but they reside here
|
||||
//! while necessary.
|
||||
|
||||
pub use hyper::server::Request as Request;
|
||||
pub use hyper::server::Response as Response;
|
||||
pub use hyper::server::Server as Server;
|
||||
pub use hyper::server::Handler as Handler;
|
||||
#[doc(hidden)] pub use hyper::server::Request as Request;
|
||||
#[doc(hidden)] pub use hyper::server::Response as Response;
|
||||
#[doc(hidden)] pub use hyper::server::Server as Server;
|
||||
#[doc(hidden)] pub use hyper::server::Handler as Handler;
|
||||
|
||||
|
||||
#[doc(hidden)] pub use hyper::net;
|
||||
|
||||
#[doc(hidden)] pub use hyper::method::Method;
|
||||
#[doc(hidden)] pub use hyper::status::StatusCode;
|
||||
#[doc(hidden)] pub use hyper::uri::RequestUri;
|
||||
#[doc(hidden)] pub use hyper::http::h1;
|
||||
#[doc(hidden)] pub use hyper::buffer;
|
||||
|
||||
pub use hyper::header;
|
||||
pub use hyper::mime;
|
||||
pub use hyper::net;
|
||||
|
||||
pub use hyper::method::Method;
|
||||
pub use hyper::status::StatusCode;
|
||||
pub use hyper::uri::RequestUri;
|
||||
pub use hyper::http::h1;
|
||||
pub use hyper::buffer;
|
||||
|
||||
/// Type alias to `hyper::Response<'a, hyper::net::Fresh>`.
|
||||
pub type FreshResponse<'a> = self::Response<'a, self::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 hyper::header::HeaderFormatter;
|
||||
use hyper::header::Header as HyperHeaderTrait;
|
||||
|
||||
macro_rules! import_hyper_items {
|
||||
($($item:ident),*) => ($(pub use hyper::header::$item;)*)
|
||||
}
|
||||
|
||||
macro_rules! import_hyper_headers {
|
||||
($($name:ident),*) => ($(
|
||||
impl ::std::convert::From<self::$name> for Header<'static> {
|
||||
fn from(header: self::$name) -> Header<'static> {
|
||||
let formatter = HeaderFormatter(&header);
|
||||
Header::new($name::header_name(), format!("{}", formatter))
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
import_hyper_items! {
|
||||
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
|
||||
AccessControlAllowCredentials, AccessControlAllowHeaders,
|
||||
AccessControlAllowMethods, AccessControlExposeHeaders,
|
||||
AccessControlMaxAge, AccessControlRequestHeaders,
|
||||
AccessControlRequestMethod, Allow, Authorization, Basic, Bearer,
|
||||
CacheControl, Connection, ContentDisposition, ContentEncoding,
|
||||
ContentLanguage, ContentLength, ContentRange, ContentType, Date, ETag,
|
||||
EntityTag, Expires, From, Headers, Host, HttpDate, IfModifiedSince,
|
||||
IfUnmodifiedSince, LastModified, Location, Origin, Prefer,
|
||||
PreferenceApplied, Protocol, Quality, QualityItem, Referer,
|
||||
StrictTransportSecurity, TransferEncoding, Upgrade, UserAgent,
|
||||
AccessControlAllowOrigin, ByteRangeSpec, CacheDirective, Charset,
|
||||
ConnectionOption, ContentRangeSpec, DispositionParam, DispositionType,
|
||||
Encoding, Expect, IfMatch, IfNoneMatch, IfRange, Pragma, Preference,
|
||||
ProtocolName, Range, RangeUnit, ReferrerPolicy, Vary, Scheme, q, qitem
|
||||
}
|
||||
|
||||
import_hyper_headers! {
|
||||
Accept, AccessControlAllowCredentials, AccessControlAllowHeaders,
|
||||
AccessControlAllowMethods, AccessControlAllowOrigin,
|
||||
AccessControlExposeHeaders, AccessControlMaxAge,
|
||||
AccessControlRequestHeaders, AccessControlRequestMethod, AcceptCharset,
|
||||
AcceptEncoding, AcceptLanguage, AcceptRanges, Allow, CacheControl,
|
||||
Connection, ContentDisposition, ContentEncoding, ContentLanguage,
|
||||
ContentLength, ContentRange, Date, ETag, Expect, Expires, Host, IfMatch,
|
||||
IfModifiedSince, IfNoneMatch, IfRange, IfUnmodifiedSince, LastModified,
|
||||
Location, Origin, Pragma, Prefer, PreferenceApplied, Range, Referer,
|
||||
ReferrerPolicy, StrictTransportSecurity, TransferEncoding, Upgrade,
|
||||
UserAgent, Vary
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,4 +23,4 @@ pub use self::content_type::ContentType;
|
|||
pub use self::status::{Status, StatusClass};
|
||||
pub use self::header::{Header, HeaderMap};
|
||||
|
||||
pub use self::cookies::{Cookie, Cookies};
|
||||
pub use self::cookies::{Cookie, Cookies, CookieJar, CookieBuilder};
|
||||
|
|
|
@ -97,6 +97,8 @@ extern crate url;
|
|||
extern crate toml;
|
||||
extern crate num_cpus;
|
||||
extern crate state;
|
||||
extern crate cookie;
|
||||
extern crate time;
|
||||
|
||||
#[cfg(test)] #[macro_use] extern crate lazy_static;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::{FromParam, FromSegments};
|
|||
|
||||
use router::Route;
|
||||
use http::uri::{URI, Segments};
|
||||
use http::{Method, ContentType, Header, HeaderMap, Cookies};
|
||||
use http::{Method, ContentType, Header, HeaderMap, Cookie, Cookies};
|
||||
|
||||
use http::hyper;
|
||||
|
||||
|
@ -247,7 +247,8 @@ impl<'r> Request<'r> {
|
|||
/// use rocket::http::{Cookie, Method, ContentType};
|
||||
///
|
||||
/// let mut request = Request::new(Method::Get, "/uri");
|
||||
/// request.cookies().add(Cookie::new("key".into(), "val".into()))
|
||||
/// request.cookies().add(Cookie::new("key", "val"));
|
||||
/// request.cookies().add(Cookie::new("ans", format!("life: {}", 38 + 4)));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn cookies(&self) -> &Cookies {
|
||||
|
@ -255,18 +256,6 @@ impl<'r> Request<'r> {
|
|||
}
|
||||
|
||||
/// Replace all of the cookies in `self` with `cookies`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Add a new cookie to a request's cookies:
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::Request;
|
||||
/// use rocket::http::{Cookie, Method, ContentType};
|
||||
///
|
||||
/// let mut request = Request::new(Method::Get, "/uri");
|
||||
/// request.cookies().add(Cookie::new("key".into(), "val".into()))
|
||||
/// ```
|
||||
#[doc(hidden)]
|
||||
#[inline(always)]
|
||||
pub fn set_cookies(&mut self, cookies: Cookies) {
|
||||
|
@ -430,8 +419,25 @@ impl<'r> Request<'r> {
|
|||
let mut request = Request::new(method, uri);
|
||||
|
||||
// Set the request cookies, if they exist. TODO: Use session key.
|
||||
if let Some(cookies) = h_headers.get::<hyper::header::Cookie>() {
|
||||
request.set_cookies(cookies.to_cookie_jar(&[]));
|
||||
if let Some(cookie_headers) = h_headers.get_raw("Cookie") {
|
||||
let mut cookies = Cookies::new(&[]);
|
||||
for header in cookie_headers {
|
||||
let raw_str = match ::std::str::from_utf8(header) {
|
||||
Ok(string) => string,
|
||||
Err(_) => continue
|
||||
};
|
||||
|
||||
for cookie_str in raw_str.split(";") {
|
||||
let cookie = match Cookie::parse_encoded(cookie_str.to_string()) {
|
||||
Ok(cookie) => cookie,
|
||||
Err(_) => continue
|
||||
};
|
||||
|
||||
cookies.add_original(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
request.set_cookies(cookies);
|
||||
}
|
||||
|
||||
// Set the rest of the headers.
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::convert::AsRef;
|
||||
|
||||
use time::Duration;
|
||||
|
||||
use outcome::IntoOutcome;
|
||||
use response::{Response, Responder};
|
||||
use request::{self, Request, FromRequest};
|
||||
use http::hyper::header;
|
||||
use http::Status;
|
||||
use http::{Status, Cookie};
|
||||
|
||||
// The name of the actual flash cookie.
|
||||
const FLASH_COOKIE_NAME: &'static str = "_flash";
|
||||
|
@ -161,12 +162,12 @@ impl<'r, R: Responder<'r>> Flash<R> {
|
|||
Flash::new(responder, "error", msg)
|
||||
}
|
||||
|
||||
fn cookie_pair(&self) -> header::CookiePair {
|
||||
fn cookie(&self) -> Cookie<'static> {
|
||||
let content = format!("{}{}{}", self.name.len(), self.name, self.message);
|
||||
let mut pair = header::CookiePair::new(FLASH_COOKIE_NAME.to_string(), content);
|
||||
pair.path = Some("/".to_string());
|
||||
pair.max_age = Some(300);
|
||||
pair
|
||||
Cookie::build(FLASH_COOKIE_NAME, content)
|
||||
.max_age(Duration::minutes(5))
|
||||
.path("/")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,9 +178,9 @@ impl<'r, R: Responder<'r>> Flash<R> {
|
|||
impl<'r, R: Responder<'r>> Responder<'r> for Flash<R> {
|
||||
fn respond(self) -> Result<Response<'r>, Status> {
|
||||
trace_!("Flash: setting message: {}:{}", self.name, self.message);
|
||||
let cookie = vec![self.cookie_pair()];
|
||||
let cookie = self.cookie();
|
||||
Response::build_from(self.responder.respond()?)
|
||||
.header_adjoin(header::SetCookie(cookie))
|
||||
.header_adjoin(cookie)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +222,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Flash<()> {
|
|||
request.cookies().remove(FLASH_COOKIE_NAME);
|
||||
|
||||
// Parse the flash.
|
||||
let content = cookie.pair().1;
|
||||
let content = cookie.value();
|
||||
let (len_str, rest) = match content.find(|c: char| !c.is_digit(10)) {
|
||||
Some(i) => (&content[..i], &content[i..]),
|
||||
None => (content, ""),
|
||||
|
|
|
@ -20,7 +20,7 @@ use catcher::{self, Catcher};
|
|||
use outcome::Outcome;
|
||||
use error::Error;
|
||||
|
||||
use http::{Method, Status};
|
||||
use http::{Method, Status, Header};
|
||||
use http::hyper::{self, header};
|
||||
use http::uri::URI;
|
||||
|
||||
|
@ -79,7 +79,7 @@ impl Rocket {
|
|||
fn issue_response(&self, mut response: Response, hyp_res: hyper::FreshResponse) {
|
||||
// Add the 'rocket' server header, and write out the response.
|
||||
// TODO: If removing Hyper, write out `Date` header too.
|
||||
response.set_header(header::Server("rocket".to_string()));
|
||||
response.set_header(Header::new("Server", "rocket"));
|
||||
|
||||
match self.write_response(response, hyp_res) {
|
||||
Ok(_) => info_!("{}", Green.paint("Response succeeded.")),
|
||||
|
@ -192,9 +192,8 @@ impl Rocket {
|
|||
match self.route(request, data) {
|
||||
Outcome::Success(mut response) => {
|
||||
// A user's route responded!
|
||||
let cookie_delta = request.cookies().delta();
|
||||
if !cookie_delta.is_empty() {
|
||||
response.adjoin_header(header::SetCookie(cookie_delta));
|
||||
for cookie in request.cookies().delta() {
|
||||
response.adjoin_header(cookie);
|
||||
}
|
||||
|
||||
response
|
||||
|
|
|
@ -195,10 +195,11 @@ impl<'r> MockRequest<'r> {
|
|||
/// use rocket::http::Cookie;
|
||||
///
|
||||
/// let req = MockRequest::new(Get, "/")
|
||||
/// .cookie(Cookie::new("user_id".into(), "12".into()));
|
||||
/// .cookie(Cookie::new("username", "sb"))
|
||||
/// .cookie(Cookie::new("user_id", format!("{}", 12)));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn cookie(self, cookie: Cookie) -> Self {
|
||||
pub fn cookie(self, cookie: Cookie<'static>) -> Self {
|
||||
self.request.cookies().add(cookie);
|
||||
self
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue