Skip to content

Commit

Permalink
feat: add async-h1 client
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Mar 2, 2020
1 parent 4c6b587 commit f9aab94
Show file tree
Hide file tree
Showing 16 changed files with 333 additions and 285 deletions.
24 changes: 15 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ documentation = "https://docs.rs/surf"
description = "HTTP client framework."
keywords = ["http", "client", "framework", "request"]
categories = ["web-programming", "web-programming::http-client"]
authors = ["Yoshua Wuyts <yoshuawuyts@gmail.com>"]
authors = ["Yoshua Wuyts <yoshuawuyts@gmail.com>", "dignifiedquire <me@dignifiedquire.com>"]
readme = "README.md"
edition = "2018"

[features]
default = ["native-client", "middleware-logger", "encoding"]
native-client = ["curl-client", "wasm-client"]
default = ["h1-client", "middleware-logger", "encoding"]
h1-client = ["async-h1", "wasm-client"]
native-client = ["curl-client", "wasm-client", "http-client/native_client"]
hyper-client = ["hyper", "hyper-tls", "native-tls", "runtime", "runtime-raw", "runtime-tokio" ]
curl-client = ["isahc"]
wasm-client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures"]
Expand All @@ -22,15 +23,20 @@ encoding = ["encoding_rs"]

[dependencies]
futures = { version = "0.3.1", features = ["compat", "io-compat"] }
http = "0.1.17"
http-types = "1.0.1"
log = { version = "0.4.7", features = ["kv_unstable"] }
mime = "0.3.13"
mime_guess = "2.0.0-alpha.6"
serde = "1.0.97"
serde_json = "1.0.40"
serde_urlencoded = "0.6.1"
url = "2.0.0"
http-client = { version = "1.1.0", features = ["native_client"] }
http-client = { git = "https://github.com/dignifiedquire/http-client-1", branch = "h1", default-features = false, features = ["h1_client"] }
async-std = { version = "1.4.0", default-features = false, features = ["std"] }

# h1-client
async-h1 = { version = "1.0.0", optional = true }
pin-project-lite = "0.1.1"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# encoding
Expand All @@ -40,12 +46,12 @@ encoding_rs = { version = "0.8.20", optional = true }
isahc = { version = "0.8", optional = true, default-features = false, features = ["http2"] }

# hyper-client
hyper = { version = "0.12.32", optional = true, default-features = false }
hyper = { version = "0.13.2", optional = true, default-features = false }
hyper-tls = { version = "0.3.2", optional = true }
native-tls = { version = "0.2.2", optional = true }
runtime = { version = "0.3.0-alpha.6", optional = true }
runtime = { version = "0.3.0-alpha.8", optional = true }
runtime-raw = { version = "0.3.0-alpha.4", optional = true }
runtime-tokio = { version = "0.3.0-alpha.5", optional = true }
runtime-tokio = { version = "0.3.0-alpha.6", optional = true }

