1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-06-25 06:39:22 +02:00

upgrade to tokio 0.2

This commit is contained in:
Nikolay Kim
2019-12-05 23:35:43 +06:00
parent b45c6cd66b
commit 205a964d8f
72 changed files with 764 additions and 555 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "awc"
version = "0.3.0-alpha.2"
version = "0.3.0-alpha.3"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix http client."
readme = "README.md"
@ -21,7 +21,7 @@ name = "awc"
path = "src/lib.rs"
[package.metadata.docs.rs]
features = ["openssl", "brotli", "flate2-zlib"]
features = ["openssl", "rustls", "brotli", "flate2-zlib"]
[features]
default = ["brotli", "flate2-zlib"]
@ -30,7 +30,7 @@ default = ["brotli", "flate2-zlib"]
openssl = ["open-ssl", "actix-http/openssl"]
# rustls
# rustls = ["rust-tls", "actix-http/rustls"]
rustls = ["rust-tls", "actix-http/rustls"]
# brotli encoding, requires c compiler
brotli = ["actix-http/brotli"]
@ -42,13 +42,13 @@ flate2-zlib = ["actix-http/flate2-zlib"]
flate2-rust = ["actix-http/flate2-rust"]
[dependencies]
actix-codec = "0.2.0-alpha.2"
actix-service = "1.0.0-alpha.2"
actix-http = "0.3.0-alpha.2"
actix-rt = "1.0.0-alpha.2"
actix-codec = "0.2.0-alpha.3"
actix-service = "1.0.0-alpha.3"
actix-http = "0.3.0-alpha.3"
actix-rt = "1.0.0-alpha.3"
base64 = "0.10.1"
bytes = "0.4"
base64 = "0.11"
bytes = "0.5.2"
derive_more = "0.99.2"
futures = "0.3.1"
log =" 0.4"
@ -59,16 +59,16 @@ serde = "1.0"
serde_json = "1.0"
serde_urlencoded = "0.6.1"
open-ssl = { version="0.10", package="openssl", optional = true }
# rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] }
rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] }
[dev-dependencies]
actix-connect = { version = "1.0.0-alpha.2", features=["openssl"] }
actix-web = { version = "2.0.0-alpha.2", features=["openssl"] }
actix-http = { version = "0.3.0-alpha.2", features=["openssl"] }
actix-http-test = { version = "0.3.0-alpha.2", features=["openssl"] }
actix-utils = "1.0.0-alpha.2"
actix-server = { version = "1.0.0-alpha.2" }
#actix-tls = { version = "0.1.0-alpha.1", features=["openssl"] }
actix-connect = { version = "1.0.0-alpha.3", features=["openssl"] }
actix-web = { version = "2.0.0-alpha.3", features=["openssl"] }
actix-http = { version = "0.3.0-alpha.3", features=["openssl"] }
actix-http-test = { version = "0.3.0-alpha.3", features=["openssl"] }
actix-utils = "1.0.0-alpha.3"
actix-server = { version = "1.0.0-alpha.3" }
actix-tls = { version = "1.0.0-alpha.3", features=["openssl", "rustls"] }
brotli2 = { version="0.3.2" }
flate2 = { version="1.0.2" }
env_logger = "0.6"

View File

