Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7.0 - breaking: completely re-write feature flags #108

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 37 additions & 47 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
backend: ["h1_client,native-tls", hyper_client, curl_client]
backend:
[
"h1-client,h1-rustls",
"hyper0_14-client,hyper0_14-rustls",
isahc0_9-client,
]

steps:
- uses: actions/checkout@master
- uses: actions/checkout@master

- name: check
run: cargo check --all-targets --workspace --no-default-features --features '${{ matrix.backend }}'
- name: check
run: cargo check --all-targets --workspace --no-default-features --features '${{ matrix.backend }}'

- name: tests
run: cargo test --all-targets --workspace --no-default-features --features '${{ matrix.backend }}'
- name: tests
run: cargo test --all-targets --workspace --no-default-features --features '${{ matrix.backend }}'

check_no_features:
name: Checking without default features
Expand All @@ -38,56 +43,41 @@ jobs:
name: Running clippy & fmt & docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@master

- name: Install nightly toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
components: clippy, rustfmt
- name: Install nightly toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
components: clippy, rustfmt

- name: clippy
run: cargo clippy --all-targets --workspace --features=docs
- name: clippy
run: cargo clippy --all-targets --workspace --features=docs

- name: fmt
run: cargo fmt --all -- --check
- name: fmt
run: cargo fmt --all -- --check

- name: docs
run: cargo doc --no-deps --features=docs
- name: docs
run: cargo doc --no-deps --features=docs

check_wasm:
name: Check wasm targets
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@master

- name: Install nightly with wasm32-unknown-unknown
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
target: wasm32-unknown-unknown
override: true

- name: check
uses: actions-rs/cargo@v1
with:
command: check
args: --target wasm32-unknown-unknown --no-default-features --features "native_client,wasm_client"

check_features:
name: Check feature combinations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@master

- name: Install cargo-hack
run: cargo install cargo-hack
- name: Install nightly with wasm32-unknown-unknown
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
target: wasm32-unknown-unknown
override: true

- name: Check all feature combinations works properly
# * `--feature-powerset` - run for the feature powerset of the package
# * `--no-dev-deps` - build without dev-dependencies to avoid https://github.com/rust-lang/cargo/issues/4866
# * `--skip docs` - skip `docs` feature
run: cargo hack check --feature-powerset --no-dev-deps --skip docs
- name: check
uses: actions-rs/cargo@v1
with:
command: check
args: --target wasm32-unknown-unknown --no-default-features --features wasm-client
90 changes: 51 additions & 39 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "http-client"
version = "6.5.3"
version = "7.0.0-alpha.1"
license = "MIT OR Apache-2.0"
repository = "https://github.com/http-rs/http-client"
documentation = "https://docs.rs/http-client"
Expand All @@ -20,55 +20,66 @@ features = ["docs"]
rustdoc-args = ["--cfg", "feature=\"docs\""]

[features]
default = ["h1_client", "native-tls"]
docs = ["h1_client", "curl_client", "wasm_client", "hyper_client"]
docs = ["h1-client", "isahc0_9-client", "wasm-client", "hyper0_14-client", "h1-rustls", "h1-native-tls"]

h1_client = ["async-h1", "async-std", "dashmap", "deadpool", "futures"]
native_client = ["curl_client", "wasm_client"]
curl_client = ["isahc", "async-std"]
wasm_client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "futures", "async-std"]
hyper_client = ["hyper", "hyper-tls", "http-types/hyperium_http", "futures-util", "tokio"]
h1-client = ["async-h1", "async-std", "dashmap", "deadpool", "futures"]
native-client = ["isahc0_9-client", "wasm-client"]
isahc0_9-client = ["isahc", "async-std"]
wasm-client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "futures", "async-std", "send_wrapper"]
hyper0_14-client = ["hyper0_14", "http-types/hyperium_http", "futures-util", "tokio1"]

native-tls = ["async-native-tls"]
rustls = ["async-tls", "rustls_crate"]
h1-rustls = ["async-rustls", "rustls_crate", "webpki-roots"]
h1-native-tls = ["async-native-tls"]

