summaryrefslogtreecommitdiffstats
path: root/toolkit/components/glean/src/init/viaduct_uploader.rs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/glean/src/init/viaduct_uploader.rs')
-rw-r--r--toolkit/components/glean/src/init/viaduct_uploader.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/toolkit/components/glean/src/init/viaduct_uploader.rs b/toolkit/components/glean/src/init/viaduct_uploader.rs
new file mode 100644
index 0000000000..d9ce4e0488
--- /dev/null
+++ b/toolkit/components/glean/src/init/viaduct_uploader.rs
@@ -0,0 +1,73 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+use glean::net::{PingUploader, UploadResult};
+use url::Url;
+use viaduct::{Error::*, Request};
+
+extern "C" {
+ fn FOG_TooLateToSend() -> bool;
+}
+
+/// An uploader that uses [Viaduct](https://github.com/mozilla/application-services/tree/main/components/viaduct).
+#[derive(Debug)]
+pub(crate) struct ViaductUploader;
+
+impl PingUploader for ViaductUploader {
+ /// Uploads a ping to a server.
+ ///
+ /// # Arguments
+ ///
+ /// * `url` - the URL path to upload the data to.
+ /// * `body` - the serialized text data to send.
+ /// * `headers` - a vector of tuples containing the headers to send with
+ /// the request, i.e. (Name, Value).
+ fn upload(&self, url: String, body: Vec<u8>, headers: Vec<(String, String)>) -> UploadResult {
+ log::trace!("FOG Ping Uploader uploading to {}", url);
+ let url_clone = url.clone();
+ let result: std::result::Result<UploadResult, viaduct::Error> = (move || {
+ // SAFETY NOTE: Safe because it returns a primitive by value.
+ if unsafe { FOG_TooLateToSend() } {
+ log::trace!("Attempted to send ping too late into shutdown.");
+ return Ok(UploadResult::done());
+ }
+ let debug_tagged = headers.iter().any(|(name, _)| name == "X-Debug-ID");
+ let localhost_port = static_prefs::pref!("telemetry.fog.test.localhost_port");
+ if localhost_port < 0
+ || (localhost_port == 0 && !debug_tagged && cfg!(feature = "disable_upload"))
+ {
+ log::info!("FOG Ping uploader faking success");
+ return Ok(UploadResult::http_status(200));
+ }
+ let parsed_url = Url::parse(&url_clone)?;
+
+ log::info!("FOG Ping uploader uploading to {:?}", parsed_url);
+
+ let mut req = Request::post(parsed_url.clone()).body(body.clone());
+ for (header_key, header_value) in &headers {
+ req = req.header(header_key.to_owned(), header_value)?;
+ }
+
+ log::trace!("FOG Ping Uploader sending ping to {}", parsed_url);
+ let res = req.send()?;
+ Ok(UploadResult::http_status(res.status as i32))
+ })();
+ log::trace!(
+ "FOG Ping Uploader completed uploading to {} (Result {:?})",
+ url,
+ result
+ );
+ match result {
+ Ok(result) => result,
+ Err(NonTlsUrl | UrlError(_)) => UploadResult::unrecoverable_failure(),
+ Err(
+ RequestHeaderError(_)
+ | BackendError(_)
+ | NetworkError(_)
+ | BackendNotInitialized
+ | SetBackendError,
+ ) => UploadResult::recoverable_failure(),
+ }
+ }
+}