From d7dc9d82f0f906ca6fa14d465be15c3ffb2c4d66 Mon Sep 17 00:00:00 2001 From: Kristof Mattei <864376+Kristof-Mattei@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:06:05 -0700 Subject: [PATCH 1/3] feat: allow for https webhooks --- Cargo.lock | 310 +++++++++++++++++++++++++++++++++---------- Cargo.toml | 13 +- src/docker.rs | 41 ++++-- src/docker_config.rs | 18 ++- src/http_client.rs | 78 +++++------ src/webhook.rs | 42 +++--- 6 files changed, 349 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85db5e75..9bd2c560 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,20 +26,17 @@ dependencies = [ "memchr", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "autoheal-rs" version = "0.0.0-development" dependencies = [ "color-eyre", "hex", + "http", "http-body-util", "hyper", + "hyper-tls", + "hyper-unix-socket", "hyper-util", "libc", "percent-encoding", @@ -66,6 +63,18 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bytes" version = "1.5.0" @@ -114,6 +123,22 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "deranged" version = "0.3.9" @@ -123,6 +148,16 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "eyre" version = "0.6.8" @@ -133,12 +168,33 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -163,12 +219,6 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" -[[package]] -name = "futures-sink" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" - [[package]] name = "futures-task" version = "0.3.29" @@ -193,31 +243,6 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "h2" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hermit-abi" version = "0.3.3" @@ -285,9 +310,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", "http", "http-body", + "http-body-util", "httparse", "httpdate", "itoa", @@ -297,10 +322,38 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "git+https://github.com/kristof-mattei/hyper-tls?rev=d6026c4d23a86dc545071c64a052613d2e412b49#d6026c4d23a86dc545071c64a052613d2e412b49" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-unix-socket" +version = "0.0.0-development" +source = "git+https://github.com/kristof-mattei/hyper-unix-socket?rev=01572fe3103857baafb0d31161ab85592810602e#01572fe3103857baafb0d31161ab85592810602e" +dependencies = [ + "bytes", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.0.0" -source = "git+https://github.com/hyperium/hyper-util?rev=1ed4c2ccdb23f576eb7024555f08b376b9d5c9eb#1ed4c2ccdb23f576eb7024555f08b376b9d5c9eb" +source = "git+https://github.com/hyperium/hyper-util?rev=ced9f812460420017705fa7cae4dca7be9e23f4a#ced9f812460420017705fa7cae4dca7be9e23f4a" dependencies = [ "bytes", "futures-channel", @@ -333,16 +386,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "1.0.9" @@ -361,6 +404,12 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "log" version = "0.4.20" @@ -402,6 +451,24 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -437,6 +504,50 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dfc0783362704e97ef3bd24261995a699468440099ef95d869b4d9732f829a" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f55da20b29f956fb01f0add8683eb26ee13ebe3ebd935e49898717c6b4b2830" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -487,6 +598,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "powerfmt" version = "0.2.0" @@ -511,6 +628,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.10.2" @@ -561,12 +687,57 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.190" @@ -616,15 +787,6 @@ dependencies = [ "libc", ] -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - [[package]] name = "smallvec" version = "1.11.1" @@ -652,6 +814,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -713,7 +888,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", - "bytes", "libc", "mio", "num_cpus", @@ -736,17 +910,13 @@ dependencies = [ ] [[package]] -name = "tokio-util" -version = "0.7.10" +name = "tokio-native-tls" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", + "native-tls", "tokio", - "tracing", ] [[package]] @@ -894,6 +1064,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index fbb325ff..5ba046ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,16 @@ tracing-subscriber = { version = "0.3.17", features = [ "tracing-log", ] } http-body-util = "0.1.0-rc.3" -hyper = { version = "1.0.0-rc.4", features = ["full"] } +hyper = { version = "1.0.0-rc.4", default-features = false } + +hyper-util = { git = "https://github.com/hyperium/hyper-util", default-features = false, features = [ + "client", + "http1", +], rev = "ced9f812460420017705fa7cae4dca7be9e23f4a" } + +hyper-tls = { git = "https://github.com/kristof-mattei/hyper-tls", rev = "d6026c4d23a86dc545071c64a052613d2e412b49" } +hyper-unix-socket = { git = "https://github.com/kristof-mattei/hyper-unix-socket", rev = "01572fe3103857baafb0d31161ab85592810602e" } + libc = "0.2.149" percent-encoding = "2.3.0" serde = { version = "1.0.190", features = ["derive"] } @@ -38,8 +47,8 @@ tokio = { version = "1.33.0", features = [ "signal", "net", ] } +http = "0.2.9" url = { version = "2.4.1", features = ["expose_internals"] } -hyper-util = { git = "https://github.com/hyperium/hyper-util", default-features = false, rev = "1ed4c2ccdb23f576eb7024555f08b376b9d5c9eb" } # We compile the Docker container with musl to get a static library. Smaller, faster. # BUT that means that we need to include openssl diff --git a/src/docker.rs b/src/docker.rs index bda96dec..3a77087a 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,14 +1,17 @@ +use std::time::Duration; + use color_eyre::eyre::bail; use http_body_util::BodyExt; use hyper::body::{Buf, Incoming}; use hyper::{Method, Response, StatusCode}; -use hyper_util::rt::TokioIo; -use tokio::net::UnixStream; +use hyper_tls::HttpsConnector; +use hyper_unix_socket::UnixSocketConnector; +use tokio::time::timeout; use crate::app_config::AppConfig; use crate::container::Container; use crate::docker_config::{DockerConfig, Endpoint}; -use crate::http_client::{build_request, build_uri, connect_tcp_stream, send_get_post}; +use crate::http_client::{build_request, execute_request}; use crate::webhook::{notify_webhook_failure, notify_webhook_success}; pub struct Docker { @@ -65,17 +68,29 @@ impl Docker { method: Method, ) -> Result, color_eyre::Report> { match &self.config.endpoint { - Endpoint::Direct(url) => { - let stream = connect_tcp_stream(url).await?; - let io = TokioIo::new(stream); - let request = build_request(&build_uri(url.clone(), path_and_query)?, method)?; - send_get_post(io, request).await + Endpoint::Direct { + url, + timeout_milliseconds, + } => { + let connector = HttpsConnector::new(); + let request = build_request(url.clone(), path_and_query, method)?; + + let response = execute_request(connector, request); + + match timeout(Duration::from_millis(*timeout_milliseconds), response).await { + Ok(Ok(o)) => Ok(o), + Ok(Err(e)) => Err(e), + Err(e) => Err(e.into()), + } }, - Endpoint::Socket(socket, url) => { - let stream = UnixStream::connect(&socket).await?; - let io = TokioIo::new(stream); - let request = build_request(&build_uri(url.clone(), path_and_query)?, method)?; - send_get_post(io, request).await + Endpoint::Socket(socket) => { + let connector = UnixSocketConnector::new(socket.clone()); + + let request = build_request("http://localhost".parse()?, path_and_query, method)?; + + execute_request(connector, request) + .await + .map_err(Into::into) }, } } diff --git a/src/docker_config.rs b/src/docker_config.rs index d8dd435a..cb397434 100644 --- a/src/docker_config.rs +++ b/src/docker_config.rs @@ -4,13 +4,15 @@ use crate::env::try_parse_env_variable_with_default; pub struct DockerConfig { pub endpoint: Endpoint, - pub curl_timeout: u32, pub options: Vec, } pub enum Endpoint { - Direct(hyper::Uri), - Socket(String, hyper::Uri), + Direct { + url: http::Uri, + timeout_milliseconds: u64, + }, + Socket(String), } impl DockerConfig { @@ -25,22 +27,24 @@ impl DockerConfig { color_eyre::Report::msg(format!("Could not convert {:?} to String", err)) })?; - let curl_timeout = try_parse_env_variable_with_default("CURL_TIMEOUT", 30)?; + let timeout_milliseconds = try_parse_env_variable_with_default("CURL_TIMEOUT", 30)?; let endpoint = if docker_socket_or_uri.starts_with(TCP_START) { docker_socket_or_uri.replace_range(..TCP_START.len(), "https://"); - Endpoint::Direct(docker_socket_or_uri.parse().unwrap()) + Endpoint::Direct { + url: docker_socket_or_uri.parse().unwrap(), + timeout_milliseconds, + } } else { // we're connecting over a socket, so the uri is localhost - Endpoint::Socket(docker_socket_or_uri, "http://localhost".parse().unwrap()) + Endpoint::Socket(docker_socket_or_uri) }; // TODO check if docker socket exists Ok(DockerConfig { endpoint, - curl_timeout, options: vec![], }) } diff --git a/src/http_client.rs b/src/http_client.rs index a91f1b17..8d591b4b 100644 --- a/src/http_client.rs +++ b/src/http_client.rs @@ -7,23 +7,19 @@ use hyper::body::{Body, Bytes}; use hyper::header::{HeaderName, IntoHeaderName}; use hyper::http::uri::PathAndQuery; use hyper::http::HeaderValue; -use hyper::rt::{Read, Write}; use hyper::{Method, Request, Response, Uri}; -use tokio::net::TcpStream; - -pub async fn connect_tcp_stream(url: &Uri) -> Result { - let host = url.host().expect("url has no host"); - let port = url.port_u16().unwrap_or(80); - let addr = format!("{}:{}", host, port); - TcpStream::connect(addr).await.map_err(Into::into) -} +use hyper_util::client::connect::Connect; +use hyper_util::client::legacy::Client; +use hyper_util::rt::TokioExecutor; pub fn build_request( - uri: &Uri, + base: Uri, + path_and_query: &str, method: Method, ) -> Result>, color_eyre::Report> { build_request_with_headers_and_body::<_, HeaderName>( - uri, + base, + path_and_query, HashMap::default(), method, Empty::::new(), @@ -32,7 +28,8 @@ pub fn build_request( #[allow(unused)] pub fn build_request_with_body( - uri: &Uri, + base: Uri, + path_and_query: &str, method: Method, body: B, ) -> Result, color_eyre::Report> @@ -41,23 +38,37 @@ where B::Data: Send, B::Error: Into>, { - build_request_with_headers_and_body::(uri, HashMap::default(), method, body) + build_request_with_headers_and_body::( + base, + path_and_query, + HashMap::default(), + method, + body, + ) } #[allow(unused)] pub fn build_request_with_headers( - uri: &Uri, + base: Uri, + path_and_query: &str, headers: HashMap, method: Method, ) -> Result>, color_eyre::Report> where K: IntoHeaderName, { - build_request_with_headers_and_body(uri, headers, method, Empty::::new()) + build_request_with_headers_and_body( + base, + path_and_query, + headers, + method, + Empty::::new(), + ) } pub fn build_request_with_headers_and_body( - uri: &Uri, + base: Uri, + path_and_query: &str, headers: HashMap, method: Method, body: B, @@ -68,43 +79,35 @@ where B::Error: Into>, K: IntoHeaderName, { - let host = uri.host().expect("Host not found in uri").to_string(); - - let mut request = Request::builder().uri(uri).body::(body)?; + let full_url = build_uri(base, path_and_query)?; - *request.method_mut() = method; + let mut request = Request::builder() + .uri(full_url) + .method(method) + .body::(body)?; let request_headers = request.headers_mut(); - // default host in case no headers are passed in but allow for overwriting - request_headers.insert(hyper::header::HOST, HeaderValue::from_str(&host)?); - for (k, v) in headers { request_headers.insert(k, v); } - // headers.insert - Ok(request) } -pub async fn send_get_post( - stream: T, + +pub async fn execute_request( + connector: C, request: Request, ) -> Result, color_eyre::Report> where - T: Read + Write + Unpin + Send + 'static, - B: Body + Send + 'static, + C: Connect + Clone + Send + Sync + 'static, + B: Body + Send + 'static + Unpin, B::Data: Send, B::Error: Into>, { - let (mut sender, conn) = hyper::client::conn::http1::handshake(stream).await?; - - tokio::task::spawn(async move { - conn.await - .map_err(|e| Into::::into(e).wrap_err("Connection failed")) - }); + let client = Client::builder(TokioExecutor::new()).build::<_, B>(connector); - let response = sender.send_request(request).await?; + let response = client.request(request).await?; Ok(response) } @@ -112,8 +115,7 @@ where pub fn build_uri(base_url: Uri, path_and_query: &str) -> Result { let mut parts = base_url.into_parts(); - parts.path_and_query = - Some(PathAndQuery::from_str(path_and_query).expect("Invalid path and query")); + parts.path_and_query = Some(PathAndQuery::from_str(path_and_query)?); Uri::from_parts(parts).map_err(Into::into) } diff --git a/src/webhook.rs b/src/webhook.rs index fffaf742..f5fff39e 100644 --- a/src/webhook.rs +++ b/src/webhook.rs @@ -1,15 +1,14 @@ -use std::collections::HashMap; - +use color_eyre::eyre::Context; +use http::Request; use http_body_util::Full; -use http_client::{build_request_with_headers_and_body, send_get_post}; use hyper::body::Bytes; use hyper::http::HeaderValue; use hyper::{Method, Uri}; -use hyper_util::rt::TokioIo; +use hyper_tls::HttpsConnector; use serde_json::json; use crate::app_config::AppConfig; -use crate::http_client; +use crate::http_client::execute_request; pub fn notify_webhook_success( app_config: &AppConfig, @@ -67,33 +66,24 @@ async fn notify_webhook_and_log(webhook_url: &Uri, text: String) { } async fn notify_webhook(webhook_url: &Uri, text: &str) -> Result<(), color_eyre::Report> { + let connector = HttpsConnector::new(); + let payload = json!({ "text": text, }); - let stream = http_client::connect_tcp_stream(webhook_url) - .await - .expect("Couldn't establish connection to webhook_url"); - - let io = TokioIo::new(stream); - - let data = serde_json::to_string(&payload).expect("Failed to serialize payload"); - - // execute webhook requests as background process to prevent healer from blocking - #[allow(clippy::mutable_key_type)] - let headers = HashMap::from_iter([( - hyper::header::CONTENT_TYPE, - HeaderValue::from_static("application/json"), - )]); + let data = serde_json::to_string(&payload).wrap_err_with(|| "Failed to serialize payload")?; - let request = build_request_with_headers_and_body( - webhook_url, - headers, - Method::POST, - Full::new(Bytes::from(data)), - )?; + let request = Request::builder() + .uri(webhook_url) + .method(Method::POST) + .header( + hyper::header::CONTENT_TYPE, + HeaderValue::from_static("application/json"), + ) + .body(Full::new(Bytes::from(data)))?; - send_get_post(io, request).await?; + execute_request(connector, request).await?; Ok(()) } From 586cbd15494baa03098ede86b0f11a4807d6671d Mon Sep 17 00:00:00 2001 From: Kristof Mattei <864376+Kristof-Mattei@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:08:21 -0700 Subject: [PATCH 2/3] fix: use static url --- src/docker.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/docker.rs b/src/docker.rs index 3a77087a..fd5d1421 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,6 +1,7 @@ use std::time::Duration; use color_eyre::eyre::bail; +use http::Uri; use http_body_util::BodyExt; use hyper::body::{Buf, Incoming}; use hyper::{Method, Response, StatusCode}; @@ -86,7 +87,8 @@ impl Docker { Endpoint::Socket(socket) => { let connector = UnixSocketConnector::new(socket.clone()); - let request = build_request("http://localhost".parse()?, path_and_query, method)?; + let request = + build_request(Uri::from_static("http://localhost"), path_and_query, method)?; execute_request(connector, request) .await From 98b80081f1cebb3b94fee5e01dd2197ee0a2519e Mon Sep 17 00:00:00 2001 From: Kristof Mattei <864376+Kristof-Mattei@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:57:51 -0700 Subject: [PATCH 3/3] fix: use native-tls via hyper-tls --- Cargo.lock | 10 ++++++++++ Cargo.toml | 11 +++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bd2c560..5a8c7d85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -536,6 +536,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.1.6+3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.94" @@ -544,6 +553,7 @@ checksum = "2f55da20b29f956fb01f0add8683eb26ee13ebe3ebd935e49898717c6b4b2830" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] diff --git a/Cargo.toml b/Cargo.toml index 5ba046ae..5055272e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,9 @@ hyper-util = { git = "https://github.com/hyperium/hyper-util", default-features "http1", ], rev = "ced9f812460420017705fa7cae4dca7be9e23f4a" } -hyper-tls = { git = "https://github.com/kristof-mattei/hyper-tls", rev = "d6026c4d23a86dc545071c64a052613d2e412b49" } +hyper-tls = { git = "https://github.com/kristof-mattei/hyper-tls", rev = "d6026c4d23a86dc545071c64a052613d2e412b49", features = [ + "vendored", +] } hyper-unix-socket = { git = "https://github.com/kristof-mattei/hyper-unix-socket", rev = "01572fe3103857baafb0d31161ab85592810602e" } libc = "0.2.149" @@ -49,10 +51,3 @@ tokio = { version = "1.33.0", features = [ ] } http = "0.2.9" url = { version = "2.4.1", features = ["expose_internals"] } - -# We compile the Docker container with musl to get a static library. Smaller, faster. -# BUT that means that we need to include openssl -# Documentation on the syntax: -# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies -[target.'cfg(all(target_arch = "x86_64", target_os="linux", target_env="musl"))'.dependencies] -# openssl = { version = "0.10.36", features = ["vendored"] }