1use std::path::PathBuf;
6
7use base::generic_channel::{GenericSender, SendResult};
8use base::id::PipelineId;
9use constellation_traits::EmbedderToConstellationMessage;
10use embedder_traits::{
11 AlertResponse, AllowOrDeny, AuthenticationResponse, ConfirmResponse, ContextMenuAction,
12 ContextMenuElementInformation, ContextMenuItem, Cursor, EmbedderControlId,
13 EmbedderControlResponse, FilePickerRequest, FilterPattern, GamepadHapticEffectType,
14 InputEventId, InputEventResult, InputMethodType, LoadStatus, MediaSessionEvent, Notification,
15 PermissionFeature, PromptResponse, RgbColor, ScreenGeometry, SelectElementOptionOrOptgroup,
16 SimpleDialogRequest, TraversalId, WebResourceRequest, WebResourceResponse,
17 WebResourceResponseMsg,
18};
19use ipc_channel::ipc::IpcSender;
20use serde::Serialize;
21use url::Url;
22use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize};
23
24use crate::proxies::ConstellationProxy;
25use crate::responders::ServoErrorSender;
26use crate::{RegisterOrUnregister, WebView};
27
28pub struct NavigationRequest {
31 pub url: Url,
32 pub(crate) pipeline_id: PipelineId,
33 pub(crate) constellation_proxy: ConstellationProxy,
34 pub(crate) response_sent: bool,
35}
36
37impl NavigationRequest {
38 pub fn allow(mut self) {
39 self.constellation_proxy
40 .send(EmbedderToConstellationMessage::AllowNavigationResponse(
41 self.pipeline_id,
42 true,
43 ));
44 self.response_sent = true;
45 }
46
47 pub fn deny(mut self) {
48 self.constellation_proxy
49 .send(EmbedderToConstellationMessage::AllowNavigationResponse(
50 self.pipeline_id,
51 false,
52 ));
53 self.response_sent = true;
54 }
55}
56
57impl Drop for NavigationRequest {
58 fn drop(&mut self) {
59 if !self.response_sent {
60 self.constellation_proxy
61 .send(EmbedderToConstellationMessage::AllowNavigationResponse(
62 self.pipeline_id,
63 true,
64 ));
65 }
66 }
67}
68
69pub(crate) struct IpcResponder<T: Serialize> {
71 response_sender: GenericSender<T>,
72 response_sent: bool,
73 default_response: Option<T>,
75}
76
77impl<T: Serialize> IpcResponder<T> {
78 pub(crate) fn new(response_sender: GenericSender<T>, default_response: T) -> Self {
79 Self {
80 response_sender,
81 response_sent: false,
82 default_response: Some(default_response),
83 }
84 }
85
86 pub(crate) fn send(&mut self, response: T) -> SendResult {
87 let result = self.response_sender.send(response);
88 self.response_sent = true;
89 result
90 }
91
92 pub(crate) fn into_inner(self) -> GenericSender<T> {
93 self.response_sender.clone()
94 }
95}
96
97impl<T: Serialize> Drop for IpcResponder<T> {
98 fn drop(&mut self) {
99 if !self.response_sent {
100 let response = self
101 .default_response
102 .take()
103 .expect("Guaranteed by inherent impl");
104 let _ = self.response_sender.send(response);
107 }
108 }
109}
110
111pub struct PermissionRequest {
115 pub(crate) requested_feature: PermissionFeature,
116 pub(crate) allow_deny_request: AllowOrDenyRequest,
117}
118
119impl PermissionRequest {
120 pub fn feature(&self) -> PermissionFeature {
121 self.requested_feature
122 }
123
124 pub fn allow(self) {
125 self.allow_deny_request.allow();
126 }
127
128 pub fn deny(self) {
129 self.allow_deny_request.deny();
130 }
131}
132
133pub struct AllowOrDenyRequest(IpcResponder<AllowOrDeny>, ServoErrorSender);
134
135impl AllowOrDenyRequest {
136 pub(crate) fn new(
137 response_sender: GenericSender<AllowOrDeny>,
138 default_response: AllowOrDeny,
139 error_sender: ServoErrorSender,
140 ) -> Self {
141 Self(
142 IpcResponder::new(response_sender, default_response),
143 error_sender,
144 )
145 }
146
147 pub fn allow(mut self) {
148 if let Err(error) = self.0.send(AllowOrDeny::Allow) {
149 self.1.raise_response_send_error(error);
150 }
151 }
152
153 pub fn deny(mut self) {
154 if let Err(error) = self.0.send(AllowOrDeny::Deny) {
155 self.1.raise_response_send_error(error);
156 }
157 }
158}
159
160#[derive(Clone, Debug, Eq, PartialEq)]
161pub struct ProtocolHandlerRegistration {
162 pub scheme: String,
163 pub url: Url,
164 pub register_or_unregister: RegisterOrUnregister,
165}
166
167pub struct AuthenticationRequest {
171 pub(crate) url: Url,
172 pub(crate) for_proxy: bool,
173 pub(crate) responder: IpcResponder<Option<AuthenticationResponse>>,
174 pub(crate) error_sender: ServoErrorSender,
175}
176
177impl AuthenticationRequest {
178 pub(crate) fn new(
179 url: Url,
180 for_proxy: bool,
181 response_sender: GenericSender<Option<AuthenticationResponse>>,
182 error_sender: ServoErrorSender,
183 ) -> Self {
184 Self {
185 url,
186 for_proxy,
187 responder: IpcResponder::new(response_sender, None),
188 error_sender,
189 }
190 }
191
192 pub fn url(&self) -> &Url {
194 &self.url
195 }
196 pub fn for_proxy(&self) -> bool {
198 self.for_proxy
199 }
200 pub fn authenticate(mut self, username: String, password: String) {
202 if let Err(error) = self
203 .responder
204 .send(Some(AuthenticationResponse { username, password }))
205 {
206 self.error_sender.raise_response_send_error(error);
207 }
208 }
209}
210
211pub struct WebResourceLoad {
215 pub request: WebResourceRequest,
216 pub(crate) responder: IpcResponder<WebResourceResponseMsg>,
217 pub(crate) error_sender: ServoErrorSender,
218}
219
220impl WebResourceLoad {
221 pub(crate) fn new(
222 web_resource_request: WebResourceRequest,
223 response_sender: GenericSender<WebResourceResponseMsg>,
224 error_sender: ServoErrorSender,
225 ) -> Self {
226 Self {
227 request: web_resource_request,
228 responder: IpcResponder::new(response_sender, WebResourceResponseMsg::DoNotIntercept),
229 error_sender,
230 }
231 }
232
233 pub fn request(&self) -> &WebResourceRequest {
235 &self.request
236 }
237 pub fn intercept(mut self, response: WebResourceResponse) -> InterceptedWebResourceLoad {
240 if let Err(error) = self.responder.send(WebResourceResponseMsg::Start(response)) {
241 self.error_sender.raise_response_send_error(error);
242 }
243 InterceptedWebResourceLoad {
244 request: self.request.clone(),
245 response_sender: self.responder.into_inner(),
246 finished: false,
247 error_sender: self.error_sender,
248 }
249 }
250}
251
252pub struct InterceptedWebResourceLoad {
258 pub request: WebResourceRequest,
259 pub(crate) response_sender: GenericSender<WebResourceResponseMsg>,
260 pub(crate) finished: bool,
261 pub(crate) error_sender: ServoErrorSender,
262}
263
264impl InterceptedWebResourceLoad {
265 pub fn send_body_data(&self, data: Vec<u8>) {
268 if let Err(error) = self
269 .response_sender
270 .send(WebResourceResponseMsg::SendBodyData(data))
271 {
272 self.error_sender.raise_response_send_error(error);
273 }
274 }
275 pub fn finish(mut self) {
277 if let Err(error) = self
278 .response_sender
279 .send(WebResourceResponseMsg::FinishLoad)
280 {
281 self.error_sender.raise_response_send_error(error);
282 }
283 self.finished = true;
284 }
285 pub fn cancel(mut self) {
287 if let Err(error) = self
288 .response_sender
289 .send(WebResourceResponseMsg::CancelLoad)
290 {
291 self.error_sender.raise_response_send_error(error);
292 }
293 self.finished = true;
294 }
295}
296
297impl Drop for InterceptedWebResourceLoad {
298 fn drop(&mut self) {
299 if !self.finished {
300 if let Err(error) = self
301 .response_sender
302 .send(WebResourceResponseMsg::FinishLoad)
303 {
304 self.error_sender.raise_response_send_error(error);
305 }
306 }
307 }
308}
309
310pub enum EmbedderControl {
312 SelectElement(SelectElement),
314 ColorPicker(ColorPicker),
316 FilePicker(FilePicker),
318 InputMethod(InputMethodControl),
321 SimpleDialog(SimpleDialog),
326 ContextMenu(ContextMenu),
330}
331
332impl EmbedderControl {
333 pub fn id(&self) -> EmbedderControlId {
334 match self {
335 EmbedderControl::SelectElement(select_element) => select_element.id,
336 EmbedderControl::ColorPicker(color_picker) => color_picker.id,
337 EmbedderControl::FilePicker(file_picker) => file_picker.id,
338 EmbedderControl::InputMethod(input_method) => input_method.id,
339 EmbedderControl::SimpleDialog(simple_dialog) => simple_dialog.id(),
340 EmbedderControl::ContextMenu(context_menu) => context_menu.id,
341 }
342 }
343}
344
345pub struct ContextMenu {
347 pub(crate) id: EmbedderControlId,
348 pub(crate) position: DeviceIntRect,
349 pub(crate) items: Vec<ContextMenuItem>,
350 pub(crate) element_info: ContextMenuElementInformation,
351 pub(crate) response_sent: bool,
352 pub(crate) constellation_proxy: ConstellationProxy,
353}
354
355impl ContextMenu {
356 pub fn id(&self) -> EmbedderControlId {
358 self.id
359 }
360
361 pub fn position(&self) -> DeviceIntRect {
365 self.position
366 }
367
368 pub fn element_info(&self) -> &ContextMenuElementInformation {
371 &self.element_info
372 }
373
374 pub fn items(&self) -> &[ContextMenuItem] {
376 &self.items
377 }
378
379 pub fn select(mut self, action: ContextMenuAction) {
381 self.constellation_proxy
382 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
383 self.id,
384 EmbedderControlResponse::ContextMenu(Some(action)),
385 ));
386 self.response_sent = true;
387 }
388
389 pub fn dismiss(mut self) {
391 self.constellation_proxy
392 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
393 self.id,
394 EmbedderControlResponse::ContextMenu(None),
395 ));
396 self.response_sent = true;
397 }
398}
399
400impl Drop for ContextMenu {
401 fn drop(&mut self) {
402 if !self.response_sent {
403 self.constellation_proxy
404 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
405 self.id,
406 EmbedderControlResponse::ContextMenu(None),
407 ));
408 }
409 }
410}
411
412pub struct SelectElement {
414 pub(crate) id: EmbedderControlId,
415 pub(crate) options: Vec<SelectElementOptionOrOptgroup>,
416 pub(crate) selected_option: Option<usize>,
417 pub(crate) position: DeviceIntRect,
418 pub(crate) constellation_proxy: ConstellationProxy,
419 pub(crate) response_sent: bool,
420}
421
422impl SelectElement {
423 pub fn id(&self) -> EmbedderControlId {
425 self.id
426 }
427
428 pub fn position(&self) -> DeviceIntRect {
432 self.position
433 }
434
435 pub fn options(&self) -> &[SelectElementOptionOrOptgroup] {
438 &self.options
439 }
440
441 pub fn select(&mut self, id: Option<usize>) {
446 self.selected_option = id;
447 }
448
449 pub fn selected_option(&self) -> Option<usize> {
450 self.selected_option
451 }
452
453 pub fn submit(mut self) {
455 self.response_sent = true;
456 self.constellation_proxy
457 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
458 self.id,
459 EmbedderControlResponse::SelectElement(self.selected_option()),
460 ));
461 }
462}
463
464impl Drop for SelectElement {
465 fn drop(&mut self) {
466 if !self.response_sent {
467 self.constellation_proxy
468 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
469 self.id,
470 EmbedderControlResponse::SelectElement(self.selected_option()),
471 ));
472 }
473 }
474}
475
476pub struct ColorPicker {
478 pub(crate) id: EmbedderControlId,
479 pub(crate) current_color: Option<RgbColor>,
480 pub(crate) position: DeviceIntRect,
481 pub(crate) constellation_proxy: ConstellationProxy,
482 pub(crate) response_sent: bool,
483}
484
485impl ColorPicker {
486 pub fn id(&self) -> EmbedderControlId {
488 self.id
489 }
490
491 pub fn position(&self) -> DeviceIntRect {
495 self.position
496 }
497
498 pub fn current_color(&self) -> Option<RgbColor> {
501 self.current_color
502 }
503
504 pub fn select(&mut self, color: Option<RgbColor>) {
505 self.current_color = color;
506 }
507
508 pub fn submit(mut self) {
510 self.response_sent = true;
511 self.constellation_proxy
512 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
513 self.id,
514 EmbedderControlResponse::ColorPicker(self.current_color),
515 ));
516 }
517}
518
519impl Drop for ColorPicker {
520 fn drop(&mut self) {
521 if !self.response_sent {
522 self.constellation_proxy
523 .send(EmbedderToConstellationMessage::EmbedderControlResponse(
524 self.id,
525 EmbedderControlResponse::ColorPicker(self.current_color),
526 ));
527 }
528 }
529}
530
531pub struct FilePicker {
533 pub(crate) id: EmbedderControlId,
534 pub(crate) file_picker_request: FilePickerRequest,
535 pub(crate) response_sender: GenericSender<Option<Vec<PathBuf>>>,
536 pub(crate) response_sent: bool,
537}
538
539impl FilePicker {
540 pub fn id(&self) -> EmbedderControlId {
542 self.id
543 }
544
545 pub fn filter_patterns(&self) -> &[FilterPattern] {
546 &self.file_picker_request.filter_patterns
547 }
548
549 pub fn allow_select_multiple(&self) -> bool {
550 self.file_picker_request.allow_select_multiple
551 }
552
553 pub fn current_paths(&self) -> &[PathBuf] {
556 &self.file_picker_request.current_paths
557 }
558
559 pub fn select(&mut self, paths: &[PathBuf]) {
560 self.file_picker_request.current_paths = paths.to_owned();
561 }
562
563 pub fn submit(mut self) {
565 let _ = self.response_sender.send(Some(std::mem::take(
566 &mut self.file_picker_request.current_paths,
567 )));
568 self.response_sent = true;
569 }
570
571 pub fn dismiss(mut self) {
573 let _ = self.response_sender.send(None);
574 self.response_sent = true;
575 }
576}
577
578impl Drop for FilePicker {
579 fn drop(&mut self) {
580 if !self.response_sent {
581 let _ = self.response_sender.send(None);
582 }
583 }
584}
585
586pub struct InputMethodControl {
588 pub(crate) id: EmbedderControlId,
589 pub(crate) input_method_type: InputMethodType,
590 pub(crate) text: String,
591 pub(crate) insertion_point: Option<u32>,
592 pub(crate) position: DeviceIntRect,
593 pub(crate) multiline: bool,
594}
595
596impl InputMethodControl {
597 pub fn input_method_type(&self) -> InputMethodType {
599 self.input_method_type
600 }
601
602 pub fn text(&self) -> String {
604 self.text.clone()
605 }
606
607 pub fn insertion_point(&self) -> Option<u32> {
610 self.insertion_point
611 }
612
613 pub fn position(&self) -> DeviceIntRect {
618 self.position
619 }
620
621 pub fn multiline(&self) -> bool {
623 self.multiline
624 }
625}
626
627pub enum SimpleDialog {
631 Alert(AlertDialog),
632 Confirm(ConfirmDialog),
633 Prompt(PromptDialog),
634}
635
636impl SimpleDialog {
637 pub fn message(&self) -> &str {
638 match self {
639 SimpleDialog::Alert(alert_dialog) => alert_dialog.message(),
640 SimpleDialog::Confirm(confirm_dialog) => confirm_dialog.message(),
641 SimpleDialog::Prompt(prompt_dialog) => prompt_dialog.message(),
642 }
643 }
644
645 pub fn confirm(self) {
646 match self {
647 SimpleDialog::Alert(alert_dialog) => alert_dialog.confirm(),
648 SimpleDialog::Confirm(confirm_dialog) => confirm_dialog.confirm(),
649 SimpleDialog::Prompt(prompt_dialog) => prompt_dialog.confirm(),
650 }
651 }
652
653 pub fn dismiss(self) {
654 match self {
655 SimpleDialog::Alert(alert_dialog) => alert_dialog.confirm(),
656 SimpleDialog::Confirm(confirm_dialog) => confirm_dialog.dismiss(),
657 SimpleDialog::Prompt(prompt_dialog) => prompt_dialog.dismiss(),
658 }
659 }
660}
661
662impl SimpleDialog {
663 fn id(&self) -> EmbedderControlId {
664 match self {
665 SimpleDialog::Alert(alert_dialog) => alert_dialog.id,
666 SimpleDialog::Confirm(confirm_dialog) => confirm_dialog.id,
667 SimpleDialog::Prompt(prompt_dialog) => prompt_dialog.id,
668 }
669 }
670}
671
672impl From<SimpleDialogRequest> for SimpleDialog {
673 fn from(simple_dialog_request: SimpleDialogRequest) -> Self {
674 match simple_dialog_request {
675 SimpleDialogRequest::Alert {
676 id,
677 message,
678 response_sender,
679 } => Self::Alert(AlertDialog {
680 id,
681 message,
682 response_sender,
683 response_sent: false,
684 }),
685 SimpleDialogRequest::Confirm {
686 id,
687 message,
688 response_sender,
689 } => Self::Confirm(ConfirmDialog {
690 id,
691 message,
692 response_sender,
693 response_sent: false,
694 }),
695 SimpleDialogRequest::Prompt {
696 id,
697 message,
698 default,
699 response_sender,
700 } => Self::Prompt(PromptDialog {
701 id,
702 message,
703 current_value: default,
704 response_sender,
705 response_sent: false,
706 }),
707 }
708 }
709}
710
711pub struct AlertDialog {
716 id: EmbedderControlId,
717 message: String,
718 response_sender: GenericSender<AlertResponse>,
719 response_sent: bool,
720}
721
722impl Drop for AlertDialog {
723 fn drop(&mut self) {
724 if !self.response_sent {
725 let _ = self.response_sender.send(AlertResponse::Ok);
726 }
727 }
728}
729
730impl AlertDialog {
731 pub fn message(&self) -> &str {
732 &self.message
733 }
734
735 pub fn confirm(self) {
737 }
739}
740
741pub struct ConfirmDialog {
747 id: EmbedderControlId,
748 message: String,
749 response_sender: GenericSender<ConfirmResponse>,
750 response_sent: bool,
751}
752
753impl ConfirmDialog {
754 pub fn message(&self) -> &str {
755 &self.message
756 }
757
758 pub fn dismiss(mut self) {
760 let _ = self.response_sender.send(ConfirmResponse::Cancel);
761 self.response_sent = true;
762 }
763
764 pub fn confirm(mut self) {
766 let _ = self.response_sender.send(ConfirmResponse::Ok);
767 self.response_sent = true;
768 }
769}
770
771impl Drop for ConfirmDialog {
772 fn drop(&mut self) {
773 if !self.response_sent {
774 let _ = self.response_sender.send(ConfirmResponse::Cancel);
775 }
776 }
777}
778
779pub struct PromptDialog {
788 id: EmbedderControlId,
789 message: String,
790 current_value: String,
791 response_sender: GenericSender<PromptResponse>,
792 response_sent: bool,
793}
794
795impl Drop for PromptDialog {
796 fn drop(&mut self) {
797 if !self.response_sent {
798 let _ = self.response_sender.send(PromptResponse::Cancel);
799 }
800 }
801}
802
803impl PromptDialog {
804 pub fn message(&self) -> &str {
805 &self.message
806 }
807
808 pub fn current_value(&self) -> &str {
809 &self.current_value
810 }
811
812 pub fn set_current_value(&mut self, new_value: &str) {
813 self.current_value = new_value.to_owned()
814 }
815
816 pub fn dismiss(mut self) {
818 let _ = self.response_sender.send(PromptResponse::Cancel);
819 self.response_sent = true;
820 }
821
822 pub fn confirm(mut self) {
825 let _ = self
826 .response_sender
827 .send(PromptResponse::Ok(self.current_value.clone()));
828 self.response_sent = true;
829 }
830}
831
832pub trait WebViewDelegate {
833 fn screen_geometry(&self, _webview: WebView) -> Option<ScreenGeometry> {
837 None
838 }
839 fn notify_url_changed(&self, _webview: WebView, _url: Url) {}
842 fn notify_page_title_changed(&self, _webview: WebView, _title: Option<String>) {}
845 fn notify_status_text_changed(&self, _webview: WebView, _status: Option<String>) {}
848 fn notify_focus_changed(&self, _webview: WebView, _focused: bool) {}
851 fn notify_animating_changed(&self, _webview: WebView, _animating: bool) {}
856 fn notify_load_status_changed(&self, _webview: WebView, _status: LoadStatus) {}
859 fn notify_cursor_changed(&self, _webview: WebView, _: Cursor) {}
862 fn notify_favicon_changed(&self, _webview: WebView) {}
865 fn notify_new_frame_ready(&self, _webview: WebView) {}
867 fn notify_history_changed(&self, _webview: WebView, _entries: Vec<Url>, _current: usize) {}
871 fn notify_traversal_complete(&self, _webview: WebView, _: TraversalId) {}
873 fn notify_closed(&self, _webview: WebView) {}
877
878 fn notify_input_event_handled(&self, _webview: WebView, _: InputEventId, _: InputEventResult) {}
882 fn notify_crashed(&self, _webview: WebView, _reason: String, _backtrace: Option<String>) {}
884 fn notify_media_session_event(&self, _webview: WebView, _event: MediaSessionEvent) {}
887 fn notify_fullscreen_state_changed(&self, _webview: WebView, _: bool) {}
893
894 fn request_navigation(&self, _webview: WebView, _navigation_request: NavigationRequest) {}
897 fn request_unload(&self, _webview: WebView, _unload_request: AllowOrDenyRequest) {}
900 fn request_move_to(&self, _webview: WebView, _: DeviceIntPoint) {}
902 fn request_protocol_handler(
908 &self,
909 _webview: WebView,
910 _protocol_handler_registration: ProtocolHandlerRegistration,
911 _allow_deny_request: AllowOrDenyRequest,
912 ) {
913 }
914 fn request_resize_to(&self, _webview: WebView, _requested_outer_size: DeviceIntSize) {}
920 fn request_open_auxiliary_webview(&self, _parent_webview: WebView) -> Option<WebView> {
923 None
924 }
925
926 fn request_permission(&self, _webview: WebView, _: PermissionRequest) {}
930
931 fn request_authentication(
932 &self,
933 _webview: WebView,
934 _authentication_request: AuthenticationRequest,
935 ) {
936 }
937
938 fn show_bluetooth_device_dialog(
941 &self,
942 _webview: WebView,
943 _: Vec<String>,
944 response_sender: GenericSender<Option<String>>,
945 ) {
946 let _ = response_sender.send(None);
947 }
948
949 fn show_embedder_control(&self, _webview: WebView, _embedder_control: EmbedderControl) {}
952
953 fn hide_embedder_control(&self, _webview: WebView, _control_id: EmbedderControlId) {}
958
959 fn play_gamepad_haptic_effect(
961 &self,
962 _webview: WebView,
963 _: usize,
964 _: GamepadHapticEffectType,
965 _: IpcSender<bool>,
966 ) {
967 }
968 fn stop_gamepad_haptic_effect(&self, _webview: WebView, _: usize, _: IpcSender<bool>) {}
970
971 fn load_web_resource(&self, _webview: WebView, _load: WebResourceLoad) {}
979
980 fn show_notification(&self, _webview: WebView, _notification: Notification) {}
982}
983
984pub(crate) struct DefaultWebViewDelegate;
985impl WebViewDelegate for DefaultWebViewDelegate {}
986
987#[cfg(test)]
988mod test {
989 use super::*;
990
991 #[test]
992 fn test_allow_deny_request() {
993 use base::generic_channel;
994
995 use crate::responders::ServoErrorChannel;
996
997 for default_response in [AllowOrDeny::Allow, AllowOrDeny::Deny] {
998 let errors = ServoErrorChannel::default();
1000 let (sender, receiver) =
1001 generic_channel::channel().expect("Failed to create IPC channel");
1002 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1003 request.allow();
1004 assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Allow));
1005 assert_eq!(receiver.try_recv().ok(), None);
1006 assert!(errors.try_recv().is_none());
1007
1008 let errors = ServoErrorChannel::default();
1010 let (sender, receiver) =
1011 generic_channel::channel().expect("Failed to create IPC channel");
1012 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1013 request.deny();
1014 assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Deny));
1015 assert_eq!(receiver.try_recv().ok(), None);
1016 assert!(errors.try_recv().is_none());
1017
1018 let errors = ServoErrorChannel::default();
1020 let (sender, receiver) =
1021 generic_channel::channel().expect("Failed to create IPC channel");
1022 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1023 drop(request);
1024 assert_eq!(receiver.try_recv().ok(), Some(default_response));
1025 assert_eq!(receiver.try_recv().ok(), None);
1026 assert!(errors.try_recv().is_none());
1027
1028 let errors = ServoErrorChannel::default();
1030 let (sender, receiver) =
1031 generic_channel::channel().expect("Failed to create IPC channel");
1032 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1033 drop(receiver);
1034 request.allow();
1035 assert!(errors.try_recv().is_some());
1036
1037 let errors = ServoErrorChannel::default();
1039 let (sender, receiver) =
1040 generic_channel::channel().expect("Failed to create IPC channel");
1041 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1042 drop(receiver);
1043 request.deny();
1044 assert!(errors.try_recv().is_some());
1045
1046 let errors = ServoErrorChannel::default();
1048 let (sender, receiver) =
1049 generic_channel::channel().expect("Failed to create IPC channel");
1050 let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
1051 drop(receiver);
1052 drop(request);
1053 assert!(errors.try_recv().is_none());
1054 }
1055 }
1056
1057 #[test]
1058 fn test_authentication_request() {
1059 use base::generic_channel;
1060
1061 use crate::responders::ServoErrorChannel;
1062
1063 let url = Url::parse("https://example.com").expect("Guaranteed by argument");
1064
1065 let errors = ServoErrorChannel::default();
1067 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1068 let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
1069 request.authenticate("diffie".to_owned(), "hunter2".to_owned());
1070 assert_eq!(
1071 receiver.try_recv().ok(),
1072 Some(Some(AuthenticationResponse {
1073 username: "diffie".to_owned(),
1074 password: "hunter2".to_owned(),
1075 }))
1076 );
1077 assert_eq!(receiver.try_recv().ok(), None);
1078 assert!(errors.try_recv().is_none());
1079
1080 let errors = ServoErrorChannel::default();
1082 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1083 let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
1084 drop(request);
1085 assert_eq!(receiver.try_recv().ok(), Some(None));
1086 assert_eq!(receiver.try_recv().ok(), None);
1087 assert!(errors.try_recv().is_none());
1088
1089 let errors = ServoErrorChannel::default();
1091 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1092 let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
1093 drop(receiver);
1094 request.authenticate("diffie".to_owned(), "hunter2".to_owned());
1095 assert!(errors.try_recv().is_some());
1096
1097 let errors = ServoErrorChannel::default();
1099 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1100 let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
1101 drop(receiver);
1102 drop(request);
1103 assert!(errors.try_recv().is_none());
1104 }
1105
1106 #[test]
1107 fn test_web_resource_load() {
1108 use base::generic_channel;
1109 use http::{HeaderMap, Method, StatusCode};
1110
1111 use crate::responders::ServoErrorChannel;
1112
1113 let web_resource_request = || WebResourceRequest {
1114 method: Method::GET,
1115 headers: HeaderMap::default(),
1116 url: Url::parse("https://example.com").expect("Guaranteed by argument"),
1117 is_for_main_frame: false,
1118 is_redirect: false,
1119 };
1120 let web_resource_response = || {
1121 WebResourceResponse::new(
1122 Url::parse("https://diffie.test").expect("Guaranteed by argument"),
1123 )
1124 .status_code(StatusCode::IM_A_TEAPOT)
1125 };
1126
1127 let errors = ServoErrorChannel::default();
1129 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1130 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1131 request.intercept(web_resource_response()).cancel();
1132 assert!(matches!(
1133 receiver.try_recv(),
1134 Ok(WebResourceResponseMsg::Start(_))
1135 ));
1136 assert!(matches!(
1137 receiver.try_recv(),
1138 Ok(WebResourceResponseMsg::CancelLoad)
1139 ));
1140 assert!(matches!(receiver.try_recv(), Err(_)));
1141 assert!(errors.try_recv().is_none());
1142
1143 let errors = ServoErrorChannel::default();
1145 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1146 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1147 drop(request.intercept(web_resource_response()));
1148 assert!(matches!(
1149 receiver.try_recv(),
1150 Ok(WebResourceResponseMsg::Start(_))
1151 ));
1152 assert!(matches!(
1153 receiver.try_recv(),
1154 Ok(WebResourceResponseMsg::FinishLoad)
1155 ));
1156 assert!(matches!(receiver.try_recv(), Err(_)));
1157 assert!(errors.try_recv().is_none());
1158
1159 let errors = ServoErrorChannel::default();
1161 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1162 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1163 drop(request);
1164 assert!(matches!(
1165 receiver.try_recv(),
1166 Ok(WebResourceResponseMsg::DoNotIntercept)
1167 ));
1168 assert!(matches!(receiver.try_recv(), Err(_)));
1169 assert!(errors.try_recv().is_none());
1170
1171 let errors = ServoErrorChannel::default();
1173 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1174 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1175 drop(receiver);
1176 request.intercept(web_resource_response()).cancel();
1177 assert!(errors.try_recv().is_some());
1178
1179 let errors = ServoErrorChannel::default();
1181 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1182 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1183 drop(receiver);
1184 drop(request.intercept(web_resource_response()));
1185 assert!(errors.try_recv().is_some());
1186
1187 let errors = ServoErrorChannel::default();
1189 let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
1190 let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
1191 drop(receiver);
1192 drop(request);
1193 assert!(errors.try_recv().is_none());
1194 }
1195}