1use std::rc::Rc;
6use std::str::FromStr;
7
8use cssparser::match_ignore_ascii_case;
9use dom_struct::dom_struct;
10use http::Method as HttpMethod;
11use http::header::{HeaderName, HeaderValue};
12use http::method::InvalidMethod;
13use js::rust::HandleObject;
14use net_traits::ReferrerPolicy as MsgReferrerPolicy;
15use net_traits::fetch::headers::is_forbidden_method;
16use net_traits::request::{
17 CacheMode as NetTraitsRequestCache, CredentialsMode as NetTraitsRequestCredentials,
18 Destination as NetTraitsRequestDestination, Origin, RedirectMode as NetTraitsRequestRedirect,
19 Referrer as NetTraitsRequestReferrer, Request as NetTraitsRequest, RequestBuilder,
20 RequestMode as NetTraitsRequestMode, Window,
21};
22use servo_url::ServoUrl;
23
24use crate::body::{BodyMixin, BodyType, Extractable, consume_body};
25use crate::conversions::Convert;
26use crate::dom::abortsignal::AbortSignal;
27use crate::dom::bindings::cell::DomRefCell;
28use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
29use crate::dom::bindings::codegen::Bindings::RequestBinding::{
30 ReferrerPolicy, RequestCache, RequestCredentials, RequestDestination, RequestInfo, RequestInit,
31 RequestMethods, RequestMode, RequestRedirect,
32};
33use crate::dom::bindings::error::{Error, Fallible};
34use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
35use crate::dom::bindings::root::{DomRoot, MutNullableDom};
36use crate::dom::bindings::str::{ByteString, DOMString, USVString};
37use crate::dom::bindings::trace::RootedTraceableBox;
38use crate::dom::globalscope::GlobalScope;
39use crate::dom::headers::{Guard, Headers};
40use crate::dom::promise::Promise;
41use crate::dom::readablestream::ReadableStream;
42use crate::script_runtime::CanGc;
43
44#[dom_struct]
45pub(crate) struct Request {
46 reflector_: Reflector,
47 #[no_trace]
48 request: DomRefCell<NetTraitsRequest>,
50 body_stream: MutNullableDom<ReadableStream>,
52 headers: MutNullableDom<Headers>,
54 signal: MutNullableDom<AbortSignal>,
56}
57
58impl Request {
59 fn new_inherited(global: &GlobalScope, url: ServoUrl) -> Request {
60 Request {
61 reflector_: Reflector::new(),
62 request: DomRefCell::new(net_request_from_global(global, url)),
63 body_stream: MutNullableDom::new(None),
64 headers: Default::default(),
65 signal: MutNullableDom::new(None),
66 }
67 }
68
69 fn new(
70 global: &GlobalScope,
71 proto: Option<HandleObject>,
72 url: ServoUrl,
73 can_gc: CanGc,
74 ) -> DomRoot<Request> {
75 reflect_dom_object_with_proto(
76 Box::new(Request::new_inherited(global, url)),
77 global,
78 proto,
79 can_gc,
80 )
81 }
82
83 fn from_net_request(
84 global: &GlobalScope,
85 proto: Option<HandleObject>,
86 net_request: NetTraitsRequest,
87 can_gc: CanGc,
88 ) -> DomRoot<Request> {
89 let r = Request::new(global, proto, net_request.current_url(), can_gc);
90 *r.request.borrow_mut() = net_request;
91 r
92 }
93
94 fn clone_from(r: &Request, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
96 let req = r.request.borrow();
98 let url = req.url();
99 let headers_guard = r.Headers(can_gc).get_guard();
100 let r_clone = Request::new(&r.global(), None, url, can_gc);
101 r_clone.request.borrow_mut().pipeline_id = req.pipeline_id;
102 {
103 let mut borrowed_r_request = r_clone.request.borrow_mut();
104 borrowed_r_request.origin = req.origin.clone();
105 }
106 *r_clone.request.borrow_mut() = req.clone();
107 r_clone
108 .Headers(can_gc)
109 .copy_from_headers(r.Headers(can_gc))?;
110 r_clone.Headers(can_gc).set_guard(headers_guard);
111 Ok(r_clone)
115 }
116
117 pub(crate) fn get_request(&self) -> NetTraitsRequest {
118 self.request.borrow().clone()
119 }
120}
121
122fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest {
123 RequestBuilder::new(global.webview_id(), url, global.get_referrer())
124 .origin(global.get_url().origin())
125 .pipeline_id(Some(global.pipeline_id()))
126 .https_state(global.get_https_state())
127 .insecure_requests_policy(global.insecure_requests_policy())
128 .has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
129 .build()
130}
131
132fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
134 match_ignore_ascii_case! { m,
135 "delete" => return Ok(HttpMethod::DELETE),
136 "get" => return Ok(HttpMethod::GET),
137 "head" => return Ok(HttpMethod::HEAD),
138 "options" => return Ok(HttpMethod::OPTIONS),
139 "post" => return Ok(HttpMethod::POST),
140 "put" => return Ok(HttpMethod::PUT),
141 _ => (),
142 }
143 debug!("Method: {:?}", m);
144 HttpMethod::from_str(m)
145}
146
147fn is_method(m: &ByteString) -> bool {
149 m.as_str().is_some()
150}
151
152fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
154 m == HttpMethod::GET || m == HttpMethod::HEAD || m == HttpMethod::POST
155}
156
157fn includes_credentials(input: &ServoUrl) -> bool {
159 !input.username().is_empty() || input.password().is_some()
160}
161
162fn request_is_disturbed(input: &Request) -> bool {
164 input.is_disturbed()
165}
166
167fn request_is_locked(input: &Request) -> bool {
169 input.is_locked()
170}
171
172impl RequestMethods<crate::DomTypeHolder> for Request {
173 fn Constructor(
175 global: &GlobalScope,
176 proto: Option<HandleObject>,
177 can_gc: CanGc,
178 mut input: RequestInfo,
179 init: RootedTraceableBox<RequestInit>,
180 ) -> Fallible<DomRoot<Request>> {
181 let temporary_request: NetTraitsRequest;
183
184 let mut fallback_mode: Option<NetTraitsRequestMode> = None;
186
187 let base_url = global.api_base_url();
189
190 let mut signal: Option<DomRoot<AbortSignal>> = None;
192
193 match input {
194 RequestInfo::USVString(USVString(ref usv_string)) => {
196 let parsed_url = base_url.join(usv_string);
198 if parsed_url.is_err() {
200 return Err(Error::Type("Url could not be parsed".to_string()));
201 }
202 let url = parsed_url.unwrap();
204 if includes_credentials(&url) {
205 return Err(Error::Type("Url includes credentials".to_string()));
206 }
207 temporary_request = net_request_from_global(global, url);
209 fallback_mode = Some(NetTraitsRequestMode::CorsMode);
211 },
212 RequestInfo::Request(ref input_request) => {
215 if request_is_disturbed(input_request) || request_is_locked(input_request) {
218 return Err(Error::Type("Input is disturbed or locked".to_string()));
219 }
220 temporary_request = input_request.request.borrow().clone();
222 signal = Some(input_request.Signal());
224 },
225 }
226
227 let origin = base_url.origin();
230
231 let mut window = Window::Client;
233
234 if !init.window.handle().is_null_or_undefined() {
241 return Err(Error::Type("Window is present and is not null".to_string()));
242 }
243
244 if !init.window.handle().is_undefined() {
246 window = Window::NoWindow;
247 }
248
249 let mut request: NetTraitsRequest;
251 request = net_request_from_global(global, temporary_request.current_url());
252 request.method = temporary_request.method;
253 request.headers = temporary_request.headers.clone();
254 request.unsafe_request = true;
255 request.window = window;
256 request.origin = Origin::Client;
258 request.referrer = temporary_request.referrer;
259 request.referrer_policy = temporary_request.referrer_policy;
260 request.mode = temporary_request.mode;
261 request.credentials_mode = temporary_request.credentials_mode;
262 request.cache_mode = temporary_request.cache_mode;
263 request.redirect_mode = temporary_request.redirect_mode;
264 request.integrity_metadata = temporary_request.integrity_metadata;
265
266 if init.body.is_some() ||
268 init.cache.is_some() ||
269 init.credentials.is_some() ||
270 init.integrity.is_some() ||
271 init.headers.is_some() ||
272 init.method.is_some() ||
273 init.mode.is_some() ||
274 init.redirect.is_some() ||
275 init.referrer.is_some() ||
276 init.referrerPolicy.is_some() ||
277 !init.window.handle().is_undefined()
278 {
279 if request.mode == NetTraitsRequestMode::Navigate {
281 request.mode = NetTraitsRequestMode::SameOrigin;
282 }
283 request.referrer = global.get_referrer();
291 request.referrer_policy = MsgReferrerPolicy::EmptyString;
293 }
298
299 if let Some(init_referrer) = init.referrer.as_ref() {
301 let referrer = &init_referrer.0;
303 if referrer.is_empty() {
305 request.referrer = NetTraitsRequestReferrer::NoReferrer;
306 } else {
308 let parsed_referrer = base_url.join(referrer);
310 if parsed_referrer.is_err() {
312 return Err(Error::Type("Failed to parse referrer url".to_string()));
313 }
314 if let Ok(parsed_referrer) = parsed_referrer {
318 if (parsed_referrer.cannot_be_a_base() &&
319 parsed_referrer.scheme() == "about" &&
320 parsed_referrer.path() == "client") ||
321 parsed_referrer.origin() != origin
322 {
323 request.referrer = global.get_referrer();
325 } else {
326 request.referrer = NetTraitsRequestReferrer::ReferrerUrl(parsed_referrer);
328 }
329 }
330 }
331 }
332
333 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() {
335 let init_referrer_policy = (*init_referrerpolicy).convert();
336 request.referrer_policy = init_referrer_policy;
337 }
338
339 let mode = init.mode.as_ref().map(|m| (*m).convert()).or(fallback_mode);
341
342 if let Some(NetTraitsRequestMode::Navigate) = mode {
344 return Err(Error::Type("Request mode is Navigate".to_string()));
345 }
346
347 if let Some(m) = mode {
349 request.mode = m;
350 }
351
352 if let Some(init_credentials) = init.credentials.as_ref() {
354 let credentials = (*init_credentials).convert();
355 request.credentials_mode = credentials;
356 }
357
358 if let Some(init_cache) = init.cache.as_ref() {
360 let cache = (*init_cache).convert();
361 request.cache_mode = cache;
362 }
363
364 if request.cache_mode == NetTraitsRequestCache::OnlyIfCached &&
367 request.mode != NetTraitsRequestMode::SameOrigin
368 {
369 return Err(Error::Type(
370 "Cache is 'only-if-cached' and mode is not 'same-origin'".to_string(),
371 ));
372 }
373
374 if let Some(init_redirect) = init.redirect.as_ref() {
376 let redirect = (*init_redirect).convert();
377 request.redirect_mode = redirect;
378 }
379
380 if let Some(init_integrity) = init.integrity.as_ref() {
382 let integrity = init_integrity.clone().to_string();
383 request.integrity_metadata = integrity;
384 }
385
386 if let Some(init_method) = init.method.as_ref() {
392 if !is_method(init_method) {
394 return Err(Error::Type("Method is not a method".to_string()));
395 }
396 if is_forbidden_method(init_method) {
397 return Err(Error::Type("Method is forbidden".to_string()));
398 }
399 let method = match init_method.as_str() {
401 Some(s) => normalize_method(s)
402 .map_err(|e| Error::Type(format!("Method is not valid: {:?}", e)))?,
403 None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
404 };
405 request.method = method;
407 }
408
409 if let Some(init_signal) = init.signal.as_ref() {
411 signal = init_signal.clone();
412 }
413 let r = Request::from_net_request(global, proto, request, can_gc);
423
424 let signals = signal.map_or(vec![], |s| vec![s]);
426 r.signal
429 .set(Some(&AbortSignal::create_dependent_abort_signal(
430 signals, global, can_gc,
431 )));
432
433 r.headers
439 .or_init(|| Headers::for_request(&r.global(), can_gc));
440
441 let headers_copy = init
445 .headers
446 .as_ref()
447 .map(|possible_header| match possible_header {
448 HeadersInit::ByteStringSequenceSequence(init_sequence) => {
449 HeadersInit::ByteStringSequenceSequence(init_sequence.clone())
450 },
451 HeadersInit::ByteStringByteStringRecord(init_map) => {
452 HeadersInit::ByteStringByteStringRecord(init_map.clone())
453 },
454 });
455
456 if r.request.borrow().mode == NetTraitsRequestMode::NoCors {
467 let borrowed_request = r.request.borrow();
468 if !is_cors_safelisted_method(&borrowed_request.method) {
470 return Err(Error::Type(
471 "The mode is 'no-cors' but the method is not a cors-safelisted method"
472 .to_string(),
473 ));
474 }
475 r.Headers(can_gc).set_guard(Guard::RequestNoCors);
477 }
478
479 match headers_copy {
480 None => {
481 if let RequestInfo::Request(ref input_request) = input {
488 r.Headers(can_gc)
489 .copy_from_headers(input_request.Headers(can_gc))?;
490 }
491 },
492 Some(headers_copy) => r.Headers(can_gc).fill(Some(headers_copy))?,
494 }
495
496 r.request.borrow_mut().headers = r.Headers(can_gc).get_headers_list();
499
500 let mut input_body = if let RequestInfo::Request(ref mut input_request) = input {
502 let mut input_request_request = input_request.request.borrow_mut();
503 input_request_request.body.take()
504 } else {
505 None
506 };
507
508 if let Some(init_body_option) = init.body.as_ref() {
511 if init_body_option.is_some() || input_body.is_some() {
512 let req = r.request.borrow();
513 let req_method = &req.method;
514 match *req_method {
515 HttpMethod::GET => {
516 return Err(Error::Type(
517 "Init's body is non-null, and request method is GET".to_string(),
518 ));
519 },
520 HttpMethod::HEAD => {
521 return Err(Error::Type(
522 "Init's body is non-null, and request method is HEAD".to_string(),
523 ));
524 },
525 _ => {},
526 }
527 }
528 }
529
530 if let Some(Some(ref init_body)) = init.body {
533 let mut extracted_body = init_body.extract(global, can_gc)?;
538
539 if let Some(contents) = extracted_body.content_type.take() {
541 let ct_header_name = b"Content-Type";
542 if !r
545 .Headers(can_gc)
546 .Has(ByteString::new(ct_header_name.to_vec()))
547 .unwrap()
548 {
549 let ct_header_val = contents.as_bytes();
550 r.Headers(can_gc).Append(
551 ByteString::new(ct_header_name.to_vec()),
552 ByteString::new(ct_header_val.to_vec()),
553 )?;
554
555 if let Ok(v) = HeaderValue::from_bytes(ct_header_val) {
559 r.request
560 .borrow_mut()
561 .headers
562 .insert(HeaderName::from_bytes(ct_header_name).unwrap(), v);
563 }
564 }
565 }
566
567 let (net_body, stream) = extracted_body.into_net_request_body();
568 r.body_stream.set(Some(&*stream));
569 input_body = Some(net_body);
570 }
571
572 r.request.borrow_mut().body = input_body;
592
593 Ok(r)
594 }
595
596 fn Method(&self) -> ByteString {
598 let r = self.request.borrow();
599 ByteString::new(r.method.as_ref().as_bytes().into())
600 }
601
602 fn Url(&self) -> USVString {
604 let r = self.request.borrow();
605 USVString(r.url_list.first().map_or("", |u| u.as_str()).into())
606 }
607
608 fn Headers(&self, can_gc: CanGc) -> DomRoot<Headers> {
610 self.headers
611 .or_init(|| Headers::new(&self.global(), can_gc))
612 }
613
614 fn Destination(&self) -> RequestDestination {
616 self.request.borrow().destination.convert()
617 }
618
619 fn Referrer(&self) -> USVString {
621 let r = self.request.borrow();
622 USVString(match r.referrer {
623 NetTraitsRequestReferrer::NoReferrer => String::from(""),
624 NetTraitsRequestReferrer::Client(_) => String::from("about:client"),
625 NetTraitsRequestReferrer::ReferrerUrl(ref u) => {
626 let u_c = u.clone();
627 u_c.into_string()
628 },
629 })
630 }
631
632 fn ReferrerPolicy(&self) -> ReferrerPolicy {
634 self.request.borrow().referrer_policy.convert()
635 }
636
637 fn Mode(&self) -> RequestMode {
639 self.request.borrow().mode.clone().convert()
640 }
641
642 fn Credentials(&self) -> RequestCredentials {
644 let r = self.request.borrow().clone();
645 r.credentials_mode.convert()
646 }
647
648 fn Cache(&self) -> RequestCache {
650 let r = self.request.borrow().clone();
651 r.cache_mode.convert()
652 }
653
654 fn Redirect(&self) -> RequestRedirect {
656 let r = self.request.borrow().clone();
657 r.redirect_mode.convert()
658 }
659
660 fn Integrity(&self) -> DOMString {
662 let r = self.request.borrow();
663 DOMString::from_string(r.integrity_metadata.clone())
664 }
665
666 fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
668 self.body()
669 }
670
671 fn BodyUsed(&self) -> bool {
673 self.is_disturbed()
674 }
675
676 fn Signal(&self) -> DomRoot<AbortSignal> {
678 self.signal
679 .get()
680 .expect("Should always be initialized in constructor and clone")
681 }
682
683 fn Clone(&self, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
685 if request_is_locked(self) {
687 return Err(Error::Type("Request is locked".to_string()));
688 }
689 if request_is_disturbed(self) {
690 return Err(Error::Type("Request is disturbed".to_string()));
691 }
692
693 let cloned_request = Request::clone_from(self, can_gc)?;
695 let signal = self.signal.get().expect("Should always be initialized");
697 let cloned_signal =
700 AbortSignal::create_dependent_abort_signal(vec![signal], &self.global(), can_gc);
701 cloned_request.signal.set(Some(&cloned_signal));
706 Ok(cloned_request)
708 }
709
710 fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
712 consume_body(self, BodyType::Text, can_gc)
713 }
714
715 fn Blob(&self, can_gc: CanGc) -> Rc<Promise> {
717 consume_body(self, BodyType::Blob, can_gc)
718 }
719
720 fn FormData(&self, can_gc: CanGc) -> Rc<Promise> {
722 consume_body(self, BodyType::FormData, can_gc)
723 }
724
725 fn Json(&self, can_gc: CanGc) -> Rc<Promise> {
727 consume_body(self, BodyType::Json, can_gc)
728 }
729
730 fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
732 consume_body(self, BodyType::ArrayBuffer, can_gc)
733 }
734
735 fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
737 consume_body(self, BodyType::Bytes, can_gc)
738 }
739}
740
741impl BodyMixin for Request {
742 fn is_disturbed(&self) -> bool {
743 let body_stream = self.body_stream.get();
744 body_stream
745 .as_ref()
746 .is_some_and(|stream| stream.is_disturbed())
747 }
748
749 fn is_locked(&self) -> bool {
750 let body_stream = self.body_stream.get();
751 body_stream.is_some_and(|stream| stream.is_locked())
752 }
753
754 fn body(&self) -> Option<DomRoot<ReadableStream>> {
755 self.body_stream.get()
756 }
757
758 fn get_mime_type(&self, can_gc: CanGc) -> Vec<u8> {
759 let headers = self.Headers(can_gc);
760 headers.extract_mime_type()
761 }
762}
763
764impl Convert<NetTraitsRequestCache> for RequestCache {
765 fn convert(self) -> NetTraitsRequestCache {
766 match self {
767 RequestCache::Default => NetTraitsRequestCache::Default,
768 RequestCache::No_store => NetTraitsRequestCache::NoStore,
769 RequestCache::Reload => NetTraitsRequestCache::Reload,
770 RequestCache::No_cache => NetTraitsRequestCache::NoCache,
771 RequestCache::Force_cache => NetTraitsRequestCache::ForceCache,
772 RequestCache::Only_if_cached => NetTraitsRequestCache::OnlyIfCached,
773 }
774 }
775}
776
777impl Convert<RequestCache> for NetTraitsRequestCache {
778 fn convert(self) -> RequestCache {
779 match self {
780 NetTraitsRequestCache::Default => RequestCache::Default,
781 NetTraitsRequestCache::NoStore => RequestCache::No_store,
782 NetTraitsRequestCache::Reload => RequestCache::Reload,
783 NetTraitsRequestCache::NoCache => RequestCache::No_cache,
784 NetTraitsRequestCache::ForceCache => RequestCache::Force_cache,
785 NetTraitsRequestCache::OnlyIfCached => RequestCache::Only_if_cached,
786 }
787 }
788}
789
790impl Convert<NetTraitsRequestCredentials> for RequestCredentials {
791 fn convert(self) -> NetTraitsRequestCredentials {
792 match self {
793 RequestCredentials::Omit => NetTraitsRequestCredentials::Omit,
794 RequestCredentials::Same_origin => NetTraitsRequestCredentials::CredentialsSameOrigin,
795 RequestCredentials::Include => NetTraitsRequestCredentials::Include,
796 }
797 }
798}
799
800impl Convert<RequestCredentials> for NetTraitsRequestCredentials {
801 fn convert(self) -> RequestCredentials {
802 match self {
803 NetTraitsRequestCredentials::Omit => RequestCredentials::Omit,
804 NetTraitsRequestCredentials::CredentialsSameOrigin => RequestCredentials::Same_origin,
805 NetTraitsRequestCredentials::Include => RequestCredentials::Include,
806 }
807 }
808}
809
810impl Convert<NetTraitsRequestDestination> for RequestDestination {
811 fn convert(self) -> NetTraitsRequestDestination {
812 match self {
813 RequestDestination::_empty => NetTraitsRequestDestination::None,
814 RequestDestination::Audio => NetTraitsRequestDestination::Audio,
815 RequestDestination::Document => NetTraitsRequestDestination::Document,
816 RequestDestination::Embed => NetTraitsRequestDestination::Embed,
817 RequestDestination::Font => NetTraitsRequestDestination::Font,
818 RequestDestination::Frame => NetTraitsRequestDestination::Frame,
819 RequestDestination::Iframe => NetTraitsRequestDestination::IFrame,
820 RequestDestination::Image => NetTraitsRequestDestination::Image,
821 RequestDestination::Manifest => NetTraitsRequestDestination::Manifest,
822 RequestDestination::Json => NetTraitsRequestDestination::Json,
823 RequestDestination::Object => NetTraitsRequestDestination::Object,
824 RequestDestination::Report => NetTraitsRequestDestination::Report,
825 RequestDestination::Script => NetTraitsRequestDestination::Script,
826 RequestDestination::Sharedworker => NetTraitsRequestDestination::SharedWorker,
827 RequestDestination::Style => NetTraitsRequestDestination::Style,
828 RequestDestination::Track => NetTraitsRequestDestination::Track,
829 RequestDestination::Video => NetTraitsRequestDestination::Video,
830 RequestDestination::Worker => NetTraitsRequestDestination::Worker,
831 RequestDestination::Xslt => NetTraitsRequestDestination::Xslt,
832 }
833 }
834}
835
836impl Convert<RequestDestination> for NetTraitsRequestDestination {
837 fn convert(self) -> RequestDestination {
838 match self {
839 NetTraitsRequestDestination::None => RequestDestination::_empty,
840 NetTraitsRequestDestination::Audio => RequestDestination::Audio,
841 NetTraitsRequestDestination::Document => RequestDestination::Document,
842 NetTraitsRequestDestination::Embed => RequestDestination::Embed,
843 NetTraitsRequestDestination::Font => RequestDestination::Font,
844 NetTraitsRequestDestination::Frame => RequestDestination::Frame,
845 NetTraitsRequestDestination::IFrame => RequestDestination::Iframe,
846 NetTraitsRequestDestination::Image => RequestDestination::Image,
847 NetTraitsRequestDestination::Manifest => RequestDestination::Manifest,
848 NetTraitsRequestDestination::Json => RequestDestination::Json,
849 NetTraitsRequestDestination::Object => RequestDestination::Object,
850 NetTraitsRequestDestination::Report => RequestDestination::Report,
851 NetTraitsRequestDestination::Script => RequestDestination::Script,
852 NetTraitsRequestDestination::ServiceWorker |
853 NetTraitsRequestDestination::AudioWorklet |
854 NetTraitsRequestDestination::PaintWorklet => {
855 panic!("ServiceWorker request destination should not be exposed to DOM")
856 },
857 NetTraitsRequestDestination::SharedWorker => RequestDestination::Sharedworker,
858 NetTraitsRequestDestination::Style => RequestDestination::Style,
859 NetTraitsRequestDestination::Track => RequestDestination::Track,
860 NetTraitsRequestDestination::Video => RequestDestination::Video,
861 NetTraitsRequestDestination::Worker => RequestDestination::Worker,
862 NetTraitsRequestDestination::Xslt => RequestDestination::Xslt,
863 NetTraitsRequestDestination::WebIdentity => RequestDestination::_empty,
864 }
865 }
866}
867
868impl Convert<NetTraitsRequestMode> for RequestMode {
869 fn convert(self) -> NetTraitsRequestMode {
870 match self {
871 RequestMode::Navigate => NetTraitsRequestMode::Navigate,
872 RequestMode::Same_origin => NetTraitsRequestMode::SameOrigin,
873 RequestMode::No_cors => NetTraitsRequestMode::NoCors,
874 RequestMode::Cors => NetTraitsRequestMode::CorsMode,
875 }
876 }
877}
878
879impl Convert<RequestMode> for NetTraitsRequestMode {
880 fn convert(self) -> RequestMode {
881 match self {
882 NetTraitsRequestMode::Navigate => RequestMode::Navigate,
883 NetTraitsRequestMode::SameOrigin => RequestMode::Same_origin,
884 NetTraitsRequestMode::NoCors => RequestMode::No_cors,
885 NetTraitsRequestMode::CorsMode => RequestMode::Cors,
886 NetTraitsRequestMode::WebSocket { .. } => {
887 unreachable!("Websocket request mode should never be exposed to Dom")
888 },
889 }
890 }
891}
892
893impl Convert<MsgReferrerPolicy> for ReferrerPolicy {
894 fn convert(self) -> MsgReferrerPolicy {
895 match self {
896 ReferrerPolicy::_empty => MsgReferrerPolicy::EmptyString,
897 ReferrerPolicy::No_referrer => MsgReferrerPolicy::NoReferrer,
898 ReferrerPolicy::No_referrer_when_downgrade => {
899 MsgReferrerPolicy::NoReferrerWhenDowngrade
900 },
901 ReferrerPolicy::Origin => MsgReferrerPolicy::Origin,
902 ReferrerPolicy::Origin_when_cross_origin => MsgReferrerPolicy::OriginWhenCrossOrigin,
903 ReferrerPolicy::Unsafe_url => MsgReferrerPolicy::UnsafeUrl,
904 ReferrerPolicy::Same_origin => MsgReferrerPolicy::SameOrigin,
905 ReferrerPolicy::Strict_origin => MsgReferrerPolicy::StrictOrigin,
906 ReferrerPolicy::Strict_origin_when_cross_origin => {
907 MsgReferrerPolicy::StrictOriginWhenCrossOrigin
908 },
909 }
910 }
911}
912
913impl Convert<ReferrerPolicy> for MsgReferrerPolicy {
914 fn convert(self) -> ReferrerPolicy {
915 match self {
916 MsgReferrerPolicy::EmptyString => ReferrerPolicy::_empty,
917 MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer,
918 MsgReferrerPolicy::NoReferrerWhenDowngrade => {
919 ReferrerPolicy::No_referrer_when_downgrade
920 },
921 MsgReferrerPolicy::Origin => ReferrerPolicy::Origin,
922 MsgReferrerPolicy::OriginWhenCrossOrigin => ReferrerPolicy::Origin_when_cross_origin,
923 MsgReferrerPolicy::UnsafeUrl => ReferrerPolicy::Unsafe_url,
924 MsgReferrerPolicy::SameOrigin => ReferrerPolicy::Same_origin,
925 MsgReferrerPolicy::StrictOrigin => ReferrerPolicy::Strict_origin,
926 MsgReferrerPolicy::StrictOriginWhenCrossOrigin => {
927 ReferrerPolicy::Strict_origin_when_cross_origin
928 },
929 }
930 }
931}
932
933impl Convert<NetTraitsRequestRedirect> for RequestRedirect {
934 fn convert(self) -> NetTraitsRequestRedirect {
935 match self {
936 RequestRedirect::Follow => NetTraitsRequestRedirect::Follow,
937 RequestRedirect::Error => NetTraitsRequestRedirect::Error,
938 RequestRedirect::Manual => NetTraitsRequestRedirect::Manual,
939 }
940 }
941}
942
943impl Convert<RequestRedirect> for NetTraitsRequestRedirect {
944 fn convert(self) -> RequestRedirect {
945 match self {
946 NetTraitsRequestRedirect::Follow => RequestRedirect::Follow,
947 NetTraitsRequestRedirect::Error => RequestRedirect::Error,
948 NetTraitsRequestRedirect::Manual => RequestRedirect::Manual,
949 }
950 }
951}