unstable-config = [] # deprecated
hyper0_14-rustls = ["hyper0_14-rustls-lib", "rustls_crate"]
hyper0_14-native-tls = ["hyper0_14-tls-lib"]

[dependencies]
async-trait = "0.1.37"
http-types = "2.3.0"
log = "0.4.7"
cfg-if = "1.0.0"

# h1_client
async-h1 = { version = "2.0.0", optional = true }
async-std = { version = "1.6.0", default-features = false, optional = true }
async-native-tls = { version = "0.3.1", optional = true }
async-trait = "0.1"
http-types = "2.3"
log = "0.4"
cfg-if = "1.0"

# h1-client
async-h1 = { version = "2.0", optional = true }
async-std = { version = "1.6", default-features = false, optional = true }
dashmap = { version = "5.3.4", optional = true }
deadpool = { version = "0.7.0", optional = true }
futures = { version = "0.3.8", optional = true }
deadpool = { version = "0.7", optional = true }
futures = { version = "0.3", optional = true }

# h1-client + h1-rustls
# async-tls = { version = "0.11", optional = true }
async-rustls = { version = "0.3", optional = true }
webpki-roots = { version = "0.22", optional = true }

# h1-client + h1-native-tls
async-native-tls = { version = "0.4", optional = true }

# hyper0_14-client
hyper0_14 = { package = "hyper", version = "0.14", features = ["client", "http1", "tcp", "stream"], optional = true }
futures-util = { version = "0.3", features = ["io"], optional = true }
tokio1 = { package = "tokio", version = "1", features = ["time"], optional = true }

# hyper0_14-client + hyper0_14-rustls
hyper0_14-rustls-lib = { package = "hyper-rustls", version = "0.23", optional = true }

# h1_client_rustls
async-tls = { version = "0.11", optional = true }
rustls_crate = { version = "0.19", optional = true, package = "rustls" }
# hyper0_14-client + hyper0_14-native-tls
hyper0_14-tls-lib = { package = "hyper-tls", version = "0.5", optional = true }

# hyper_client
hyper = { version = "0.13.6", features = ["tcp"], optional = true }
hyper-tls = { version = "0.4.3", optional = true }
futures-util = { version = "0.3.5", features = ["io"], optional = true }
tokio = { version = "0.2", features = ["time"], optional = true }
# h1-rustls or hyper0_14-rustls
rustls_crate = { package = "rustls", version = "0.20", optional = true }

# curl_client
# isahc0_9-client
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
isahc = { version = "0.9", optional = true, default-features = false, features = ["http2"] }

