Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add client hints for requestmeta #1802

Merged
merged 39 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1a398b0
wip
TBS1996 Jan 31, 2023
244196a
wip
TBS1996 Jan 31, 2023
9f4a092
wip
TBS1996 Feb 1, 2023
420d9ca
wip
TBS1996 Feb 1, 2023
6cb6e9c
wip
TBS1996 Feb 1, 2023
e8ccc58
savepoint
TBS1996 Feb 1, 2023
d1cbbb8
wip
TBS1996 Feb 1, 2023
f1b908a
wip
TBS1996 Feb 1, 2023
6a26595
wip
TBS1996 Feb 1, 2023
6b78a21
wip
TBS1996 Feb 1, 2023
4c2640d
wip
TBS1996 Feb 2, 2023
7c18540
wip
TBS1996 Feb 3, 2023
f626c7d
wip
TBS1996 Feb 3, 2023
1eec4c4
wip
TBS1996 Feb 3, 2023
f14d667
wip
TBS1996 Feb 3, 2023
c0f7170
wip
TBS1996 Feb 3, 2023
3272c9e
add test for request_meta serialization
TBS1996 Feb 6, 2023
b909ed4
Merge branch 'master' into feat/reqmetahints
TBS1996 Feb 6, 2023
87b54b5
wip
TBS1996 Feb 6, 2023
03a5619
Merge branch 'feat/reqmetahints' of https://github.com/getsentry/rela…
TBS1996 Feb 6, 2023
cf42d55
wip
TBS1996 Feb 6, 2023
b2e0211
wip
TBS1996 Feb 6, 2023
7255410
Merge branch 'master' into feat/reqmetahints
TBS1996 Feb 7, 2023
1419367
wip
TBS1996 Feb 7, 2023
dd8b949
wip
TBS1996 Feb 7, 2023
7c8f540
:wip
TBS1996 Feb 7, 2023
70e8dc6
wip
TBS1996 Feb 8, 2023
6b6d1f1
wip
TBS1996 Feb 8, 2023
6276a22
wip
TBS1996 Feb 8, 2023
d7667ea
wip
TBS1996 Feb 8, 2023
e5c654f
wip
TBS1996 Feb 8, 2023
4433cf3
wip
TBS1996 Feb 8, 2023
d156217
Merge branch 'master' into feat/reqmetahints
TBS1996 Feb 8, 2023
97fe2df
Update CHANGELOG.md
TBS1996 Feb 8, 2023
a0401e7
wip
TBS1996 Feb 8, 2023
6f5a012
Merge branch 'feat/reqmetahints' of https://github.com/getsentry/rela…
TBS1996 Feb 8, 2023
2cb0dd3
wip
TBS1996 Feb 9, 2023
8bab11d
wip
TBS1996 Feb 9, 2023
b075668
wip
TBS1996 Feb 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**Features**:

