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 script_bindings::cformat;
23use servo_url::ServoUrl;
24
25use crate::body::{BodyMixin, BodyType, Extractable, clone_body_stream_for_dom_body, consume_body};
26use crate::conversions::Convert;
27use crate::dom::abortsignal::AbortSignal;
28use crate::dom::bindings::cell::DomRefCell;
29use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
30use crate::dom::bindings::codegen::Bindings::RequestBinding::{
31 ReferrerPolicy, RequestCache, RequestCredentials, RequestDestination, RequestInfo, RequestInit,
32 RequestMethods, RequestMode, RequestRedirect,
33};
34use crate::dom::bindings::error::{Error, Fallible};
35use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
36use crate::dom::bindings::root::{DomRoot, MutNullableDom};
37use crate::dom::bindings::str::{ByteString, DOMString, USVString};
38use crate::dom::bindings::trace::RootedTraceableBox;
39use crate::dom::globalscope::GlobalScope;
40use crate::dom::headers::{Guard, Headers};
41use crate::dom::promise::Promise;
42use crate::dom::stream::readablestream::ReadableStream;
43use crate::fetch::RequestWithGlobalScope;
44use crate::script_runtime::CanGc;
45
46#[dom_struct]
47pub(crate) struct Request {
48 reflector_: Reflector,
49 #[no_trace]
50 request: DomRefCell<NetTraitsRequest>,
52 body_stream: MutNullableDom<ReadableStream>,
54 headers: MutNullableDom<Headers>,
56 signal: MutNullableDom<AbortSignal>,
58}
59
60impl Request {
61 fn new_inherited(global: &GlobalScope, url: ServoUrl) -> Request {
62 Request {
63 reflector_: Reflector::new(),
64 request: DomRefCell::new(net_request_from_global(global, url)),
65 body_stream: MutNullableDom::new(None),
66 headers: Default::default(),
67 signal: MutNullableDom::new(None),
68 }
69 }
70
71 fn new(
72 global: &GlobalScope,
73 proto: Option<HandleObject>,
74 url: ServoUrl,
75 can_gc: CanGc,
76 ) -> DomRoot<Request> {
77 reflect_dom_object_with_proto(
78 Box::new(Request::new_inherited(global, url)),
79 global,
80 proto,
81 can_gc,
82 )
83 }
84
85 fn from_net_request(
86 global: &GlobalScope,
87 proto: Option<HandleObject>,
88 net_request: NetTraitsRequest,
89 can_gc: CanGc,
90 ) -> DomRoot<Request> {
91 let r = Request::new(global, proto, net_request.current_url(), can_gc);
92 *r.request.borrow_mut() = net_request;
93 r
94 }
95
96 pub(crate) fn constructor(
98 global: &GlobalScope,
99 proto: Option<HandleObject>,
100 can_gc: CanGc,
101 mut input: RequestInfo,
102 init: &RequestInit,
103 ) -> Fallible<DomRoot<Request>> {
104 let temporary_request: NetTraitsRequest;
106
107 let mut fallback_mode: Option<NetTraitsRequestMode> = None;
109
110 let base_url = global.api_base_url();
112
113 let mut signal: Option<DomRoot<AbortSignal>> = None;
115
116 let mut input_body_is_unusable = false;
118
119 match input {
120 RequestInfo::USVString(USVString(ref usv_string)) => {
122 let parsed_url = base_url.join(usv_string);
124 if parsed_url.is_err() {
126 return Err(Error::Type(c"Url could not be parsed".to_owned()));
127 }
128 let url = parsed_url.unwrap();
130 if includes_credentials(&url) {
131 return Err(Error::Type(c"Url includes credentials".to_owned()));
132 }
133 temporary_request = net_request_from_global(global, url);
135 fallback_mode = Some(NetTraitsRequestMode::CorsMode);
137 },
138 RequestInfo::Request(ref input_request) => {
141 input_body_is_unusable = input_request.is_unusable();
143 temporary_request = input_request.request.borrow().clone();
145 signal = Some(input_request.Signal());
147 },
148 }
149
150 let origin = global.origin().immutable();
152
153 let mut traversable_for_user_prompts = TraversableForUserPrompts::Client;
155
156 if !init.window.handle().is_null_or_undefined() {
163 return Err(Error::Type(c"Window is present and is not null".to_owned()));
164 }
165
166 if !init.window.handle().is_undefined() {
168 traversable_for_user_prompts = TraversableForUserPrompts::NoTraversable;
169 }
170
171 let mut request: NetTraitsRequest;
173 request = net_request_from_global(global, temporary_request.current_url());
174 request.method = temporary_request.method;
175 request.headers = temporary_request.headers.clone();
176 request.unsafe_request = true;
177 request.traversable_for_user_prompts = traversable_for_user_prompts;
178 request.origin = Origin::Client;
180 request.referrer = temporary_request.referrer;
181 request.referrer_policy = temporary_request.referrer_policy;
182 request.mode = temporary_request.mode;
183 request.credentials_mode = temporary_request.credentials_mode;
184 request.cache_mode = temporary_request.cache_mode;
185 request.redirect_mode = temporary_request.redirect_mode;
186 request.integrity_metadata = temporary_request.integrity_metadata;
187
188 if init.body.is_some() ||
190 init.cache.is_some() ||
191 init.credentials.is_some() ||
192 init.integrity.is_some() ||
193 init.headers.is_some() ||
194 init.keepalive.is_some() ||
195 init.method.is_some() ||
196 init.mode.is_some() ||
197 init.redirect.is_some() ||
198 init.referrer.is_some() ||
199 init.referrerPolicy.is_some() ||
200 !init.window.handle().is_undefined()
201 {
202 if request.mode == NetTraitsRequestMode::Navigate {
204 request.mode = NetTraitsRequestMode::SameOrigin;
205 }
206 request.referrer = global.get_referrer();
214 request.referrer_policy = MsgReferrerPolicy::EmptyString;
216 }
221
222 if let Some(init_referrer) = init.referrer.as_ref() {
224 let referrer = &init_referrer.0;
226 if referrer.is_empty() {
228 request.referrer = NetTraitsRequestReferrer::NoReferrer;
229 } else {
231 let parsed_referrer = base_url.join(referrer);
233 if parsed_referrer.is_err() {
235 return Err(Error::Type(c"Failed to parse referrer url".to_owned()));
236 }
237 if let Ok(parsed_referrer) = parsed_referrer {
241 if (parsed_referrer.cannot_be_a_base() &&
242 parsed_referrer.scheme() == "about" &&
243 parsed_referrer.path() == "client") ||
244 parsed_referrer.origin() != *origin
245 {
246 request.referrer = global.get_referrer();
248 } else {
249 request.referrer = NetTraitsRequestReferrer::ReferrerUrl(parsed_referrer);
251 }
252 }
253 }
254 }
255
256 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() {
258 let init_referrer_policy = (*init_referrerpolicy).convert();
259 request.referrer_policy = init_referrer_policy;
260 }
261
262 let mode = init.mode.as_ref().map(|m| (*m).convert()).or(fallback_mode);
264
265 if let Some(NetTraitsRequestMode::Navigate) = mode {
267 return Err(Error::Type(c"Request mode is Navigate".to_owned()));
268 }
269
270 if let Some(m) = mode {
272 request.mode = m;
273 }
274
275 if let Some(init_credentials) = init.credentials.as_ref() {
277 let credentials = (*init_credentials).convert();
278 request.credentials_mode = credentials;
279 }
280
281 if let Some(init_cache) = init.cache.as_ref() {
283 let cache = (*init_cache).convert();
284 request.cache_mode = cache;
285 }
286
287 if request.cache_mode == NetTraitsRequestCache::OnlyIfCached &&
290 request.mode != NetTraitsRequestMode::SameOrigin
291 {
292 return Err(Error::Type(
293 c"Cache is 'only-if-cached' and mode is not 'same-origin'".to_owned(),
294 ));
295 }
296
297 if let Some(init_redirect) = init.redirect.as_ref() {
299 let redirect = (*init_redirect).convert();
300 request.redirect_mode = redirect;
301 }
302
303 if let Some(init_integrity) = init.integrity.as_ref() {
305 let integrity = init_integrity.clone().to_string();
306 request.integrity_metadata = integrity;
307 }
308
309 if let Some(init_keepalive) = init.keepalive {
311 request.keep_alive = init_keepalive;
312 }
313
314 if let Some(init_method) = init.method.as_ref() {
317 if !is_method(init_method) {
319 return Err(Error::Type(c"Method is not a method".to_owned()));
320 }
321 if is_forbidden_method(init_method) {
322 return Err(Error::Type(c"Method is forbidden".to_owned()));
323 }
324 let method = match init_method.as_str() {
326 Some(s) => normalize_method(s)
327 .map_err(|e| Error::Type(cformat!("Method is not valid: {:?}", e)))?,
328 None => return Err(Error::Type(c"Method is not a valid UTF8".to_owned())),
329 };
330 request.method = method;
332 }
333
334 if let Some(init_signal) = init.signal.as_ref() {
336 signal = init_signal.clone();
337 }
338 let r = Request::from_net_request(global, proto, request, can_gc);
348
349 let signals = signal.map_or(vec![], |s| vec![s]);
351 r.signal
354 .set(Some(&AbortSignal::create_dependent_abort_signal(
355 signals, global, can_gc,
356 )));
357
358 r.headers
364 .or_init(|| Headers::for_request(&r.global(), can_gc));
365
366 let headers_copy = init
370 .headers
371 .as_ref()
372 .map(|possible_header| match possible_header {
373 HeadersInit::ByteStringSequenceSequence(init_sequence) => {
374 HeadersInit::ByteStringSequenceSequence(init_sequence.clone())
375 },
376 HeadersInit::ByteStringByteStringRecord(init_map) => {
377 HeadersInit::ByteStringByteStringRecord(init_map.clone())
378 },
379 });
380
381 if r.request.borrow().mode == NetTraitsRequestMode::NoCors {
392 let borrowed_request = r.request.borrow();
393 if !is_cors_safelisted_method(&borrowed_request.method) {
395 return Err(Error::Type(
396 c"The mode is 'no-cors' but the method is not a cors-safelisted method"
397 .to_owned(),
398 ));
399 }
400 r.Headers(can_gc).set_guard(Guard::RequestNoCors);
402 }
403
404 match headers_copy {
405 None => {
406 if let RequestInfo::Request(ref input_request) = input {
413 r.Headers(can_gc)
414 .copy_from_headers(input_request.Headers(can_gc))?;
415 }
416 },
417 Some(headers_copy) => r.Headers(can_gc).fill(Some(headers_copy))?,
419 }
420
421 r.request.borrow_mut().headers = r.Headers(can_gc).get_headers_list();
424
425 let input_body = if let RequestInfo::Request(ref mut input_request) = input {
427 let mut input_request_request = input_request.request.borrow_mut();
428 r.body_stream.set(input_request.body().as_deref());
429 input_request_request.body.take()
430 } else {
431 None
432 };
433
434 if init.body.as_ref().is_some_and(|body| body.is_some()) || input_body.is_some() {
437 let req = r.request.borrow();
438 let req_method = &req.method;
439 match *req_method {
440 HttpMethod::GET => {
441 return Err(Error::Type(
442 c"Init's body is non-null, and request method is GET".to_owned(),
443 ));
444 },
445 HttpMethod::HEAD => {
446 return Err(Error::Type(
447 c"Init's body is non-null, and request method is HEAD".to_owned(),
448 ));
449 },
450 _ => {},
451 }
452 }
453
454 let mut init_body = None;
456 if let Some(Some(ref input_init_body)) = init.body {
458 let mut body_with_type =
460 input_init_body.extract(global, r.request.borrow().keep_alive, can_gc)?;
461
462 if let Some(contents) = body_with_type.content_type.take() {
464 let ct_header_name = b"Content-Type";
465 if !r
468 .Headers(can_gc)
469 .Has(ByteString::new(ct_header_name.to_vec()))
470 .unwrap()
471 {
472 let ct_header_val = contents.as_bytes();
473 r.Headers(can_gc).Append(
474 ByteString::new(ct_header_name.to_vec()),
475 ByteString::new(ct_header_val.to_vec()),
476 )?;
477
478 if let Ok(v) = HeaderValue::from_bytes(&ct_header_val) {
482 r.request
483 .borrow_mut()
484 .headers
485 .insert(HeaderName::from_bytes(ct_header_name).unwrap(), v);
486 }
487 }
488 }
489
490 let (net_body, stream) = body_with_type.into_net_request_body();
492 r.body_stream.set(Some(&*stream));
493 init_body = Some(net_body);
494 }
495
496 let final_body = init_body.or(input_body);
503
504 if final_body
506 .as_ref()
507 .is_some_and(|body| body.source_is_null())
508 {
509 let request_mode = &r.request.borrow().mode;
513 if *request_mode != NetTraitsRequestMode::CorsMode &&
514 *request_mode != NetTraitsRequestMode::SameOrigin
515 {
516 return Err(Error::Type(
517 c"Request mode must be Cors or SameOrigin".to_owned(),
518 ));
519 }
520 }
523
524 if input_body_is_unusable {
531 return Err(Error::Type(c"Input body is unusable".to_owned()));
532 }
533
534 r.request.borrow_mut().body = final_body;
536
537 Ok(r)
538 }
539
540 fn clone_from(r: &Request, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
542 let req = r.request.borrow();
543 let url = req.url();
544 let headers_guard = r.Headers(can_gc).get_guard();
545
546 let mut new_req_inner = req.clone();
548 let body = new_req_inner.body.take();
549
550 let r_clone = Request::new(&r.global(), None, url, can_gc);
551 *r_clone.request.borrow_mut() = new_req_inner;
552
553 if let Some(body) = body {
556 r_clone.request.borrow_mut().body = Some(body);
557 }
558
559 r_clone
560 .Headers(can_gc)
561 .copy_from_headers(r.Headers(can_gc))?;
562 r_clone.Headers(can_gc).set_guard(headers_guard);
563
564 clone_body_stream_for_dom_body(&r.body_stream, &r_clone.body_stream, can_gc)?;
565
566 Ok(r_clone)
568 }
569
570 pub(crate) fn get_request(&self) -> NetTraitsRequest {
571 self.request.borrow().clone()
572 }
573}
574
575fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest {
576 RequestBuilder::new(global.webview_id(), url, global.get_referrer())
577 .with_global_scope(global)
578 .build()
579}
580
581fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
583 match_ignore_ascii_case! { m,
584 "delete" => return Ok(HttpMethod::DELETE),
585 "get" => return Ok(HttpMethod::GET),
586 "head" => return Ok(HttpMethod::HEAD),
587 "options" => return Ok(HttpMethod::OPTIONS),
588 "post" => return Ok(HttpMethod::POST),
589 "put" => return Ok(HttpMethod::PUT),
590 _ => (),
591 }
592 debug!("Method: {:?}", m);
593 HttpMethod::from_str(m)
594}
595
596fn is_method(m: &ByteString) -> bool {
598 m.as_str().is_some()
599}
600
601fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
603 m == HttpMethod::GET || m == HttpMethod::HEAD || m == HttpMethod::POST
604}
605
606fn includes_credentials(input: &ServoUrl) -> bool {
608 !input.username().is_empty() || input.password().is_some()
609}
610
611impl RequestMethods<crate::DomTypeHolder> for Request {
612 fn Constructor(
614 global: &GlobalScope,
615 proto: Option<HandleObject>,
616 can_gc: CanGc,
617 input: RequestInfo,
618 init: RootedTraceableBox<RequestInit>,
619 ) -> Fallible<DomRoot<Request>> {
620 Self::constructor(global, proto, can_gc, input, &init)
621 }
622
623 fn Method(&self) -> ByteString {
625 let r = self.request.borrow();
626 ByteString::new(r.method.as_ref().as_bytes().into())
627 }
628
629 fn Url(&self) -> USVString {
631 let r = self.request.borrow();
632 USVString(r.url_list.first().map_or("", |u| u.as_str()).into())
633 }
634
635 fn Headers(&self, can_gc: CanGc) -> DomRoot<Headers> {
637 self.headers
638 .or_init(|| Headers::new(&self.global(), can_gc))
639 }
640
641 fn Destination(&self) -> RequestDestination {
643 self.request.borrow().destination.convert()
644 }
645
646 fn Referrer(&self) -> USVString {
648 let r = self.request.borrow();
649 USVString(match r.referrer {
650 NetTraitsRequestReferrer::NoReferrer => String::from(""),
651 NetTraitsRequestReferrer::Client(_) => String::from("about:client"),
652 NetTraitsRequestReferrer::ReferrerUrl(ref u) => {
653 let u_c = u.clone();
654 u_c.into_string()
655 },
656 })
657 }
658
659 fn ReferrerPolicy(&self) -> ReferrerPolicy {
661 self.request.borrow().referrer_policy.convert()
662 }
663
664 fn Mode(&self) -> RequestMode {
666 self.request.borrow().mode.clone().convert()
667 }
668
669 fn Credentials(&self) -> RequestCredentials {
671 let r = self.request.borrow().clone();
672 r.credentials_mode.convert()
673 }
674
675 fn Cache(&self) -> RequestCache {
677 let r = self.request.borrow().clone();
678 r.cache_mode.convert()
679 }
680
681 fn Redirect(&self) -> RequestRedirect {
683 let r = self.request.borrow().clone();
684 r.redirect_mode.convert()
685 }
686
687 fn Integrity(&self) -> DOMString {
689 let r = self.request.borrow();
690 DOMString::from_string(r.integrity_metadata.clone())
691 }
692
693 fn Keepalive(&self) -> bool {
695 self.request.borrow().keep_alive
696 }
697
698 fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
700 self.body()
701 }
702
703 fn BodyUsed(&self) -> bool {
705 self.is_body_used()
706 }
707
708 fn Signal(&self) -> DomRoot<AbortSignal> {
710 self.signal
711 .get()
712 .expect("Should always be initialized in constructor and clone")
713 }
714
715 fn Clone(&self, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
717 if self.is_unusable() {
719 return Err(Error::Type(c"Request is unusable".to_owned()));
720 }
721
722 let cloned_request = Request::clone_from(self, can_gc)?;
724 let signal = self.signal.get().expect("Should always be initialized");
726 let cloned_signal =
729 AbortSignal::create_dependent_abort_signal(vec![signal], &self.global(), can_gc);
730 cloned_request.signal.set(Some(&cloned_signal));
735 Ok(cloned_request)
737 }
738
739 fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
741 consume_body(self, BodyType::Text, can_gc)
742 }
743
744 fn Blob(&self, can_gc: CanGc) -> Rc<Promise> {
746 consume_body(self, BodyType::Blob, can_gc)
747 }
748
749 fn FormData(&self, can_gc: CanGc) -> Rc<Promise> {
751 consume_body(self, BodyType::FormData, can_gc)
752 }
753
754 fn Json(&self, can_gc: CanGc) -> Rc<Promise> {
756 consume_body(self, BodyType::Json, can_gc)
757 }
758
759 fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
761 consume_body(self, BodyType::ArrayBuffer, can_gc)
762 }
763
764 fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
766 consume_body(self, BodyType::Bytes, can_gc)
767 }
768}
769
770impl BodyMixin for Request {
771 fn is_body_used(&self) -> bool {
772 let body_stream = self.body_stream.get();
773 body_stream
774 .as_ref()
775 .is_some_and(|stream| stream.is_disturbed())
776 }
777
778 fn is_unusable(&self) -> bool {
779 let body_stream = self.body_stream.get();
780 body_stream
781 .as_ref()
782 .is_some_and(|stream| stream.is_disturbed() || stream.is_locked())
783 }
784
785 fn body(&self) -> Option<DomRoot<ReadableStream>> {
786 self.body_stream.get()
787 }
788
789 fn get_mime_type(&self, can_gc: CanGc) -> Vec<u8> {
790 let headers = self.Headers(can_gc);
791 headers.extract_mime_type()
792 }
793}
794
795impl Convert<NetTraitsRequestCache> for RequestCache {
796 fn convert(self) -> NetTraitsRequestCache {
797 match self {
798 RequestCache::Default => NetTraitsRequestCache::Default,
799 RequestCache::No_store => NetTraitsRequestCache::NoStore,
800 RequestCache::Reload => NetTraitsRequestCache::Reload,
801 RequestCache::No_cache => NetTraitsRequestCache::NoCache,
802 RequestCache::Force_cache => NetTraitsRequestCache::ForceCache,
803 RequestCache::Only_if_cached => NetTraitsRequestCache::OnlyIfCached,
804 }
805 }
806}
807
808impl Convert<RequestCache> for NetTraitsRequestCache {
809 fn convert(self) -> RequestCache {
810 match self {
811 NetTraitsRequestCache::Default => RequestCache::Default,
812 NetTraitsRequestCache::NoStore => RequestCache::No_store,
813 NetTraitsRequestCache::Reload => RequestCache::Reload,
814 NetTraitsRequestCache::NoCache => RequestCache::No_cache,
815 NetTraitsRequestCache::ForceCache => RequestCache::Force_cache,
816 NetTraitsRequestCache::OnlyIfCached => RequestCache::Only_if_cached,
817 }
818 }
819}
820
821impl Convert<NetTraitsRequestCredentials> for RequestCredentials {
822 fn convert(self) -> NetTraitsRequestCredentials {
823 match self {
824 RequestCredentials::Omit => NetTraitsRequestCredentials::Omit,
825 RequestCredentials::Same_origin => NetTraitsRequestCredentials::CredentialsSameOrigin,
826 RequestCredentials::Include => NetTraitsRequestCredentials::Include,
827 }
828 }
829}
830
831impl Convert<RequestCredentials> for NetTraitsRequestCredentials {
832 fn convert(self) -> RequestCredentials {
833 match self {
834 NetTraitsRequestCredentials::Omit => RequestCredentials::Omit,
835 NetTraitsRequestCredentials::CredentialsSameOrigin => RequestCredentials::Same_origin,
836 NetTraitsRequestCredentials::Include => RequestCredentials::Include,
837 }
838 }
839}
840
841impl Convert<NetTraitsRequestDestination> for RequestDestination {
842 fn convert(self) -> NetTraitsRequestDestination {
843 match self {
844 RequestDestination::_empty => NetTraitsRequestDestination::None,
845 RequestDestination::Audio => NetTraitsRequestDestination::Audio,
846 RequestDestination::Document => NetTraitsRequestDestination::Document,
847 RequestDestination::Embed => NetTraitsRequestDestination::Embed,
848 RequestDestination::Font => NetTraitsRequestDestination::Font,
849 RequestDestination::Frame => NetTraitsRequestDestination::Frame,
850 RequestDestination::Iframe => NetTraitsRequestDestination::IFrame,
851 RequestDestination::Image => NetTraitsRequestDestination::Image,
852 RequestDestination::Manifest => NetTraitsRequestDestination::Manifest,
853 RequestDestination::Json => NetTraitsRequestDestination::Json,
854 RequestDestination::Object => NetTraitsRequestDestination::Object,
855 RequestDestination::Report => NetTraitsRequestDestination::Report,
856 RequestDestination::Script => NetTraitsRequestDestination::Script,
857 RequestDestination::Sharedworker => NetTraitsRequestDestination::SharedWorker,
858 RequestDestination::Style => NetTraitsRequestDestination::Style,
859 RequestDestination::Track => NetTraitsRequestDestination::Track,
860 RequestDestination::Video => NetTraitsRequestDestination::Video,
861 RequestDestination::Worker => NetTraitsRequestDestination::Worker,
862 RequestDestination::Xslt => NetTraitsRequestDestination::Xslt,
863 }
864 }
865}
866
867impl Convert<RequestDestination> for NetTraitsRequestDestination {
868 fn convert(self) -> RequestDestination {
869 match self {
870 NetTraitsRequestDestination::None => RequestDestination::_empty,
871 NetTraitsRequestDestination::Audio => RequestDestination::Audio,
872 NetTraitsRequestDestination::Document => RequestDestination::Document,
873 NetTraitsRequestDestination::Embed => RequestDestination::Embed,
874 NetTraitsRequestDestination::Font => RequestDestination::Font,
875 NetTraitsRequestDestination::Frame => RequestDestination::Frame,
876 NetTraitsRequestDestination::IFrame => RequestDestination::Iframe,
877 NetTraitsRequestDestination::Image => RequestDestination::Image,
878 NetTraitsRequestDestination::Manifest => RequestDestination::Manifest,
879 NetTraitsRequestDestination::Json => RequestDestination::Json,
880 NetTraitsRequestDestination::Object => RequestDestination::Object,
881 NetTraitsRequestDestination::Report => RequestDestination::Report,
882 NetTraitsRequestDestination::Script => RequestDestination::Script,
883 NetTraitsRequestDestination::ServiceWorker |
884 NetTraitsRequestDestination::AudioWorklet |
885 NetTraitsRequestDestination::PaintWorklet => {
886 panic!("ServiceWorker request destination should not be exposed to DOM")
887 },
888 NetTraitsRequestDestination::SharedWorker => RequestDestination::Sharedworker,
889 NetTraitsRequestDestination::Style => RequestDestination::Style,
890 NetTraitsRequestDestination::Track => RequestDestination::Track,
891 NetTraitsRequestDestination::Video => RequestDestination::Video,
892 NetTraitsRequestDestination::Worker => RequestDestination::Worker,
893 NetTraitsRequestDestination::Xslt => RequestDestination::Xslt,
894 NetTraitsRequestDestination::WebIdentity => RequestDestination::_empty,
895 }
896 }
897}
898
899impl Convert<NetTraitsRequestMode> for RequestMode {
900 fn convert(self) -> NetTraitsRequestMode {
901 match self {
902 RequestMode::Navigate => NetTraitsRequestMode::Navigate,
903 RequestMode::Same_origin => NetTraitsRequestMode::SameOrigin,
904 RequestMode::No_cors => NetTraitsRequestMode::NoCors,
905 RequestMode::Cors => NetTraitsRequestMode::CorsMode,
906 }
907 }
908}
909
910impl Convert<RequestMode> for NetTraitsRequestMode {
911 fn convert(self) -> RequestMode {
912 match self {
913 NetTraitsRequestMode::Navigate => RequestMode::Navigate,
914 NetTraitsRequestMode::SameOrigin => RequestMode::Same_origin,
915 NetTraitsRequestMode::NoCors => RequestMode::No_cors,
916 NetTraitsRequestMode::CorsMode => RequestMode::Cors,
917 NetTraitsRequestMode::WebSocket { .. } => {
918 unreachable!("Websocket request mode should never be exposed to Dom")
919 },
920 }
921 }
922}
923
924impl Convert<MsgReferrerPolicy> for ReferrerPolicy {
925 fn convert(self) -> MsgReferrerPolicy {
926 match self {
927 ReferrerPolicy::_empty => MsgReferrerPolicy::EmptyString,
928 ReferrerPolicy::No_referrer => MsgReferrerPolicy::NoReferrer,
929 ReferrerPolicy::No_referrer_when_downgrade => {
930 MsgReferrerPolicy::NoReferrerWhenDowngrade
931 },
932 ReferrerPolicy::Origin => MsgReferrerPolicy::Origin,
933 ReferrerPolicy::Origin_when_cross_origin => MsgReferrerPolicy::OriginWhenCrossOrigin,
934 ReferrerPolicy::Unsafe_url => MsgReferrerPolicy::UnsafeUrl,
935 ReferrerPolicy::Same_origin => MsgReferrerPolicy::SameOrigin,
936 ReferrerPolicy::Strict_origin => MsgReferrerPolicy::StrictOrigin,
937 ReferrerPolicy::Strict_origin_when_cross_origin => {
938 MsgReferrerPolicy::StrictOriginWhenCrossOrigin
939 },
940 }
941 }
942}
943
944impl Convert<ReferrerPolicy> for MsgReferrerPolicy {
945 fn convert(self) -> ReferrerPolicy {
946 match self {
947 MsgReferrerPolicy::EmptyString => ReferrerPolicy::_empty,
948 MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer,
949 MsgReferrerPolicy::NoReferrerWhenDowngrade => {
950 ReferrerPolicy::No_referrer_when_downgrade
951 },
952 MsgReferrerPolicy::Origin => ReferrerPolicy::Origin,
953 MsgReferrerPolicy::OriginWhenCrossOrigin => ReferrerPolicy::Origin_when_cross_origin,
954 MsgReferrerPolicy::UnsafeUrl => ReferrerPolicy::Unsafe_url,
955 MsgReferrerPolicy::SameOrigin => ReferrerPolicy::Same_origin,
956 MsgReferrerPolicy::StrictOrigin => ReferrerPolicy::Strict_origin,
957 MsgReferrerPolicy::StrictOriginWhenCrossOrigin => {
958 ReferrerPolicy::Strict_origin_when_cross_origin
959 },
960 }
961 }
962}
963
964impl Convert<NetTraitsRequestRedirect> for RequestRedirect {
965 fn convert(self) -> NetTraitsRequestRedirect {
966 match self {
967 RequestRedirect::Follow => NetTraitsRequestRedirect::Follow,
968 RequestRedirect::Error => NetTraitsRequestRedirect::Error,
969 RequestRedirect::Manual => NetTraitsRequestRedirect::Manual,
970 }
971 }
972}
973
974impl Convert<RequestRedirect> for NetTraitsRequestRedirect {
975 fn convert(self) -> RequestRedirect {
976 match self {
977 NetTraitsRequestRedirect::Follow => RequestRedirect::Follow,
978 NetTraitsRequestRedirect::Error => RequestRedirect::Error,
979 NetTraitsRequestRedirect::Manual => RequestRedirect::Manual,
980 }
981 }
982}