mirror of https://github.com/fafhrd91/actix-web
add IntoHeaderPair trait
This commit is contained in:
parent
22749150ae
commit
dacf8f7b6b
|
@ -1,7 +1,10 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
### Changed
|
||||||
* `Response::content_type` now takes an `impl IntoHeaderValue` to support `mime` types. [#1894]
|
* `Response::content_type` now takes an `impl IntoHeaderValue` to support `mime` types. [#1894]
|
||||||
|
* `Response::set` and `Response::header` methods; use the respective `Response::set_header` and
|
||||||
|
`Response::append_header` methods. [#1869]
|
||||||
|
|
||||||
[#1894]: https://github.com/actix/actix-web/pull/1894
|
[#1894]: https://github.com/actix/actix-web/pull/1894
|
||||||
|
|
||||||
|
@ -32,7 +35,12 @@
|
||||||
[#1813]: https://github.com/actix/actix-web/pull/1813
|
[#1813]: https://github.com/actix/actix-web/pull/1813
|
||||||
[#1857]: https://github.com/actix/actix-web/pull/1857
|
[#1857]: https://github.com/actix/actix-web/pull/1857
|
||||||
[#1864]: https://github.com/actix/actix-web/pull/1864
|
[#1864]: https://github.com/actix/actix-web/pull/1864
|
||||||
|
<<<<<<< HEAD
|
||||||
[#1878]: https://github.com/actix/actix-web/pull/1878
|
[#1878]: https://github.com/actix/actix-web/pull/1878
|
||||||
|
=======
|
||||||
|
[#1869]: https://github.com/actix/actix-web/pull/1869
|
||||||
|
|
||||||
|
>>>>>>> 587000a2... add IntoHeaderPair trait
|
||||||
|
|
||||||
## 2.2.0 - 2020-11-25
|
## 2.2.0 - 2020-11-25
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -42,14 +42,13 @@ use crate::httpmessage::HttpMessage;
|
||||||
/// let mut builder = Response::Ok();
|
/// let mut builder = Response::Ok();
|
||||||
/// builder.set(IfRange::EntityTag(EntityTag::new(
|
/// builder.set(IfRange::EntityTag(EntityTag::new(
|
||||||
/// false,
|
/// false,
|
||||||
/// "xyzzy".to_owned(),
|
/// "abc".to_owned(),
|
||||||
/// )));
|
/// )));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_http::Response;
|
|
||||||
/// use actix_http::http::header::IfRange;
|
|
||||||
/// use std::time::{Duration, SystemTime};
|
/// use std::time::{Duration, SystemTime};
|
||||||
|
/// use actix_http::{http::header::IfRange, Response};
|
||||||
///
|
///
|
||||||
/// let mut builder = Response::Ok();
|
/// let mut builder = Response::Ok();
|
||||||
/// let fetched = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
|
/// let fetched = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
|
||||||
|
@ -57,9 +56,10 @@ use crate::httpmessage::HttpMessage;
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum IfRange {
|
pub enum IfRange {
|
||||||
/// The entity-tag the client has of the resource
|
/// The entity-tag the client has of the resource.
|
||||||
EntityTag(EntityTag),
|
EntityTag(EntityTag),
|
||||||
/// The date when the client retrieved the resource
|
|
||||||
|
/// The date when the client retrieved the resource.
|
||||||
Date(HttpDate),
|
Date(HttpDate),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
use std::convert::{Infallible, TryFrom};
|
||||||
|
|
||||||
|
use either::Either;
|
||||||
|
use http::{
|
||||||
|
header::{HeaderName, InvalidHeaderName, InvalidHeaderValue},
|
||||||
|
HeaderValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A trait for transforming things
|
||||||
|
pub trait IntoHeaderPair: Sized {
|
||||||
|
type Error;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (HeaderName, HeaderValue) {
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (HeaderName, &str) {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let value = HeaderValue::try_from(value)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (&str, HeaderValue) {
|
||||||
|
type Error = InvalidHeaderName;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let name = HeaderName::try_from(name)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (&str, &str) {
|
||||||
|
type Error = Either<InvalidHeaderName, InvalidHeaderValue>;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let name = HeaderName::try_from(name).map_err(Either::Left)?;
|
||||||
|
let value = HeaderValue::try_from(value).map_err(Either::Right)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (HeaderName, String) {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let value = HeaderValue::try_from(&value)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (String, HeaderValue) {
|
||||||
|
type Error = InvalidHeaderName;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let name = HeaderName::try_from(&name)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderPair for (String, String) {
|
||||||
|
type Error = Either<InvalidHeaderName, InvalidHeaderValue>;
|
||||||
|
|
||||||
|
fn try_into_header_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
|
||||||
|
let (name, value) = self;
|
||||||
|
let name = HeaderName::try_from(&name).map_err(Either::Left)?;
|
||||||
|
let value = HeaderValue::try_from(&value).map_err(Either::Right)?;
|
||||||
|
Ok((name, value))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use bytes::Bytes;
|
||||||
|
use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue};
|
||||||
|
use mime::Mime;
|
||||||
|
|
||||||
|
/// A trait for any object that can be Converted to a `HeaderValue`
|
||||||
|
pub trait IntoHeaderValue: Sized {
|
||||||
|
/// The type returned in the event of a conversion error.
|
||||||
|
type Error: Into<HttpError>;
|
||||||
|
|
||||||
|
/// Try to convert value to a Header pair value.
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for HeaderValue {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoHeaderValue for &'a str {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
self.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoHeaderValue for &'a [u8] {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
HeaderValue::from_bytes(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for Bytes {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
HeaderValue::from_maybe_shared(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for Vec<u8> {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
HeaderValue::try_from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for String {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
HeaderValue::try_from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for usize {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
let s = format!("{}", self);
|
||||||
|
HeaderValue::try_from(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for u64 {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
let s = format!("{}", self);
|
||||||
|
HeaderValue::try_from(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoHeaderValue for Mime {
|
||||||
|
type Error = InvalidHeaderValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||||
|
HeaderValue::try_from(format!("{}", self))
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use http::header::{HeaderName, HeaderValue};
|
||||||
/// A set of HTTP headers
|
/// A set of HTTP headers
|
||||||
///
|
///
|
||||||
/// `HeaderMap` is an multi-map of [`HeaderName`] to values.
|
/// `HeaderMap` is an multi-map of [`HeaderName`] to values.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct HeaderMap {
|
pub struct HeaderMap {
|
||||||
pub(crate) inner: AHashMap<HeaderName, Value>,
|
pub(crate) inner: AHashMap<HeaderName, Value>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
//! Various HTTP headers.
|
//! Various HTTP headers.
|
||||||
|
|
||||||
use std::{convert::TryFrom, fmt, str::FromStr};
|
use std::{fmt, str::FromStr};
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use http::Error as HttpError;
|
|
||||||
use mime::Mime;
|
|
||||||
use percent_encoding::{AsciiSet, CONTROLS};
|
use percent_encoding::{AsciiSet, CONTROLS};
|
||||||
|
|
||||||
pub use http::header::*;
|
pub use http::header::*;
|
||||||
|
@ -12,6 +10,9 @@ pub use http::header::*;
|
||||||
use crate::error::ParseError;
|
use crate::error::ParseError;
|
||||||
use crate::httpmessage::HttpMessage;
|
use crate::httpmessage::HttpMessage;
|
||||||
|
|
||||||
|
mod into_pair;
|
||||||
|
mod into_value;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
pub(crate) mod map;
|
pub(crate) mod map;
|
||||||
mod shared;
|
mod shared;
|
||||||
|
@ -19,15 +20,14 @@ pub use self::common::*;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use self::shared::*;
|
pub use self::shared::*;
|
||||||
|
|
||||||
|
pub use self::into_pair::IntoHeaderPair;
|
||||||
|
pub use self::into_value::IntoHeaderValue;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use self::map::GetAll;
|
pub use self::map::GetAll;
|
||||||
pub use self::map::HeaderMap;
|
pub use self::map::HeaderMap;
|
||||||
|
|
||||||
/// A trait for any object that will represent a header field and value.
|
/// A trait for any object that already represents a valid header field and value.
|
||||||
pub trait Header
|
pub trait Header: IntoHeaderValue {
|
||||||
where
|
|
||||||
Self: IntoHeaderValue,
|
|
||||||
{
|
|
||||||
/// Returns the name of the header field
|
/// Returns the name of the header field
|
||||||
fn name() -> HeaderName;
|
fn name() -> HeaderName;
|
||||||
|
|
||||||
|
@ -35,98 +35,6 @@ where
|
||||||
fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError>;
|
fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for any object that can be Converted to a `HeaderValue`
|
|
||||||
pub trait IntoHeaderValue: Sized {
|
|
||||||
/// The type returned in the event of a conversion error.
|
|
||||||
type Error: Into<HttpError>;
|
|
||||||
|
|
||||||
/// Try to convert value to a Header value.
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for HeaderValue {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> IntoHeaderValue for &'a str {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
self.parse()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> IntoHeaderValue for &'a [u8] {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
HeaderValue::from_bytes(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for Bytes {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
HeaderValue::from_maybe_shared(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for Vec<u8> {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
HeaderValue::try_from(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for String {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
HeaderValue::try_from(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for usize {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
let s = format!("{}", self);
|
|
||||||
HeaderValue::try_from(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for u64 {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
let s = format!("{}", self);
|
|
||||||
HeaderValue::try_from(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoHeaderValue for Mime {
|
|
||||||
type Error = InvalidHeaderValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
|
||||||
HeaderValue::try_from(format!("{}", self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents supported types of content encodings
|
/// Represents supported types of content encodings
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
pub enum ContentEncoding {
|
pub enum ContentEncoding {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Copied for `hyper::header::shared`;
|
//! Originally taken from `hyper::header::shared`.
|
||||||
|
|
||||||
pub use self::charset::Charset;
|
pub use self::charset::Charset;
|
||||||
pub use self::encoding::Encoding;
|
pub use self::encoding::Encoding;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::payload::Payload;
|
||||||
|
|
||||||
struct Cookies(Vec<Cookie<'static>>);
|
struct Cookies(Vec<Cookie<'static>>);
|
||||||
|
|
||||||
/// Trait that implements general purpose operations on http messages
|
/// Trait that implements general purpose operations on HTTP messages.
|
||||||
pub trait HttpMessage: Sized {
|
pub trait HttpMessage: Sized {
|
||||||
/// Type of message payload stream
|
/// Type of message payload stream
|
||||||
type Stream;
|
type Stream;
|
||||||
|
@ -30,8 +30,8 @@ pub trait HttpMessage: Sized {
|
||||||
/// Mutable reference to a the request's extensions container
|
/// Mutable reference to a the request's extensions container
|
||||||
fn extensions_mut(&self) -> RefMut<'_, Extensions>;
|
fn extensions_mut(&self) -> RefMut<'_, Extensions>;
|
||||||
|
|
||||||
|
/// Get a header.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
/// Get a header
|
|
||||||
fn get_header<H: Header>(&self) -> Option<H>
|
fn get_header<H: Header>(&self) -> Option<H>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
|
@ -43,8 +43,8 @@ pub trait HttpMessage: Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the request content type. If request does not contain
|
/// Read the request content type. If request did not contain a *Content-Type* header, an empty
|
||||||
/// *Content-Type* header, empty str get returned.
|
/// string is returned.
|
||||||
fn content_type(&self) -> &str {
|
fn content_type(&self) -> &str {
|
||||||
if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
|
if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
|
||||||
if let Ok(content_type) = content_type.to_str() {
|
if let Ok(content_type) = content_type.to_str() {
|
||||||
|
@ -90,7 +90,7 @@ pub trait HttpMessage: Sized {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if request has chunked transfer encoding
|
/// Check if request has chunked transfer encoding.
|
||||||
fn chunked(&self) -> Result<bool, ParseError> {
|
fn chunked(&self) -> Result<bool, ParseError> {
|
||||||
if let Some(encodings) = self.headers().get(header::TRANSFER_ENCODING) {
|
if let Some(encodings) = self.headers().get(header::TRANSFER_ENCODING) {
|
||||||
if let Ok(s) = encodings.to_str() {
|
if let Ok(s) = encodings.to_str() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::body::{Body, BodyStream, MessageBody, ResponseBody};
|
||||||
use crate::cookie::{Cookie, CookieJar};
|
use crate::cookie::{Cookie, CookieJar};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::extensions::Extensions;
|
use crate::extensions::Extensions;
|
||||||
use crate::header::{Header, IntoHeaderValue};
|
use crate::header::{Header, IntoHeaderPair, IntoHeaderValue};
|
||||||
use crate::http::header::{self, HeaderName, HeaderValue};
|
use crate::http::header::{self, HeaderName, HeaderValue};
|
||||||
use crate::http::{Error as HttpError, HeaderMap, StatusCode};
|
use crate::http::{Error as HttpError, HeaderMap, StatusCode};
|
||||||
use crate::message::{BoxedResponseHead, ConnectionType, ResponseHead};
|
use crate::message::{BoxedResponseHead, ConnectionType, ResponseHead};
|
||||||
|
@ -399,35 +399,57 @@ impl ResponseBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a header.
|
/// Insert a header, replacing any that existed with an equivalent field name.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_http::{http, Request, Response};
|
/// use actix_http::{http, Request, Response};
|
||||||
///
|
///
|
||||||
/// fn index(req: Request) -> Response {
|
/// fn index(req: Request) -> Response {
|
||||||
/// Response::Ok()
|
/// Response::Ok()
|
||||||
/// .set_header("X-TEST", "value")
|
/// .set_header(("X-TEST", "value"))
|
||||||
/// .set_header(http::header::CONTENT_TYPE, "application/json")
|
/// .set_header(ContentType(mime::APPLICATION_JSON))
|
||||||
/// .finish()
|
/// .finish()
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
|
pub fn insert_header<H>(&mut self, header: H) -> &mut Self
|
||||||
where
|
where
|
||||||
HeaderName: TryFrom<K>,
|
H: IntoHeaderPair,
|
||||||
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
|
H::Error: Into<HttpError>,
|
||||||
V: IntoHeaderValue,
|
|
||||||
{
|
{
|
||||||
if let Some(parts) = parts(&mut self.head, &self.err) {
|
if let Some(parts) = parts(&mut self.head, &self.err) {
|
||||||
match HeaderName::try_from(key) {
|
match header.try_into_header_pair() {
|
||||||
Ok(key) => match value.try_into() {
|
Ok((key, value)) => parts.headers.insert(key, value),
|
||||||
Ok(value) => {
|
|
||||||
parts.headers.insert(key, value);
|
|
||||||
}
|
|
||||||
Err(e) => self.err = Some(e.into()),
|
|
||||||
},
|
|
||||||
Err(e) => self.err = Some(e.into()),
|
Err(e) => self.err = Some(e.into()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append a header, keeping any that existed with an equivalent field name.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_http::{http, Request, Response};
|
||||||
|
///
|
||||||
|
/// fn index(req: Request) -> Response {
|
||||||
|
/// Response::Ok()
|
||||||
|
/// .append_header(("X-TEST", "value"))
|
||||||
|
/// .append_header(ContentType(mime::APPLICATION_JSON))
|
||||||
|
/// .finish()
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn append_header<H>(&mut self, header: H) -> &mut Self
|
||||||
|
where
|
||||||
|
H: IntoHeaderPair,
|
||||||
|
H::Error: Into<HttpError>,
|
||||||
|
{
|
||||||
|
if let Some(parts) = parts(&mut self.head, &self.err) {
|
||||||
|
match header.try_into_header_pair() {
|
||||||
|
Ok((key, value)) => parts.headers.append(key, value),
|
||||||
|
Err(e) => self.err = Some(e.into()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +480,13 @@ impl ResponseBuilder {
|
||||||
if let Some(parts) = parts(&mut self.head, &self.err) {
|
if let Some(parts) = parts(&mut self.head, &self.err) {
|
||||||
parts.set_connection_type(ConnectionType::Upgrade);
|
parts.set_connection_type(ConnectionType::Upgrade);
|
||||||
}
|
}
|
||||||
self.set_header(header::UPGRADE, value)
|
|
||||||
|
// TODO: fix signature
|
||||||
|
if let Ok(value) = value.try_into() {
|
||||||
|
self.insert_header((header::UPGRADE, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Force close connection, even if it is marked as keep-alive
|
/// Force close connection, even if it is marked as keep-alive
|
||||||
|
|
Loading…
Reference in New Issue