1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-25 19:11:10 +00:00

Merge pull request #1385 from JohnTitor/http-2-alpha

Release actix-http 2.0.0-alpha.1
This commit is contained in:
Yuki Okushi 2020-02-27 14:47:32 +09:00 committed by GitHub
commit 1fa02b5f1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 309 additions and 225 deletions

View file

@ -71,7 +71,7 @@ actix-threadpool = "0.3.1"
actix-tls = "1.0.0"
actix-web-codegen = "0.2.0"
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"
awc = { version = "1.0.1", default-features = false }
bytes = "0.5.3"
@ -93,7 +93,7 @@ open-ssl = { version="0.10", package = "openssl", optional = true }
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
[dev-dependencies]
actix = "0.9.0"
actix = "0.10.0-alpha.1"
rand = "0.7"
env_logger = "0.6"
serde_derive = "1.0"

View file

@ -19,7 +19,7 @@ path = "src/lib.rs"
[dependencies]
actix-web = { version = "2.0.0-rc", default-features = false }
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"
actix-service = "1.0.1"
bitflags = "1"
bytes = "0.5.3"

View file

@ -23,7 +23,7 @@ actix-codec = "0.2.0"
actix-service = "1.0.1"
actix-router = "0.2.1"
actix-rt = "1.0.0"
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"
bytes = "0.5.3"
futures = "0.3.1"

View file

@ -1,10 +1,10 @@
# Changes
# [Unreleased]
## [2.0.0-alpha.1] - 2020-02-27
### Changed
* Update the `time` dependency to 0.2.7
* Update the `time` dependency to 0.2.7.
* Moved actors messages support from actix crate, enabled with feature `actors`.

View file

@ -1,6 +1,6 @@
[package]
name = "actix-http"
version = "1.0.1"
version = "2.0.0-alpha.1"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix http primitives"
readme = "README.md"
@ -99,7 +99,7 @@ actix-http-test = { version = "1.0.0", features=["openssl"] }
actix-tls = { version = "1.0.0", features=["openssl"] }
criterion = "0.3"
futures = "0.3.1"
env_logger = "0.6"
env_logger = "0.7"
serde_derive = "1.0"
open-ssl = { version="0.10", package = "openssl" }
rust-tls = { version="0.16", package = "rustls" }

View file