@ -1,10 +1,11 @@
use std::cell::RefCell;
use std::convert::TryFrom;
use std::fmt;
use std::rc::Rc;
use std::time::Duration;
use actix_http::client::{Connect, ConnectError, Connection, Connector};
use actix_http::http::{header, HeaderMap, HeaderName, HttpTryFrom};
use actix_http::http::{header, Error as HttpError, HeaderMap, HeaderName};
use actix_service::Service;
use crate::connect::ConnectorWrapper;
@ -97,8 +98,8 @@ impl ClientBuilder {
/// get added to every request.
pub fn header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
<HeaderName as HttpTryFrom<K>>::Error: fmt::Debug,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: fmt::Debug + Into<HttpError>,
V: header::IntoHeaderValue,
V::Error: fmt::Debug,
{

View File

@ -1,7 +1,7 @@
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll};
use std::{fmt, io, net};
use std::{fmt, io, mem, net};
use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_http::body::Body;
@ -201,7 +201,10 @@ impl fmt::Debug for BoxedSocket {
}
impl AsyncRead for BoxedSocket {
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
unsafe fn prepare_uninitialized_buffer(
&self,
buf: &mut [mem::MaybeUninit<u8>],
) -> bool {
self.0.as_read().prepare_uninitialized_buffer(buf)
}

View File

@ -3,13 +3,14 @@ pub use actix_http::client::{
ConnectError, FreezeRequestError, InvalidUrl, SendRequestError,
};
pub use actix_http::error::PayloadError;
pub use actix_http::http::Error as HttpError;
pub use actix_http::ws::HandshakeError as WsHandshakeError;
pub use actix_http::ws::ProtocolError as WsProtocolError;
use actix_http::ResponseError;
use serde_json::error::Error as JsonError;
use actix_http::http::{header::HeaderValue, Error as HttpError, StatusCode};
use actix_http::http::{header::HeaderValue, StatusCode};
use derive_more::{Display, From};
/// Websocket client error

View File

@ -1,3 +1,4 @@
use std::convert::TryFrom;
use std::net;
use std::rc::Rc;
use std::time::Duration;
@ -8,9 +9,7 @@ use serde::Serialize;
use actix_http::body::Body;
use actix_http::http::header::IntoHeaderValue;
use actix_http::http::{
Error as HttpError, HeaderMap, HeaderName, HttpTryFrom, Method, Uri,
};
use actix_http::http::{Error as HttpError, HeaderMap, HeaderName, Method, Uri};
use actix_http::{Error, RequestHead};
use crate::sender::{RequestSender, SendClientRequest};
@ -112,7 +111,8 @@ impl FrozenClientRequest {
/// Create a `FrozenSendBuilder` with an extra header
pub fn extra_header<K, V>(&self, key: K, value: V) -> FrozenSendBuilder
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
self.extra_headers(HeaderMap::new())
@ -139,7 +139,8 @@ impl FrozenSendBuilder {
/// Insert a header, it overrides existing header in `FrozenClientRequest`.
pub fn extra_header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {

View File

@ -19,12 +19,13 @@
//! }
//! ```
use std::cell::RefCell;
use std::convert::TryFrom;
use std::rc::Rc;
use std::time::Duration;
pub use actix_http::{client::Connector, cookie, http};
use actix_http::http::{HeaderMap, HttpTryFrom, Method, Uri};
use actix_http::http::{Error as HttpError, HeaderMap, Method, Uri};
use actix_http::RequestHead;
mod builder;
@ -102,7 +103,8 @@ impl Client {
/// Construct HTTP request.
pub fn request<U>(&self, method: Method, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
let mut req = ClientRequest::new(method, url, self.0.clone());
@ -118,7 +120,8 @@ impl Client {
/// copies all headers and the method.
pub fn request_from<U>(&self, url: U, head: &RequestHead) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
let mut req = self.request(head.method.clone(), url);
for (key, value) in head.headers.iter() {
@ -130,7 +133,8 @@ impl Client {
/// Construct HTTP *GET* request.
pub fn get<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::GET, url)
}
@ -138,7 +142,8 @@ impl Client {
/// Construct HTTP *HEAD* request.
pub fn head<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::HEAD, url)
}
@ -146,7 +151,8 @@ impl Client {
/// Construct HTTP *PUT* request.
pub fn put<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::PUT, url)
}
@ -154,7 +160,8 @@ impl Client {
/// Construct HTTP *POST* request.
pub fn post<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::POST, url)
}
@ -162,7 +169,8 @@ impl Client {
/// Construct HTTP *PATCH* request.
pub fn patch<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::PATCH, url)
}
@ -170,7 +178,8 @@ impl Client {
/// Construct HTTP *DELETE* request.
pub fn delete<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::DELETE, url)
}
@ -178,7 +187,8 @@ impl Client {
/// Construct HTTP *OPTIONS* request.
pub fn options<U>(&self, url: U) -> ClientRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
self.request(Method::OPTIONS, url)
}
@ -186,7 +196,8 @@ impl Client {
/// Construct WebSockets request.
pub fn ws<U>(&self, url: U) -> ws::WebsocketsRequest
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
let mut req = ws::WebsocketsRequest::new(url, self.0.clone());
for (key, value) in self.0.headers.iter() {

View File

@ -1,10 +1,10 @@
use std::convert::TryFrom;
use std::fmt::Write as FmtWrite;
use std::io::Write;
use std::rc::Rc;
use std::time::Duration;
use std::{fmt, net};
use bytes::{BufMut, Bytes, BytesMut};
use bytes::Bytes;
use futures::Stream;
use percent_encoding::percent_encode;
use serde::Serialize;
@ -13,8 +13,8 @@ use actix_http::body::Body;
use actix_http::cookie::{Cookie, CookieJar, USERINFO};
use actix_http::http::header::{self, Header, IntoHeaderValue};
use actix_http::http::{
uri, ConnectionType, Error as HttpError, HeaderMap, HeaderName, HeaderValue,
HttpTryFrom, Method, Uri, Version,
uri, ConnectionType, Error as HttpError, HeaderMap, HeaderName, HeaderValue, Method,
Uri, Version,
};
use actix_http::{Error, RequestHead};
@ -67,7 +67,8 @@ impl ClientRequest {
/// Create new client request builder.
pub(crate) fn new<U>(method: Method, uri: U, config: Rc<ClientConfig>) -> Self
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
ClientRequest {
config,
@ -86,7 +87,8 @@ impl ClientRequest {
#[inline]
pub fn uri<U>(mut self, uri: U) -> Self
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
match Uri::try_from(uri) {
Ok(uri) => self.head.uri = uri,
@ -196,7 +198,8 @@ impl ClientRequest {
/// ```
pub fn header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -212,7 +215,8 @@ impl ClientRequest {
/// Insert a header, replaces existing header.
pub fn set_header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -228,7 +232,8 @@ impl ClientRequest {
/// Insert a header only if it is not yet set.
pub fn set_header_if_none<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -264,7 +269,8 @@ impl ClientRequest {
#[inline]
pub fn content_type<V>(mut self, value: V) -> Self
where
HeaderValue: HttpTryFrom<V>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
{
match HeaderValue::try_from(value) {
Ok(value) => self.head.headers.insert(header::CONTENT_TYPE, value),
@ -276,9 +282,7 @@ impl ClientRequest {
/// Set content length
#[inline]
pub fn content_length(self, len: u64) -> Self {
let mut wrt = BytesMut::new().writer();
let _ = write!(wrt, "{}", len);
self.header(header::CONTENT_LENGTH, wrt.get_mut().take().freeze())
self.header(header::CONTENT_LENGTH, len)
}
/// Set HTTP basic authorization header
@ -513,9 +517,9 @@ impl ClientRequest {
let uri = &self.head.uri;
if uri.host().is_none() {
return Err(InvalidUrl::MissingHost.into());
} else if uri.scheme_part().is_none() {
} else if uri.scheme().is_none() {
return Err(InvalidUrl::MissingScheme.into());
} else if let Some(scheme) = uri.scheme_part() {
} else if let Some(scheme) = uri.scheme() {
match scheme.as_str() {
"http" | "ws" | "https" | "wss" => (),
_ => return Err(InvalidUrl::UnknownScheme.into()),
@ -551,7 +555,7 @@ impl ClientRequest {
let https = slf
.head
.uri
.scheme_part()
.scheme()
.map(|s| s == &uri::Scheme::HTTPS)
.unwrap_or(true);

View File

@ -348,7 +348,7 @@ where
continue;
}
}
Poll::Ready(None) => Poll::Ready(Ok(this.buf.take().freeze())),
Poll::Ready(None) => Poll::Ready(Ok(this.buf.split().freeze())),
Poll::Pending => Poll::Pending,
};
}

View File

@ -1,9 +1,10 @@
//! Test helpers for actix http client to use during testing.
use std::convert::TryFrom;
use std::fmt::Write as FmtWrite;
use actix_http::cookie::{Cookie, CookieJar, USERINFO};
use actix_http::http::header::{self, Header, HeaderValue, IntoHeaderValue};
use actix_http::http::{HeaderName, HttpTryFrom, StatusCode, Version};
use actix_http::http::{Error as HttpError, HeaderName, StatusCode, Version};
use actix_http::{h1, Payload, ResponseHead};
use bytes::Bytes;
use percent_encoding::percent_encode;
@ -31,7 +32,8 @@ impl TestResponse {
/// Create TestResponse and set header
pub fn with_header<K, V>(key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
Self::default().header(key, value)
@ -55,7 +57,8 @@ impl TestResponse {
/// Append a header
pub fn header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
if let Ok(key) = HeaderName::try_from(key) {

View File

@ -1,4 +1,5 @@
//! Websockets client
use std::convert::TryFrom;
use std::fmt::Write as FmtWrite;
use std::net::SocketAddr;
use std::rc::Rc;
@ -7,7 +8,7 @@ use std::{fmt, str};
use actix_codec::Framed;
use actix_http::cookie::{Cookie, CookieJar};
use actix_http::{ws, Payload, RequestHead};
use actix_rt::time::Timeout;
use actix_rt::time::timeout;
use percent_encoding::percent_encode;
use actix_http::cookie::USERINFO;
@ -19,7 +20,7 @@ use crate::http::header::{
self, HeaderName, HeaderValue, IntoHeaderValue, AUTHORIZATION,
};
use crate::http::{
ConnectionType, Error as HttpError, HttpTryFrom, Method, StatusCode, Uri, Version,
ConnectionType, Error as HttpError, Method, StatusCode, Uri, Version,
};
use crate::response::ClientResponse;
use crate::ClientConfig;
@ -41,7 +42,8 @@ impl WebsocketsRequest {
/// Create new websocket connection
pub(crate) fn new<U>(uri: U, config: Rc<ClientConfig>) -> Self
where
Uri: HttpTryFrom<U>,
Uri: TryFrom<U>,
<Uri as TryFrom<U>>::Error: Into<HttpError>,
{
let mut err = None;
let mut head = RequestHead::default();
@ -102,9 +104,10 @@ impl WebsocketsRequest {
}
/// Set request Origin
pub fn origin<V>(mut self, origin: V) -> Self
pub fn origin<V, E>(mut self, origin: V) -> Self
where
HeaderValue: HttpTryFrom<V>,
HeaderValue: TryFrom<V, Error = E>,
HttpError: From<E>,
{
match HeaderValue::try_from(origin) {
Ok(value) => self.origin = Some(value),
@ -133,7 +136,8 @@ impl WebsocketsRequest {
/// To override header use `set_header()` method.
pub fn header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -151,7 +155,8 @@ impl WebsocketsRequest {
/// Insert a header, replaces existing header.
pub fn set_header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -169,7 +174,8 @@ impl WebsocketsRequest {
/// Insert a header only if it is not yet set.
pub fn set_header_if_none<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: HttpTryFrom<K>,
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
V: IntoHeaderValue,
{
match HeaderName::try_from(key) {
@ -220,9 +226,9 @@ impl WebsocketsRequest {
let uri = &self.head.uri;
if uri.host().is_none() {
return Err(InvalidUrl::MissingHost.into());
} else if uri.scheme_part().is_none() {
} else if uri.scheme().is_none() {
return Err(InvalidUrl::MissingScheme.into());
} else if let Some(scheme) = uri.scheme_part() {
} else if let Some(scheme) = uri.scheme() {
match scheme.as_str() {
"http" | "ws" | "https" | "wss" => (),
_ => return Err(InvalidUrl::UnknownScheme.into()),
@ -295,8 +301,8 @@ impl WebsocketsRequest {
.open_tunnel(head, self.addr);
// set request timeout
let (head, framed) = if let Some(timeout) = self.config.timeout {
Timeout::new(fut, timeout)
let (head, framed) = if let Some(to) = self.config.timeout {
timeout(to, fut)
.await
.map_err(|_| SendRequestError::Timeout.into())
.and_then(|res| res)?

View File

@ -1,21 +1,17 @@
#![cfg(feature = "rustls")]
use rust_tls::ClientConfig;
use std::io::Result;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::HttpService;
use actix_http_test::TestServer;
use actix_server::ssl::OpensslAcceptor;
use actix_service::{pipeline_factory, ServiceFactory};
use actix_web::http::Version;
use actix_web::{web, App, HttpResponse};
use futures::future::ok;
use open_ssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslVerifyMode};
use rust_tls::ClientConfig;
fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> Result<OpensslAcceptor<T, ()>> {
fn ssl_acceptor() -> SslAcceptor {
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_verify_callback(SslVerifyMode::NONE, |_, _| true);
@ -33,8 +29,8 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> Result<OpensslAcceptor<T, ()>> {
Err(open_ssl::ssl::AlpnError::NOACK)
}
});
builder.set_alpn_protos(b"\x02h2")?;
Ok(actix_server::ssl::OpensslAcceptor::new(builder.build()))
builder.set_alpn_protos(b"\x02h2").unwrap();
builder.build()
}
mod danger {
@ -55,7 +51,6 @@ mod danger {
// #[actix_rt::test]
async fn _test_connection_reuse_h2() {
let openssl = ssl_acceptor().unwrap();
let num = Arc::new(AtomicUsize::new(0));
let num2 = num.clone();
@ -65,15 +60,11 @@ async fn _test_connection_reuse_h2() {
num2.fetch_add(1, Ordering::Relaxed);
ok(io)
})
.and_then(
openssl
.clone()
.map_err(|e| println!("Openssl error: {}", e)),
)
.and_then(
HttpService::build()
.h2(App::new()
.service(web::resource("/").route(web::to(|| HttpResponse::Ok()))))
.openssl(ssl_acceptor())
.map_err(|_| ()),
)
});

View File

@ -63,10 +63,7 @@ async fn test_simple() {
.await
.unwrap();
let item = framed.next().await.unwrap().unwrap();
assert_eq!(
item,
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
);
assert_eq!(item, ws::Frame::Binary(Some(BytesMut::from(&b"text"[..]))));
framed.send(ws::Message::Ping("text".into())).await.unwrap();
let item = framed.next().await.unwrap().unwrap();