# wasm-client
[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down Expand Up @@ -76,4 +82,4 @@ features = [
async-std = { version = "1.0", features = ["attributes"] }
femme = "1.1.0"
serde = { version = "1.0.97", features = ["derive"] }
mockito = "0.22.0"
mockito = "0.23.3"
4 changes: 2 additions & 2 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use async_std::task;

// The need for Ok with turbofish is explained here
// https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html
fn main() -> Result<(), surf::Exception> {
fn main() -> Result<(), http_types::Error> {
femme::start(log::LevelFilter::Info)?;

task::block_on(async {
let uri = "https://httpbin.org/get";
let string: String = surf::get(uri).recv_string().await?;
println!("{}", string);
Ok::<(), surf::Exception>(())
Ok::<(), http_types::Error>(())
})
}
6 changes: 3 additions & 3 deletions examples/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl<C: HttpClient> Middleware<C> for Printer {
req: Request,
client: C,
next: Next<'a, C>,
) -> BoxFuture<'a, Result<Response, surf::Exception>> {
) -> BoxFuture<'a, Result<Response, http_types::Error>> {
Box::pin(async move {
println!("sending a request!");
let res = next.run(req, client).await?;
Expand All @@ -22,13 +22,13 @@ impl<C: HttpClient> Middleware<C> for Printer {

// The need for Ok with turbofish is explained here
// https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html
fn main() -> Result<(), surf::Exception> {
fn main() -> Result<(), http_types::Error> {
femme::start(log::LevelFilter::Info)?;

task::block_on(async {
surf::get("https://httpbin.org/get")
.middleware(Printer {})
.await?;
Ok::<(), surf::Exception>(())
Ok::<(), http_types::Error>(())
})
}
28 changes: 13 additions & 15 deletions examples/next_reuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,26 @@ impl<C: HttpClient> Middleware<C> for Doubler {
req: Request,
client: C,
next: Next<'a, C>,
) -> BoxFuture<'a, Result<Response, surf::Exception>> {
) -> BoxFuture<'a, Result<Response, http_types::Error>> {
if req.method().is_safe() {
let mut new_req = Request::new(Body::empty());
*new_req.method_mut() = req.method().clone();
*new_req.uri_mut() = req.uri().clone();
*new_req.version_mut() = req.version().clone();
*new_req.headers_mut() = req.headers().clone();
Box::pin(async move {
let mut new_req = Request::new(req.method().clone(), req.url().clone());
new_req.set_version(req.version().clone());
for (name, value) in &req {
new_req.insert_header(name.clone(), &value[..])?;
}

let mut buf = Vec::new();
let (res1, res2) =
futures::future::join(next.run(req, client.clone()), next.run(new_req, client))
.await;

let res = res1?;
let mut body = res.into_body();
body.read_to_end(&mut buf).await?;
let mut res = res1?;
res.read_to_end(&mut buf).await?;

let mut res = res2?;
let mut body = std::mem::replace(res.body_mut(), Body::empty());
body.read_to_end(&mut buf).await?;

*res.body_mut() = Body::from(buf);
res.read_to_end(&mut buf).await?;
res.set_body(Body::from(buf));
Ok(res)
})
} else {
Expand All @@ -43,7 +41,7 @@ impl<C: HttpClient> Middleware<C> for Doubler {

// The need for Ok with turbofish is explained here
// https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html
fn main() -> Result<(), surf::Exception> {
fn main() -> Result<(), http_types::Error> {
femme::start(log::LevelFilter::Info).unwrap();
task::block_on(async {
let mut res = surf::get("https://httpbin.org/get")
Expand All @@ -53,6 +51,6 @@ fn main() -> Result<(), surf::Exception> {
let body = res.body_bytes().await?;
let body = String::from_utf8_lossy(&body);
println!("{}", body);
Ok::<(), surf::Exception>(())
Ok::<(), http_types::Error>(())
})
}
4 changes: 2 additions & 2 deletions examples/persistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use async_std::task;

// The need for Ok with turbofish is explained here
// https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html
fn main() -> Result<(), surf::Exception> {
fn main() -> Result<(), http_types::Error> {
femme::start(log::LevelFilter::Info).unwrap();
task::block_on(async {
let client = surf::Client::new();
let req1 = client.get("https://httpbin.org/get").recv_string();
let req2 = client.get("https://httpbin.org/get").recv_string();
futures::future::try_join(req1, req2).await?;
Ok::<(), surf::Exception>(())
Ok::<(), http_types::Error>(())
})
}
6 changes: 3 additions & 3 deletions examples/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use async_std::task;

// The need for Ok with turbofish is explained here
// https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html
fn main() -> Result<(), surf::Exception> {
fn main() -> Result<(), http_types::Error> {
femme::start(log::LevelFilter::Info).unwrap();
task::block_on(async {
let uri = "https://httpbin.org/post";
let data = serde_json::json!({ "name": "chashu" });
let res = surf::post(uri).body_json(&data).unwrap().await?;
assert_eq!(res.status(), 200);
Ok::<(), surf::Exception>(())
assert_eq!(res.status(), http_types::StatusCode::Ok);
Ok::<(), http_types::Error>(())
})
}
38 changes: 29 additions & 9 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use http_client::HttpClient;
#[cfg(feature = "native-client")]
use http_client::native::NativeClient;

#[cfg(feature = "h1-client")]
use http_client::h1::H1Client;

/// An HTTP client, capable of creating new `Request`s.
///
/// # Examples
Expand Down Expand Up @@ -39,6 +42,23 @@ impl Client<NativeClient> {
}
}

#[cfg(feature = "h1-client")]
impl Client<H1Client> {
/// Create a new instance.
///
/// # Examples
///
/// ```no_run
/// # #[async_std::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
/// let client = surf::Client::new();
/// # Ok(()) }
/// ```
pub fn new() -> Self {
Self::with_client(H1Client::new())
}
}

impl<C: HttpClient> Client<C> {
/// Create a new instance with an `http_client::HttpClient` instance.
// TODO(yw): hidden from docs until we make the traits public.
Expand Down Expand Up @@ -70,7 +90,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn get(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::GET, uri, self.client.clone())
Request::with_client(http_types::Method::Get, uri, self.client.clone())
}

/// Perform an HTTP `HEAD` request using the `Client` connection.
Expand All @@ -94,7 +114,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn head(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::HEAD, uri, self.client.clone())
Request::with_client(http_types::Method::Head, uri, self.client.clone())
}

/// Perform an HTTP `POST` request using the `Client` connection.
Expand All @@ -118,7 +138,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn post(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::POST, uri, self.client.clone())
Request::with_client(http_types::Method::Post, uri, self.client.clone())
}

/// Perform an HTTP `PUT` request using the `Client` connection.
Expand All @@ -142,7 +162,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn put(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::PUT, uri, self.client.clone())
Request::with_client(http_types::Method::Put, uri, self.client.clone())
}

/// Perform an HTTP `DELETE` request using the `Client` connection.
Expand All @@ -166,7 +186,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn delete(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::DELETE, uri, self.client.clone())
Request::with_client(http_types::Method::Delete, uri, self.client.clone())
}

/// Perform an HTTP `CONNECT` request using the `Client` connection.
Expand All @@ -190,7 +210,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn connect(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::CONNECT, uri, self.client.clone())
Request::with_client(http_types::Method::Connect, uri, self.client.clone())
}

/// Perform an HTTP `OPTIONS` request using the `Client` connection.
Expand All @@ -214,7 +234,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn options(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::OPTIONS, uri, self.client.clone())
Request::with_client(http_types::Method::Options, uri, self.client.clone())
}

/// Perform an HTTP `TRACE` request using the `Client` connection.
Expand All @@ -238,7 +258,7 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn trace(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::TRACE, uri, self.client.clone())
Request::with_client(http_types::Method::Trace, uri, self.client.clone())
}

/// Perform an HTTP `PATCH` request using the `Client` connection.
Expand All @@ -262,6 +282,6 @@ impl<C: HttpClient> Client<C> {
/// ```
pub fn patch(&self, uri: impl AsRef<str>) -> Request<C> {
let uri = uri.as_ref().parse().unwrap();
Request::with_client(http::Method::PATCH, uri, self.client.clone())
Request::with_client(http_types::Method::Patch, uri, self.client.clone())
}
}
62 changes: 0 additions & 62 deletions src/headers.rs

This file was deleted.

Loading

0 comments on commit f9aab94

Please sign in to comment.