Basic cookie extractor (#114)

* Basic cookie extractor

* Update futures-preview and pin-utils

* Clean up as discussed in the PR

* minimal docs added

* change as per new extract trait

* fix cookie extractor example
This commit is contained in:
Murali 2019-01-25 03:27:41 +11:00 committed by Yoshua Wuyts
parent bf1e3d8103
commit fd575921f8
5 changed files with 77 additions and 0 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ dist/
npm-debug.log*
Cargo.lock
.DS_Store
.idea

View File

@ -24,6 +24,7 @@ serde_qs = "0.4.1"
slog = "2.4.1"
slog-term = "2.4.0"
slog-async = "2.3.0"
cookie="0.11"
path-table = "1.0.0"
[dependencies.multipart]

View File

@ -0,0 +1,18 @@
#![feature(async_await, futures_api)]
use tide::Cookies;
/// Tide will use the the `Cookies`'s `Extract` implementation to build this parameter.
///
async fn hello_cookies(cookies: Cookies) -> String {
format!("hello cookies: {:?}", cookies)
}
fn main() {
let mut app = tide::App::new(());
app.at("/").get(hello_cookies);
let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve();
}

55
src/cookies.rs Normal file
View File

@ -0,0 +1,55 @@
use cookie::{Cookie, CookieJar, ParseError};
use futures::future;
use crate::{configuration::Store, response::IntoResponse, Extract, Request, Response, RouteMatch};
/// A representation of cookies which wraps `CookieJar` from `cookie` crate
///
/// Currently this only exposes getting cookie by name but future enhancements might allow more
/// operation. `Cookies` implements`Extract` so that handler methods can have a `Cookies` parameter.
///
#[derive(Clone, Debug)]
pub struct Cookies {
content: CookieJar,
}
impl Cookies {
/// returns a `Cookie` by name of the cookie
#[inline]
pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {
self.content.get(name)
}
}
impl<S: 'static> Extract<S> for Cookies {
type Fut = future::Ready<Result<Self, Response>>;
fn extract(
data: &mut S,
req: &mut Request,
params: &Option<RouteMatch<'_>>,
store: &Store,
) -> Self::Fut {
let cookie_jar = match req.headers().get("Cookie") {
Some(raw_cookies) => parse_from_header(raw_cookies.to_str().unwrap()),
_ => Ok(CookieJar::new()),
};
let resp = cookie_jar
.map(|c| Cookies { content: c })
.map_err(|_e| http::status::StatusCode::BAD_REQUEST.into_response());
future::ready(resp)
}
}
fn parse_from_header(s: &str) -> Result<CookieJar, ParseError> {
let mut jar = CookieJar::new();
s.split(';').try_for_each(|s| -> Result<_, ParseError> {
jar.add(Cookie::parse(s.trim().to_owned())?);
Ok(())
})?;
Ok(jar)
}

View File

@ -14,6 +14,7 @@
mod app;
pub mod body;
pub mod configuration;
mod cookies;
mod endpoint;
mod extract;
pub mod head;
@ -25,6 +26,7 @@ mod router;
pub use crate::{
app::{App, AppData},
configuration::ExtractConfiguration,
cookies::Cookies,
endpoint::Endpoint,
extract::Extract,
middleware::Middleware,