rustenium_core/
network.rs1use crate::error::{PostDataError, SessionSendError};
2use crate::transport::ConnectionTransport;
3use crate::{BidiSession, CommandResponseState};
4use form_urlencoded;
5use rustenium_bidi_definitions::Command;
6use rustenium_bidi_definitions::network::command_builders::{
7 ContinueRequestBuilder, ContinueWithAuthBuilder, FailRequestBuilder, ProvideResponseBuilder
8};
9use rustenium_bidi_definitions::network::events::{AuthRequiredParams, BeforeRequestSentParams
10};
11use rustenium_bidi_definitions::network::type_builders::{ContinueWithAuthCredentialsBuilder, ContinueWithAuthNoCredentialsBuilder};
12use rustenium_bidi_definitions::network::types::{AuthCredentials, BaseParameters, ContinueWithAuthCredentialsAction, ContinueWithAuthCredentialsContinueWithAuthNoCredentialsUnion, ContinueWithAuthNoCredentialsAction, Header, Request};
13use tokio::sync::oneshot;
14
15#[derive(Debug, Clone)]
17pub enum NetworkRequestHandledState {
18 Continued,
20 Aborted,
22 Responded,
24}
25use serde_json;
26use std::collections::HashMap;
27use std::sync::Arc;
28use tokio::sync::Mutex;
29
30pub struct NetworkRequest<T: ConnectionTransport> {
32 pub base: BaseParameters,
33 session: Arc<Mutex<BidiSession<T>>>,
34}
35
36impl<T: ConnectionTransport> std::fmt::Debug for NetworkRequest<T> {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 f.debug_struct("NetworkRequest")
39 .field("base", &self.base)
40 .field("session", &"<Arc<Mutex<Session>>>")
41 .finish()
42 }
43}
44
45impl<T: ConnectionTransport> NetworkRequest<T> {
46 pub fn new(params: BeforeRequestSentParams, session: Arc<Mutex<BidiSession<T>>>) -> Self {
47 NetworkRequest {
48 base: params.base_parameters,
49 session,
50 }
51 }
52
53 pub fn from_auth_required(params: AuthRequiredParams, session: Arc<Mutex<BidiSession<T>>>) -> Self {
54 NetworkRequest {
55 base: params.base_parameters,
56 session,
57 }
58 }
59
60 pub fn request_id(&self) -> &Request {
62 &self.base.request.request
63 }
64
65 pub fn url(&self) -> &str {
67 &self.base.request.url
68 }
69
70 pub fn headers(&self) -> &Vec<Header> {
72 &self.base.request.headers
73 }
74
75 pub fn method(&self) -> &str {
77 &self.base.request.method
78 }
79
80 pub fn has_post_data(&self) -> bool {
82 self.base
83 .request
84 .extensible
85 .get("goog:hasPostData")
86 .and_then(|v| v.as_bool())
87 .unwrap_or(false)
88 }
89
90 pub fn post_data(&self) -> Option<&str> {
92 self.base
93 .request
94 .extensible
95 .get("goog:postData")
96 .and_then(|v| v.as_str())
97 }
98
99 pub fn post_data_json(
102 &self,
103 ) -> Result<serde_json::Map<String, serde_json::Value>, PostDataError> {
104 let data = self.post_data().ok_or(PostDataError::NoPostData)?;
105
106 let value: serde_json::Value = serde_json::from_str(data)?;
107
108 value
109 .as_object()
110 .cloned()
111 .ok_or(PostDataError::NotJsonObject)
112 }
113
114 pub fn post_data_form(&self) -> Result<HashMap<String, String>, PostDataError> {
117 let data = self.post_data().ok_or(PostDataError::NoPostData)?;
118
119 let parsed: HashMap<String, String> = form_urlencoded::parse(data.as_bytes())
120 .into_owned()
121 .collect();
122
123 Ok(parsed)
124 }
125
126 pub async fn is_handled(&self) -> bool {
128 self.session
129 .lock()
130 .await
131 .handled_network_requests
132 .lock()
133 .unwrap()
134 .contains_key(self.request_id().as_ref())
135 }
136
137 pub async fn get_handled_state(&self) -> Option<NetworkRequestHandledState> {
139 self.session
140 .lock()
141 .await
142 .handled_network_requests
143 .lock()
144 .unwrap()
145 .get(self.request_id().as_ref())
146 .cloned()
147 }
148
149 async fn mark_handled(&self, state: NetworkRequestHandledState) {
151 let session = self.session.lock().await;
152 session
153 .handled_network_requests
154 .lock()
155 .unwrap()
156 .insert(self.base.request.request.clone().into(), state);
157 }
158
159 pub async fn continue_(&self) -> oneshot::Receiver<CommandResponseState> {
161 let command: Command = ContinueRequestBuilder::default()
162 .request(self.base.request.request.clone())
163 .build()
164 .unwrap()
165 .into(); let rx = self
168 .session
169 .lock()
170 .await
171 .send_and_get_receiver(command)
172 .await;
173 self.mark_handled(NetworkRequestHandledState::Continued)
174 .await;
175 rx
176 }
177
178 pub async fn continue_with(
180 &self,
181 continue_request: ContinueRequestBuilder,
182 ) -> oneshot::Receiver<CommandResponseState> {
183 let continue_request = continue_request.request(self.base.request.request.clone()).build().unwrap();
184 let rx = self
185 .session
186 .lock()
187 .await
188 .send_and_get_receiver(continue_request)
189 .await;
190 self.mark_handled(NetworkRequestHandledState::Continued)
191 .await;
192 rx
193 }
194
195 pub async fn abort(&self) -> oneshot::Receiver<CommandResponseState> {
197 let command = FailRequestBuilder::default()
198 .request(self.base.request.request.clone())
199 .build().unwrap();
200
201 let rx = self
202 .session
203 .lock()
204 .await
205 .send_and_get_receiver(command)
206 .await;
207 self.mark_handled(NetworkRequestHandledState::Aborted).await;
208 rx
209 }
210
211 pub async fn respond(
213 &self,
214 provide_response_builder: ProvideResponseBuilder
215 ) -> oneshot::Receiver<CommandResponseState> {
216 let command = provide_response_builder.request(self.request_id().clone()).build().unwrap();
217
218 let rx = self
219 .session
220 .lock()
221 .await
222 .send_and_get_receiver(command)
223 .await;
224 self.mark_handled(NetworkRequestHandledState::Responded)
225 .await;
226 rx
227 }
228
229 pub async fn continue_with_auth(
231 &self,
232 credentials: AuthCredentials,
233 ) -> Result<(), SessionSendError> {
234 let command =
235 ContinueWithAuthBuilder::default().continue_with_auth_credentials_continue_with_auth_no_credentials_union(ContinueWithAuthCredentialsContinueWithAuthNoCredentialsUnion::ContinueWithAuthCredentials(
236 ContinueWithAuthCredentialsBuilder::default().action(ContinueWithAuthCredentialsAction::ProvideCredentials).credentials(
237 credentials).build().unwrap())).request(self.request_id().clone()).build().unwrap();
238
239 self.session.lock().await.send(command).await.map(|_| ())
240 }
241 pub async fn continue_with_no_auth(&self, action: ContinueWithAuthNoCredentialsAction) -> Result<(), SessionSendError> {
242 let command = ContinueWithAuthBuilder::default().continue_with_auth_credentials_continue_with_auth_no_credentials_union(ContinueWithAuthCredentialsContinueWithAuthNoCredentialsUnion::ContinueWithAuthNoCredentials(
243 ContinueWithAuthNoCredentialsBuilder::default().action(action).build().unwrap()
244 )).request(self.request_id().clone()).build().unwrap();
245
246
247 self.session.lock().await.send(command).await.map(|_| ())
248 }
249}