diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 7309ea92..7d3e41b0 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -12,7 +12,7 @@ Sentry integration for tower-based crates. edition = "2018" [features] -http = ["http_", "pin-project"] +http = ["http_", "pin-project", "url"] [dependencies] tower-layer = "0.3" @@ -20,6 +20,7 @@ tower-service = "0.3" http_ = { package = "http", version = "0.2.6", optional = true } pin-project = { version = "1.0.10", optional = true } sentry-core = { version = "0.25.0", path = "../sentry-core", default-features = false, features = ["client"] } +url = { version = "2.2.2", optional = true } [dev-dependencies] anyhow = "1" diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 3fd98388..43a659bf 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -1,8 +1,9 @@ +use std::convert::TryInto; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; -use http_::{Request, Response, StatusCode}; +use http_::{header, uri, Request, Response, StatusCode}; use sentry_core::protocol; use tower_layer::Layer; use tower_service::Service; @@ -136,7 +137,7 @@ where fn call(&mut self, request: Request) -> Self::Future { let sentry_req = sentry_core::protocol::Request { method: Some(request.method().to_string()), - url: request.uri().to_string().parse().ok(), + url: get_url_from_request(&request), headers: request .headers() .into_iter() @@ -186,3 +187,15 @@ fn map_status(status: StatusCode) -> protocol::SpanStatus { _ => protocol::SpanStatus::UnknownError, } } + +fn get_url_from_request(request: &Request) -> Option { + let uri = request.uri().clone(); + let mut uri_parts = uri.into_parts(); + uri_parts.scheme.get_or_insert(uri::Scheme::HTTP); + if uri_parts.authority.is_none() { + let host = request.headers().get(header::HOST)?.as_bytes(); + uri_parts.authority = Some(host.try_into().ok()?); + } + let uri = uri::Uri::from_parts(uri_parts).ok()?; + uri.to_string().parse().ok() +}