# wasm_client
# wasm-client
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = { version = "0.3.25", optional = true }
wasm-bindgen = { version = "0.2.48", optional = true }
wasm-bindgen-futures = { version = "0.4.5", optional = true }
futures = { version = "0.3.1", optional = true }
send_wrapper = { version = "0.6.0", features = ["futures"] }
send_wrapper = { version = "0.6.0", features = ["futures"], optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.25"
Expand All @@ -90,14 +101,15 @@ features = [
]

[dev-dependencies]
async-std = { version = "1.6.0", features = ["unstable", "attributes"] }
portpicker = "0.1.0"
tide = { version = "0.15.0", default-features = false, features = ["h1-server"] }
tide-rustls = { version = "0.1.4" }
tokio = { version = "0.2.21", features = ["macros"] }
async-std = { version = "1.6", features = ["unstable", "attributes"] }
portpicker = "0.1"
tide = { version = "0.16", default-features = false, features = ["h1-server"] }
tide-rustls = { version = "0.3" }
tokio1 = { package = "tokio", version = "1", features = ["macros", "rt-multi-thread"] }
hyper0_14 = { package = "hyper", version = "0.14", features = ["server"] }
serde = "1.0"
serde_json = "1.0"
mockito = "0.23.3"
mockito = "0.31"

[dev-dependencies.getrandom]
version = "0.2"
Expand Down
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,37 @@
</h3>
</div>

## Installation
## Note on intent

With [cargo add][cargo-add] installed run:
This crate is designed to support developer-facing clients instead of being used directly.

```sh
$ cargo add http-client
```

[cargo-add]: https://github.com/killercup/cargo-edit
If you are looking for a Rust HTTP Client library which can support multiple backend http implementations,
consider using [Surf](https://crates.io/crates/surf), which depends on this library and provides a good developer experience.

## Safety

For non-wasm clients, this crate uses ``#![deny(unsafe_code)]`` to ensure everything is implemented in
100% Safe Rust.


## Feature Flags

This crate does not work without specifying feature flags. No features are set by default.

The following client backends are supported:
- [`async-h1`]() version 1.x, via the `h1-client` feature.
- [`hyper`]() version 0.14.x via the `hyper0_14-client` feature.
- libcurl through [`isahc`]() version 0.9.x via the `isahc0_9-client` feature.
- WASM to JavaScript `fetch` via the `wasm-client` feature.

Additionally TLS support can be enabled by the following options:
- `h1-rustls` uses [`rustls`](https://crates.io/crates/rustls) for the `h1-client`.
- `h1-native-tls` uses OpenSSL for the `h1-client` _(not recommended, no automated testing)_.
- `hyper0_14-rustls` uses [`rustls`](https://crates.io/crates/rustls) for the `hyper0-14-client`.
- `hyper0_14-native-tls` uses OpenSSL for the `hyper0_14-client` _(not recommended, no automated testing)_.
- `isahc0_9-client` (implicit support).
- `wasm-client` (implicit support).

## Contributing

Want to join us? Check out our ["Contributing" guide][contributing] and take a
Expand Down
61 changes: 53 additions & 8 deletions examples/print_client_debug.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,67 @@
#[cfg(any(
feature = "h1-client",
feature = "hyper0_14-client",
feature = "isahc0_9-client",
feature = "wasm-client"
))]
use http_client::HttpClient;
#[cfg(any(
feature = "h1-client",
feature = "hyper0_14-client",
feature = "isahc0_9-client",
feature = "wasm-client"
))]
use http_types::{Method, Request};

#[cfg(any(feature = "h1_client", feature = "docs"))]
#[cfg(feature = "hyper0_14-client")]
#[allow(unused_imports)]
use tokio1 as tokio;

#[cfg(any(feature = "h1-client", feature = "docs"))]
use http_client::h1::H1Client as Client;
#[cfg(all(feature = "hyper_client", not(feature = "docs")))]
#[cfg(all(feature = "hyper0_14-client", not(feature = "docs")))]
use http_client::hyper::HyperClient as Client;
#[cfg(all(feature = "curl_client", not(feature = "docs")))]
#[cfg(all(feature = "isahc0_9-client", not(feature = "docs")))]
use http_client::isahc::IsahcClient as Client;
#[cfg(all(feature = "wasm_client", not(feature = "docs")))]
#[cfg(all(feature = "wasm-client", not(feature = "docs")))]
use http_client::wasm::WasmClient as Client;

#[async_std::main]
#[cfg(any(
feature = "h1-client",
feature = "hyper0_14-client",
feature = "isahc0_9-client",
feature = "wasm-client"
))]
#[cfg_attr(
any(
feature = "h1-client",
feature = "isahc0_9-client",
feature = "wasm-client"
),
async_std::main
)]
#[cfg_attr(all(feature = "hyper0_14-client", not(feature = "docs")), tokio::main)]
async fn main() {
let client = Client::new();

let req = Request::new(Method::Get, "http://example.org");
let mut args = std::env::args();
args.next(); // ignore binary name
let arg = args.next();
println!("{arg:?}");
let req = Request::new(Method::Get, arg.as_deref().unwrap_or("http://example.org"));

let response = client.send(req).await.unwrap();
dbg!(response);

client.send(req).await.unwrap();
dbg!(&client);
}

dbg!(client);
#[cfg(not(any(
feature = "h1-client",
feature = "hyper0_14-client",
feature = "isahc0_9-client",
feature = "wasm-client"
)))]
fn main() {
eprintln!("ERROR: A client backend must be select via `--features`: h1-client, hyper0_14-client, isahc0_9-client, wasm-client")
}
Loading