sentinel_proxy/proxy/
context.rs1use std::sync::Arc;
7use std::time::Instant;
8
9use sentinel_config::{BodyStreamingMode, Config, RouteConfig, ServiceType};
10
11use crate::websocket::WebSocketHandler;
12
13pub struct RequestContext {
19 start_time: Instant,
21
22 pub(crate) trace_id: String,
25
26 pub(crate) config: Option<Arc<Config>>,
29
30 pub(crate) route_id: Option<String>,
33 pub(crate) route_config: Option<Arc<RouteConfig>>,
35 pub(crate) upstream: Option<String>,
37 pub(crate) upstream_attempts: u32,
39
40 pub(crate) method: String,
43 pub(crate) path: String,
45 pub(crate) query: Option<String>,
47
48 pub(crate) client_ip: String,
51 pub(crate) user_agent: Option<String>,
53 pub(crate) referer: Option<String>,
55 pub(crate) host: Option<String>,
57
58 pub(crate) request_body_bytes: u64,
61 pub(crate) response_bytes: u64,
63
64 pub(crate) connection_reused: bool,
67 pub(crate) is_websocket_upgrade: bool,
69
70 pub(crate) websocket_inspection_enabled: bool,
73 pub(crate) websocket_skip_inspection: bool,
75 pub(crate) websocket_inspection_agents: Vec<String>,
77 pub(crate) websocket_handler: Option<Arc<WebSocketHandler>>,
79
80 pub(crate) cache_eligible: bool,
83
84 pub(crate) body_inspection_enabled: bool,
87 pub(crate) body_bytes_inspected: u64,
89 pub(crate) body_buffer: Vec<u8>,
91 pub(crate) body_inspection_agents: Vec<String>,
93
94 pub(crate) request_body_streaming_mode: BodyStreamingMode,
97 pub(crate) request_body_chunk_index: u32,
99 pub(crate) agent_needs_more: bool,
101 pub(crate) response_body_streaming_mode: BodyStreamingMode,
103 pub(crate) response_body_chunk_index: u32,
105 pub(crate) response_body_bytes_inspected: u64,
107 pub(crate) response_body_inspection_enabled: bool,
109 pub(crate) response_body_inspection_agents: Vec<String>,
111}
112
113impl RequestContext {
114 pub fn new() -> Self {
116 Self {
117 start_time: Instant::now(),
118 trace_id: String::new(),
119 config: None,
120 route_id: None,
121 route_config: None,
122 upstream: None,
123 upstream_attempts: 0,
124 method: String::new(),
125 path: String::new(),
126 query: None,
127 client_ip: String::new(),
128 user_agent: None,
129 referer: None,
130 host: None,
131 request_body_bytes: 0,
132 response_bytes: 0,
133 connection_reused: false,
134 is_websocket_upgrade: false,
135 websocket_inspection_enabled: false,
136 websocket_skip_inspection: false,
137 websocket_inspection_agents: Vec::new(),
138 websocket_handler: None,
139 cache_eligible: false,
140 body_inspection_enabled: false,
141 body_bytes_inspected: 0,
142 body_buffer: Vec::new(),
143 body_inspection_agents: Vec::new(),
144 request_body_streaming_mode: BodyStreamingMode::Buffer,
145 request_body_chunk_index: 0,
146 agent_needs_more: false,
147 response_body_streaming_mode: BodyStreamingMode::Buffer,
148 response_body_chunk_index: 0,
149 response_body_bytes_inspected: 0,
150 response_body_inspection_enabled: false,
151 response_body_inspection_agents: Vec::new(),
152 }
153 }
154
155 #[inline]
159 pub fn start_time(&self) -> Instant {
160 self.start_time
161 }
162
163 #[inline]
165 pub fn elapsed(&self) -> std::time::Duration {
166 self.start_time.elapsed()
167 }
168
169 #[inline]
173 pub fn correlation_id(&self) -> &str {
174 &self.trace_id
175 }
176
177 #[inline]
179 pub fn trace_id(&self) -> &str {
180 &self.trace_id
181 }
182
183 #[inline]
185 pub fn route_id(&self) -> Option<&str> {
186 self.route_id.as_deref()
187 }
188
189 #[inline]
191 pub fn upstream(&self) -> Option<&str> {
192 self.upstream.as_deref()
193 }
194
195 #[inline]
197 pub fn route_config(&self) -> Option<&Arc<RouteConfig>> {
198 self.route_config.as_ref()
199 }
200
201 #[inline]
203 pub fn global_config(&self) -> Option<&Arc<Config>> {
204 self.config.as_ref()
205 }
206
207 #[inline]
209 pub fn service_type(&self) -> Option<ServiceType> {
210 self.route_config.as_ref().map(|c| c.service_type.clone())
211 }
212
213 #[inline]
215 pub fn upstream_attempts(&self) -> u32 {
216 self.upstream_attempts
217 }
218
219 #[inline]
221 pub fn method(&self) -> &str {
222 &self.method
223 }
224
225 #[inline]
227 pub fn path(&self) -> &str {
228 &self.path
229 }
230
231 #[inline]
233 pub fn query(&self) -> Option<&str> {
234 self.query.as_deref()
235 }
236
237 #[inline]
239 pub fn client_ip(&self) -> &str {
240 &self.client_ip
241 }
242
243 #[inline]
245 pub fn user_agent(&self) -> Option<&str> {
246 self.user_agent.as_deref()
247 }
248
249 #[inline]
251 pub fn referer(&self) -> Option<&str> {
252 self.referer.as_deref()
253 }
254
255 #[inline]
257 pub fn host(&self) -> Option<&str> {
258 self.host.as_deref()
259 }
260
261 #[inline]
263 pub fn response_bytes(&self) -> u64 {
264 self.response_bytes
265 }
266
267 #[inline]
271 pub fn set_trace_id(&mut self, trace_id: impl Into<String>) {
272 self.trace_id = trace_id.into();
273 }
274
275 #[inline]
277 pub fn set_route_id(&mut self, route_id: impl Into<String>) {
278 self.route_id = Some(route_id.into());
279 }
280
281 #[inline]
283 pub fn set_upstream(&mut self, upstream: impl Into<String>) {
284 self.upstream = Some(upstream.into());
285 }
286
287 #[inline]
289 pub fn inc_upstream_attempts(&mut self) {
290 self.upstream_attempts += 1;
291 }
292
293 #[inline]
295 pub fn set_response_bytes(&mut self, bytes: u64) {
296 self.response_bytes = bytes;
297 }
298}
299
300impl Default for RequestContext {
301 fn default() -> Self {
302 Self::new()
303 }
304}