remove cookies feature from http crate

This commit is contained in:
Rob Ede 2021-04-08 20:49:20 +01:00
parent 913b69893f
commit adc94f505d
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
11 changed files with 33 additions and 213 deletions

View File

@ -18,10 +18,6 @@ edition = "2018"
# features that docs.rs will build with
features = ["openssl", "rustls", "compress", "secure-cookies"]
[badges]
travis-ci = { repository = "actix/actix-web", branch = "master" }
codecov = { repository = "actix/actix-web", branch = "master", service = "github" }
[lib]
name = "actix_web"
path = "src/lib.rs"
@ -46,10 +42,10 @@ default = ["compress", "cookies"]
compress = ["actix-http/compress"]
# support for cookies
cookies = ["actix-http/cookies"]
cookies = ["cookie"]
# secure cookies feature
secure-cookies = ["actix-http/secure-cookies"]
secure-cookies = ["cookie/secure"]
# openssl
openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"]
@ -88,7 +84,7 @@ actix-http = "3.0.0-beta.5"
ahash = "0.7"
bytes = "1"
cookie = "0.15"
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
derive_more = "0.99.5"
either = "1.5.3"
encoding_rs = "0.8"

View File

@ -16,7 +16,7 @@ edition = "2018"
[package.metadata.docs.rs]
# features that docs.rs will build with
features = ["openssl", "rustls", "compress", "cookies", "secure-cookies"]
features = ["openssl", "rustls", "compress"]
[lib]
name = "actix_http"
@ -34,12 +34,6 @@ rustls = ["actix-tls/rustls"]
# enable compression support
compress = ["flate2", "brotli2"]
# support for cookies
cookies = ["cookie"]
# support for secure cookies
secure-cookies = ["cookies", "cookie/secure"]
# trust-dns as client dns resolver
trust-dns = ["trust-dns-resolver"]
@ -55,7 +49,6 @@ base64 = "0.13"
bitflags = "1.2"
bytes = "1"
bytestring = "1"
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
derive_more = "0.99.5"
encoding_rs = "0.8"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
@ -95,7 +88,7 @@ actix-tls = { version = "3.0.0-beta.5", features = ["openssl"] }
criterion = "0.3"
env_logger = "0.8"
rcgen = "0.8"
serde_derive = "1.0"
serde = { version = "1.0", features = ["derive"] }
tls-openssl = { version = "0.10", package = "openssl" }
tls-rustls = { version = "0.19", package = "rustls" }

View File