@ -17,23 +17,18 @@ async fn main() -> io::Result<()> {
HttpService::build()
.client_timeout(1000)
.client_disconnect(1000)
.finish(|mut req: Request| {
async move {
let mut body = BytesMut::new();
while let Some(item) = req.payload().next().await {
body.extend_from_slice(&item?);
}
info!("request body: {:?}", body);
Ok::<_, Error>(
Response::Ok()
.header(
"x-head",
HeaderValue::from_static("dummy value!"),
)
.body(body),
)
.finish(|mut req: Request| async move {
let mut body = BytesMut::new();
while let Some(item) = req.payload().next().await {
body.extend_from_slice(&item?);
}
info!("request body: {:?}", body);
Ok::<_, Error>(
Response::Ok()
.header("x-head", HeaderValue::from_static("dummy value!"))
.body(body),
)
})
.tcp()
})?

View file

@ -36,7 +36,10 @@ impl BodySize {
pub trait MessageBody {
fn size(&self) -> BodySize;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>>;
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>>;
downcast_get_type_id!();
}
@ -48,7 +51,10 @@ impl MessageBody for () {
BodySize::Empty
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
Poll::Ready(None)
}
}
@ -58,7 +64,10 @@ impl<T: MessageBody + Unpin> MessageBody for Box<T> {
self.as_ref().size()
}
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
Pin::new(self.get_mut().as_mut()).poll_next(cx)
}
}
@ -103,7 +112,10 @@ impl<B: MessageBody> MessageBody for ResponseBody<B> {
}
#[project]
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
#[project]
match self.project() {
ResponseBody::Body(body) => body.poll_next(cx),
@ -164,7 +176,10 @@ impl MessageBody for Body {
}
#[project]
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
#[project]
match self.project() {
Body::None => Poll::Ready(None),
@ -285,7 +300,10 @@ impl MessageBody for Bytes {
BodySize::Sized(self.len())
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
if self.is_empty() {
Poll::Ready(None)
} else {
@ -299,11 +317,16 @@ impl MessageBody for BytesMut {
BodySize::Sized(self.len())
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
if self.is_empty() {
Poll::Ready(None)
} else {
Poll::Ready(Some(Ok(mem::replace(self.get_mut(), BytesMut::new()).freeze())))
Poll::Ready(Some(Ok(
mem::replace(self.get_mut(), BytesMut::new()).freeze()
)))
}
}
}
@ -313,7 +336,10 @@ impl MessageBody for &'static str {
BodySize::Sized(self.len())
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
if self.is_empty() {
Poll::Ready(None)
} else {
@ -329,11 +355,17 @@ impl MessageBody for Vec<u8> {
BodySize::Sized(self.len())
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
if self.is_empty() {
Poll::Ready(None)
} else {
Poll::Ready(Some(Ok(Bytes::from(mem::replace(self.get_mut(), Vec::new())))))
Poll::Ready(Some(Ok(Bytes::from(mem::replace(
self.get_mut(),
Vec::new(),
)))))
}
}
}
@ -343,7 +375,10 @@ impl MessageBody for String {
BodySize::Sized(self.len())
}
fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
if self.is_empty() {
Poll::Ready(None)
} else {
@ -390,7 +425,10 @@ where
/// Empty values are skipped to prevent [`BodyStream`]'s transmission being
/// ended on a zero-length chunk, but rather proceed until the underlying
/// [`Stream`] ends.
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
let mut stream = self.project().stream;
loop {
let stream = stream.as_mut();
@ -433,7 +471,10 @@ where
/// Empty values are skipped to prevent [`SizedStream`]'s transmission being
/// ended on a zero-length chunk, but rather proceed until the underlying
/// [`Stream`] ends.
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
let mut stream: Pin<&mut S> = self.project().stream;
loop {
let stream = stream.as_mut();
@ -478,7 +519,10 @@ mod tests {
assert_eq!("test".size(), BodySize::Sized(4));
assert_eq!(
poll_fn(|cx| Pin::new(&mut "test").poll_next(cx)).await.unwrap().ok(),
poll_fn(|cx| Pin::new(&mut "test").poll_next(cx))
.await
.unwrap()
.ok(),
Some(Bytes::from("test"))
);
}
@ -497,10 +541,7 @@ mod tests {
assert_eq!(sb.size(), BodySize::Sized(4));
assert_eq!(
poll_fn(|cx| sb.as_mut().poll_next(cx))
.await
.unwrap()
.ok(),
poll_fn(|cx| sb.as_mut().poll_next(cx)).await.unwrap().ok(),
Some(Bytes::from("test"))
);
}
@ -535,7 +576,7 @@ mod tests {
Some(Bytes::from("test"))
);
}
#[actix_rt::test]
async fn test_bytes_mut() {
let b = BytesMut::from("test");
@ -569,7 +610,9 @@ mod tests {
#[actix_rt::test]
async fn test_unit() {
assert_eq!(().size(), BodySize::Empty);
assert!(poll_fn(|cx| Pin::new(&mut ()).poll_next(cx)).await.is_none());
assert!(poll_fn(|cx| Pin::new(&mut ()).poll_next(cx))
.await
.is_none());
}
#[actix_rt::test]
@ -628,11 +671,17 @@ mod tests {
pin_mut!(body);
assert_eq!(
poll_fn(|cx| body.as_mut().poll_next(cx)).await.unwrap().ok(),
poll_fn(|cx| body.as_mut().poll_next(cx))
.await
.unwrap()
.ok(),
Some(Bytes::from("1")),
);
assert_eq!(
poll_fn(|cx| body.as_mut().poll_next(cx)).await.unwrap().ok(),
poll_fn(|cx| body.as_mut().poll_next(cx))
.await
.unwrap()
.ok(),
Some(Bytes::from("2")),
);
}
@ -648,14 +697,14 @@ mod tests {
let _z = **y;
Ok::<_, ()>(Bytes::new())
})));
let waker = noop_waker();
let mut context = Context::from_waker(&waker);
pin_mut!(body_stream);
let _ = body_stream.as_mut().unwrap().poll_next(&mut context);
sender.send(()).unwrap();
let _ = std::mem::replace(&mut body_stream, Err([0; 32])).unwrap().poll_next(&mut context);
let _ = std::mem::replace(&mut body_stream, Err([0; 32])).unwrap().poll_next(&mut context);
}*/
}
@ -670,11 +719,17 @@ mod tests {
);
pin_mut!(body);
assert_eq!(
poll_fn(|cx| body.as_mut().poll_next(cx)).await.unwrap().ok(),
poll_fn(|cx| body.as_mut().poll_next(cx))
.await
.unwrap()
.ok(),
Some(Bytes::from("1")),
);
assert_eq!(
poll_fn(|cx| body.as_mut().poll_next(cx)).await.unwrap().ok(),
poll_fn(|cx| body.as_mut().poll_next(cx))
.await
.unwrap()
.ok(),
Some(Bytes::from("2")),
);
}

View file

@ -8,7 +8,7 @@ use bytes::buf::BufMutExt;
use bytes::{Bytes, BytesMut};
use futures_core::Stream;
use futures_util::future::poll_fn;
use futures_util::{SinkExt, StreamExt, pin_mut};
use futures_util::{pin_mut, SinkExt, StreamExt};
use crate::error::PayloadError;
use crate::h1;

View file

@ -16,8 +16,8 @@ use fxhash::FxHashMap;
use h2::client::{handshake, Connection, SendRequest};
use http::uri::Authority;
use indexmap::IndexSet;
use slab::Slab;
use pin_project::pin_project;
use slab::Slab;
use super::connection::{ConnectionType, IoConnection};
use super::error::ConnectError;

View file

@ -211,7 +211,12 @@ impl Date {
}
fn update(&mut self) {
self.pos = 0;
write!(self, "{}", OffsetDateTime::now().format("%a, %d %b %Y %H:%M:%S GMT")).unwrap();
write!(
self,
"{}",
OffsetDateTime::now().format("%a, %d %b %Y %H:%M:%S GMT")
)
.unwrap();
}
}
@ -282,7 +287,6 @@ impl DateService {
mod tests {
use super::*;
// Test modifying the date from within the closure
// passed to `set_date`
#[test]
@ -290,9 +294,7 @@ mod tests {
let service = DateService::new();
// Make sure that `check_date` doesn't try to spawn a task
service.0.update();
service.set_date(|_| {
service.0.reset()
});
service.set_date(|_| service.0.reset());
}
#[test]

View file

@ -109,7 +109,8 @@ impl CookieBuilder {
pub fn max_age_time(mut self, value: Duration) -> CookieBuilder {
// Truncate any nanoseconds from the Duration, as they aren't represented within `Max-Age`
// and would cause two otherwise identical `Cookie` instances to not be equivalent to one another.
self.cookie.set_max_age(Duration::seconds(value.whole_seconds()));
self.cookie
.set_max_age(Duration::seconds(value.whole_seconds()));
self
}

View file

@ -533,8 +533,8 @@ mod test {
#[test]
#[cfg(feature = "secure-cookies")]
fn delta() {
use time::Duration;
use std::collections::HashMap;
use time::Duration;
let mut c = CookieJar::new();

View file

@ -1015,7 +1015,9 @@ mod tests {
assert_eq!(&cookie.to_string(), "foo=bar; Domain=www.rust-lang.org");
let time_str = "Wed, 21 Oct 2015 07:28:00 GMT";
let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().assume_utc();
let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S")
.unwrap()
.assume_utc();
let cookie = Cookie::build("foo", "bar").expires(expires).finish();
assert_eq!(
&cookie.to_string(),

View file

@ -376,7 +376,9 @@ mod tests {
);
let time_str = "Wed, 21 Oct 2015 07:28:00 GMT";
let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().assume_utc();
let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S")
.unwrap()
.assume_utc();
expected.set_expires(expires);
assert_eq_parse!(
" foo=bar ;HttpOnly; Secure; Max-Age=4; Path=/foo; \
@ -385,7 +387,9 @@ mod tests {
);
unexpected.set_domain("foo.com");
let bad_expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%S:%M").unwrap().assume_utc();
let bad_expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%S:%M")
.unwrap()
.assume_utc();
expected.set_expires(bad_expires);
assert_ne_parse!(
" foo=bar ;HttpOnly; Secure; Max-Age=4; Path=/foo; \
@ -414,8 +418,15 @@ mod tests {
#[test]
fn do_not_panic_on_large_max_ages() {
let max_duration = Duration::max_value();
let expected = Cookie::build("foo", "bar").max_age_time(max_duration).finish();
let overflow_duration = max_duration.checked_add(Duration::nanoseconds(1)).unwrap_or(max_duration);
assert_eq_parse!(format!(" foo=bar; Max-Age={:?}", overflow_duration.whole_seconds()), expected);
let expected = Cookie::build("foo", "bar")
.max_age_time(max_duration)
.finish();
let overflow_duration = max_duration
.checked_add(Duration::nanoseconds(1))
.unwrap_or(max_duration);
assert_eq_parse!(
format!(" foo=bar; Max-Age={:?}", overflow_duration.whole_seconds()),
expected
);
}
}

View file

@ -94,9 +94,12 @@ impl<B: MessageBody> MessageBody for EncoderBody<B> {
EncoderBody::BoxedStream(ref b) => b.size(),
}
}
#[project]
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
#[project]
match self.project() {
EncoderBody::Bytes(b) => {
@ -112,7 +115,6 @@ impl<B: MessageBody> MessageBody for EncoderBody<B> {
}
}
impl<B: MessageBody> MessageBody for Encoder<B> {
fn size(&self) -> BodySize {
if self.encoder.is_none() {
@ -121,8 +123,11 @@ impl<B: MessageBody> MessageBody for Encoder<B> {
BodySize::Stream
}
}
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Error>>> {
let mut this = self.project();
loop {
if *this.eof {

View file

@ -14,7 +14,6 @@ use derive_more::{Display, From};
pub use futures_channel::oneshot::Canceled;
use http::uri::InvalidUri;
use http::{header, Error as HttpError, StatusCode};
use httparse;
use serde::de::value::Error as DeError;
use serde_json::error::Error as JsonError;
use serde_urlencoded::ser::Error as FormError;
@ -954,12 +953,12 @@ impl ResponseError for fail_ure::Error {}
#[cfg(feature = "actors")]
/// `InternalServerError` for `actix::MailboxError`
/// This is supported on feature=`actors` only
impl ResponseError for actix::MailboxError {}
impl ResponseError for actix::MailboxError {}
#[cfg(feature = "actors")]
/// `InternalServerError` for `actix::ResolverError`
/// This is supported on feature=`actors` only
impl ResponseError for actix::actors::resolver::ResolverError {}
impl ResponseError for actix::actors::resolver::ResolverError {}
#[cfg(test)]
mod tests {

View file

@ -8,7 +8,6 @@ use actix_codec::Decoder;
use bytes::{Buf, Bytes, BytesMut};
use http::header::{HeaderName, HeaderValue};
use http::{header, Method, StatusCode, Uri, Version};
use httparse;
use log::{debug, error, trace};
use crate::error::ParseError;

View file

@ -1,3 +1,6 @@
// Because MSRV is 1.39.0.
#![allow(clippy::mem_replace_with_default)]
use std::collections::VecDeque;
use std::future::Future;
use std::pin::Pin;
@ -297,7 +300,10 @@ where
/// true - got whouldblock
/// false - didnt get whouldblock
#[pin_project::project]
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Result<bool, DispatchError> {
if self.write_buf.is_empty() {
return Ok(false);
}
@ -308,8 +314,7 @@ where
let InnerDispatcher { io, write_buf, .. } = self.project();
let mut io = Pin::new(io.as_mut().unwrap());
while written < len {
match io.as_mut().poll_write(cx, &write_buf[written..])
{
match io.as_mut().poll_write(cx, &write_buf[written..]) {
Poll::Ready(Ok(0)) => {
return Err(DispatchError::Io(io::Error::new(
io::ErrorKind::WriteZero,
@ -359,7 +364,8 @@ where
}
fn send_continue(self: Pin<&mut Self>) {
self.project().write_buf
self.project()
.write_buf
.extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
}
@ -376,47 +382,44 @@ where
Some(DispatcherMessage::Item(req)) => {
Some(self.as_mut().handle_request(req, cx)?)
}
Some(DispatcherMessage::Error(res)) => {
Some(self.as_mut().send_response(res, ResponseBody::Other(Body::Empty))?)
}
Some(DispatcherMessage::Error(res)) => Some(
self.as_mut()
.send_response(res, ResponseBody::Other(Body::Empty))?,
),
Some(DispatcherMessage::Upgrade(req)) => {
return Ok(PollResponse::Upgrade(req));
}
None => None,
},
State::ExpectCall(fut) => {
match fut.poll(cx) {
Poll::Ready(Ok(req)) => {
self.as_mut().send_continue();
this = self.as_mut().project();
this.state.set(State::ServiceCall(this.service.call(req)));
continue;
}
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
Some(self.as_mut().send_response(res, body.into_body())?)
}
Poll::Pending => None,
State::ExpectCall(fut) => match fut.poll(cx) {
Poll::Ready(Ok(req)) => {
self.as_mut().send_continue();
this = self.as_mut().project();
this.state.set(State::ServiceCall(this.service.call(req)));
continue;
}
}
State::ServiceCall(fut) => {
match fut.poll(cx) {
Poll::Ready(Ok(res)) => {
let (res, body) = res.into().replace_body(());
let state = self.as_mut().send_response(res, body)?;
this = self.as_mut().project();
this.state.set(state);
continue;
}
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
Some(self.as_mut().send_response(res, body.into_body())?)
}
Poll::Pending => None,
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
Some(self.as_mut().send_response(res, body.into_body())?)
}
}
Poll::Pending => None,
},
State::ServiceCall(fut) => match fut.poll(cx) {
Poll::Ready(Ok(res)) => {
let (res, body) = res.into().replace_body(());
let state = self.as_mut().send_response(res, body)?;
this = self.as_mut().project();
this.state.set(state);
continue;
}
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
Some(self.as_mut().send_response(res, body.into_body())?)
}
Poll::Pending => None,
},
State::SendPayload(mut stream) => {
loop {
if this.write_buf.len() < HW_BUFFER_SIZE {
@ -627,7 +630,10 @@ where
}
/// keep-alive timer
fn poll_keepalive(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> {
fn poll_keepalive(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Result<(), DispatchError> {
let mut this = self.as_mut().project();
if this.ka_timer.is_none() {
// shutdown timeout
@ -738,7 +744,11 @@ where
if !inner.write_buf.is_empty() || inner.io.is_none() {
Poll::Pending
} else {
match Pin::new(inner.project().io).as_pin_mut().unwrap().poll_shutdown(cx) {
match Pin::new(inner.project().io)
.as_pin_mut()
.unwrap()
.poll_shutdown(cx)
{
Poll::Ready(res) => {
Poll::Ready(res.map_err(DispatchError::from))
}
@ -751,7 +761,11 @@ where
let should_disconnect =
if !inner.flags.contains(Flags::READ_DISCONNECT) {
let mut inner_p = inner.as_mut().project();
read_available(cx, inner_p.io.as_mut().unwrap(), &mut inner_p.read_buf)?
read_available(
cx,
inner_p.io.as_mut().unwrap(),
&mut inner_p.read_buf,
)?
} else {
None
};
@ -783,11 +797,18 @@ where
std::mem::replace(inner_p.codec, Codec::default()),
std::mem::replace(inner_p.read_buf, BytesMut::default()),
);
parts.write_buf = std::mem::replace(inner_p.write_buf, BytesMut::default());
parts.write_buf = std::mem::replace(
inner_p.write_buf,
BytesMut::default(),
);
let framed = Framed::from_parts(parts);
let upgrade = inner_p.upgrade.take().unwrap().call((req, framed));
self.as_mut().project().inner.set(DispatcherState::Upgrade(upgrade));
return self.poll(cx);
let upgrade =
inner_p.upgrade.take().unwrap().call((req, framed));
self.as_mut()
.project()
.inner
.set(DispatcherState::Upgrade(upgrade));
return self.poll(cx);
}
// we didnt get WouldBlock from write operation,
@ -834,12 +855,10 @@ where
}
}
}
DispatcherState::Upgrade(fut) => {
fut.poll(cx).map_err(|e| {
error!("Upgrade handler error: {}", e);
DispatchError::Upgrade
})
}
DispatcherState::Upgrade(fut) => fut.poll(cx).map_err(|e| {
error!("Upgrade handler error: {}", e);
DispatchError::Upgrade
}),
}
}
}
@ -931,7 +950,10 @@ mod tests {
if let DispatcherState::Normal(ref mut inner) = h1.inner {
assert!(inner.flags.contains(Flags::READ_DISCONNECT));
assert_eq!(&inner.io.take().unwrap().write_buf[..26], b"HTTP/1.1 400 Bad Request\r\n");
assert_eq!(
&inner.io.take().unwrap().write_buf[..26],
b"HTTP/1.1 400 Bad Request\r\n"
);
}
})
.await;

View file

@ -255,63 +255,60 @@ where
#[project]
match this.state.project() {
ServiceResponseState::ServiceCall(call, send) => {
match call.poll(cx) {
Poll::Ready(Ok(res)) => {
let (res, body) = res.into().replace_body(());
ServiceResponseState::ServiceCall(call, send) => match call.poll(cx) {
Poll::Ready(Ok(res)) => {
let (res, body) = res.into().replace_body(());
let mut send = send.take().unwrap();
let mut size = body.size();
let h2_res =
self.as_mut().prepare_response(res.head(), &mut size);
this = self.as_mut().project();
let mut send = send.take().unwrap();
let mut size = body.size();
let h2_res = self.as_mut().prepare_response(res.head(), &mut size);
this = self.as_mut().project();
let stream = match send.send_response(h2_res, size.is_eof()) {
Err(e) => {
trace!("Error sending h2 response: {:?}", e);
return Poll::Ready(());
}
Ok(stream) => stream,
};
if size.is_eof() {
Poll::Ready(())
} else {
this.state.set(ServiceResponseState::SendPayload(stream, body));
self.poll(cx)
let stream = match send.send_response(h2_res, size.is_eof()) {
Err(e) => {
trace!("Error sending h2 response: {:?}", e);
return Poll::Ready(());
}
}
Poll::Pending => Poll::Pending,
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
Ok(stream) => stream,
};
let mut send = send.take().unwrap();
let mut size = body.size();
let h2_res =
self.as_mut().prepare_response(res.head(), &mut size);
this = self.as_mut().project();
let stream = match send.send_response(h2_res, size.is_eof()) {
Err(e) => {
trace!("Error sending h2 response: {:?}", e);
return Poll::Ready(());
}
Ok(stream) => stream,
};
if size.is_eof() {
Poll::Ready(())
} else {
this.state.set(ServiceResponseState::SendPayload(
stream,
body.into_body(),
));
self.poll(cx)
}
if size.is_eof() {
Poll::Ready(())
} else {
this.state
.set(ServiceResponseState::SendPayload(stream, body));
self.poll(cx)
}
}
}
Poll::Pending => Poll::Pending,
Poll::Ready(Err(e)) => {
let res: Response = e.into().into();
let (res, body) = res.replace_body(());
let mut send = send.take().unwrap();
let mut size = body.size();
let h2_res = self.as_mut().prepare_response(res.head(), &mut size);
this = self.as_mut().project();
let stream = match send.send_response(h2_res, size.is_eof()) {
Err(e) => {
trace!("Error sending h2 response: {:?}", e);
return Poll::Ready(());
}
Ok(stream) => stream,
};
if size.is_eof() {
Poll::Ready(())
} else {
this.state.set(ServiceResponseState::SendPayload(
stream,
body.into_body(),
));
self.poll(cx)
}
}
},
ServiceResponseState::SendPayload(ref mut stream, ref mut body) => loop {
loop {
if let Some(ref mut buffer) = this.buffer {

View file

@ -83,13 +83,11 @@ where
Error = DispatchError,
InitError = S::InitError,
> {
pipeline_factory(fn_factory(|| {
async {
Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
let peer_addr = io.peer_addr().ok();
ok::<_, DispatchError>((io, peer_addr))
}))
}
pipeline_factory(fn_factory(|| async {
Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
let peer_addr = io.peer_addr().ok();
ok::<_, DispatchError>((io, peer_addr))
}))
}))
.and_then(self)
}

View file

@ -423,7 +423,7 @@ impl ContentDisposition {
/// Return the value of *name* if exists.
pub fn get_name(&self) -> Option<&str> {
self.parameters.iter().filter_map(|p| p.as_name()).nth(0)
self.parameters.iter().filter_map(|p| p.as_name()).next()
}
/// Return the value of *filename* if exists.
@ -431,7 +431,7 @@ impl ContentDisposition {
self.parameters
.iter()
.filter_map(|p| p.as_filename())
.nth(0)
.next()
}
/// Return the value of *filename\** if exists.
@ -439,7 +439,7 @@ impl ContentDisposition {
self.parameters
.iter()
.filter_map(|p| p.as_filename_ext())
.nth(0)
.next()
}
/// Return the value of the parameter which the `name` matches.
@ -448,7 +448,7 @@ impl ContentDisposition {
self.parameters
.iter()
.filter_map(|p| p.as_unknown(name))
.nth(0)
.next()
}
/// Return the value of the extended parameter which the `name` matches.
@ -457,7 +457,7 @@ impl ContentDisposition {
self.parameters
.iter()
.filter_map(|p| p.as_unknown_ext(name))
.nth(0)
.next()
}
}

View file

@ -5,7 +5,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use bytes::{buf::BufMutExt, BytesMut};
use http::header::{HeaderValue, InvalidHeaderValue};
use time::{PrimitiveDateTime, OffsetDateTime, offset};
use time::{offset, OffsetDateTime, PrimitiveDateTime};
use crate::error::ParseError;
use crate::header::IntoHeaderValue;
@ -21,7 +21,7 @@ impl FromStr for HttpDate {
fn from_str(s: &str) -> Result<HttpDate, ParseError> {
match time_parser::parse_http_date(s) {
Some(t) => Ok(HttpDate(t.assume_utc())),
None => Err(ParseError::Header)
None => Err(ParseError::Header),
}
}
}
@ -49,7 +49,14 @@ impl IntoHeaderValue for HttpDate {
fn try_into(self) -> Result<HeaderValue, Self::Error> {
let mut wrt = BytesMut::with_capacity(29).writer();
write!(wrt, "{}", self.0.to_offset(offset!(UTC)).format("%a, %d %b %Y %H:%M:%S GMT")).unwrap();
write!(
wrt,
"{}",
self.0
.to_offset(offset!(UTC))
.format("%a, %d %b %Y %H:%M:%S GMT")
)
.unwrap();
HeaderValue::from_maybe_shared(wrt.get_mut().split().freeze())
}
}
@ -66,14 +73,13 @@ impl From<HttpDate> for SystemTime {
#[cfg(test)]
mod tests {
use super::HttpDate;
use time::{PrimitiveDateTime, date, time};
use time::{date, time, PrimitiveDateTime};
#[test]
fn test_date() {
let nov_07 = HttpDate(PrimitiveDateTime::new(
date!(1994-11-07),
time!(8:48:37)
).assume_utc());
let nov_07 = HttpDate(
PrimitiveDateTime::new(date!(1994 - 11 - 07), time!(8:48:37)).assume_utc(),
);
assert_eq!(
"Sun, 07 Nov 1994 08:48:37 GMT".parse::<HttpDate>().unwrap(),

View file

@ -117,7 +117,7 @@ pub fn write_content_length(n: usize, bytes: &mut BytesMut) {
} else if n < 1_000_000 {
let n = n as u32;
let d100000 = (n / 100000) as u8;
let d100000 = (n / 100_000) as u8;
let d10000 = ((n / 10000) % 10) as u8;
let d1000 = ((n / 1000) % 10) as u8;
let d100 = ((n / 100) % 10) as u8;
@ -149,7 +149,7 @@ pub(crate) fn write_usize(n: usize, bytes: &mut BytesMut) {
let lsd = (n % 10) as u8;
// remove the lsd from n
n = n / 10;
n /= 10;
buf.put_u8(DIGITS_START + lsd);
}

View file

@ -21,7 +21,7 @@ macro_rules! downcast_get_type_id {
{
(std::any::TypeId::of::<Self>(), PrivateHelper(()))
}
}
};
}
//Generate implementation for dyn $name

View file

@ -9,7 +9,6 @@ use std::{fmt, str};
use bytes::{Bytes, BytesMut};
use futures_core::Stream;
use serde::Serialize;
use serde_json;
use crate::body::{Body, BodyStream, MessageBody, ResponseBody};
use crate::cookie::{Cookie, CookieJar};

View file

@ -1,4 +1,4 @@
use time::{OffsetDateTime, PrimitiveDateTime, Date};
use time::{Date, OffsetDateTime, PrimitiveDateTime};
/// Attempt to parse a `time` string as one of either RFC 1123, RFC 850, or asctime.
pub fn parse_http_date(time: &str) -> Option<PrimitiveDateTime> {
@ -29,10 +29,10 @@ fn try_parse_rfc_850(time: &str) -> Option<PrimitiveDateTime> {
match Date::try_from_ymd(expanded_year, dt.month(), dt.day()) {
Ok(date) => Some(PrimitiveDateTime::new(date, dt.time())),
Err(_) => None
Err(_) => None,
}
}
Err(_) => None
Err(_) => None,
}
}

View file

@ -2,7 +2,6 @@ use std::convert::TryFrom;
use bytes::{Buf, BufMut, BytesMut};
use log::debug;
use rand;
use crate::ws::mask::apply_mask;
use crate::ws::proto::{CloseCode, CloseReason, OpCode};

View file

@ -1,5 +1,3 @@
use base64;
use sha1;
use std::convert::{From, Into};
use std::fmt;

View file

@ -97,11 +97,9 @@ async fn test_h2_body() -> io::Result<()> {
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
let mut srv = test_server(move || {
HttpService::build()
.h2(|mut req: Request<_>| {
async move {
let body = load_body(req.take_payload()).await?;
Ok::<_, Error>(Response::Ok().body(body))
}
.h2(|mut req: Request<_>| async move {
let body = load_body(req.take_payload()).await?;
Ok::<_, Error>(Response::Ok().body(body))
})
.openssl(ssl_acceptor())
.map_err(|_| ())

View file

@ -104,11 +104,9 @@ async fn test_h2_body1() -> io::Result<()> {
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
let mut srv = test_server(move || {
HttpService::build()
.h2(|mut req: Request<_>| {
async move {
let body = load_body(req.take_payload()).await?;
Ok::<_, Error>(Response::Ok().body(body))
}
.h2(|mut req: Request<_>| async move {
let body = load_body(req.take_payload()).await?;
Ok::<_, Error>(Response::Ok().body(body))
})
.rustls(ssl_acceptor())
});

View file

@ -29,4 +29,4 @@ twoway = "0.2"
[dev-dependencies]
actix-rt = "1.0.0"
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"

View file

@ -16,9 +16,9 @@ name = "actix_web_actors"
path = "src/lib.rs"
[dependencies]
actix = "0.9.0"
actix = "0.10.0-alpha.1"
actix-web = "2.0.0"
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"
actix-codec = "0.2.0"
bytes = "0.5.2"
futures = "0.3.1"

View file

@ -36,7 +36,7 @@ compress = ["actix-http/compress"]
[dependencies]
actix-codec = "0.2.0"
actix-service = "1.0.1"
actix-http = "1.0.1"
actix-http = "2.0.0-alpha.1"
actix-rt = "1.0.0"
base64 = "0.11"
@ -56,7 +56,7 @@ rust-tls = { version = "0.16.0", package="rustls", optional = true, features = [
[dev-dependencies]
actix-connect = { version = "1.0.1", features=["openssl"] }
actix-web = { version = "2.0.0", features=["openssl"] }
actix-http = { version = "1.0.1", features=["openssl"] }
actix-http = { version = "2.0.0-alpha.1", features=["openssl"] }
actix-http-test = { version = "1.0.0", features=["openssl"] }
actix-utils = "1.0.3"
actix-server = "1.0.0"

View file

@ -55,5 +55,5 @@ time = { version = "0.2.7", default-features = false, features = ["std"] }
open-ssl = { version="0.10", package="openssl", optional = true }
[dev-dependencies]
actix-web = { version = "2.0.0" }
actix-http = { version = "1.0.1" }
actix-web = "2.0.0"
actix-http = "2.0.0-alpha.1"