Skip to content

Commit 8c701e8

Browse files
authored
feat: add embedded-svc based http transport (#654)
embedded-svc is used on esp32 for doing https
1 parent 0b4b06c commit 8c701e8

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

sentry/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ ureq = ["dep:ureq", "httpdate"]
5050
# transport settings
5151
native-tls = ["dep:native-tls", "reqwest?/default-tls", "ureq?/native-tls"]
5252
rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"]
53+
embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"]
5354

5455
[dependencies]
5556
sentry-core = { version = "0.32.3", path = "../sentry-core", features = [
@@ -82,6 +83,9 @@ rustls = { version = "0.21.2", optional = true, features = [
8283
"dangerous_configuration",
8384
] }
8485
webpki-roots = { version = "0.25.1", optional = true }
86+
embedded-svc = { version = "0.27.1", optional = true }
87+
[target.'cfg(target_os = "espidf")'.dependencies]
88+
esp-idf-svc = { version = "0.48.1", optional = true }
8589

8690
[dev-dependencies]
8791
sentry-anyhow = { path = "../sentry-anyhow" }
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use crate::{sentry_debug, ClientOptions, Transport};
2+
use embedded_svc::http::client::Client as HttpClient;
3+
use esp_idf_svc::{http::client::EspHttpConnection, io::Write};
4+
5+
/// Transport using the embedded-svc http client
6+
pub struct EmbeddedSVCHttpTransport {
7+
options: ClientOptions,
8+
}
9+
10+
impl EmbeddedSVCHttpTransport {
11+
/// Creates a new transport
12+
pub fn new(options: &ClientOptions) -> Self {
13+
Self {
14+
options: options.clone(),
15+
}
16+
}
17+
}
18+
19+
impl EmbeddedSVCHttpTransport {
20+
fn send_envelope(
21+
&self,
22+
envelope: sentry_core::Envelope,
23+
) -> Result<(), Box<dyn std::error::Error>> {
24+
let dsn = self
25+
.options
26+
.dsn
27+
.as_ref()
28+
.ok_or_else(|| "No DSN specified")?;
29+
let user_agent = &self.options.user_agent;
30+
let auth = dsn.to_auth(Some(user_agent)).to_string();
31+
let headers = [("X-Sentry-Auth", auth.as_str())];
32+
let url = dsn.envelope_api_url();
33+
34+
let mut body = Vec::new();
35+
envelope.to_writer(&mut body)?;
36+
37+
let config = esp_idf_svc::http::client::Configuration {
38+
use_global_ca_store: true,
39+
crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach),
40+
..Default::default()
41+
};
42+
43+
let mut client = HttpClient::wrap(EspHttpConnection::new(&config)?);
44+
45+
let mut request = client.post(url.as_str(), &headers)?;
46+
request.write_all(&body)?;
47+
request.flush()?;
48+
let mut response = request.submit()?;
49+
50+
// read the whole response
51+
let mut buf = [0u8; 1024];
52+
while response.read(&mut buf)? > 0 {}
53+
54+
Ok(())
55+
}
56+
}
57+
58+
impl Transport for EmbeddedSVCHttpTransport {
59+
fn send_envelope(&self, envelope: sentry_core::Envelope) {
60+
if let Err(err) = self.send_envelope(envelope) {
61+
sentry_debug!("Failed to send envelope: {}", err);
62+
}
63+
}
64+
}

sentry/src/transports/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ mod reqwest;
1818
#[cfg(feature = "reqwest")]
1919
pub use self::reqwest::ReqwestHttpTransport;
2020

21+
#[cfg(all(target_os = "espidf", feature = "embedded-svc-http"))]
22+
mod embedded_svc_http;
23+
#[cfg(all(target_os = "espidf", feature = "embedded-svc-http"))]
24+
pub use self::embedded_svc_http::EmbeddedSVCHttpTransport;
25+
2126
#[cfg(feature = "curl")]
2227
mod curl;
2328
#[cfg(feature = "curl")]
@@ -38,6 +43,7 @@ type DefaultTransport = ReqwestHttpTransport;
3843

3944
#[cfg(all(
4045
feature = "curl",
46+
not(all(target_os = "espidf", feature = "embedded-svc-http")),
4147
not(feature = "reqwest"),
4248
not(feature = "surf"),
4349
not(feature = "ureq")
@@ -46,6 +52,7 @@ type DefaultTransport = CurlHttpTransport;
4652

4753
#[cfg(all(
4854
feature = "surf",
55+
not(all(target_os = "espidf", feature = "embedded-svc-http")),
4956
not(feature = "reqwest"),
5057
not(feature = "curl"),
5158
not(feature = "ureq")
@@ -54,14 +61,26 @@ type DefaultTransport = SurfHttpTransport;
5461

5562
#[cfg(all(
5663
feature = "ureq",
64+
not(all(target_os = "espidf", feature = "embedded-svc-http")),
5765
not(feature = "reqwest"),
5866
not(feature = "curl"),
5967
not(feature = "surf")
6068
))]
6169
type DefaultTransport = UreqHttpTransport;
6270

71+
#[cfg(all(
72+
target_os = "espidf",
73+
feature = "embedded-svc-http",
74+
not(feature = "reqwest"),
75+
not(feature = "curl"),
76+
not(feature = "surf"),
77+
not(feature = "ureq")
78+
))]
79+
type DefaultTransport = EmbeddedSVCHttpTransport;
80+
6381
/// The default http transport.
6482
#[cfg(any(
83+
all(target_os = "espidf", feature = "embedded-svc-http"),
6584
feature = "reqwest",
6685
feature = "curl",
6786
feature = "surf",
@@ -80,6 +99,7 @@ pub struct DefaultTransportFactory;
8099
impl TransportFactory for DefaultTransportFactory {
81100
fn create_transport(&self, options: &ClientOptions) -> Arc<dyn Transport> {
82101
#[cfg(any(
102+
all(target_os = "espidf", feature = "embedded-svc-http"),
83103
feature = "reqwest",
84104
feature = "curl",
85105
feature = "surf",
@@ -89,6 +109,7 @@ impl TransportFactory for DefaultTransportFactory {
89109
Arc::new(HttpTransport::new(options))
90110
}
91111
#[cfg(not(any(
112+
all(target_os = "espidf", feature = "embedded-svc-http"),
92113
feature = "reqwest",
93114
feature = "curl",
94115
feature = "surf",

0 commit comments

Comments
 (0)