@ -53,9 +53,6 @@ pub mod h2;
pub mod test;
pub mod ws;
#[cfg(feature = "cookies")]
use cookie;
pub use self::builder::HttpServiceBuilder;
pub use self::config::{KeepAlive, ServiceConfig};
pub use self::error::{Error, ResponseError, Result};
@ -76,8 +73,6 @@ pub mod http {
pub use http::{uri, Error, Uri};
pub use http::{Method, StatusCode, Version};
#[cfg(feature = "cookies")]
pub use crate::cookie::{Cookie, CookieBuilder};
pub use crate::header::HeaderMap;
/// A collection of HTTP headers and helpers.

View File

@ -5,8 +5,6 @@ use std::{
fmt, net, str,
};
#[cfg(feature = "cookies")]
use cookie::{Cookie, ParseError as CookieParseError};
use http::{header, Method, Uri, Version};
use crate::{
@ -17,9 +15,6 @@ use crate::{
HttpMessage,
};
#[cfg(feature = "cookies")]
struct Cookies(Vec<Cookie<'static>>);
/// Request
pub struct Request<P = PayloadStream> {
pub(crate) payload: Payload<P>,
@ -175,42 +170,6 @@ impl<P> Request<P> {
pub fn peer_addr(&self) -> Option<net::SocketAddr> {
self.head().peer_addr
}
/// Load request cookies.
#[cfg(feature = "cookies")]
pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
if self.extensions().get::<Cookies>().is_none() {
let mut cookies = Vec::new();
for hdr in self.headers().get_all(header::COOKIE) {
let s =
str::from_utf8(hdr.as_bytes()).map_err(CookieParseError::from)?;
for cookie_str in s.split(';').map(|s| s.trim()) {
if !cookie_str.is_empty() {
cookies.push(Cookie::parse_encoded(cookie_str)?.into_owned());
}
}
}
self.extensions_mut().insert(Cookies(cookies));
}
Ok(Ref::map(self.extensions(), |ext| {
&ext.get::<Cookies>().unwrap().0
}))
}
/// Return request cookie.
#[cfg(feature = "cookies")]
pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
if let Ok(cookies) = self.cookies() {
for cookie in cookies.iter() {
if cookie.name() == name {
return Some(cookie.to_owned());
}
}
}
None
}
}
impl<P> fmt::Debug for Request<P> {

View File

@ -25,11 +25,6 @@ use crate::{
},
message::{BoxedResponseHead, ConnectionType, ResponseHead},
};
#[cfg(feature = "cookies")]
use crate::{
cookie::{Cookie, CookieJar},
http::header::HeaderValue,
};
/// An HTTP Response
pub struct Response<B = Body> {
@ -248,34 +243,12 @@ impl Future for Response {
}
}
#[cfg(feature = "cookies")]
pub struct CookieIter<'a> {
iter: header::GetAll<'a>,
}
#[cfg(feature = "cookies")]
impl<'a> Iterator for CookieIter<'a> {
type Item = Cookie<'a>;
#[inline]
fn next(&mut self) -> Option<Cookie<'a>> {
for v in self.iter.by_ref() {
if let Ok(c) = Cookie::parse_encoded(v.to_str().ok()?) {
return Some(c);
}
}
None
}
}
/// An HTTP response builder.
///
/// This type can be used to construct an instance of `Response` through a builder-like pattern.
pub struct ResponseBuilder {
head: Option<BoxedResponseHead>,
err: Option<HttpError>,
#[cfg(feature = "cookies")]
cookies: Option<CookieJar>,
}
impl ResponseBuilder {
@ -285,8 +258,6 @@ impl ResponseBuilder {
ResponseBuilder {
head: Some(BoxedResponseHead::new(status)),
err: None,
#[cfg(feature = "cookies")]
cookies: None,
}
}
@ -353,7 +324,10 @@ impl ResponseBuilder {
}
/// Replaced with [`Self::insert_header()`].
#[deprecated = "Replaced with `insert_header((key, value))`."]
#[deprecated(
since = "4.0.0",
note = "Replaced with `insert_header((key, value))`. Will be removed in v5."
)]
pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
where
K: TryInto<HeaderName>,
@ -374,7 +348,10 @@ impl ResponseBuilder {
}
/// Replaced with [`Self::append_header()`].
#[deprecated = "Replaced with `append_header((key, value))`."]
#[deprecated(
since = "4.0.0",
note = "Replaced with `append_header((key, value))`. Will be removed in v5."
)]
pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Self
where
K: TryInto<HeaderName>,
@ -467,89 +444,6 @@ impl ResponseBuilder {
self
}
/// Set a cookie
///
/// ```
/// use actix_http::{http, Request, Response};
///
/// fn index(req: Request) -> Response {
/// Response::Ok()
/// .cookie(
/// http::Cookie::build("name", "value")
/// .domain("www.rust-lang.org")
/// .path("/")
/// .secure(true)
/// .http_only(true)
/// .finish(),
/// )
/// .finish()
/// }
/// ```
#[cfg(feature = "cookies")]
pub fn cookie<'c>(&mut self, cookie: Cookie<'c>) -> &mut Self {
if self.cookies.is_none() {
let mut jar = CookieJar::new();
jar.add(cookie.into_owned());
self.cookies = Some(jar)
} else {
self.cookies.as_mut().unwrap().add(cookie.into_owned());
}
self
}
/// Remove cookie
///
/// ```
/// use actix_http::{http, Request, Response, HttpMessage};
///
/// fn index(req: Request) -> Response {
/// let mut builder = Response::Ok();
///
/// if let Some(ref cookie) = req.cookie("name") {
/// builder.del_cookie(cookie);
/// }
///
/// builder.finish()
/// }
/// ```
#[cfg(feature = "cookies")]
pub fn del_cookie<'a>(&mut self, cookie: &Cookie<'a>) -> &mut Self {
if self.cookies.is_none() {
self.cookies = Some(CookieJar::new())
}
let jar = self.cookies.as_mut().unwrap();
let cookie = cookie.clone().into_owned();
jar.add_original(cookie.clone());
jar.remove(cookie);
self
}
/// This method calls provided closure with builder reference if value is `true`.
#[doc(hidden)]
#[deprecated = "Use an if statement."]
pub fn if_true<F>(&mut self, value: bool, f: F) -> &mut Self
where
F: FnOnce(&mut ResponseBuilder),
{
if value {
f(self);
}
self
}
/// This method calls provided closure with builder reference if value is `Some`.
#[doc(hidden)]
#[deprecated = "Use an if-let construction."]
pub fn if_some<T, F>(&mut self, value: Option<T>, f: F) -> &mut Self
where
F: FnOnce(T, &mut ResponseBuilder),
{
if let Some(val) = value {
f(val, self);
}
self
}
/// Responses extensions
#[inline]
pub fn extensions(&self) -> Ref<'_, Extensions> {
@ -580,19 +474,7 @@ impl ResponseBuilder {
return Response::from(Error::from(e)).into_body();
}
// allow unused mut when cookies feature is disabled
#[allow(unused_mut)]
let mut response = self.head.take().expect("cannot reuse response builder");
#[cfg(feature = "cookies")]
if let Some(ref jar) = self.cookies {
for cookie in jar.delta() {
match HeaderValue::from_str(&cookie.to_string()) {
Ok(val) => response.headers.append(header::SET_COOKIE, val),
Err(e) => return Response::from(Error::from(e)).into_body(),
};
}
}
let response = self.head.take().expect("cannot reuse response builder");
Response {
head: response,
@ -648,8 +530,6 @@ impl ResponseBuilder {
ResponseBuilder {
head: self.head.take(),
err: self.err.take(),
#[cfg(feature = "cookies")]
cookies: self.cookies.take(),
}
}
}
@ -671,8 +551,6 @@ impl<B> From<Response<B>> for ResponseBuilder {
ResponseBuilder {
head: Some(res.head),
err: None,
#[cfg(feature = "cookies")]
cookies: None,
}
}
}
@ -693,8 +571,6 @@ impl<'a> From<&'a ResponseHead> for ResponseBuilder {
ResponseBuilder {
head: Some(msg),
err: None,
#[cfg(feature = "cookies")]
cookies: None,
}
}
}
@ -866,6 +742,7 @@ mod tests {
#[test]
fn test_serde_json_in_body() {
use serde_json::json;
let resp =
ResponseBuilder::new(StatusCode::OK).body(json!({"test-key":"test-value"}));
assert_eq!(resp.body().get_ref(), br#"{"test-key":"test-value"}"#);

View File

@ -20,7 +20,7 @@ openssl = ["tls-openssl", "actix-http/openssl"]
[dependencies]
actix-codec = "0.4.0-beta.1"
actix-http = { version = "3.0.0-beta.5", features = ["cookies"] }
actix-http = "3.0.0-beta.5"
actix-http-test = { version = "3.0.0-beta.4", features = [] }
actix-service = "2.0.0-beta.4"
actix-utils = "3.0.0-beta.2"

View File

@ -41,7 +41,7 @@ rustls = ["tls-rustls", "actix-http/rustls"]
compress = ["actix-http/compress"]
# cookie parsing and cookie jar
cookies = ["actix-http/cookies"]
cookies = ["cookie"]
# trust-dns as dns resolver
trust-dns = ["actix-http/trust-dns"]
@ -54,7 +54,7 @@ actix-rt = { version = "2.1", default-features = false }
base64 = "0.13"
bytes = "1"
cookie = "0.15"
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
derive_more = "0.99.5"
futures-core = { version = "0.3.7", default-features = false }
itoa = "0.4"

View File

@ -494,7 +494,7 @@ impl ClientRequest {
let cookie: String = jar
.delta()
// ensure only name=value is written to cookie header
.map(|c| Cookie::new(c.name(), c.value()).encoded().to_string())
.map(|c| c.stripped().encoded().to_string())
.collect::<Vec<_>>()
.join("; ");

View File

@ -280,7 +280,7 @@ impl WebsocketsRequest {
let cookie: String = jar
.delta()
// ensure only name=value is written to cookie header
.map(|c| Cookie::new(c.name(), c.value()).encoded().to_string())
.map(|c| c.stripped().encoded().to_string())
.collect::<Vec<_>>()
.join("; ");

View File

@ -340,7 +340,7 @@ impl HttpResponseBuilder {
/// Set HTTP status code of this response.
#[inline]
pub fn status(&mut self, status: StatusCode) -> &mut Self {
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.status = status;
}
self
@ -361,7 +361,7 @@ impl HttpResponseBuilder {
where
H: IntoHeaderPair,
{
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
match header.try_into_header_pair() {
Ok((key, value)) => {
parts.headers.insert(key, value);
@ -389,7 +389,7 @@ impl HttpResponseBuilder {
where
H: IntoHeaderPair,
{
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
match header.try_into_header_pair() {
Ok((key, value)) => parts.headers.append(key, value),
Err(e) => self.err = Some(e.into()),
@ -444,7 +444,7 @@ impl HttpResponseBuilder {
/// Set the custom reason for the response.
#[inline]
pub fn reason(&mut self, reason: &'static str) -> &mut Self {
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.reason = Some(reason);
}
self
@ -453,7 +453,7 @@ impl HttpResponseBuilder {
/// Set connection type to KeepAlive
#[inline]
pub fn keep_alive(&mut self) -> &mut Self {
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.set_connection_type(ConnectionType::KeepAlive);
}
self
@ -465,7 +465,7 @@ impl HttpResponseBuilder {
where
V: IntoHeaderValue,
{
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.set_connection_type(ConnectionType::Upgrade);
}
@ -479,7 +479,7 @@ impl HttpResponseBuilder {
/// Force close connection, even if it is marked as keep-alive
#[inline]
pub fn force_close(&mut self) -> &mut Self {
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.set_connection_type(ConnectionType::Close);
}
self
@ -491,7 +491,7 @@ impl HttpResponseBuilder {
let mut buf = itoa::Buffer::new();
self.insert_header((header::CONTENT_LENGTH, buf.format(len)));
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
parts.no_chunking(true);
}
self
@ -503,7 +503,7 @@ impl HttpResponseBuilder {
where
V: IntoHeaderValue,
{
if let Some(parts) = self.parts() {
if let Some(parts) = self.inner() {
match value.try_into_value() {
Ok(value) => {
parts.headers.insert(header::CONTENT_TYPE, value);
@ -560,7 +560,7 @@ impl HttpResponseBuilder {
/// }
/// ```
#[cfg(feature = "cookies")]
pub fn del_cookie<'a>(&mut self, cookie: &Cookie<'a>) -> &mut Self {
pub fn del_cookie(&mut self, cookie: &Cookie<'_>) -> &mut Self {
if self.cookies.is_none() {
self.cookies = Some(CookieJar::new())
}
@ -639,7 +639,7 @@ impl HttpResponseBuilder {
pub fn json(&mut self, value: impl Serialize) -> HttpResponse {
match serde_json::to_string(&value) {
Ok(body) => {
let contains = if let Some(parts) = self.parts() {
let contains = if let Some(parts) = self.inner() {
parts.headers.contains_key(header::CONTENT_TYPE)
} else {
true
@ -674,7 +674,7 @@ impl HttpResponseBuilder {
}
#[inline]
fn parts(&mut self) -> Option<&mut ResponseHead> {
fn inner(&mut self) -> Option<&mut ResponseHead> {
if self.err.is_some() {
return None;
}

View File

@ -520,7 +520,7 @@ impl TestRequest {
.cookies
.delta()
// ensure only name=value is written to cookie header
.map(|c| Cookie::new(c.name(), c.value()).encoded().to_string())
.map(|c| c.stripped().encoded().to_string())
.collect::<Vec<_>>()
.join("; ");