-
-
Notifications
You must be signed in to change notification settings - Fork 413
Expand file tree
/
Copy pathSentryTracePropagation.m
More file actions
118 lines (102 loc) · 4.79 KB
/
Copy pathSentryTracePropagation.m
File metadata and controls
118 lines (102 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#import <SentryBaggage.h>
#import <SentryInternalDefines.h>
#import <SentryLogC.h>
#import <SentrySwift.h>
#import <SentryTraceHeader.h>
#import <SentryTracePropagation.h>
static NSString *const SENTRY_TRACEPARENT = @"traceparent";
@implementation SentryTracePropagation
+ (void)addBaggageHeader:(SentryBaggage *)baggage
traceHeader:(SentryTraceHeader *)traceHeader
propagateTraceparent:(BOOL)propagateTraceparent
tracePropagationTargets:(NSArray *_Nullable)tracePropagationTargets
toRequest:(NSURLSessionTask *)sessionTask
{
// Snapshot currentRequest once — the property is volatile and can become a zombie
// between repeated accesses if the task completes on another thread.
NSURLRequest *request = sessionTask.currentRequest;
if (request == nil) {
return;
}
if (![SentryTracePropagation isTargetMatch:SENTRY_UNWRAP_NULLABLE(NSURL, request.URL)
withTargets:tracePropagationTargets ?: @[]]) {
SENTRY_LOG_DEBUG(
@"Not adding trace_id and baggage headers for %@", request.URL.absoluteString);
return;
}
NSString *baggageHeader = @"";
if (baggage != nil) {
NSString *_Nullable rawHeader
= SENTRY_UNWRAP_NULLABLE(NSString, request.allHTTPHeaderFields[SENTRY_BAGGAGE_HEADER]);
NSDictionary *originalBaggage = [SentryBaggageSerialization decode:rawHeader ?: @""];
if (originalBaggage[@"sentry-trace_id"] == nil) {
baggageHeader = [baggage toHTTPHeaderWithOriginalBaggage:originalBaggage];
}
}
if ([request isKindOfClass:[NSMutableURLRequest class]]) {
NSMutableURLRequest *mutableRequest = (NSMutableURLRequest *)request;
[SentryTracePropagation addHeaderFieldsToRequest:mutableRequest
traceHeader:traceHeader
baggageHeader:baggageHeader
propagateTraceparent:propagateTraceparent];
} else {
SEL setCurrentRequestSelector = NSSelectorFromString(@"setCurrentRequest:");
if ([sessionTask respondsToSelector:setCurrentRequestSelector]) {
NSMutableURLRequest *newRequest = [request mutableCopy];
[SentryTracePropagation addHeaderFieldsToRequest:newRequest
traceHeader:traceHeader
baggageHeader:baggageHeader
propagateTraceparent:propagateTraceparent];
void (*func)(id, SEL, id param)
= (void *)[sessionTask methodForSelector:setCurrentRequestSelector];
func(sessionTask, setCurrentRequestSelector, newRequest);
}
}
}
+ (BOOL)sessionTaskRequiresPropagation:(NSURLSessionTask *)sessionTask
tracePropagationTargets:(NSArray *)tracePropagationTargets
{
return sessionTask.currentRequest != nil &&
[SentryTracePropagation
isTargetMatch:SENTRY_UNWRAP_NULLABLE(NSURL, sessionTask.currentRequest.URL)
withTargets:tracePropagationTargets];
}
+ (void)addHeaderFieldsToRequest:(NSMutableURLRequest *)request
traceHeader:(SentryTraceHeader *)traceHeader
baggageHeader:(NSString *)baggageHeader
propagateTraceparent:(BOOL)propagateTraceparent
{
if ([request valueForHTTPHeaderField:SENTRY_TRACE_HEADER] == nil) {
[request setValue:traceHeader.value forHTTPHeaderField:SENTRY_TRACE_HEADER];
}
if (propagateTraceparent && [request valueForHTTPHeaderField:SENTRY_TRACEPARENT] == nil) {
NSString *traceparent = [NSString stringWithFormat:@"00-%@-%@-%02x",
traceHeader.traceId.sentryIdString, traceHeader.spanId.sentrySpanIdString,
traceHeader.sampled == kSentrySampleDecisionYes ? 1 : 0];
[request setValue:traceparent forHTTPHeaderField:SENTRY_TRACEPARENT];
}
if (baggageHeader.length > 0) {
[request setValue:baggageHeader forHTTPHeaderField:SENTRY_BAGGAGE_HEADER];
}
}
+ (BOOL)isTargetMatch:(NSURL *)URL withTargets:(NSArray *)targets
{
for (id targetCheck in targets) {
if ([targetCheck isKindOfClass:[NSRegularExpression class]]) {
NSString *string = URL.absoluteString;
NSUInteger numberOfMatches =
[targetCheck numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
if (numberOfMatches > 0) {
return YES;
}
} else if ([targetCheck isKindOfClass:[NSString class]]) {
if ([URL.absoluteString containsString:targetCheck]) {
return YES;
}
}
}
return NO;
}
@end