playwright_core/protocol/
request.rs

1// Request protocol object
2//
3// Represents an HTTP request. Created during navigation operations.
4// In Playwright's architecture, navigation creates a Request which receives a Response.
5
6use crate::channel_owner::{ChannelOwner, ChannelOwnerImpl, ParentOrConnection};
7use crate::error::Result;
8use serde_json::Value;
9use std::any::Any;
10use std::sync::Arc;
11
12/// Request represents an HTTP request during navigation.
13///
14/// Request objects are created by the server during navigation operations.
15/// They are parents to Response objects.
16///
17/// See: <https://playwright.dev/docs/api/class-request>
18#[derive(Clone)]
19pub struct Request {
20    base: ChannelOwnerImpl,
21}
22
23impl Request {
24    /// Creates a new Request from protocol initialization
25    ///
26    /// This is called by the object factory when the server sends a `__create__` message
27    /// for a Request object.
28    pub fn new(
29        parent: Arc<dyn ChannelOwner>,
30        type_name: String,
31        guid: Arc<str>,
32        initializer: Value,
33    ) -> Result<Self> {
34        let base = ChannelOwnerImpl::new(
35            ParentOrConnection::Parent(parent),
36            type_name,
37            guid,
38            initializer,
39        );
40
41        Ok(Self { base })
42    }
43
44    /// Returns the URL of the request.
45    ///
46    /// See: <https://playwright.dev/docs/api/class-request#request-url>
47    pub fn url(&self) -> &str {
48        self.initializer()
49            .get("url")
50            .and_then(|v| v.as_str())
51            .unwrap_or("")
52    }
53
54    /// Returns the HTTP method of the request (GET, POST, etc.).
55    ///
56    /// See: <https://playwright.dev/docs/api/class-request#request-method>
57    pub fn method(&self) -> &str {
58        self.initializer()
59            .get("method")
60            .and_then(|v| v.as_str())
61            .unwrap_or("GET")
62    }
63
64    /// Returns the resource type of the request (e.g., "document", "stylesheet", "image", "fetch", etc.).
65    ///
66    /// See: <https://playwright.dev/docs/api/class-request#request-resource-type>
67    pub fn resource_type(&self) -> &str {
68        self.initializer()
69            .get("resourceType")
70            .and_then(|v| v.as_str())
71            .unwrap_or("other")
72    }
73
74    /// Check if this request is for a navigation (main document).
75    ///
76    /// A navigation request is when the request is for the main frame's document.
77    /// This is used to distinguish between main document loads and subresource loads.
78    pub fn is_navigation_request(&self) -> bool {
79        self.resource_type() == "document"
80    }
81}
82
83impl ChannelOwner for Request {
84    fn guid(&self) -> &str {
85        self.base.guid()
86    }
87
88    fn type_name(&self) -> &str {
89        self.base.type_name()
90    }
91
92    fn parent(&self) -> Option<Arc<dyn ChannelOwner>> {
93        self.base.parent()
94    }
95
96    fn connection(&self) -> Arc<dyn crate::connection::ConnectionLike> {
97        self.base.connection()
98    }
99
100    fn initializer(&self) -> &Value {
101        self.base.initializer()
102    }
103
104    fn channel(&self) -> &crate::channel::Channel {
105        self.base.channel()
106    }
107
108    fn dispose(&self, reason: crate::channel_owner::DisposeReason) {
109        self.base.dispose(reason)
110    }
111
112    fn adopt(&self, child: Arc<dyn ChannelOwner>) {
113        self.base.adopt(child)
114    }
115
116    fn add_child(&self, guid: Arc<str>, child: Arc<dyn ChannelOwner>) {
117        self.base.add_child(guid, child)
118    }
119
120    fn remove_child(&self, guid: &str) {
121        self.base.remove_child(guid)
122    }
123
124    fn on_event(&self, _method: &str, _params: Value) {
125        // Request events will be handled in future phases
126    }
127
128    fn was_collected(&self) -> bool {
129        self.base.was_collected()
130    }
131
132    fn as_any(&self) -> &dyn Any {
133        self
134    }
135}
136
137impl std::fmt::Debug for Request {
138    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139        f.debug_struct("Request")
140            .field("guid", &self.guid())
141            .finish()
142    }
143}