diff --git a/Cargo.toml b/Cargo.toml index 4f96e962..314c5ecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ async-trait = "0.1" connection-string = "0.2" num-traits = "0.2" uuid = "1.0" +cfg-if = "1.0" [target.'cfg(windows)'.dependencies] winauth = { version = "0.0.4", optional = true } diff --git a/README.md b/README.md index 44398dc5..f3a63b4d 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,15 @@ A native Microsoft SQL Server (TDS) client for Rust. | `sql-browser-smol` | SQL Browser implementation for the `TcpStream` of smol. | `disabled` | | `integrated-auth-gssapi` | Support for using Integrated Auth via GSSAPI | `disabled` | +#### TLS feature flags + +There are three TLS feature flags: `native-tls` which uses system libraries; `rustls` which is a pure rust solution; and `vendored-openssl` which uses a prepackaged binary. By default this library will use `native-tls`. Because of the way default features +currently work with cargo, if you select another TLS implementation, you will get that implementation *and* the `native-tls` implementation. + +To avoid duplication of implementations, this library will use any specified TLS feature in preference of `native-tls`. This means that by default the library will use `native-tls`, but in the case of either `rustls` or `vendored-openssl` being supplied, those choices will take preference. + +If you experience issues with TLS handshake, simply add `tiberius = {version = "*", features = ["rustls"]}` to your cargo file. + ### Supported protocols Tiberius does not rely on any protocol when connecting to an SQL Server instance. Instead the `Client` takes a socket that implements the `AsyncRead` and `AsyncWrite` traits from the [futures-rs](https://crates.io/crates/futures) crate. diff --git a/src/client/tls_stream.rs b/src/client/tls_stream.rs index 9eba1060..f534f80c 100644 --- a/src/client/tls_stream.rs +++ b/src/client/tls_stream.rs @@ -1,44 +1,39 @@ use crate::Config; use futures_util::io::{AsyncRead, AsyncWrite}; -#[cfg(feature = "native-tls")] -mod native_tls_stream; - -#[cfg(feature = "rustls")] -mod rustls_tls_stream; - -#[cfg(feature = "vendored-openssl")] -mod opentls_tls_stream; - -#[cfg(feature = "native-tls")] -pub(crate) use native_tls_stream::TlsStream; - -#[cfg(feature = "rustls")] -pub(crate) use rustls_tls_stream::TlsStream; - -#[cfg(feature = "vendored-openssl")] -pub(crate) use opentls_tls_stream::TlsStream; - -#[cfg(feature = "rustls")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - TlsStream::new(config, stream).await -} - -#[cfg(feature = "native-tls")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - native_tls_stream::create_tls_stream(config, stream).await -} - -#[cfg(feature = "vendored-openssl")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - opentls_tls_stream::create_tls_stream(config, stream).await +cfg_if::cfg_if! { + if #[cfg(feature = "rustls")] { + mod rustls_tls_stream; + + pub(crate) use rustls_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + TlsStream::new(config, stream).await + } + } else if #[cfg(feature = "vendored-openssl")] { + mod opentls_tls_stream; + + pub(crate) use opentls_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + opentls_tls_stream::create_tls_stream(config, stream).await + } + } else if #[cfg(feature = "native-tls")] { + mod native_tls_stream; + + pub(crate) use native_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + native_tls_stream::create_tls_stream(config, stream).await + } + } } diff --git a/src/tds/time/chrono.rs b/src/tds/time/chrono.rs index 4bdb59a5..b448f8d4 100644 --- a/src/tds/time/chrono.rs +++ b/src/tds/time/chrono.rs @@ -81,7 +81,7 @@ from_sql!( let offset = chrono::Duration::minutes(dto.offset as i64); let naive = NaiveDateTime::new(date, time).sub(offset); - chrono::DateTime::from_utc(naive, Utc) + chrono::DateTime::from_naive_utc_and_offset(naive, Utc) }); chrono::DateTime: ColumnData::DateTimeOffset(ref dto) => dto.map(|dto| { let date = from_days(dto.datetime2.date.days() as i64, 1); @@ -91,7 +91,7 @@ from_sql!( let offset = FixedOffset::east_opt((dto.offset as i32) * 60).unwrap(); let naive = NaiveDateTime::new(date, time); - chrono::DateTime::from_utc(naive, offset) + chrono::DateTime::from_naive_utc_and_offset(naive, offset) }) ); diff --git a/tests/query.rs b/tests/query.rs index 527ab025..f2177ea2 100644 --- a/tests/query.rs +++ b/tests/query.rs @@ -2237,7 +2237,7 @@ where .unwrap() .and_hms_opt(16, 20, 0) .unwrap(); - let dt: DateTime = DateTime::from_utc(naive, Utc); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, Utc); let row = conn .query("SELECT @P1", &[&dt]) @@ -2276,7 +2276,7 @@ where .unwrap(); let fixed = FixedOffset::east_opt(3600 * 3).unwrap(); - let dt: DateTime = DateTime::from_utc(naive, fixed); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, fixed); let row = conn .query("SELECT @P1", &[&dt]) @@ -2314,7 +2314,7 @@ where .and_hms_opt(16, 20, 0) .unwrap(); let fixed = FixedOffset::east_opt(3600 * 3).unwrap(); - let dt: DateTime = DateTime::from_utc(naive, fixed); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, fixed); let row = conn .query(format!("SELECT CAST('{}' AS datetimeoffset(7))", dt), &[])