1use serde::{Deserialize, Serialize};
8
9use super::network::{Request, ResourceType};
10
11pub type RequestId = String;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct HeaderEntry {
17 pub name: String,
19 pub value: String,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
25#[derive(Default)]
26pub enum RequestStage {
27 #[default]
29 Request,
30 Response,
32}
33
34
35#[derive(Debug, Clone, Serialize, Deserialize, Default)]
37#[serde(rename_all = "camelCase")]
38pub struct RequestPattern {
39 #[serde(skip_serializing_if = "Option::is_none")]
42 pub url_pattern: Option<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub resource_type: Option<ResourceType>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub request_stage: Option<RequestStage>,
51}
52
53impl RequestPattern {
54 pub fn all() -> Self {
56 Self::default()
57 }
58
59 pub fn url(pattern: impl Into<String>) -> Self {
61 Self {
62 url_pattern: Some(pattern.into()),
63 ..Default::default()
64 }
65 }
66
67 #[must_use]
69 pub fn with_resource_type(mut self, resource_type: ResourceType) -> Self {
70 self.resource_type = Some(resource_type);
71 self
72 }
73
74 #[must_use]
76 pub fn with_stage(mut self, stage: RequestStage) -> Self {
77 self.request_stage = Some(stage);
78 self
79 }
80}
81
82#[derive(Debug, Clone, Serialize, Default)]
88#[serde(rename_all = "camelCase")]
89pub struct EnableParams {
90 #[serde(skip_serializing_if = "Option::is_none")]
94 pub patterns: Option<Vec<RequestPattern>>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
99 pub handle_auth_requests: Option<bool>,
100}
101
102#[derive(Debug, Clone, Serialize, Default)]
104pub struct DisableParams {}
105
106#[derive(Debug, Clone, Serialize, Default)]
108#[serde(rename_all = "camelCase")]
109pub struct ContinueRequestParams {
110 pub request_id: RequestId,
112
113 #[serde(skip_serializing_if = "Option::is_none")]
115 pub url: Option<String>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
119 pub method: Option<String>,
120
121 #[serde(skip_serializing_if = "Option::is_none")]
124 pub post_data: Option<String>,
125
126 #[serde(skip_serializing_if = "Option::is_none")]
128 pub headers: Option<Vec<HeaderEntry>>,
129
130 #[serde(skip_serializing_if = "Option::is_none")]
132 pub intercept_response: Option<bool>,
133}
134
135#[derive(Debug, Clone, Serialize)]
137#[serde(rename_all = "camelCase")]
138pub struct FulfillRequestParams {
139 pub request_id: RequestId,
141
142 pub response_code: i32,
144
145 #[serde(skip_serializing_if = "Option::is_none")]
147 pub response_headers: Option<Vec<HeaderEntry>>,
148
149 #[serde(skip_serializing_if = "Option::is_none")]
152 pub binary_response_headers: Option<String>,
153
154 #[serde(skip_serializing_if = "Option::is_none")]
159 pub body: Option<String>,
160
161 #[serde(skip_serializing_if = "Option::is_none")]
164 pub response_phrase: Option<String>,
165}
166
167#[derive(Debug, Clone, Serialize)]
169#[serde(rename_all = "camelCase")]
170pub struct FailRequestParams {
171 pub request_id: RequestId,
173
174 pub error_reason: ErrorReason,
176}
177
178#[derive(Debug, Clone, Serialize)]
180#[serde(rename_all = "camelCase")]
181pub struct GetResponseBodyParams {
182 pub request_id: RequestId,
184}
185
186#[derive(Debug, Clone, Deserialize)]
188#[serde(rename_all = "camelCase")]
189pub struct GetResponseBodyResult {
190 pub body: String,
192
193 pub base64_encoded: bool,
195}
196
197#[derive(Debug, Clone, Serialize)]
199#[serde(rename_all = "camelCase")]
200pub struct ContinueWithAuthParams {
201 pub request_id: RequestId,
203
204 pub auth_challenge_response: AuthChallengeResponse,
206}
207
208#[derive(Debug, Clone, Serialize, Default)]
210#[serde(rename_all = "camelCase")]
211pub struct ContinueResponseParams {
212 pub request_id: RequestId,
214
215 #[serde(skip_serializing_if = "Option::is_none")]
217 pub response_code: Option<i32>,
218
219 #[serde(skip_serializing_if = "Option::is_none")]
221 pub response_phrase: Option<String>,
222
223 #[serde(skip_serializing_if = "Option::is_none")]
225 pub response_headers: Option<Vec<HeaderEntry>>,
226
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub binary_response_headers: Option<String>,
230}
231
232#[derive(Debug, Clone, Deserialize)]
242#[serde(rename_all = "camelCase")]
243pub struct RequestPausedEvent {
244 pub request_id: RequestId,
246
247 pub request: Request,
249
250 pub frame_id: String,
252
253 pub resource_type: ResourceType,
255
256 #[serde(skip_serializing_if = "Option::is_none")]
258 pub response_error_reason: Option<ErrorReason>,
259
260 #[serde(skip_serializing_if = "Option::is_none")]
262 pub response_status_code: Option<i32>,
263
264 #[serde(skip_serializing_if = "Option::is_none")]
266 pub response_status_text: Option<String>,
267
268 #[serde(skip_serializing_if = "Option::is_none")]
270 pub response_headers: Option<Vec<HeaderEntry>>,
271
272 #[serde(skip_serializing_if = "Option::is_none")]
275 pub network_id: Option<String>,
276
277 #[serde(skip_serializing_if = "Option::is_none")]
280 pub redirected_request_id: Option<RequestId>,
281}
282
283impl RequestPausedEvent {
284 pub fn is_response_stage(&self) -> bool {
286 self.response_error_reason.is_some() || self.response_status_code.is_some()
287 }
288
289 pub fn is_request_stage(&self) -> bool {
291 !self.is_response_stage()
292 }
293
294 pub fn is_redirect(&self) -> bool {
296 if let Some(code) = self.response_status_code {
297 matches!(code, 301 | 302 | 303 | 307 | 308)
298 && self.response_headers.as_ref().is_some_and(|headers| {
299 headers.iter().any(|h| h.name.eq_ignore_ascii_case("location"))
300 })
301 } else {
302 false
303 }
304 }
305}
306
307#[derive(Debug, Clone, Deserialize)]
312#[serde(rename_all = "camelCase")]
313pub struct AuthRequiredEvent {
314 pub request_id: RequestId,
316
317 pub request: Request,
319
320 pub frame_id: String,
322
323 pub resource_type: ResourceType,
325
326 pub auth_challenge: AuthChallenge,
328}
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
336#[derive(Default)]
337pub enum ErrorReason {
338 #[default]
340 Failed,
341 Aborted,
343 TimedOut,
345 AccessDenied,
347 ConnectionClosed,
349 ConnectionReset,
351 ConnectionRefused,
353 ConnectionAborted,
355 ConnectionFailed,
357 NameNotResolved,
359 InternetDisconnected,
361 AddressUnreachable,
363 BlockedByClient,
365 BlockedByResponse,
367}
368
369
370impl ErrorReason {
371 pub fn as_str(&self) -> &'static str {
373 match self {
374 Self::Failed => "Failed",
375 Self::Aborted => "Aborted",
376 Self::TimedOut => "TimedOut",
377 Self::AccessDenied => "AccessDenied",
378 Self::ConnectionClosed => "ConnectionClosed",
379 Self::ConnectionReset => "ConnectionReset",
380 Self::ConnectionRefused => "ConnectionRefused",
381 Self::ConnectionAborted => "ConnectionAborted",
382 Self::ConnectionFailed => "ConnectionFailed",
383 Self::NameNotResolved => "NameNotResolved",
384 Self::InternetDisconnected => "InternetDisconnected",
385 Self::AddressUnreachable => "AddressUnreachable",
386 Self::BlockedByClient => "BlockedByClient",
387 Self::BlockedByResponse => "BlockedByResponse",
388 }
389 }
390}
391
392#[derive(Debug, Clone, Deserialize)]
394#[serde(rename_all = "camelCase")]
395pub struct AuthChallenge {
396 pub source: AuthChallengeSource,
398
399 pub origin: String,
401
402 pub scheme: String,
404
405 pub realm: String,
407}
408
409#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
411pub enum AuthChallengeSource {
412 Server,
414 Proxy,
416}
417
418#[derive(Debug, Clone, Serialize)]
420#[serde(rename_all = "camelCase")]
421pub struct AuthChallengeResponse {
422 pub response: AuthChallengeResponseType,
424
425 #[serde(skip_serializing_if = "Option::is_none")]
428 pub username: Option<String>,
429
430 #[serde(skip_serializing_if = "Option::is_none")]
433 pub password: Option<String>,
434}
435
436#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
438pub enum AuthChallengeResponseType {
439 Default,
441 CancelAuth,
443 ProvideCredentials,
445}
446
447impl AuthChallengeResponse {
448 pub fn default_response() -> Self {
450 Self {
451 response: AuthChallengeResponseType::Default,
452 username: None,
453 password: None,
454 }
455 }
456
457 pub fn cancel() -> Self {
459 Self {
460 response: AuthChallengeResponseType::CancelAuth,
461 username: None,
462 password: None,
463 }
464 }
465
466 pub fn provide_credentials(username: impl Into<String>, password: impl Into<String>) -> Self {
468 Self {
469 response: AuthChallengeResponseType::ProvideCredentials,
470 username: Some(username.into()),
471 password: Some(password.into()),
472 }
473 }
474}
475
476