1
1
use httpdate:: parse_http_date;
2
2
use std:: time:: { Duration , SystemTime } ;
3
3
4
- // TODO: maybe move this someplace where we can filter an `Envelope`s items.
4
+ use crate :: protocol:: EnvelopeItem ;
5
+ use crate :: Envelope ;
5
6
6
7
/// A Utility that helps with rate limiting sentry requests.
7
8
#[ derive( Debug , Default ) ]
@@ -10,6 +11,7 @@ pub struct RateLimiter {
10
11
error : Option < SystemTime > ,
11
12
session : Option < SystemTime > ,
12
13
transaction : Option < SystemTime > ,
14
+ attachment : Option < SystemTime > ,
13
15
}
14
16
15
17
impl RateLimiter {
@@ -55,6 +57,7 @@ impl RateLimiter {
55
57
"error" => self . error = new_time,
56
58
"session" => self . session = new_time,
57
59
"transaction" => self . transaction = new_time,
60
+ "attachment" => self . attachment = new_time,
58
61
_ => { }
59
62
}
60
63
}
@@ -66,7 +69,10 @@ impl RateLimiter {
66
69
}
67
70
}
68
71
69
- /// Query the RateLimiter for a certain category of event.
72
+ /// Query the RateLimiter if a certain category of event is currently rate limited.
73
+ ///
74
+ /// If the given category is rate limited, it will return the remaining
75
+ /// [`Duration`] for which it is.
70
76
pub fn is_disabled ( & self , category : RateLimitingCategory ) -> Option < Duration > {
71
77
if let Some ( ts) = self . global {
72
78
let time_left = ts. duration_since ( SystemTime :: now ( ) ) . ok ( ) ;
@@ -79,14 +85,38 @@ impl RateLimiter {
79
85
RateLimitingCategory :: Error => self . error ,
80
86
RateLimitingCategory :: Session => self . session ,
81
87
RateLimitingCategory :: Transaction => self . transaction ,
88
+ RateLimitingCategory :: Attachment => self . attachment ,
82
89
} ?;
83
90
time_left. duration_since ( SystemTime :: now ( ) ) . ok ( )
84
91
}
92
+
93
+ /// Query the RateLimiter for a certain category of event.
94
+ ///
95
+ /// Returns `true` if the category is *not* rate limited and should be sent.
96
+ pub fn is_enabled ( & self , category : RateLimitingCategory ) -> bool {
97
+ self . is_disabled ( category) . is_none ( )
98
+ }
99
+
100
+ /// Filters the [`Envelope`] according to the current rate limits.
101
+ ///
102
+ /// Returns [`None`] if all the envelope items were filtered out.
103
+ pub fn filter_envelope ( & self , envelope : Envelope ) -> Option < Envelope > {
104
+ envelope. filter ( |item| {
105
+ self . is_enabled ( match item {
106
+ EnvelopeItem :: Event ( _) => RateLimitingCategory :: Error ,
107
+ EnvelopeItem :: SessionUpdate ( _) | EnvelopeItem :: SessionAggregates ( _) => {
108
+ RateLimitingCategory :: Session
109
+ }
110
+ EnvelopeItem :: Transaction ( _) => RateLimitingCategory :: Transaction ,
111
+ EnvelopeItem :: Attachment ( _) => RateLimitingCategory :: Attachment ,
112
+ _ => RateLimitingCategory :: Any ,
113
+ } )
114
+ } )
115
+ }
85
116
}
86
117
87
118
/// The Category of payload that a Rate Limit refers to.
88
119
#[ non_exhaustive]
89
- #[ allow( dead_code) ]
90
120
pub enum RateLimitingCategory {
91
121
/// Rate Limit for any kind of payload.
92
122
Any ,
@@ -96,6 +126,8 @@ pub enum RateLimitingCategory {
96
126
Session ,
97
127
/// Rate Limit pertaining to Transactions.
98
128
Transaction ,
129
+ /// Rate Limit pertaining to Attachments.
130
+ Attachment ,
99
131
}
100
132
101
133
#[ cfg( test) ]
0 commit comments