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, TraversableForUserPrompts,
21};
22use servo_url::ServoUrl;
23
24use crate::body::{BodyMixin, BodyType, Extractable, clone_body_stream_for_dom_body, 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::stream::readablestream::ReadableStream;
42use crate::fetch::RequestWithGlobalScope;
43use crate::script_runtime::CanGc;
44
45#[dom_struct]
46pub(crate) struct Request {
47 reflector_: Reflector,
48 #[no_trace]
49 request: DomRefCell<NetTraitsRequest>,
51 body_stream: MutNullableDom<ReadableStream>,
53 headers: MutNullableDom<Headers>,
55 signal: MutNullableDom<AbortSignal>,
57}
58
59impl Request {
60 fn new_inherited(global: &GlobalScope, url: ServoUrl) -> Request {
61 Request {
62 reflector_: Reflector::new(),
63 request: DomRefCell::new(net_request_from_global(global, url)),
64 body_stream: MutNullableDom::new(None),
65 headers: Default::default(),
66 signal: MutNullableDom::new(None),
67 }
68 }
69
70 fn new(
71 global: &GlobalScope,
72 proto: Option<HandleObject>,
73 url: ServoUrl,
74 can_gc: CanGc,
75 ) -> DomRoot<Request> {
76 reflect_dom_object_with_proto(
77 Box::new(Request::new_inherited(global, url)),
78 global,
79 proto,
80 can_gc,
81 )
82 }
83
84 fn from_net_request(
85 global: &GlobalScope,
86 proto: Option<HandleObject>,
87 net_request: NetTraitsRequest,
88 can_gc: CanGc,
89 ) -> DomRoot<Request> {
90 let r = Request::new(global, proto, net_request.current_url(), can_gc);
91 *r.request.borrow_mut() = net_request;
92 r
93 }
94
95 pub(crate) fn constructor(
97 global: &GlobalScope,
98 proto: Option<HandleObject>,
99 can_gc: CanGc,
100 mut input: RequestInfo,
101 init: &RequestInit,
102 ) -> Fallible<DomRoot<Request>> {
103 let temporary_request: NetTraitsRequest;
105
106 let mut fallback_mode: Option<NetTraitsRequestMode> = None;
108
109 let base_url = global.api_base_url();
111
112 let mut signal: Option<DomRoot<AbortSignal>> = None;
114
115 let mut input_body_is_unusable = false;
117
118 match input {
119 RequestInfo::USVString(USVString(ref usv_string)) => {
121 let parsed_url = base_url.join(usv_string);
123 if parsed_url.is_err() {
125 return Err(Error::Type("Url could not be parsed".to_string()));
126 }
127 let url = parsed_url.unwrap();
129 if includes_credentials(&url) {
130 return Err(Error::Type("Url includes credentials".to_string()));
131 }
132 temporary_request = net_request_from_global(global, url);
134 fallback_mode = Some(NetTraitsRequestMode::CorsMode);
136 },
137 RequestInfo::Request(ref input_request) => {
140 input_body_is_unusable = input_request.is_unusable();
142 temporary_request = input_request.request.borrow().clone();
144 signal = Some(input_request.Signal());
146 },
147 }
148
149 let origin = global.origin().immutable();
151
152 let mut traversable_for_user_prompts = TraversableForUserPrompts::Client;
154
155 if !init.window.handle().is_null_or_undefined() {
162 return Err(Error::Type("Window is present and is not null".to_string()));
163 }
164
165 if !init.window.handle().is_undefined() {
167 traversable_for_user_prompts = TraversableForUserPrompts::NoTraversable;
168 }
169
170 let mut request: NetTraitsRequest;
172 request = net_request_from_global(global, temporary_request.current_url());
173 request.method = temporary_request.method;
174 request.headers = temporary_request.headers.clone();
175 request.unsafe_request = true;
176 request.traversable_for_user_prompts = traversable_for_user_prompts;
177 request.origin = Origin::Client;
179 request.referrer = temporary_request.referrer;
180 request.referrer_policy = temporary_request.referrer_policy;
181 request.mode = temporary_request.mode;
182 request.credentials_mode = temporary_request.credentials_mode;
183 request.cache_mode = temporary_request.cache_mode;
184 request.redirect_mode = temporary_request.redirect_mode;
185 request.integrity_metadata = temporary_request.integrity_metadata;
186
187 if init.body.is_some() ||
189 init.cache.is_some() ||
190 init.credentials.is_some() ||
191 init.integrity.is_some() ||
192 init.headers.is_some() ||
193 init.keepalive.is_some() ||
194 init.method.is_some() ||
195 init.mode.is_some() ||
196 init.redirect.is_some() ||
197 init.referrer.is_some() ||
198 init.referrerPolicy.is_some() ||
199 !init.window.handle().is_undefined()
200 {
201 if request.mode == NetTraitsRequestMode::Navigate {
203 request.mode = NetTraitsRequestMode::SameOrigin;
204 }
205 request.referrer = global.get_referrer();
213 request.referrer_policy = MsgReferrerPolicy::EmptyString;
215 }
220
221 if let Some(init_referrer) = init.referrer.as_ref() {
223 let referrer = &init_referrer.0;
225 if referrer.is_empty() {
227 request.referrer = NetTraitsRequestReferrer::NoReferrer;
228 } else {
230 let parsed_referrer = base_url.join(referrer);
232 if parsed_referrer.is_err() {
234 return Err(Error::Type("Failed to parse referrer url".to_string()));
235 }
236 if let Ok(parsed_referrer) = parsed_referrer {
240 if (parsed_referrer.cannot_be_a_base() &&
241 parsed_referrer.scheme() == "about" &&
242 parsed_referrer.path() == "client") ||
243 parsed_referrer.origin() != *origin
244 {
245 request.referrer = global.get_referrer();
247 } else {
248 request.referrer = NetTraitsRequestReferrer::ReferrerUrl(parsed_referrer);
250 }
251 }
252 }
253 }
254
255 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() {
257 let init_referrer_policy = (*init_referrerpolicy).convert();
258 request.referrer_policy = init_referrer_policy;
259 }
260
261 let mode = init.mode.as_ref().map(|m| (*m).convert()).or(fallback_mode);
263
264 if let Some(NetTraitsRequestMode::Navigate) = mode {
266 return Err(Error::Type("Request mode is Navigate".to_string()));
267 }
268
269 if let Some(m) = mode {
271 request.mode = m;
272 }
273
274 if let Some(init_credentials) = init.credentials.as_ref() {
276 let credentials = (*init_credentials).convert();
277 request.credentials_mode = credentials;
278 }
279
280 if let Some(init_cache) = init.cache.as_ref() {
282 let cache = (*init_cache).convert();
283 request.cache_mode = cache;
284 }
285
286 if request.cache_mode == NetTraitsRequestCache::OnlyIfCached &&
289 request.mode != NetTraitsRequestMode::SameOrigin
290 {
291 return Err(Error::Type(
292 "Cache is 'only-if-cached' and mode is not 'same-origin'".to_string(),
293 ));
294 }
295
296 if let Some(init_redirect) = init.redirect.as_ref() {
298 let redirect = (*init_redirect).convert();
299 request.redirect_mode = redirect;
300 }
301
302 if let Some(init_integrity) = init.integrity.as_ref() {
304 let integrity = init_integrity.clone().to_string();
305 request.integrity_metadata = integrity;
306 }
307
308 if let Some(init_keepalive) = init.keepalive {
310 request.keep_alive = init_keepalive;
311 }
312
313 if let Some(init_method) = init.method.as_ref() {
316 if !is_method(init_method) {
318 return Err(Error::Type("Method is not a method".to_string()));
319 }
320 if is_forbidden_method(init_method) {
321 return Err(Error::Type("Method is forbidden".to_string()));
322 }
323 let method = match init_method.as_str() {
325 Some(s) => normalize_method(s)
326 .map_err(|e| Error::Type(format!("Method is not valid: {:?}", e)))?,
327 None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
328 };
329 request.method = method;
331 }
332
333 if let Some(init_signal) = init.signal.as_ref() {
335 signal = init_signal.clone();
336 }
337 let r = Request::from_net_request(global, proto, request, can_gc);
347
348 let signals = signal.map_or(vec![], |s| vec![s]);
350 r.signal
353 .set(Some(&AbortSignal::create_dependent_abort_signal(
354 signals, global, can_gc,
355 )));
356
357 r.headers
363 .or_init(|| Headers::for_request(&r.global(), can_gc));
364
365 let headers_copy = init
369 .headers
370 .as_ref()
371 .map(|possible_header| match possible_header {
372 HeadersInit::ByteStringSequenceSequence(init_sequence) => {
373 HeadersInit::ByteStringSequenceSequence(init_sequence.clone())
374 },
375 HeadersInit::ByteStringByteStringRecord(init_map) => {
376 HeadersInit::ByteStringByteStringRecord(init_map.clone())
377 },
378 });
379
380 if r.request.borrow().mode == NetTraitsRequestMode::NoCors {
391 let borrowed_request = r.request.borrow();
392 if !is_cors_safelisted_method(&borrowed_request.method) {
394 return Err(Error::Type(
395 "The mode is 'no-cors' but the method is not a cors-safelisted method"
396 .to_string(),
397 ));
398 }
399 r.Headers(can_gc).set_guard(Guard::RequestNoCors);
401 }
402
403 match headers_copy {
404 None => {
405 if let RequestInfo::Request(ref input_request) = input {
412 r.Headers(can_gc)
413 .copy_from_headers(input_request.Headers(can_gc))?;
414 }
415 },
416 Some(headers_copy) => r.Headers(can_gc).fill(Some(headers_copy))?,
418 }
419
420 r.request.borrow_mut().headers = r.Headers(can_gc).get_headers_list();
423
424 let input_body = if let RequestInfo::Request(ref mut input_request) = input {
426 let mut input_request_request = input_request.request.borrow_mut();
427 r.body_stream.set(input_request.body().as_deref());
428 input_request_request.body.take()
429 } else {
430 None
431 };
432
433 if init.body.as_ref().is_some_and(|body| body.is_some()) || input_body.is_some() {
436 let req = r.request.borrow();
437 let req_method = &req.method;
438 match *req_method {
439 HttpMethod::GET => {
440 return Err(Error::Type(
441 "Init's body is non-null, and request method is GET".to_string(),
442 ));
443 },
444 HttpMethod::HEAD => {
445 return Err(Error::Type(
446 "Init's body is non-null, and request method is HEAD".to_string(),
447 ));
448 },
449 _ => {},
450 }
451 }
452
453 let mut init_body = None;
455 if let Some(Some(ref input_init_body)) = init.body {
457 let mut body_with_type =
459 input_init_body.extract(global, r.request.borrow().keep_alive, can_gc)?;
460
461 if let Some(contents) = body_with_type.content_type.take() {
463 let ct_header_name = b"Content-Type";
464 if !r
467 .Headers(can_gc)
468 .Has(ByteString::new(ct_header_name.to_vec()))
469 .unwrap()
470 {
471 let ct_header_val = contents.as_bytes();
472 r.Headers(can_gc).Append(
473 ByteString::new(ct_header_name.to_vec()),
474 ByteString::new(ct_header_val.to_vec()),
475 )?;
476
477 if let Ok(v) = HeaderValue::from_bytes(&ct_header_val) {
481 r.request
482 .borrow_mut()
483 .headers
484 .insert(HeaderName::from_bytes(ct_header_name).unwrap(), v);
485 }
486 }
487 }
488
489 let (net_body, stream) = body_with_type.into_net_request_body();
491 r.body_stream.set(Some(&*stream));
492 init_body = Some(net_body);
493 }
494
495 let final_body = init_body.or(input_body);
502
503 if final_body
505 .as_ref()
506 .is_some_and(|body| body.source_is_null())
507 {
508 let request_mode = &r.request.borrow().mode;
512 if *request_mode != NetTraitsRequestMode::CorsMode &&
513 *request_mode != NetTraitsRequestMode::SameOrigin
514 {
515 return Err(Error::Type(
516 "Request mode must be Cors or SameOrigin".to_string(),
517 ));
518 }
519 }
522
523 if input_body_is_unusable {
530 return Err(Error::Type("Input body is unusable".to_string()));
531 }
532
533 r.request.borrow_mut().body = final_body;
535
536 Ok(r)
537 }
538
539 fn clone_from(r: &Request, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
541 let req = r.request.borrow();
542 let url = req.url();
543 let headers_guard = r.Headers(can_gc).get_guard();
544
545 let mut new_req_inner = req.clone();
547 let body = new_req_inner.body.take();
548
549 let r_clone = Request::new(&r.global(), None, url, can_gc);
550 *r_clone.request.borrow_mut() = new_req_inner;
551
552 if let Some(body) = body {
555 r_clone.request.borrow_mut().body = Some(body);
556 }
557
558 r_clone
559 .Headers(can_gc)
560 .copy_from_headers(r.Headers(can_gc))?;
561 r_clone.Headers(can_gc).set_guard(headers_guard);
562
563 clone_body_stream_for_dom_body(&r.body_stream, &r_clone.body_stream, can_gc)?;
564
565 Ok(r_clone)
567 }
568
569 pub(crate) fn get_request(&self) -> NetTraitsRequest {
570 self.request.borrow().clone()
571 }
572}
573
574fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest {
575 RequestBuilder::new(global.webview_id(), url, global.get_referrer())
576 .with_global_scope(global)
577 .build()
578}
579
580fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
582 match_ignore_ascii_case! { m,
583 "delete" => return Ok(HttpMethod::DELETE),
584 "get" => return Ok(HttpMethod::GET),
585 "head" => return Ok(HttpMethod::HEAD),
586 "options" => return Ok(HttpMethod::OPTIONS),
587 "post" => return Ok(HttpMethod::POST),
588 "put" => return Ok(HttpMethod::PUT),
589 _ => (),
590 }
591 debug!("Method: {:?}", m);
592 HttpMethod::from_str(m)
593}
594
595fn is_method(m: &ByteString) -> bool {
597 m.as_str().is_some()
598}
599
600fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
602 m == HttpMethod::GET || m == HttpMethod::HEAD || m == HttpMethod::POST
603}
604
605fn includes_credentials(input: &ServoUrl) -> bool {
607 !input.username().is_empty() || input.password().is_some()
608}
609
610impl RequestMethods<crate::DomTypeHolder> for Request {
611 fn Constructor(
613 global: &GlobalScope,
614 proto: Option<HandleObject>,
615 can_gc: CanGc,
616 input: RequestInfo,
617 init: RootedTraceableBox<RequestInit>,
618 ) -> Fallible<DomRoot<Request>> {
619 Self::constructor(global, proto, can_gc, input, &init)
620 }
621
622 fn Method(&self) -> ByteString {
624 let r = self.request.borrow();
625 ByteString::new(r.method.as_ref().as_bytes().into())
626 }
627
628 fn Url(&self) -> USVString {
630 let r = self.request.borrow();
631 USVString(r.url_list.first().map_or("", |u| u.as_str()).into())
632 }
633
634 fn Headers(&self, can_gc: CanGc) -> DomRoot<Headers> {
636 self.headers
637 .or_init(|| Headers::new(&self.global(), can_gc))
638 }
639
640 fn Destination(&self) -> RequestDestination {
642 self.request.borrow().destination.convert()
643 }
644
645 fn Referrer(&self) -> USVString {
647 let r = self.request.borrow();
648 USVString(match r.referrer {
649 NetTraitsRequestReferrer::NoReferrer => String::from(""),
650 NetTraitsRequestReferrer::Client(_) => String::from("about:client"),
651 NetTraitsRequestReferrer::ReferrerUrl(ref u) => {
652 let u_c = u.clone();
653 u_c.into_string()
654 },
655 })
656 }
657
658 fn ReferrerPolicy(&self) -> ReferrerPolicy {
660 self.request.borrow().referrer_policy.convert()
661 }
662
663 fn Mode(&self) -> RequestMode {
665 self.request.borrow().mode.clone().convert()
666 }
667
668 fn Credentials(&self) -> RequestCredentials {
670 let r = self.request.borrow().clone();
671 r.credentials_mode.convert()
672 }
673
674 fn Cache(&self) -> RequestCache {
676 let r = self.request.borrow().clone();
677 r.cache_mode.convert()
678 }
679
680 fn Redirect(&self) -> RequestRedirect {
682 let r = self.request.borrow().clone();
683 r.redirect_mode.convert()
684 }
685
686 fn Integrity(&self) -> DOMString {
688 let r = self.request.borrow();
689 DOMString::from_string(r.integrity_metadata.clone())
690 }
691
692 fn Keepalive(&self) -> bool {
694 self.request.borrow().keep_alive
695 }
696
697 fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
699 self.body()
700 }
701
702 fn BodyUsed(&self) -> bool {
704 self.is_body_used()
705 }
706
707 fn Signal(&self) -> DomRoot<AbortSignal> {
709 self.signal
710 .get()
711 .expect("Should always be initialized in constructor and clone")
712 }
713
714 fn Clone(&self, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
716 if self.is_unusable() {
718 return Err(Error::Type("Request is unusable".to_string()));
719 }
720
721 let cloned_request = Request::clone_from(self, can_gc)?;
723 let signal = self.signal.get().expect("Should always be initialized");
725 let cloned_signal =
728 AbortSignal::create_dependent_abort_signal(vec![signal], &self.global(), can_gc);
729 cloned_request.signal.set(Some(&cloned_signal));
734 Ok(cloned_request)
736 }
737
738 fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
740 consume_body(self, BodyType::Text, can_gc)
741 }
742
743 fn Blob(&self, can_gc: CanGc) -> Rc<Promise> {
745 consume_body(self, BodyType::Blob, can_gc)
746 }
747
748 fn FormData(&self, can_gc: CanGc) -> Rc<Promise> {
750 consume_body(self, BodyType::FormData, can_gc)
751 }
752
753 fn Json(&self, can_gc: CanGc) -> Rc<Promise> {
755 consume_body(self, BodyType::Json, can_gc)
756 }
757
758 fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
760 consume_body(self, BodyType::ArrayBuffer, can_gc)
761 }
762
763 fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
765 consume_body(self, BodyType::Bytes, can_gc)
766 }
767}
768
769impl BodyMixin for Request {
770 fn is_body_used(&self) -> bool {
771 let body_stream = self.body_stream.get();
772 body_stream
773 .as_ref()
774 .is_some_and(|stream| stream.is_disturbed())
775 }
776
777 fn is_unusable(&self) -> bool {
778 let body_stream = self.body_stream.get();
779 body_stream
780 .as_ref()
781 .is_some_and(|stream| stream.is_disturbed() || stream.is_locked())
782 }
783
784 fn body(&self) -> Option<DomRoot<ReadableStream>> {
785 self.body_stream.get()
786 }
787
788 fn get_mime_type(&self, can_gc: CanGc) -> Vec<u8> {
789 let headers = self.Headers(can_gc);
790 headers.extract_mime_type()
791 }
792}
793
794impl Convert<NetTraitsRequestCache> for RequestCache {
795 fn convert(self) -> NetTraitsRequestCache {
796 match self {
797 RequestCache::Default => NetTraitsRequestCache::Default,
798 RequestCache::No_store => NetTraitsRequestCache::NoStore,
799 RequestCache::Reload => NetTraitsRequestCache::Reload,
800 RequestCache::No_cache => NetTraitsRequestCache::NoCache,
801 RequestCache::Force_cache => NetTraitsRequestCache::ForceCache,
802 RequestCache::Only_if_cached => NetTraitsRequestCache::OnlyIfCached,
803 }
804 }
805}
806
807impl Convert<RequestCache> for NetTraitsRequestCache {
808 fn convert(self) -> RequestCache {
809 match self {
810 NetTraitsRequestCache::Default => RequestCache::Default,
811 NetTraitsRequestCache::NoStore => RequestCache::No_store,
812 NetTraitsRequestCache::Reload => RequestCache::Reload,
813 NetTraitsRequestCache::NoCache => RequestCache::No_cache,
814 NetTraitsRequestCache::ForceCache => RequestCache::Force_cache,
815 NetTraitsRequestCache::OnlyIfCached => RequestCache::Only_if_cached,
816 }
817 }
818}
819
820impl Convert<NetTraitsRequestCredentials> for RequestCredentials {
821 fn convert(self) -> NetTraitsRequestCredentials {
822 match self {
823 RequestCredentials::Omit => NetTraitsRequestCredentials::Omit,
824 RequestCredentials::Same_origin => NetTraitsRequestCredentials::CredentialsSameOrigin,
825 RequestCredentials::Include => NetTraitsRequestCredentials::Include,
826 }
827 }
828}
829
830impl Convert<RequestCredentials> for NetTraitsRequestCredentials {
831 fn convert(self) -> RequestCredentials {
832 match self {
833 NetTraitsRequestCredentials::Omit => RequestCredentials::Omit,
834 NetTraitsRequestCredentials::CredentialsSameOrigin => RequestCredentials::Same_origin,
835 NetTraitsRequestCredentials::Include => RequestCredentials::Include,
836 }
837 }
838}
839
840impl Convert<NetTraitsRequestDestination> for RequestDestination {
841 fn convert(self) -> NetTraitsRequestDestination {
842 match self {
843 RequestDestination::_empty => NetTraitsRequestDestination::None,
844 RequestDestination::Audio => NetTraitsRequestDestination::Audio,
845 RequestDestination::Document => NetTraitsRequestDestination::Document,
846 RequestDestination::Embed => NetTraitsRequestDestination::Embed,
847 RequestDestination::Font => NetTraitsRequestDestination::Font,
848 RequestDestination::Frame => NetTraitsRequestDestination::Frame,
849 RequestDestination::Iframe => NetTraitsRequestDestination::IFrame,
850 RequestDestination::Image => NetTraitsRequestDestination::Image,
851 RequestDestination::Manifest => NetTraitsRequestDestination::Manifest,
852 RequestDestination::Json => NetTraitsRequestDestination::Json,
853 RequestDestination::Object => NetTraitsRequestDestination::Object,
854 RequestDestination::Report => NetTraitsRequestDestination::Report,
855 RequestDestination::Script => NetTraitsRequestDestination::Script,
856 RequestDestination::Sharedworker => NetTraitsRequestDestination::SharedWorker,
857 RequestDestination::Style => NetTraitsRequestDestination::Style,
858 RequestDestination::Track => NetTraitsRequestDestination::Track,
859 RequestDestination::Video => NetTraitsRequestDestination::Video,
860 RequestDestination::Worker => NetTraitsRequestDestination::Worker,
861 RequestDestination::Xslt => NetTraitsRequestDestination::Xslt,
862 }
863 }
864}
865
866impl Convert<RequestDestination> for NetTraitsRequestDestination {
867 fn convert(self) -> RequestDestination {
868 match self {
869 NetTraitsRequestDestination::None => RequestDestination::_empty,
870 NetTraitsRequestDestination::Audio => RequestDestination::Audio,
871 NetTraitsRequestDestination::Document => RequestDestination::Document,
872 NetTraitsRequestDestination::Embed => RequestDestination::Embed,
873 NetTraitsRequestDestination::Font => RequestDestination::Font,
874 NetTraitsRequestDestination::Frame => RequestDestination::Frame,
875 NetTraitsRequestDestination::IFrame => RequestDestination::Iframe,
876 NetTraitsRequestDestination::Image => RequestDestination::Image,
877 NetTraitsRequestDestination::Manifest => RequestDestination::Manifest,
878 NetTraitsRequestDestination::Json => RequestDestination::Json,
879 NetTraitsRequestDestination::Object => RequestDestination::Object,
880 NetTraitsRequestDestination::Report => RequestDestination::Report,
881 NetTraitsRequestDestination::Script => RequestDestination::Script,
882 NetTraitsRequestDestination::ServiceWorker |
883 NetTraitsRequestDestination::AudioWorklet |
884 NetTraitsRequestDestination::PaintWorklet => {
885 panic!("ServiceWorker request destination should not be exposed to DOM")
886 },
887 NetTraitsRequestDestination::SharedWorker => RequestDestination::Sharedworker,
888 NetTraitsRequestDestination::Style => RequestDestination::Style,
889 NetTraitsRequestDestination::Track => RequestDestination::Track,
890 NetTraitsRequestDestination::Video => RequestDestination::Video,
891 NetTraitsRequestDestination::Worker => RequestDestination::Worker,
892 NetTraitsRequestDestination::Xslt => RequestDestination::Xslt,
893 NetTraitsRequestDestination::WebIdentity => RequestDestination::_empty,
894 }
895 }
896}
897
898impl Convert<NetTraitsRequestMode> for RequestMode {
899 fn convert(self) -> NetTraitsRequestMode {
900 match self {
901 RequestMode::Navigate => NetTraitsRequestMode::Navigate,
902 RequestMode::Same_origin => NetTraitsRequestMode::SameOrigin,
903 RequestMode::No_cors => NetTraitsRequestMode::NoCors,
904 RequestMode::Cors => NetTraitsRequestMode::CorsMode,
905 }
906 }
907}
908
909impl Convert<RequestMode> for NetTraitsRequestMode {
910 fn convert(self) -> RequestMode {
911 match self {
912 NetTraitsRequestMode::Navigate => RequestMode::Navigate,
913 NetTraitsRequestMode::SameOrigin => RequestMode::Same_origin,
914 NetTraitsRequestMode::NoCors => RequestMode::No_cors,
915 NetTraitsRequestMode::CorsMode => RequestMode::Cors,
916 NetTraitsRequestMode::WebSocket { .. } => {
917 unreachable!("Websocket request mode should never be exposed to Dom")
918 },
919 }
920 }
921}
922
923impl Convert<MsgReferrerPolicy> for ReferrerPolicy {
924 fn convert(self) -> MsgReferrerPolicy {
925 match self {
926 ReferrerPolicy::_empty => MsgReferrerPolicy::EmptyString,
927 ReferrerPolicy::No_referrer => MsgReferrerPolicy::NoReferrer,
928 ReferrerPolicy::No_referrer_when_downgrade => {
929 MsgReferrerPolicy::NoReferrerWhenDowngrade
930 },
931 ReferrerPolicy::Origin => MsgReferrerPolicy::Origin,
932 ReferrerPolicy::Origin_when_cross_origin => MsgReferrerPolicy::OriginWhenCrossOrigin,
933 ReferrerPolicy::Unsafe_url => MsgReferrerPolicy::UnsafeUrl,
934 ReferrerPolicy::Same_origin => MsgReferrerPolicy::SameOrigin,
935 ReferrerPolicy::Strict_origin => MsgReferrerPolicy::StrictOrigin,
936 ReferrerPolicy::Strict_origin_when_cross_origin => {
937 MsgReferrerPolicy::StrictOriginWhenCrossOrigin
938 },
939 }
940 }
941}
942
943impl Convert<ReferrerPolicy> for MsgReferrerPolicy {
944 fn convert(self) -> ReferrerPolicy {
945 match self {
946 MsgReferrerPolicy::EmptyString => ReferrerPolicy::_empty,
947 MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer,
948 MsgReferrerPolicy::NoReferrerWhenDowngrade => {
949 ReferrerPolicy::No_referrer_when_downgrade
950 },
951 MsgReferrerPolicy::Origin => ReferrerPolicy::Origin,
952 MsgReferrerPolicy::OriginWhenCrossOrigin => ReferrerPolicy::Origin_when_cross_origin,
953 MsgReferrerPolicy::UnsafeUrl => ReferrerPolicy::Unsafe_url,
954 MsgReferrerPolicy::SameOrigin => ReferrerPolicy::Same_origin,
955 MsgReferrerPolicy::StrictOrigin => ReferrerPolicy::Strict_origin,
956 MsgReferrerPolicy::StrictOriginWhenCrossOrigin => {
957 ReferrerPolicy::Strict_origin_when_cross_origin
958 },
959 }
960 }
961}
962
963impl Convert<NetTraitsRequestRedirect> for RequestRedirect {
964 fn convert(self) -> NetTraitsRequestRedirect {
965 match self {
966 RequestRedirect::Follow => NetTraitsRequestRedirect::Follow,
967 RequestRedirect::Error => NetTraitsRequestRedirect::Error,
968 RequestRedirect::Manual => NetTraitsRequestRedirect::Manual,
969 }
970 }
971}
972
973impl Convert<RequestRedirect> for NetTraitsRequestRedirect {
974 fn convert(self) -> RequestRedirect {
975 match self {
976 NetTraitsRequestRedirect::Follow => RequestRedirect::Follow,
977 NetTraitsRequestRedirect::Error => RequestRedirect::Error,
978 NetTraitsRequestRedirect::Manual => RequestRedirect::Manual,
979 }
980 }
981}