Skip to content

Commit e8714ea

Browse files
authored
fix: better HTTPS errors with disabled native-tls or rustls-tls (#229)
1 parent abf7448 commit e8714ea

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,14 @@ jobs:
100100
- run: cargo test --features uuid,time
101101
- run: cargo test --all-features
102102

103-
# Temporary runs tests with `cloud_` prefix only until we validate that the rest of the tests are working
104103
- name: Run tests with ClickHouse Cloud
105104
env:
106105
CLICKHOUSE_TEST_ENVIRONMENT: cloud
107106
CLICKHOUSE_CLOUD_HOST: ${{ secrets.INTEGRATIONS_TEAM_TESTS_CLOUD_HOST_SMT }}
108107
CLICKHOUSE_CLOUD_PASSWORD: ${{ secrets.INTEGRATIONS_TEAM_TESTS_CLOUD_PASSWORD_SMT }}
109108
CLICKHOUSE_CLOUD_JWT_ACCESS_TOKEN: ${{ secrets.INTEGRATIONS_TEAM_TESTS_CLOUD_JWT_DESERT_VM_43 }}
109+
# Temporary runs tests with `cloud_` prefix only until we validate that the rest of the tests are working
110+
# `https_errors` should assert ClickHouse Cloud connection errors without enabled TLS features
110111
run: |
111112
cargo test cloud_ --features rustls-tls -- --nocapture
113+
cargo test https_errors -- --nocapture

src/error.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,20 @@ impl From<hyper::Error> for Error {
5858

5959
impl From<hyper_util::client::legacy::Error> for Error {
6060
fn from(error: hyper_util::client::legacy::Error) -> Self {
61+
#[cfg(not(any(feature = "rustls-tls", feature = "native-tls")))]
62+
if error.is_connect() {
63+
static SCHEME_IS_NOT_HTTP: &str = "invalid URL, scheme is not http";
64+
65+
let src = error.source().unwrap();
66+
// Unfortunately, this seems to be the only way, as `INVALID_NOT_HTTP` is not public.
67+
// See https://github.com/hyperium/hyper-util/blob/v0.1.14/src/client/legacy/connect/http.rs#L491-L495
68+
if src.to_string() == SCHEME_IS_NOT_HTTP {
69+
return Self::Unsupported(format!(
70+
"{SCHEME_IS_NOT_HTTP}; if you are trying to connect via HTTPS, \
71+
consider enabling `native-tls` or `rustls-tls` feature"
72+
));
73+
}
74+
}
6175
Self::Network(Box::new(error))
6276
}
6377
}

tests/it/https_errors.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::{get_cloud_url, require_env_var};
2+
use clickhouse::Client;
3+
4+
#[tokio::test]
5+
async fn test_https_error_on_missing_feature() {
6+
check_cloud_test_env!();
7+
let valid_token = require_env_var("CLICKHOUSE_CLOUD_JWT_ACCESS_TOKEN");
8+
let client = Client::default()
9+
.with_url(get_cloud_url())
10+
.with_access_token(valid_token);
11+
let result = client
12+
.query("SELECT 42")
13+
.fetch_one::<u8>()
14+
.await
15+
.err()
16+
.map(|e| e.to_string())
17+
.expect("expected a TLS Error, got Ok instead");
18+
19+
for fragment in [
20+
"invalid URL, scheme is not http",
21+
"HTTPS",
22+
"`native-tls` or `rustls-tls`",
23+
] {
24+
assert!(
25+
result.contains(fragment),
26+
"TLS error message should contain `{}`",
27+
fragment
28+
);
29+
}
30+
}

tests/it/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ mod compression;
115115
mod cursor_error;
116116
mod cursor_stats;
117117
mod fetch_bytes;
118+
mod https_errors;
118119
mod insert;
119120
mod inserter;
120121
mod int128;

0 commit comments

Comments
 (0)