mirror of
https://github.com/ntex-rs/ntex-extras.git
synced 2025-04-03 21:07:40 +03:00
upgrade ntex 0.5 release
This commit is contained in:
parent
74148e3ddf
commit
6ec85aa238
10 changed files with 124 additions and 200 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ntex-cors"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["ntex contributors <team@ntex.rs>"]
|
||||
description = "Cross-origin resource sharing (CORS) for ntex applications."
|
||||
readme = "README.md"
|
||||
|
@ -16,6 +16,9 @@ name = "ntex_cors"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
ntex = "0.3.18"
|
||||
derive_more = "0.99.11"
|
||||
futures = "0.3.13"
|
||||
ntex = "0.5.10"
|
||||
derive_more = "0.99"
|
||||
futures = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
ntex = { version = "0.5", features=["tokio"] }
|
||||
|
|
|
@ -45,19 +45,19 @@
|
|||
//! endpoint.
|
||||
//!
|
||||
//! Cors middleware automatically handle *OPTIONS* preflight request.
|
||||
use std::collections::HashSet;
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::FromIterator;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{
|
||||
collections::HashSet, convert::TryFrom, iter::FromIterator, marker::PhantomData, rc::Rc,
|
||||
};
|
||||
|
||||
use derive_more::Display;
|
||||
use futures::future::{ok, Either, FutureExt, LocalBoxFuture, Ready};
|
||||
use ntex::http::header::{self, HeaderName, HeaderValue};
|
||||
use ntex::http::{error::HttpError, HeaderMap, Method, RequestHead, StatusCode, Uri};
|
||||
use ntex::service::{Service, Transform};
|
||||
use ntex::web::dev::{WebRequest, WebResponse};
|
||||
use ntex::web::{DefaultError, ErrorRenderer, HttpResponse, WebResponseError};
|
||||
use ntex::web::{
|
||||
DefaultError, ErrorRenderer, HttpResponse, WebRequest, WebResponse, WebResponseError,
|
||||
};
|
||||
|
||||
/// A set of errors that can occur during processing CORS
|
||||
#[derive(Debug, Display)]
|
||||
|
@ -196,7 +196,7 @@ impl Cors {
|
|||
}
|
||||
|
||||
/// Build a new CORS default middleware
|
||||
pub fn default() -> CorsFactory {
|
||||
pub fn default<Err>() -> CorsFactory<Err> {
|
||||
let inner = Inner {
|
||||
origins: AllOrSome::default(),
|
||||
origins_str: None,
|
||||
|
@ -220,7 +220,7 @@ impl Cors {
|
|||
supports_credentials: false,
|
||||
vary_header: true,
|
||||
};
|
||||
CorsFactory { inner: Rc::new(inner) }
|
||||
CorsFactory { inner: Rc::new(inner), _t: PhantomData }
|
||||
}
|
||||
|
||||
/// Add an origin that are allowed to make requests.
|
||||
|
@ -462,7 +462,7 @@ impl Cors {
|
|||
}
|
||||
|
||||
/// Construct cors middleware
|
||||
pub fn finish(self) -> CorsFactory {
|
||||
pub fn finish<Err>(self) -> CorsFactory<Err> {
|
||||
let mut slf = if !self.methods {
|
||||
self.allowed_methods(vec![
|
||||
Method::GET,
|
||||
|
@ -503,7 +503,7 @@ impl Cors {
|
|||
);
|
||||
}
|
||||
|
||||
CorsFactory { inner: Rc::new(cors) }
|
||||
CorsFactory { inner: Rc::new(cors), _t: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,27 +716,20 @@ impl Inner {
|
|||
///
|
||||
/// The Cors struct contains the settings for CORS requests to be validated and
|
||||
/// for responses to be generated.
|
||||
pub struct CorsFactory {
|
||||
pub struct CorsFactory<Err> {
|
||||
inner: Rc<Inner>,
|
||||
_t: PhantomData<Err>,
|
||||
}
|
||||
|
||||
impl<S, Err> Transform<S> for CorsFactory
|
||||
impl<S, Err> Transform<S> for CorsFactory<Err>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse>,
|
||||
S: Service<WebRequest<Err>, Response = WebResponse>,
|
||||
S::Future: 'static,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<S::Error>,
|
||||
CorsError: WebResponseError<Err>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
type Transform = CorsMiddleware<S>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
type Service = CorsMiddleware<S>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(CorsMiddleware { service, inner: self.inner.clone() })
|
||||
fn new_transform(&self, service: S) -> Self::Service {
|
||||
CorsMiddleware { service, inner: self.inner.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -750,15 +743,14 @@ pub struct CorsMiddleware<S> {
|
|||
inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
impl<S, Err> Service for CorsMiddleware<S>
|
||||
impl<S, Err> Service<WebRequest<Err>> for CorsMiddleware<S>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse>,
|
||||
S: Service<WebRequest<Err>, Response = WebResponse>,
|
||||
S::Future: 'static,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<S::Error>,
|
||||
CorsError: WebResponseError<Err>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type Future = Either<
|
||||
|
@ -803,19 +795,20 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ntex::service::{fn_service, Transform};
|
||||
use ntex::web::test::{self, TestRequest};
|
||||
use ntex::web::{self, test, test::TestRequest};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[ntex::test]
|
||||
#[should_panic(expected = "Credentials are allowed, but the Origin is set to")]
|
||||
async fn cors_validates_illegal_allow_credentials() {
|
||||
let _cors = Cors::new().supports_credentials().send_wildcard().finish();
|
||||
let _cors =
|
||||
Cors::new().supports_credentials().send_wildcard().finish::<web::DefaultError>();
|
||||
}
|
||||
|
||||
#[ntex::test]
|
||||
async fn validate_origin_allows_all_origins() {
|
||||
let cors = Cors::new().finish().new_transform(test::ok_service()).await.unwrap();
|
||||
let cors = Cors::new().finish().new_transform(test::ok_service());
|
||||
let req =
|
||||
TestRequest::with_header("Origin", "https://www.example.com").to_srv_request();
|
||||
|
||||
|
@ -825,7 +818,7 @@ mod tests {
|
|||
|
||||
#[ntex::test]
|
||||
async fn default() {
|
||||
let cors = Cors::default().new_transform(test::ok_service()).await.unwrap();
|
||||
let cors = Cors::default().new_transform(test::ok_service());
|
||||
let req =
|
||||
TestRequest::with_header("Origin", "https://www.example.com").to_srv_request();
|
||||
|
||||
|
@ -842,9 +835,7 @@ mod tests {
|
|||
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
|
@ -923,9 +914,7 @@ mod tests {
|
|||
let cors = Cors::new()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service::<web::DefaultError>());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.unknown.com")
|
||||
.method(Method::GET)
|
||||
|
@ -940,9 +929,7 @@ mod tests {
|
|||
let cors = Cors::new()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::GET)
|
||||
|
@ -954,12 +941,7 @@ mod tests {
|
|||
|
||||
#[ntex::test]
|
||||
async fn test_no_origin_response() {
|
||||
let cors = Cors::new()
|
||||
.disable_preflight()
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let cors = Cors::new().disable_preflight().finish().new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::default().method(Method::GET).to_srv_request();
|
||||
let resp = test::call_service(&cors, req).await;
|
||||
|
@ -987,9 +969,7 @@ mod tests {
|
|||
.expose_headers(exposed_headers.clone())
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
|
@ -1033,9 +1013,7 @@ mod tests {
|
|||
ok::<_, std::convert::Infallible>(req.into_response(
|
||||
HttpResponse::Ok().header(header::VARY, "Accept").finish(),
|
||||
))
|
||||
}))
|
||||
.await
|
||||
.unwrap();
|
||||
}));
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
.to_srv_request();
|
||||
|
@ -1050,9 +1028,7 @@ mod tests {
|
|||
.allowed_origin("https://www.example.com")
|
||||
.allowed_origin("https://www.google.com")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
|
@ -1073,9 +1049,7 @@ mod tests {
|
|||
.allowed_origin("https://example.org")
|
||||
.allowed_methods(vec![Method::GET])
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://example.com")
|
||||
.method(Method::GET)
|
||||
|
@ -1105,9 +1079,7 @@ mod tests {
|
|||
.allowed_origin("https://example.org")
|
||||
.allowed_methods(vec![Method::GET])
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
.new_transform(test::ok_service());
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://example.com")
|
||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET")
|
||||
|
|
|
@ -18,16 +18,16 @@ name = "ntex_files"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
ntex = "0.3.18"
|
||||
bitflags = "1.2"
|
||||
ntex = "0.5.10"
|
||||
bitflags = "1.3"
|
||||
futures = "0.3"
|
||||
derive_more = "0.99.11"
|
||||
derive_more = "0.99"
|
||||
hyperx = "1.0.0"
|
||||
log = "0.4"
|
||||
mime = "0.3"
|
||||
mime_guess = "2.0.1"
|
||||
percent-encoding = "2.1"
|
||||
v_htmlescape = "0.13"
|
||||
v_htmlescape = "0.14.1"
|
||||
|
||||
[dev-dependencies]
|
||||
ntex = { version = "0.3.18", features=["openssl", "compress"] }
|
||||
ntex = { version = "0.5", features=["tokio", "openssl", "compress"] }
|
||||
|
|
|
@ -17,10 +17,10 @@ use ntex::router::{ResourceDef, ResourcePath};
|
|||
use ntex::service::boxed::{self, BoxService, BoxServiceFactory};
|
||||
use ntex::service::{IntoServiceFactory, Service, ServiceFactory};
|
||||
use ntex::util::Bytes;
|
||||
use ntex::web::dev::{WebRequest, WebResponse, WebServiceConfig, WebServiceFactory};
|
||||
use ntex::web::dev::{WebServiceConfig, WebServiceFactory};
|
||||
use ntex::web::error::ErrorRenderer;
|
||||
use ntex::web::guard::Guard;
|
||||
use ntex::web::{self, FromRequest, HttpRequest, HttpResponse};
|
||||
use ntex::web::{self, FromRequest, HttpRequest, HttpResponse, WebRequest, WebResponse};
|
||||
use percent_encoding::{utf8_percent_encode, CONTROLS};
|
||||
use v_htmlescape::escape as escape_html_entity;
|
||||
|
||||
|
@ -366,13 +366,9 @@ impl<Err: ErrorRenderer> Files<Err> {
|
|||
/// Sets default handler which is used when no matched file could be found.
|
||||
pub fn default_handler<F, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: IntoServiceFactory<U>,
|
||||
U: ServiceFactory<
|
||||
Config = (),
|
||||
Request = WebRequest<Err>,
|
||||
Response = WebResponse,
|
||||
Error = Err::Container,
|
||||
> + 'static,
|
||||
F: IntoServiceFactory<U, WebRequest<Err>>,
|
||||
U: ServiceFactory<WebRequest<Err>, Response = WebResponse, Error = Err::Container>
|
||||
+ 'static,
|
||||
{
|
||||
// create and configure default resource
|
||||
self.default = Some(Rc::new(boxed::factory(f.into_factory().map_init_err(|_| ()))));
|
||||
|
@ -399,15 +395,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Err> ServiceFactory for Files<Err>
|
||||
impl<Err> ServiceFactory<WebRequest<Err>> for Files<Err>
|
||||
where
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<FilesError>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = Err::Container;
|
||||
type Config = ();
|
||||
type Service = FilesService<Err>;
|
||||
type InitError = ();
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
|
||||
|
@ -475,12 +469,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Err> Service for FilesService<Err>
|
||||
impl<Err> Service<WebRequest<Err>> for FilesService<Err>
|
||||
where
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<FilesError>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = Err::Container;
|
||||
type Future = Either<
|
||||
|
|
|
@ -21,10 +21,13 @@ default = ["cookie-policy"]
|
|||
cookie-policy = ["cookie/secure", "ntex/cookie"]
|
||||
|
||||
[dependencies]
|
||||
ntex = "0.3.18"
|
||||
futures = "0.3.13"
|
||||
ntex = "0.5.10"
|
||||
futures = "0.3"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
derive_more = "0.99.11"
|
||||
cookie = { version = "0.15", features = ["private"] }
|
||||
time = { version = "0.2.5", default-features = false, features = ["std"] }
|
||||
derive_more = "0.99"
|
||||
cookie = { version = "0.16", features = ["private"] }
|
||||
time = { version = "0.3", default-features = false, features = ["std"] }
|
||||
|
||||
[dev-dependencies]
|
||||
ntex = { version = "0.5", features=["tokio"] }
|
||||
|
|
|
@ -44,12 +44,9 @@
|
|||
//! .service(web::resource("/login.html").to(login))
|
||||
//! .service(web::resource("/logout.html").to(logout));
|
||||
//! ```
|
||||
use std::convert::Infallible;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
use std::time::SystemTime;
|
||||
use std::{convert::Infallible, future::Future, rc::Rc};
|
||||
|
||||
use cookie::{Cookie, CookieJar, Key, SameSite};
|
||||
use derive_more::{Display, From};
|
||||
|
@ -62,8 +59,10 @@ use ntex::http::header::{self, HeaderValue};
|
|||
use ntex::http::{HttpMessage, Payload};
|
||||
use ntex::service::{Service, Transform};
|
||||
use ntex::util::Extensions;
|
||||
use ntex::web::dev::{WebRequest, WebResponse};
|
||||
use ntex::web::{DefaultError, ErrorRenderer, FromRequest, HttpRequest, WebResponseError};
|
||||
use ntex::web::{
|
||||
DefaultError, ErrorRenderer, FromRequest, HttpRequest, WebRequest, WebResponse,
|
||||
WebResponseError,
|
||||
};
|
||||
|
||||
/// The extractor type to obtain your identity from a request.
|
||||
///
|
||||
|
@ -210,66 +209,46 @@ pub trait IdentityPolicy<Err>: Sized + 'static {
|
|||
/// .secure(false),
|
||||
/// ));
|
||||
/// ```
|
||||
pub struct IdentityService<T, Err> {
|
||||
pub struct IdentityService<T> {
|
||||
backend: Rc<T>,
|
||||
_t: PhantomData<Err>,
|
||||
}
|
||||
|
||||
impl<T, Err> IdentityService<T, Err> {
|
||||
impl<T> IdentityService<T> {
|
||||
/// Create new identity service with specified backend.
|
||||
pub fn new(backend: T) -> Self {
|
||||
IdentityService { backend: Rc::new(backend), _t: PhantomData }
|
||||
IdentityService { backend: Rc::new(backend) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T, Err> Transform<S> for IdentityService<T, Err>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse> + 'static,
|
||||
S::Future: 'static,
|
||||
T: IdentityPolicy<Err>,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<S::Error>,
|
||||
Err::Container: From<T::Error>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
type Transform = IdentityServiceMiddleware<S, T, Err>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
impl<S, T> Transform<S> for IdentityService<T> {
|
||||
type Service = IdentityServiceMiddleware<S, T>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(IdentityServiceMiddleware {
|
||||
backend: self.backend.clone(),
|
||||
service: Rc::new(service),
|
||||
_t: PhantomData,
|
||||
})
|
||||
fn new_transform(&self, service: S) -> Self::Service {
|
||||
IdentityServiceMiddleware { backend: self.backend.clone(), service: Rc::new(service) }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct IdentityServiceMiddleware<S, T, Err> {
|
||||
pub struct IdentityServiceMiddleware<S, T> {
|
||||
backend: Rc<T>,
|
||||
service: Rc<S>,
|
||||
_t: PhantomData<Err>,
|
||||
}
|
||||
|
||||
impl<S, T, Err> Clone for IdentityServiceMiddleware<S, T, Err> {
|
||||
impl<S, T> Clone for IdentityServiceMiddleware<S, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { backend: self.backend.clone(), service: self.service.clone(), _t: PhantomData }
|
||||
Self { backend: self.backend.clone(), service: self.service.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T, Err> Service for IdentityServiceMiddleware<S, T, Err>
|
||||
impl<S, T, Err> Service<WebRequest<Err>> for IdentityServiceMiddleware<S, T>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse> + 'static,
|
||||
S: Service<WebRequest<Err>, Response = WebResponse> + 'static,
|
||||
S::Future: 'static,
|
||||
T: IdentityPolicy<Err>,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<S::Error>,
|
||||
Err::Container: From<T::Error>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
@ -313,7 +292,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
struct CookieIdentityInner<Err> {
|
||||
struct CookieIdentityInner {
|
||||
key: Key,
|
||||
key_v2: Key,
|
||||
name: String,
|
||||
|
@ -324,7 +303,6 @@ struct CookieIdentityInner<Err> {
|
|||
same_site: Option<SameSite>,
|
||||
visit_deadline: Option<Duration>,
|
||||
login_deadline: Option<Duration>,
|
||||
_t: PhantomData<Err>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
|
@ -341,8 +319,8 @@ struct CookieIdentityExtention {
|
|||
login_timestamp: Option<SystemTime>,
|
||||
}
|
||||
|
||||
impl<Err: ErrorRenderer> CookieIdentityInner<Err> {
|
||||
fn new(key: &[u8]) -> CookieIdentityInner<Err> {
|
||||
impl CookieIdentityInner {
|
||||
fn new(key: &[u8]) -> CookieIdentityInner {
|
||||
let key_v2: Vec<u8> = key.iter().chain([1, 0, 0, 0].iter()).cloned().collect();
|
||||
CookieIdentityInner {
|
||||
key: Key::derive_from(key),
|
||||
|
@ -355,7 +333,6 @@ impl<Err: ErrorRenderer> CookieIdentityInner<Err> {
|
|||
same_site: None,
|
||||
visit_deadline: None,
|
||||
login_deadline: None,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,15 +354,12 @@ impl<Err: ErrorRenderer> CookieIdentityInner<Err> {
|
|||
cookie.set_path(self.path.clone());
|
||||
cookie.set_secure(self.secure);
|
||||
cookie.set_http_only(true);
|
||||
cookie.set_max_age(self.max_age);
|
||||
|
||||
if let Some(ref domain) = self.domain {
|
||||
cookie.set_domain(domain.clone());
|
||||
}
|
||||
|
||||
if let Some(max_age) = self.max_age {
|
||||
cookie.set_max_age(max_age);
|
||||
}
|
||||
|
||||
if let Some(same_site) = self.same_site {
|
||||
cookie.set_same_site(same_site);
|
||||
}
|
||||
|
@ -405,7 +379,7 @@ impl<Err: ErrorRenderer> CookieIdentityInner<Err> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn load(&self, req: &WebRequest<Err>) -> Option<CookieValue> {
|
||||
fn load<Err>(&self, req: &WebRequest<Err>) -> Option<CookieValue> {
|
||||
let cookie = req.cookie(&self.name)?;
|
||||
let mut jar = CookieJar::new();
|
||||
jar.add_original(cookie.clone());
|
||||
|
@ -472,7 +446,7 @@ impl<Err: ErrorRenderer> CookieIdentityInner<Err> {
|
|||
/// .secure(true),
|
||||
/// ));
|
||||
/// ```
|
||||
pub struct CookieIdentityPolicy<Err>(Rc<CookieIdentityInner<Err>>);
|
||||
pub struct CookieIdentityPolicy(Rc<CookieIdentityInner>);
|
||||
|
||||
#[derive(Debug, Display, From)]
|
||||
pub enum CookieIdentityPolicyError {
|
||||
|
@ -482,7 +456,7 @@ pub enum CookieIdentityPolicyError {
|
|||
|
||||
impl WebResponseError<DefaultError> for CookieIdentityPolicyError {}
|
||||
|
||||
impl<Err: ErrorRenderer> CookieIdentityPolicy<Err> {
|
||||
impl CookieIdentityPolicy {
|
||||
/// Construct new `CookieIdentityPolicy` instance.
|
||||
///
|
||||
/// Panics if key length is less than 32 bytes.
|
||||
|
@ -551,7 +525,7 @@ impl<Err: ErrorRenderer> CookieIdentityPolicy<Err> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Err: ErrorRenderer> IdentityPolicy<Err> for CookieIdentityPolicy<Err> {
|
||||
impl<Err: ErrorRenderer> IdentityPolicy<Err> for CookieIdentityPolicy {
|
||||
type Error = CookieIdentityPolicyError;
|
||||
type Future = Ready<Result<Option<String>, CookieIdentityPolicyError>>;
|
||||
type ResponseFuture = Ready<Result<(), CookieIdentityPolicyError>>;
|
||||
|
@ -610,10 +584,9 @@ mod tests {
|
|||
use std::borrow::Borrow;
|
||||
|
||||
use super::*;
|
||||
use ntex::http::StatusCode;
|
||||
use ntex::service::into_service;
|
||||
use ntex::web::test::{self, TestRequest};
|
||||
use ntex::web::{self, error, App, Error, HttpResponse};
|
||||
use ntex::{http::StatusCode, service::into_service, time};
|
||||
|
||||
const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
|
||||
const COOKIE_NAME: &'static str = "ntex_auth";
|
||||
|
@ -731,18 +704,11 @@ mod tests {
|
|||
}
|
||||
|
||||
async fn create_identity_server<
|
||||
F: Fn(CookieIdentityPolicy<DefaultError>) -> CookieIdentityPolicy<DefaultError>
|
||||
+ Sync
|
||||
+ Send
|
||||
+ Clone
|
||||
+ 'static,
|
||||
F: Fn(CookieIdentityPolicy) -> CookieIdentityPolicy + Sync + Send + Clone + 'static,
|
||||
>(
|
||||
f: F,
|
||||
) -> impl ntex::service::Service<
|
||||
Request = ntex::http::Request,
|
||||
Response = WebResponse,
|
||||
Error = Error,
|
||||
> {
|
||||
) -> impl ntex::service::Service<ntex::http::Request, Response = WebResponse, Error = Error>
|
||||
{
|
||||
test::init_service(
|
||||
App::new()
|
||||
.wrap(IdentityService::new(f(CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
||||
|
@ -1051,10 +1017,9 @@ mod tests {
|
|||
let srv = IdentityServiceMiddleware {
|
||||
backend: Rc::new(Ident),
|
||||
service: Rc::new(into_service(|_: WebRequest<DefaultError>| async move {
|
||||
ntex::rt::time::delay_for(std::time::Duration::from_secs(100)).await;
|
||||
time::sleep(time::Seconds(100)).await;
|
||||
Err::<WebResponse, _>(error::ErrorBadRequest("error"))
|
||||
})),
|
||||
_t: PhantomData,
|
||||
};
|
||||
|
||||
let srv2 = srv.clone();
|
||||
|
@ -1062,7 +1027,7 @@ mod tests {
|
|||
ntex::rt::spawn(async move {
|
||||
let _ = srv2.call(req).await;
|
||||
});
|
||||
ntex::rt::time::delay_for(std::time::Duration::from_millis(50)).await;
|
||||
time::sleep(time::Millis(50)).await;
|
||||
|
||||
let _ = lazy(|cx| srv.poll_ready(cx)).await;
|
||||
}
|
||||
|
|
|
@ -16,10 +16,13 @@ name = "ntex_multipart"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
ntex = "0.3.18"
|
||||
derive_more = "0.99.11"
|
||||
ntex = "0.5.10"
|
||||
derive_more = "0.99"
|
||||
httparse = "1.3"
|
||||
futures = "0.3.13"
|
||||
futures = "0.3"
|
||||
log = "0.4"
|
||||
mime = "0.3"
|
||||
twoway = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
ntex = { version = "0.5", features=["tokio"] }
|
||||
|
|
|
@ -22,10 +22,13 @@ default = ["cookie-session"]
|
|||
cookie-session = ["cookie/secure", "ntex/cookie"]
|
||||
|
||||
[dependencies]
|
||||
ntex = "0.3.18"
|
||||
cookie = "0.15"
|
||||
derive_more = "0.99.11"
|
||||
futures = "0.3.13"
|
||||
ntex = "0.5.10"
|
||||
cookie = "0.16"
|
||||
derive_more = "0.99"
|
||||
futures = "0.3"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
time = { version = "0.2.5", default-features = false, features = ["std"] }
|
||||
time = { version = "0.3", default-features = false, features = ["std"] }
|
||||
|
||||
[dev-dependencies]
|
||||
ntex = { version = "0.5", features=["tokio"] }
|
||||
|
|
|
@ -17,18 +17,16 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
use std::convert::Infallible;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use cookie::{Cookie, CookieJar, Key, SameSite};
|
||||
use derive_more::{Display, From};
|
||||
use futures::future::{ok, FutureExt, LocalBoxFuture, Ready};
|
||||
use futures::future::{FutureExt, LocalBoxFuture};
|
||||
use ntex::http::header::{HeaderValue, SET_COOKIE};
|
||||
use ntex::http::HttpMessage;
|
||||
use ntex::service::{Service, Transform};
|
||||
use ntex::web::dev::{WebRequest, WebResponse};
|
||||
use ntex::web::{DefaultError, ErrorRenderer, WebResponseError};
|
||||
use ntex::web::{DefaultError, ErrorRenderer, WebRequest, WebResponse, WebResponseError};
|
||||
use serde_json::error::Error as JsonError;
|
||||
use time::{Duration, OffsetDateTime};
|
||||
|
||||
|
@ -52,7 +50,7 @@ enum CookieSecurity {
|
|||
Private,
|
||||
}
|
||||
|
||||
struct CookieSessionInner<Err> {
|
||||
struct CookieSessionInner {
|
||||
key: Key,
|
||||
security: CookieSecurity,
|
||||
name: String,
|
||||
|
@ -63,10 +61,9 @@ struct CookieSessionInner<Err> {
|
|||
max_age: Option<Duration>,
|
||||
expires_in: Option<Duration>,
|
||||
same_site: Option<SameSite>,
|
||||
_t: PhantomData<Err>,
|
||||
}
|
||||
|
||||
impl<Err> CookieSessionInner<Err> {
|
||||
impl CookieSessionInner {
|
||||
fn new(key: &[u8], security: CookieSecurity) -> Self {
|
||||
CookieSessionInner {
|
||||
security,
|
||||
|
@ -79,7 +76,6 @@ impl<Err> CookieSessionInner<Err> {
|
|||
max_age: None,
|
||||
expires_in: None,
|
||||
same_site: None,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +130,7 @@ impl<Err> CookieSessionInner<Err> {
|
|||
fn remove_cookie(&self, res: &mut WebResponse) -> Result<(), Infallible> {
|
||||
let mut cookie = Cookie::named(self.name.clone());
|
||||
cookie.set_value("");
|
||||
cookie.set_max_age(Duration::zero());
|
||||
cookie.set_max_age(Duration::ZERO);
|
||||
cookie.set_expires(OffsetDateTime::now_utc() - Duration::days(365));
|
||||
|
||||
let val = HeaderValue::from_str(&cookie.to_string()).unwrap();
|
||||
|
@ -143,7 +139,7 @@ impl<Err> CookieSessionInner<Err> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn load(&self, req: &WebRequest<Err>) -> (bool, HashMap<String, String>) {
|
||||
fn load<Err>(&self, req: &WebRequest<Err>) -> (bool, HashMap<String, String>) {
|
||||
if let Ok(cookies) = req.cookies() {
|
||||
for cookie in cookies.iter() {
|
||||
if cookie.name() == self.name {
|
||||
|
@ -206,9 +202,9 @@ impl<Err> CookieSessionInner<Err> {
|
|||
/// .secure(true))
|
||||
/// .service(web::resource("/").to(|| async { HttpResponse::Ok() }));
|
||||
/// ```
|
||||
pub struct CookieSession<Err>(Rc<CookieSessionInner<Err>>);
|
||||
pub struct CookieSession(Rc<CookieSessionInner>);
|
||||
|
||||
impl<Err> CookieSession<Err> {
|
||||
impl CookieSession {
|
||||
/// Construct new *signed* `CookieSessionBackend` instance.
|
||||
///
|
||||
/// Panics if key length is less than 32 bytes.
|
||||
|
@ -285,41 +281,28 @@ impl<Err> CookieSession<Err> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, Err> Transform<S> for CookieSession<Err>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<CookieSessionError>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
type Transform = CookieSessionMiddleware<S, Err>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
impl<S> Transform<S> for CookieSession {
|
||||
type Service = CookieSessionMiddleware<S>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(CookieSessionMiddleware { service, inner: self.0.clone() })
|
||||
fn new_transform(&self, service: S) -> Self::Service {
|
||||
CookieSessionMiddleware { service, inner: self.0.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Cookie session middleware
|
||||
pub struct CookieSessionMiddleware<S, Err> {
|
||||
pub struct CookieSessionMiddleware<S> {
|
||||
service: S,
|
||||
inner: Rc<CookieSessionInner<Err>>,
|
||||
inner: Rc<CookieSessionInner>,
|
||||
}
|
||||
|
||||
impl<S, Err> Service for CookieSessionMiddleware<S, Err>
|
||||
impl<S, Err> Service<WebRequest<Err>> for CookieSessionMiddleware<S>
|
||||
where
|
||||
S: Service<Request = WebRequest<Err>, Response = WebResponse>,
|
||||
S: Service<WebRequest<Err>, Response = WebResponse>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
Err: ErrorRenderer,
|
||||
Err::Container: From<CookieSessionError>,
|
||||
{
|
||||
type Request = WebRequest<Err>;
|
||||
type Response = WebResponse;
|
||||
type Error = S::Error;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
@ -382,8 +365,8 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ntex::util::Bytes;
|
||||
use ntex::web::{self, test, App};
|
||||
use ntex::{time, util::Bytes};
|
||||
|
||||
#[ntex::test]
|
||||
async fn cookie_session() {
|
||||
|
@ -494,7 +477,7 @@ mod tests {
|
|||
.expires()
|
||||
.expect("Expiration is set");
|
||||
|
||||
ntex::rt::time::delay_for(std::time::Duration::from_secs(1)).await;
|
||||
time::sleep(time::Seconds::ONE).await;
|
||||
|
||||
let request = test::TestRequest::with_uri("/test/").to_request();
|
||||
let response = app.call(request).await.unwrap();
|
||||
|
|
|
@ -49,8 +49,7 @@ use std::rc::Rc;
|
|||
use futures::future::{ok, Ready};
|
||||
use ntex::http::{Payload, RequestHead};
|
||||
use ntex::util::Extensions;
|
||||
use ntex::web::dev::{WebRequest, WebResponse};
|
||||
use ntex::web::{Error, FromRequest, HttpRequest};
|
||||
use ntex::web::{Error, FromRequest, HttpRequest, WebRequest, WebResponse};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue