mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 18:34:36 +01:00
refactor RequestHead/ResponseHead
This commit is contained in:
parent
fb9c94c3e0
commit
3edc515bac
@ -12,7 +12,7 @@ use flate2::write::{GzEncoder, ZlibEncoder};
|
|||||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||||
use crate::http::header::{ContentEncoding, CONTENT_ENCODING};
|
use crate::http::header::{ContentEncoding, CONTENT_ENCODING};
|
||||||
use crate::http::{HeaderValue, HttpTryFrom, StatusCode};
|
use crate::http::{HeaderValue, HttpTryFrom, StatusCode};
|
||||||
use crate::{Error, Head, ResponseHead};
|
use crate::{Error, ResponseHead};
|
||||||
|
|
||||||
use super::Writer;
|
use super::Writer;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ impl<B: MessageBody> Encoder<B> {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
update_head(encoding, head);
|
update_head(encoding, head);
|
||||||
head.no_chunking = false;
|
head.no_chunking(false);
|
||||||
ResponseBody::Body(Encoder {
|
ResponseBody::Body(Encoder {
|
||||||
body: EncoderBody::Other(stream),
|
body: EncoderBody::Other(stream),
|
||||||
encoder: ContentEncoder::encoder(encoding),
|
encoder: ContentEncoder::encoder(encoding),
|
||||||
@ -72,7 +72,7 @@ impl<B: MessageBody> Encoder<B> {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
update_head(encoding, head);
|
update_head(encoding, head);
|
||||||
head.no_chunking = false;
|
head.no_chunking(false);
|
||||||
ResponseBody::Body(Encoder {
|
ResponseBody::Body(Encoder {
|
||||||
body: EncoderBody::Body(stream),
|
body: EncoderBody::Body(stream),
|
||||||
encoder: ContentEncoder::encoder(encoding),
|
encoder: ContentEncoder::encoder(encoding),
|
||||||
|
@ -129,7 +129,7 @@ impl Decoder for ClientCodec {
|
|||||||
debug_assert!(!self.inner.payload.is_some(), "Payload decoder is set");
|
debug_assert!(!self.inner.payload.is_some(), "Payload decoder is set");
|
||||||
|
|
||||||
if let Some((req, payload)) = self.inner.decoder.decode(src)? {
|
if let Some((req, payload)) = self.inner.decoder.decode(src)? {
|
||||||
if let Some(ctype) = req.ctype {
|
if let Some(ctype) = req.ctype() {
|
||||||
// do not use peer's keep-alive
|
// do not use peer's keep-alive
|
||||||
self.inner.ctype = if ctype == ConnectionType::KeepAlive {
|
self.inner.ctype = if ctype == ConnectionType::KeepAlive {
|
||||||
self.inner.ctype
|
self.inner.ctype
|
||||||
|
@ -154,7 +154,7 @@ impl Encoder for Codec {
|
|||||||
res.head_mut().version = self.version;
|
res.head_mut().version = self.version;
|
||||||
|
|
||||||
// connection status
|
// connection status
|
||||||
self.ctype = if let Some(ct) = res.head().ctype {
|
self.ctype = if let Some(ct) = res.head().ctype() {
|
||||||
if ct == ConnectionType::KeepAlive {
|
if ct == ConnectionType::KeepAlive {
|
||||||
self.ctype
|
self.ctype
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,7 +158,9 @@ pub(crate) trait MessageType: Sized {
|
|||||||
|
|
||||||
impl MessageType for Request {
|
impl MessageType for Request {
|
||||||
fn set_connection_type(&mut self, ctype: Option<ConnectionType>) {
|
fn set_connection_type(&mut self, ctype: Option<ConnectionType>) {
|
||||||
self.head_mut().ctype = ctype;
|
if let Some(ctype) = ctype {
|
||||||
|
self.head_mut().set_connection_type(ctype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headers_mut(&mut self) -> &mut HeaderMap {
|
fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||||
@ -228,7 +230,9 @@ impl MessageType for Request {
|
|||||||
|
|
||||||
impl MessageType for ResponseHead {
|
impl MessageType for ResponseHead {
|
||||||
fn set_connection_type(&mut self, ctype: Option<ConnectionType>) {
|
fn set_connection_type(&mut self, ctype: Option<ConnectionType>) {
|
||||||
self.ctype = ctype;
|
if let Some(ctype) = ctype {
|
||||||
|
ResponseHead::set_connection_type(self, ctype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headers_mut(&mut self) -> &mut HeaderMap {
|
fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||||
@ -814,7 +818,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Close));
|
assert_eq!(req.head().connection_type(), ConnectionType::Close);
|
||||||
|
|
||||||
let mut buf = BytesMut::from(
|
let mut buf = BytesMut::from(
|
||||||
"GET /test HTTP/1.1\r\n\
|
"GET /test HTTP/1.1\r\n\
|
||||||
@ -822,7 +826,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Close));
|
assert_eq!(req.head().connection_type(), ConnectionType::Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -834,7 +838,7 @@ mod tests {
|
|||||||
|
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Close));
|
assert_eq!(req.head().connection_type(), ConnectionType::Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -845,7 +849,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::KeepAlive));
|
assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
|
||||||
|
|
||||||
let mut buf = BytesMut::from(
|
let mut buf = BytesMut::from(
|
||||||
"GET /test HTTP/1.0\r\n\
|
"GET /test HTTP/1.0\r\n\
|
||||||
@ -853,7 +857,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::KeepAlive));
|
assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -864,7 +868,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::KeepAlive));
|
assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -886,7 +890,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert_eq!(req.head().ctype, None);
|
|
||||||
assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
|
assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,7 +903,7 @@ mod tests {
|
|||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert!(req.upgrade());
|
assert!(req.upgrade());
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Upgrade));
|
assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
|
||||||
|
|
||||||
let mut buf = BytesMut::from(
|
let mut buf = BytesMut::from(
|
||||||
"GET /test HTTP/1.1\r\n\
|
"GET /test HTTP/1.1\r\n\
|
||||||
@ -910,7 +913,7 @@ mod tests {
|
|||||||
let req = parse_ready!(&mut buf);
|
let req = parse_ready!(&mut buf);
|
||||||
|
|
||||||
assert!(req.upgrade());
|
assert!(req.upgrade());
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Upgrade));
|
assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1008,7 +1011,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let mut reader = MessageDecoder::<Request>::default();
|
let mut reader = MessageDecoder::<Request>::default();
|
||||||
let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
|
let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
|
||||||
assert_eq!(req.head().ctype, Some(ConnectionType::Upgrade));
|
assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
|
||||||
assert!(req.upgrade());
|
assert!(req.upgrade());
|
||||||
assert!(pl.is_unhandled());
|
assert!(pl.is_unhandled());
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::body::BodySize;
|
|||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::header::ContentEncoding;
|
use crate::header::ContentEncoding;
|
||||||
use crate::helpers;
|
use crate::helpers;
|
||||||
use crate::message::{ConnectionType, RequestHead, ResponseHead};
|
use crate::message::{ConnectionType, Head, RequestHead, ResponseHead};
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ impl<T: MessageType> Default for MessageEncoder<T> {
|
|||||||
pub(crate) trait MessageType: Sized {
|
pub(crate) trait MessageType: Sized {
|
||||||
fn status(&self) -> Option<StatusCode>;
|
fn status(&self) -> Option<StatusCode>;
|
||||||
|
|
||||||
fn connection_type(&self) -> Option<ConnectionType>;
|
// fn connection_type(&self) -> Option<ConnectionType>;
|
||||||
|
|
||||||
fn headers(&self) -> &HeaderMap;
|
fn headers(&self) -> &HeaderMap;
|
||||||
|
|
||||||
@ -168,12 +168,12 @@ impl MessageType for Response<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn chunked(&self) -> bool {
|
fn chunked(&self) -> bool {
|
||||||
!self.head().no_chunking
|
self.head().chunked()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connection_type(&self) -> Option<ConnectionType> {
|
//fn connection_type(&self) -> Option<ConnectionType> {
|
||||||
self.head().ctype
|
// self.head().ctype
|
||||||
}
|
//}
|
||||||
|
|
||||||
fn headers(&self) -> &HeaderMap {
|
fn headers(&self) -> &HeaderMap {
|
||||||
&self.head().headers
|
&self.head().headers
|
||||||
@ -196,12 +196,8 @@ impl MessageType for RequestHead {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connection_type(&self) -> Option<ConnectionType> {
|
|
||||||
self.ctype
|
|
||||||
}
|
|
||||||
|
|
||||||
fn chunked(&self) -> bool {
|
fn chunked(&self) -> bool {
|
||||||
!self.no_chunking
|
self.chunked()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headers(&self) -> &HeaderMap {
|
fn headers(&self) -> &HeaderMap {
|
||||||
|
@ -35,7 +35,7 @@ pub use self::config::{KeepAlive, ServiceConfig};
|
|||||||
pub use self::error::{Error, ResponseError, Result};
|
pub use self::error::{Error, ResponseError, Result};
|
||||||
pub use self::extensions::Extensions;
|
pub use self::extensions::Extensions;
|
||||||
pub use self::httpmessage::HttpMessage;
|
pub use self::httpmessage::HttpMessage;
|
||||||
pub use self::message::{Head, Message, RequestHead, ResponseHead};
|
pub use self::message::{Message, RequestHead, ResponseHead};
|
||||||
pub use self::payload::{Payload, PayloadStream};
|
pub use self::payload::{Payload, PayloadStream};
|
||||||
pub use self::request::Request;
|
pub use self::request::Request;
|
||||||
pub use self::response::{Response, ResponseBuilder};
|
pub use self::response::{Response, ResponseBuilder};
|
||||||
|
@ -2,6 +2,8 @@ use std::cell::{Ref, RefCell, RefMut};
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use bitflags::bitflags;
|
||||||
|
|
||||||
use crate::extensions::Extensions;
|
use crate::extensions::Extensions;
|
||||||
use crate::http::{header, HeaderMap, Method, StatusCode, Uri, Version};
|
use crate::http::{header, HeaderMap, Method, StatusCode, Uri, Version};
|
||||||
|
|
||||||
@ -16,39 +18,22 @@ pub enum ConnectionType {
|
|||||||
Upgrade,
|
Upgrade,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub(crate) struct Flags: u8 {
|
||||||
|
const CLOSE = 0b0000_0001;
|
||||||
|
const KEEP_ALIVE = 0b0000_0010;
|
||||||
|
const UPGRADE = 0b0000_0100;
|
||||||
|
const NO_CHUNKING = 0b0000_1000;
|
||||||
|
const ENC_BR = 0b0001_0000;
|
||||||
|
const ENC_DEFLATE = 0b0010_0000;
|
||||||
|
const ENC_GZIP = 0b0100_0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait Head: Default + 'static {
|
pub trait Head: Default + 'static {
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
|
|
||||||
/// Read the message headers.
|
|
||||||
fn headers(&self) -> &HeaderMap;
|
|
||||||
|
|
||||||
/// Mutable reference to the message headers.
|
|
||||||
fn headers_mut(&mut self) -> &mut HeaderMap;
|
|
||||||
|
|
||||||
/// Connection type
|
|
||||||
fn connection_type(&self) -> ConnectionType;
|
|
||||||
|
|
||||||
/// Set connection type of the message
|
|
||||||
fn set_connection_type(&mut self, ctype: ConnectionType);
|
|
||||||
|
|
||||||
fn upgrade(&self) -> bool {
|
|
||||||
if let Some(hdr) = self.headers().get(header::CONNECTION) {
|
|
||||||
if let Ok(s) = hdr.to_str() {
|
|
||||||
s.to_ascii_lowercase().contains("upgrade")
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if keep-alive is enabled
|
|
||||||
fn keep_alive(&self) -> bool {
|
|
||||||
self.connection_type() == ConnectionType::KeepAlive
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pool() -> &'static MessagePool<Self>;
|
fn pool() -> &'static MessagePool<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +43,8 @@ pub struct RequestHead {
|
|||||||
pub method: Method,
|
pub method: Method,
|
||||||
pub version: Version,
|
pub version: Version,
|
||||||
pub headers: HeaderMap,
|
pub headers: HeaderMap,
|
||||||
pub ctype: Option<ConnectionType>,
|
|
||||||
pub no_chunking: bool,
|
|
||||||
pub extensions: RefCell<Extensions>,
|
pub extensions: RefCell<Extensions>,
|
||||||
|
flags: Flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RequestHead {
|
impl Default for RequestHead {
|
||||||
@ -70,8 +54,7 @@ impl Default for RequestHead {
|
|||||||
method: Method::default(),
|
method: Method::default(),
|
||||||
version: Version::HTTP_11,
|
version: Version::HTTP_11,
|
||||||
headers: HeaderMap::with_capacity(16),
|
headers: HeaderMap::with_capacity(16),
|
||||||
ctype: None,
|
flags: Flags::empty(),
|
||||||
no_chunking: false,
|
|
||||||
extensions: RefCell::new(Extensions::new()),
|
extensions: RefCell::new(Extensions::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,45 +62,11 @@ impl Default for RequestHead {
|
|||||||
|
|
||||||
impl Head for RequestHead {
|
impl Head for RequestHead {
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
self.ctype = None;
|
self.flags = Flags::empty();
|
||||||
self.headers.clear();
|
self.headers.clear();
|
||||||
self.extensions.borrow_mut().clear();
|
self.extensions.borrow_mut().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headers(&self) -> &HeaderMap {
|
|
||||||
&self.headers
|
|
||||||
}
|
|
||||||
|
|
||||||
fn headers_mut(&mut self) -> &mut HeaderMap {
|
|
||||||
&mut self.headers
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_connection_type(&mut self, ctype: ConnectionType) {
|
|
||||||
self.ctype = Some(ctype)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn connection_type(&self) -> ConnectionType {
|
|
||||||
if let Some(ct) = self.ctype {
|
|
||||||
ct
|
|
||||||
} else if self.version < Version::HTTP_11 {
|
|
||||||
ConnectionType::Close
|
|
||||||
} else {
|
|
||||||
ConnectionType::KeepAlive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn upgrade(&self) -> bool {
|
|
||||||
if let Some(hdr) = self.headers().get(header::CONNECTION) {
|
|
||||||
if let Ok(s) = hdr.to_str() {
|
|
||||||
s.to_ascii_lowercase().contains("upgrade")
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pool() -> &'static MessagePool<Self> {
|
fn pool() -> &'static MessagePool<Self> {
|
||||||
REQUEST_POOL.with(|p| *p)
|
REQUEST_POOL.with(|p| *p)
|
||||||
}
|
}
|
||||||
@ -135,6 +84,70 @@ impl RequestHead {
|
|||||||
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||||
self.extensions.borrow_mut()
|
self.extensions.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the message headers.
|
||||||
|
pub fn headers(&self) -> &HeaderMap {
|
||||||
|
&self.headers
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutable reference to the message headers.
|
||||||
|
pub fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||||
|
&mut self.headers
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Set connection type of the message
|
||||||
|
pub fn set_connection_type(&mut self, ctype: ConnectionType) {
|
||||||
|
match ctype {
|
||||||
|
ConnectionType::Close => self.flags.insert(Flags::CLOSE),
|
||||||
|
ConnectionType::KeepAlive => self.flags.insert(Flags::KEEP_ALIVE),
|
||||||
|
ConnectionType::Upgrade => self.flags.insert(Flags::UPGRADE),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Connection type
|
||||||
|
pub fn connection_type(&self) -> ConnectionType {
|
||||||
|
if self.flags.contains(Flags::CLOSE) {
|
||||||
|
ConnectionType::Close
|
||||||
|
} else if self.flags.contains(Flags::KEEP_ALIVE) {
|
||||||
|
ConnectionType::KeepAlive
|
||||||
|
} else if self.flags.contains(Flags::UPGRADE) {
|
||||||
|
ConnectionType::Upgrade
|
||||||
|
} else if self.version < Version::HTTP_11 {
|
||||||
|
ConnectionType::Close
|
||||||
|
} else {
|
||||||
|
ConnectionType::KeepAlive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Connection upgrade status
|
||||||
|
pub fn upgrade(&self) -> bool {
|
||||||
|
if let Some(hdr) = self.headers().get(header::CONNECTION) {
|
||||||
|
if let Ok(s) = hdr.to_str() {
|
||||||
|
s.to_ascii_lowercase().contains("upgrade")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Get response body chunking state
|
||||||
|
pub fn chunked(&self) -> bool {
|
||||||
|
!self.flags.contains(Flags::NO_CHUNKING)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn no_chunking(&mut self, val: bool) {
|
||||||
|
if val {
|
||||||
|
self.flags.insert(Flags::NO_CHUNKING);
|
||||||
|
} else {
|
||||||
|
self.flags.remove(Flags::NO_CHUNKING);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -143,9 +156,8 @@ pub struct ResponseHead {
|
|||||||
pub status: StatusCode,
|
pub status: StatusCode,
|
||||||
pub headers: HeaderMap,
|
pub headers: HeaderMap,
|
||||||
pub reason: Option<&'static str>,
|
pub reason: Option<&'static str>,
|
||||||
pub no_chunking: bool,
|
|
||||||
pub(crate) ctype: Option<ConnectionType>,
|
|
||||||
pub(crate) extensions: RefCell<Extensions>,
|
pub(crate) extensions: RefCell<Extensions>,
|
||||||
|
flags: Flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ResponseHead {
|
impl Default for ResponseHead {
|
||||||
@ -155,13 +167,24 @@ impl Default for ResponseHead {
|
|||||||
status: StatusCode::OK,
|
status: StatusCode::OK,
|
||||||
headers: HeaderMap::with_capacity(16),
|
headers: HeaderMap::with_capacity(16),
|
||||||
reason: None,
|
reason: None,
|
||||||
no_chunking: false,
|
flags: Flags::empty(),
|
||||||
ctype: None,
|
|
||||||
extensions: RefCell::new(Extensions::new()),
|
extensions: RefCell::new(Extensions::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Head for ResponseHead {
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.reason = None;
|
||||||
|
self.flags = Flags::empty();
|
||||||
|
self.headers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pool() -> &'static MessagePool<Self> {
|
||||||
|
RESPONSE_POOL.with(|p| *p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ResponseHead {
|
impl ResponseHead {
|
||||||
/// Message extensions
|
/// Message extensions
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -174,31 +197,37 @@ impl ResponseHead {
|
|||||||
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||||
self.extensions.borrow_mut()
|
self.extensions.borrow_mut()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Head for ResponseHead {
|
#[inline]
|
||||||
fn clear(&mut self) {
|
/// Read the message headers.
|
||||||
self.ctype = None;
|
pub fn headers(&self) -> &HeaderMap {
|
||||||
self.reason = None;
|
|
||||||
self.no_chunking = false;
|
|
||||||
self.headers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn headers(&self) -> &HeaderMap {
|
|
||||||
&self.headers
|
&self.headers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headers_mut(&mut self) -> &mut HeaderMap {
|
#[inline]
|
||||||
|
/// Mutable reference to the message headers.
|
||||||
|
pub fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||||
&mut self.headers
|
&mut self.headers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_connection_type(&mut self, ctype: ConnectionType) {
|
#[inline]
|
||||||
self.ctype = Some(ctype)
|
/// Set connection type of the message
|
||||||
|
pub fn set_connection_type(&mut self, ctype: ConnectionType) {
|
||||||
|
match ctype {
|
||||||
|
ConnectionType::Close => self.flags.insert(Flags::CLOSE),
|
||||||
|
ConnectionType::KeepAlive => self.flags.insert(Flags::KEEP_ALIVE),
|
||||||
|
ConnectionType::Upgrade => self.flags.insert(Flags::UPGRADE),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connection_type(&self) -> ConnectionType {
|
#[inline]
|
||||||
if let Some(ct) = self.ctype {
|
pub fn connection_type(&self) -> ConnectionType {
|
||||||
ct
|
if self.flags.contains(Flags::CLOSE) {
|
||||||
|
ConnectionType::Close
|
||||||
|
} else if self.flags.contains(Flags::KEEP_ALIVE) {
|
||||||
|
ConnectionType::KeepAlive
|
||||||
|
} else if self.flags.contains(Flags::UPGRADE) {
|
||||||
|
ConnectionType::Upgrade
|
||||||
} else if self.version < Version::HTTP_11 {
|
} else if self.version < Version::HTTP_11 {
|
||||||
ConnectionType::Close
|
ConnectionType::Close
|
||||||
} else {
|
} else {
|
||||||
@ -206,16 +235,18 @@ impl Head for ResponseHead {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade(&self) -> bool {
|
#[inline]
|
||||||
|
/// Check if keep-alive is enabled
|
||||||
|
pub fn keep_alive(&self) -> bool {
|
||||||
|
self.connection_type() == ConnectionType::KeepAlive
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Check upgrade status of this message
|
||||||
|
pub fn upgrade(&self) -> bool {
|
||||||
self.connection_type() == ConnectionType::Upgrade
|
self.connection_type() == ConnectionType::Upgrade
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pool() -> &'static MessagePool<Self> {
|
|
||||||
RESPONSE_POOL.with(|p| *p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResponseHead {
|
|
||||||
/// Get custom reason for the response
|
/// Get custom reason for the response
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reason(&self) -> &str {
|
pub fn reason(&self) -> &str {
|
||||||
@ -227,6 +258,35 @@ impl ResponseHead {
|
|||||||
.unwrap_or("<unknown status code>")
|
.unwrap_or("<unknown status code>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn ctype(&self) -> Option<ConnectionType> {
|
||||||
|
if self.flags.contains(Flags::CLOSE) {
|
||||||
|
Some(ConnectionType::Close)
|
||||||
|
} else if self.flags.contains(Flags::KEEP_ALIVE) {
|
||||||
|
Some(ConnectionType::KeepAlive)
|
||||||
|
} else if self.flags.contains(Flags::UPGRADE) {
|
||||||
|
Some(ConnectionType::Upgrade)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Get response body chunking state
|
||||||
|
pub fn chunked(&self) -> bool {
|
||||||
|
!self.flags.contains(Flags::NO_CHUNKING)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Set no chunking for payload
|
||||||
|
pub fn no_chunking(&mut self, val: bool) {
|
||||||
|
if val {
|
||||||
|
self.flags.insert(Flags::NO_CHUNKING);
|
||||||
|
} else {
|
||||||
|
self.flags.remove(Flags::NO_CHUNKING);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Message<T: Head> {
|
pub struct Message<T: Head> {
|
||||||
|
@ -15,7 +15,7 @@ use serde_json;
|
|||||||
use crate::body::{Body, BodyStream, MessageBody, ResponseBody};
|
use crate::body::{Body, BodyStream, MessageBody, ResponseBody};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::header::{Header, IntoHeaderValue};
|
use crate::header::{Header, IntoHeaderValue};
|
||||||
use crate::message::{ConnectionType, Head, Message, ResponseHead};
|
use crate::message::{ConnectionType, Message, ResponseHead};
|
||||||
|
|
||||||
/// An HTTP Response
|
/// An HTTP Response
|
||||||
pub struct Response<B = Body> {
|
pub struct Response<B = Body> {
|
||||||
@ -462,7 +462,7 @@ impl ResponseBuilder {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn no_chunking(&mut self) -> &mut Self {
|
pub fn no_chunking(&mut self) -> &mut Self {
|
||||||
if let Some(parts) = parts(&mut self.head, &self.err) {
|
if let Some(parts) = parts(&mut self.head, &self.err) {
|
||||||
parts.no_chunking = true;
|
parts.no_chunking(true);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -740,7 +740,7 @@ impl<'a> From<&'a ResponseHead> for ResponseBuilder {
|
|||||||
msg.status = head.status;
|
msg.status = head.status;
|
||||||
msg.reason = head.reason;
|
msg.reason = head.reason;
|
||||||
msg.headers = head.headers.clone();
|
msg.headers = head.headers.clone();
|
||||||
msg.no_chunking = head.no_chunking;
|
msg.no_chunking(!head.chunked());
|
||||||
|
|
||||||
ResponseBuilder {
|
ResponseBuilder {
|
||||||
head: Some(msg),
|
head: Some(msg),
|
||||||
|
@ -15,7 +15,7 @@ use sha1::Sha1;
|
|||||||
|
|
||||||
use crate::body::BodySize;
|
use crate::body::BodySize;
|
||||||
use crate::h1;
|
use crate::h1;
|
||||||
use crate::message::{ConnectionType, Head, ResponseHead};
|
use crate::message::{ConnectionType, ResponseHead};
|
||||||
use crate::ws::Codec;
|
use crate::ws::Codec;
|
||||||
|
|
||||||
use super::{ClientError, Connect, Protocol};
|
use super::{ClientError, Connect, Protocol};
|
||||||
|
@ -17,7 +17,7 @@ pub use actix_http::ws::{
|
|||||||
CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError,
|
CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use actix_web::dev::{Head, HttpResponseBuilder};
|
use actix_web::dev::HttpResponseBuilder;
|
||||||
use actix_web::error::{Error, ErrorInternalServerError, PayloadError};
|
use actix_web::error::{Error, ErrorInternalServerError, PayloadError};
|
||||||
use actix_web::http::{header, Method, StatusCode};
|
use actix_web::http::{header, Method, StatusCode};
|
||||||
use actix_web::{HttpMessage, HttpRequest, HttpResponse};
|
use actix_web::{HttpMessage, HttpRequest, HttpResponse};
|
||||||
|
@ -19,7 +19,7 @@ use actix_http::http::{
|
|||||||
uri, ConnectionType, Error as HttpError, HeaderName, HeaderValue, HttpTryFrom,
|
uri, ConnectionType, Error as HttpError, HeaderName, HeaderValue, HttpTryFrom,
|
||||||
Method, Uri, Version,
|
Method, Uri, Version,
|
||||||
};
|
};
|
||||||
use actix_http::{Error, Head, Payload, RequestHead};
|
use actix_http::{Error, Payload, RequestHead};
|
||||||
|
|
||||||
use crate::response::ClientResponse;
|
use crate::response::ClientResponse;
|
||||||
use crate::{Connect, PayloadError};
|
use crate::{Connect, PayloadError};
|
||||||
|
@ -145,7 +145,7 @@ pub mod dev {
|
|||||||
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody};
|
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||||
pub use actix_http::ResponseBuilder as HttpResponseBuilder;
|
pub use actix_http::ResponseBuilder as HttpResponseBuilder;
|
||||||
pub use actix_http::{
|
pub use actix_http::{
|
||||||
Extensions, Head, Payload, PayloadStream, RequestHead, ResponseHead,
|
Extensions, Payload, PayloadStream, RequestHead, ResponseHead,
|
||||||
};
|
};
|
||||||
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
|
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
|
||||||
pub use actix_server::Server;
|
pub use actix_server::Server;
|
||||||
|
@ -46,7 +46,7 @@ use derive_more::Display;
|
|||||||
use futures::future::{ok, Either, Future, FutureResult};
|
use futures::future::{ok, Either, Future, FutureResult};
|
||||||
use futures::Poll;
|
use futures::Poll;
|
||||||
|
|
||||||
use crate::dev::{Head, RequestHead};
|
use crate::dev::RequestHead;
|
||||||
use crate::error::{ResponseError, Result};
|
use crate::error::{ResponseError, Result};
|
||||||
use crate::http::header::{self, HeaderName, HeaderValue};
|
use crate::http::header::{self, HeaderName, HeaderValue};
|
||||||
use crate::http::{self, HttpTryFrom, Method, StatusCode, Uri};
|
use crate::http::{self, HttpTryFrom, Method, StatusCode, Uri};
|
||||||
|
Loading…
Reference in New Issue
Block a user