Skip to content

Commit

Permalink
Split TLS features and add docs. (#363)
Browse files Browse the repository at this point in the history
* Re-work and document features.

* Add build steps to check features.
  • Loading branch information
tomusdrw authored Jun 30, 2020
1 parent 723f5c5 commit 95b5866
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ script:
- cargo check
- cargo build
- cargo test
- cargo check --no-default-features
- cargo check --no-default-features --features http
- cargo check --no-default-features --features http-tls
- cargo check --no-default-features --features ws
- cargo check --no-default-features --features ws-tls

after_success: |
[ $TRAVIS_BRANCH = master ] &&
Expand Down
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "web3"
version = "0.12.0"
version = "0.13.0"
description = "Ethereum JSON-RPC client."
homepage = "https://github.com/tomusdrw/rust-web3"
repository = "https://github.com/tomusdrw/rust-web3"
Expand Down Expand Up @@ -31,14 +31,15 @@ zeroize = "1.1.0"
# Optional deps
## HTTP
base64 = { version = "0.12.0", optional = true }
hyper = { version = "0.13", optional = true }
hyper = { version = "0.13", optional = true, default-features = false, features = ["stream", "tcp"] }
hyper-tls = { version = "0.4", optional = true }
native-tls = { version = "0.2", optional = true }
url = { version = "2.1.0", optional = true }
## WS
async-native-tls = { version = "0.3", optional = true }
async-std = { version = "1.5.0", optional = true }
soketto = { version = "0.4.1", optional = true }
## Shared (WS, HTTP)
native-tls = { version = "0.2", optional = true }
url = { version = "2.1.0", optional = true }

[dev-dependencies]
# For examples
Expand All @@ -48,9 +49,10 @@ tokio = { version = "0.2", features = ["full"] }
async-std = { version = "1.5.0", features = ["attributes"] }

[features]
default = ["http", "ws", "tls"]
default = ["http", "ws", "http-tls", "ws-tls"]
http = ["hyper", "url", "base64"]
tls = ["hyper-tls", "native-tls"]
ws = ["soketto", "async-std", "async-native-tls"]
http-tls = ["hyper-tls", "native-tls", "http"]
ws = ["soketto", "async-std", "url"]
ws-tls = ["async-native-tls", "native-tls", "ws"]

[workspace]
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ The solidity compiler is generating the binary and abi code for the smart contra

For more see [examples folder](./examples).

# Opt-out Features
- `http` - Enables HTTP transport (requires `tokio` runtime, because of `hyper`).
- `http-tls` - Enables TLS support for HTTP transport (implies `http`).
- `ws` - Enables WS transport.
- `ws-tls` - Enables TLS support for WS transport (implies `ws`).

## Futures migration
- [ ] Get rid of parking_lot (replace with async-aware locks if really needed).
- [ ] Consider getting rid of `Unpin` requirements. (#361)
Expand Down
21 changes: 4 additions & 17 deletions src/transports/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,6 @@ impl From<hyper::header::InvalidHeaderValue> for Error {
}
}

impl From<url::ParseError> for Error {
fn from(err: url::ParseError) -> Self {
Error::Transport(format!("{:?}", err))
}
}

#[cfg(feature = "tls")]
impl From<native_tls::Error> for Error {
fn from(err: native_tls::Error) -> Self {
Error::Transport(format!("{:?}", err))
}
}

// The max string length of a request without transfer-encoding: chunked.
const MAX_SINGLE_CHUNK: usize = 256;

Expand All @@ -56,18 +43,18 @@ pub struct Http {
id: Arc<AtomicUsize>,
url: hyper::Uri,
basic_auth: Option<HeaderValue>,
#[cfg(feature = "tls")]
#[cfg(feature = "http-tls")]
client: hyper::Client<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>,
#[cfg(not(feature = "tls"))]
#[cfg(not(feature = "http-tls"))]
client: hyper::Client<hyper::client::HttpConnector>,
}

impl Http {
/// Create new HTTP transport connecting to given URL.
pub fn new(url: &str) -> error::Result<Self> {
#[cfg(feature = "tls")]
#[cfg(feature = "http-tls")]
let client = hyper::Client::builder().build::<_, hyper::Body>(hyper_tls::HttpsConnector::new());
#[cfg(not(feature = "tls"))]
#[cfg(not(feature = "http-tls"))]
let client = hyper::Client::new();

let basic_auth = {
Expand Down
14 changes: 14 additions & 0 deletions src/transports/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ pub use self::http::Http;
pub mod ws;
#[cfg(feature = "ws")]
pub use self::ws::WebSocket;

#[cfg(feature = "url")]
impl From<url::ParseError> for crate::Error {
fn from(err: url::ParseError) -> Self {
crate::Error::Transport(format!("{:?}", err))
}
}

#[cfg(feature = "native-tls")]
impl From<native_tls::Error> for crate::Error {
fn from(err: native_tls::Error) -> Self {
crate::Error::Transport(format!("{:?}", err))
}
}
15 changes: 13 additions & 2 deletions src/transports/ws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use futures::{
};
use futures::{AsyncRead, AsyncWrite};

#[cfg(feature = "ws-tls")]
use async_native_tls::TlsStream;
use async_std::net::TcpStream;
use soketto::connection;
Expand Down Expand Up @@ -45,6 +46,7 @@ enum MaybeTlsStream<S> {
/// Unencrypted socket stream.
Plain(S),
/// Encrypted socket stream.
#[cfg(feature = "ws-tls")]
Tls(TlsStream<S>),
}

Expand All @@ -55,6 +57,7 @@ where
fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize, std::io::Error>> {
match self.get_mut() {
MaybeTlsStream::Plain(ref mut s) => Pin::new(s).poll_read(cx, buf),
#[cfg(feature = "ws-tls")]
MaybeTlsStream::Tls(ref mut s) => Pin::new(s).poll_read(cx, buf),
}
}
Expand All @@ -67,20 +70,23 @@ where
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize, std::io::Error>> {
match self.get_mut() {
MaybeTlsStream::Plain(ref mut s) => Pin::new(s).poll_write(cx, buf),
#[cfg(feature = "ws-tls")]
MaybeTlsStream::Tls(ref mut s) => Pin::new(s).poll_write(cx, buf),
}
}

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), std::io::Error>> {
match self.get_mut() {
MaybeTlsStream::Plain(ref mut s) => Pin::new(s).poll_flush(cx),
#[cfg(feature = "ws-tls")]
MaybeTlsStream::Tls(ref mut s) => Pin::new(s).poll_flush(cx),
}
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), std::io::Error>> {
match self.get_mut() {
MaybeTlsStream::Plain(ref mut s) => Pin::new(s).poll_close(cx),
#[cfg(feature = "ws-tls")]
MaybeTlsStream::Tls(ref mut s) => Pin::new(s).poll_close(cx),
}
}
Expand Down Expand Up @@ -112,8 +118,13 @@ impl WsServerTask {
let stream = TcpStream::connect(addrs).await?;

let socket = if scheme == "wss" {
let stream = async_native_tls::connect(host, stream).await?;
MaybeTlsStream::Tls(stream)
#[cfg(feature = "ws-tls")]
{
let stream = async_native_tls::connect(host, stream).await?;
MaybeTlsStream::Tls(stream)
}
#[cfg(not(feature = "ws-tls"))]
panic!("The library was compiled without TLS support. Enable ws-tls feature.");
} else {
MaybeTlsStream::Plain(stream)
};
Expand Down

0 comments on commit 95b5866

Please sign in to comment.