- Add support for client hints. ([#1752](https://github.com/getsentry/relay/pull/1752), [#1802](https://github.com/getsentry/relay/pull/1802))
- Use client hint headers instead of User-Agent when available. ([#1752](https://github.com/getsentry/relay/pull/1752), [#1802](https://github.com/getsentry/relay/pull/1802))
- Apply all configured data scrubbing rules on Replays. ([#1731](https://github.com/getsentry/relay/pull/1731))
- Add count transactions toward root project. ([#1734](https://github.com/getsentry/relay/pull/1734))
- Add or remove the profile ID on the transaction's profiling context. ([#1801](https://github.com/getsentry/relay/pull/1801))
Expand Down
12 changes: 7 additions & 5 deletions relay-general/src/protocol/replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,16 @@ impl Replay {
None => return,
};

let mut user_agent_info = RawUserAgentInfo::from_headers(headers);
let user_agent_info = RawUserAgentInfo::from_headers(headers);

if user_agent_info.is_empty() {
user_agent_info = default_user_agent.clone();
}
let user_agent_info = if user_agent_info.is_empty() {
default_user_agent
} else {
&user_agent_info
};

let contexts = self.contexts.get_or_insert_with(|| Contexts::new());
user_agent::normalize_user_agent_info_generic(contexts, &self.platform, &user_agent_info);
user_agent::normalize_user_agent_info_generic(contexts, &self.platform, user_agent_info);
}

fn normalize_platform(&mut self) {
Expand Down
91 changes: 60 additions & 31 deletions relay-general/src/store/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ use super::{schema, transactions, BreakdownsConfig, TransactionNameRule};
use crate::processor::{MaxChars, ProcessValue, ProcessingState, Processor};
use crate::protocol::{
self, AsPair, Breadcrumb, ClientSdkInfo, Context, Contexts, DebugImage, Event, EventId,
EventType, Exception, Frame, HeaderName, HeaderValue, Headers, IpAddr, Level, LogEntry,
Measurement, Measurements, Request, SpanStatus, Stacktrace, Tags, TraceContext, User,
VALID_PLATFORMS,
EventType, Exception, Frame, Headers, IpAddr, Level, LogEntry, Measurement, Measurements,
Request, SpanStatus, Stacktrace, Tags, TraceContext, User, VALID_PLATFORMS,
};
use crate::store::{ClockDriftProcessor, GeoIpLookup, StoreConfig};
use crate::types::{
Annotated, Empty, Error, ErrorKind, FromValue, Meta, Object, ProcessingAction,
ProcessingResult, Value,
};
use crate::user_agent::{ClientHints, RawUserAgentInfo};
use crate::user_agent::RawUserAgentInfo;

pub mod breakdowns;
mod contexts;
Expand Down Expand Up @@ -584,38 +583,15 @@ fn normalize_security_report(
}

if !user_agent.is_empty() {
let request = event
let headers = event
.request
.value_mut()
.get_or_insert_with(Request::default);

let headers = request
.get_or_insert_with(Request::default)
.headers
.value_mut()
.get_or_insert_with(Headers::default);

let mut insert_header = |key: &str, val: Option<&str>| {
if let Some(val) = val {
if !headers.contains(key) {
headers.insert(HeaderName::new(key), Annotated::new(HeaderValue::new(val)));
}
}
};

insert_header(RawUserAgentInfo::USER_AGENT, user_agent.user_agent);
insert_header(
ClientHints::SEC_CH_UA_PLATFORM,
user_agent.client_hints.sec_ch_ua_platform,
);
insert_header(
ClientHints::SEC_CH_UA_PLATFORM_VERSION,
user_agent.client_hints.sec_ch_ua_platform_version,
);
insert_header(ClientHints::SEC_CH_UA, user_agent.client_hints.sec_ch_ua);
insert_header(
ClientHints::SEC_CH_UA_MODEL,
user_agent.client_hints.sec_ch_ua_model,
);
user_agent.populate_event_headers(headers);
}
}

Expand Down Expand Up @@ -1019,11 +995,12 @@ mod tests {

use crate::processor::process_value;
use crate::protocol::{
ContextInner, DebugMeta, Frame, Geo, LenientString, LogEntry, PairList, RawStacktrace,
ContextInner, Csp, DebugMeta, Frame, Geo, LenientString, LogEntry, PairList, RawStacktrace,
Span, SpanId, TagEntry, TraceId, Values,
};
use crate::testutils::{get_path, get_value};
use crate::types::{FromValue, SerializableAnnotated};
use crate::user_agent::ClientHints;

use super::*;

Expand Down Expand Up @@ -2453,4 +2430,56 @@ mod tests {
)
"###);
}

#[test]
fn test_normalize_security_report() {
let mut event = Event {
csp: Annotated::from(Csp::default()),
..Default::default()
};
let ipaddr = IpAddr("213.164.1.114".to_string());

let client_ip = Some(&ipaddr);
let user_agent = RawUserAgentInfo::new_test_dummy();

normalize_security_report(&mut event, client_ip, &user_agent);

let headers = event
.request
.value_mut()
.get_or_insert_with(Request::default)
.headers
.value_mut()
.get_or_insert_with(Headers::default);

assert_eq!(
event.user.value().unwrap().ip_address,
Annotated::from(ipaddr)
);
assert_eq!(
headers.get_header(RawUserAgentInfo::USER_AGENT),
user_agent.user_agent
);
assert_eq!(
headers.get_header(ClientHints::SEC_CH_UA),
user_agent.client_hints.sec_ch_ua,
);
assert_eq!(
headers.get_header(ClientHints::SEC_CH_UA_MODEL),
user_agent.client_hints.sec_ch_ua_model,
);
assert_eq!(
headers.get_header(ClientHints::SEC_CH_UA_PLATFORM),
user_agent.client_hints.sec_ch_ua_platform,
);
assert_eq!(
headers.get_header(ClientHints::SEC_CH_UA_PLATFORM_VERSION),
user_agent.client_hints.sec_ch_ua_platform_version,
);

assert!(
std::mem::size_of_val(&ClientHints::<&str>::default()) == 64,
"If you add new fields, update the test accordingly"
);
}
}
45 changes: 43 additions & 2 deletions relay-general/src/user_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use uaparser::{Parser, UserAgentParser};

use crate::protocol::{Headers, Request};
use crate::protocol::{HeaderName, HeaderValue, Headers, Request};
use crate::types::Annotated;

#[doc(inline)]
Expand Down Expand Up @@ -126,6 +126,31 @@ impl RawUserAgentInfo<String> {
}

impl<'a> RawUserAgentInfo<&'a str> {
pub fn populate_event_headers(&self, headers: &mut Headers) {
TBS1996 marked this conversation as resolved.
Show resolved Hide resolved
let mut insert_header = |key: &str, val: Option<&str>| {
if let Some(val) = val {
if !headers.contains(key) {
headers.insert(HeaderName::new(key), Annotated::new(HeaderValue::new(val)));
}
}
};

insert_header(RawUserAgentInfo::USER_AGENT, self.user_agent);
insert_header(
ClientHints::SEC_CH_UA_PLATFORM,
self.client_hints.sec_ch_ua_platform,
);
insert_header(
ClientHints::SEC_CH_UA_PLATFORM_VERSION,
self.client_hints.sec_ch_ua_platform_version,
);
insert_header(ClientHints::SEC_CH_UA, self.client_hints.sec_ch_ua);
insert_header(
ClientHints::SEC_CH_UA_MODEL,
self.client_hints.sec_ch_ua_model,
);
}
TBS1996 marked this conversation as resolved.
Show resolved Hide resolved

pub fn from_headers(headers: &'a Headers) -> Self {
let mut contexts: RawUserAgentInfo<&str> = Self::default();

Expand Down Expand Up @@ -155,7 +180,7 @@ pub struct ClientHints<S: Default + AsRef<str>> {
}

impl<S: AsRef<str> + Default> ClientHints<S> {
/// Checks every field of a passed-in ClientHints if it contains a value, and if it does,
/// Checks every field of a passed-in ClientHints instance if it contains a value, and if it does,
/// copy it to self.
pub fn copy_from(&mut self, other: ClientHints<S>) {
if other.sec_ch_ua_platform_version.is_some() {
Expand Down Expand Up @@ -201,6 +226,22 @@ impl ClientHints<String> {
mod tests {
use super::*;

//impl<S: AsRef<str> + Default> RawUserAgentInfo<S> {
TBS1996 marked this conversation as resolved.
Show resolved Hide resolved
impl RawUserAgentInfo<&str> {
pub fn new_test_dummy() -> Self {
Self {
user_agent: Some("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0"),
client_hints: ClientHints {
sec_ch_ua_platform: Some("macOS"),
sec_ch_ua_platform_version: Some("13.2.0"),
sec_ch_ua: Some(r#""Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110""#),
sec_ch_ua_model: Some("some model"),
}

}
}
}

#[test]
fn test_default_empty() {
assert!(RawUserAgentInfo::<&str>::default().is_empty());
Expand Down