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::bindings::cell::DomRefCell;
27use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
28use crate::dom::bindings::codegen::Bindings::RequestBinding::{
29 ReferrerPolicy, RequestCache, RequestCredentials, RequestDestination, RequestInfo, RequestInit,
30 RequestMethods, RequestMode, RequestRedirect,
31};
32use crate::dom::bindings::error::{Error, Fallible};
33use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
34use crate::dom::bindings::root::{DomRoot, MutNullableDom};
35use crate::dom::bindings::str::{ByteString, DOMString, USVString};
36use crate::dom::bindings::trace::RootedTraceableBox;
37use crate::dom::globalscope::GlobalScope;
38use crate::dom::headers::{Guard, Headers};
39use crate::dom::promise::Promise;
40use crate::dom::readablestream::ReadableStream;
41use crate::script_runtime::CanGc;
42
43#[dom_struct]
44pub(crate) struct Request {
45 reflector_: Reflector,
46 #[no_trace]
47 request: DomRefCell<NetTraitsRequest>,
48 body_stream: MutNullableDom<ReadableStream>,
49 headers: MutNullableDom<Headers>,
50}
51
52impl Request {
53 fn new_inherited(global: &GlobalScope, url: ServoUrl) -> Request {
54 Request {
55 reflector_: Reflector::new(),
56 request: DomRefCell::new(net_request_from_global(global, url)),
57 body_stream: MutNullableDom::new(None),
58 headers: Default::default(),
59 }
60 }
61
62 fn new(
63 global: &GlobalScope,
64 proto: Option<HandleObject>,
65 url: ServoUrl,
66 can_gc: CanGc,
67 ) -> DomRoot<Request> {
68 reflect_dom_object_with_proto(
69 Box::new(Request::new_inherited(global, url)),
70 global,
71 proto,
72 can_gc,
73 )
74 }
75
76 fn from_net_request(
77 global: &GlobalScope,
78 proto: Option<HandleObject>,
79 net_request: NetTraitsRequest,
80 can_gc: CanGc,
81 ) -> DomRoot<Request> {
82 let r = Request::new(global, proto, net_request.current_url(), can_gc);
83 *r.request.borrow_mut() = net_request;
84 r
85 }
86
87 fn clone_from(r: &Request, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
88 let req = r.request.borrow();
89 let url = req.url();
90 let headers_guard = r.Headers(can_gc).get_guard();
91 let r_clone = Request::new(&r.global(), None, url, can_gc);
92 r_clone.request.borrow_mut().pipeline_id = req.pipeline_id;
93 {
94 let mut borrowed_r_request = r_clone.request.borrow_mut();
95 borrowed_r_request.origin = req.origin.clone();
96 }
97 *r_clone.request.borrow_mut() = req.clone();
98 r_clone
99 .Headers(can_gc)
100 .copy_from_headers(r.Headers(can_gc))?;
101 r_clone.Headers(can_gc).set_guard(headers_guard);
102 Ok(r_clone)
103 }
104
105 pub(crate) fn get_request(&self) -> NetTraitsRequest {
106 self.request.borrow().clone()
107 }
108}
109
110fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest {
111 RequestBuilder::new(global.webview_id(), url, global.get_referrer())
112 .origin(global.get_url().origin())
113 .pipeline_id(Some(global.pipeline_id()))
114 .https_state(global.get_https_state())
115 .insecure_requests_policy(global.insecure_requests_policy())
116 .has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
117 .build()
118}
119
120fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
122 match_ignore_ascii_case! { m,
123 "delete" => return Ok(HttpMethod::DELETE),
124 "get" => return Ok(HttpMethod::GET),
125 "head" => return Ok(HttpMethod::HEAD),
126 "options" => return Ok(HttpMethod::OPTIONS),
127 "post" => return Ok(HttpMethod::POST),
128 "put" => return Ok(HttpMethod::PUT),
129 _ => (),
130 }
131 debug!("Method: {:?}", m);
132 HttpMethod::from_str(m)
133}
134
135fn is_method(m: &ByteString) -> bool {
137 m.as_str().is_some()
138}
139
140fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
142 m == HttpMethod::GET || m == HttpMethod::HEAD || m == HttpMethod::POST
143}
144
145fn includes_credentials(input: &ServoUrl) -> bool {
147 !input.username().is_empty() || input.password().is_some()
148}
149
150fn request_is_disturbed(input: &Request) -> bool {
152 input.is_disturbed()
153}
154
155fn request_is_locked(input: &Request) -> bool {
157 input.is_locked()
158}
159
160impl RequestMethods<crate::DomTypeHolder> for Request {
161 fn Constructor(
163 global: &GlobalScope,
164 proto: Option<HandleObject>,
165 can_gc: CanGc,
166 mut input: RequestInfo,
167 init: RootedTraceableBox<RequestInit>,
168 ) -> Fallible<DomRoot<Request>> {
169 let temporary_request: NetTraitsRequest;
171
172 let mut fallback_mode: Option<NetTraitsRequestMode> = None;
174
175 let base_url = global.api_base_url();
177
178 match input {
181 RequestInfo::USVString(USVString(ref usv_string)) => {
183 let parsed_url = base_url.join(usv_string);
185 if parsed_url.is_err() {
187 return Err(Error::Type("Url could not be parsed".to_string()));
188 }
189 let url = parsed_url.unwrap();
191 if includes_credentials(&url) {
192 return Err(Error::Type("Url includes credentials".to_string()));
193 }
194 temporary_request = net_request_from_global(global, url);
196 fallback_mode = Some(NetTraitsRequestMode::CorsMode);
198 },
199 RequestInfo::Request(ref input_request) => {
201 if request_is_disturbed(input_request) || request_is_locked(input_request) {
204 return Err(Error::Type("Input is disturbed or locked".to_string()));
205 }
206 temporary_request = input_request.request.borrow().clone();
208 },
210 }
211
212 let origin = base_url.origin();
215
216 let mut window = Window::Client;
218
219 if !init.window.handle().is_null_or_undefined() {
224 return Err(Error::Type("Window is present and is not null".to_string()));
225 }
226
227 if !init.window.handle().is_undefined() {
229 window = Window::NoWindow;
230 }
231
232 let mut request: NetTraitsRequest;
234 request = net_request_from_global(global, temporary_request.current_url());
235 request.method = temporary_request.method;
236 request.headers = temporary_request.headers.clone();
237 request.unsafe_request = true;
238 request.window = window;
239 request.origin = Origin::Client;
241 request.referrer = temporary_request.referrer;
242 request.referrer_policy = temporary_request.referrer_policy;
243 request.mode = temporary_request.mode;
244 request.credentials_mode = temporary_request.credentials_mode;
245 request.cache_mode = temporary_request.cache_mode;
246 request.redirect_mode = temporary_request.redirect_mode;
247 request.integrity_metadata = temporary_request.integrity_metadata;
248
249 if init.body.is_some() ||
251 init.cache.is_some() ||
252 init.credentials.is_some() ||
253 init.integrity.is_some() ||
254 init.headers.is_some() ||
255 init.method.is_some() ||
256 init.mode.is_some() ||
257 init.redirect.is_some() ||
258 init.referrer.is_some() ||
259 init.referrerPolicy.is_some() ||
260 !init.window.handle().is_undefined()
261 {
262 if request.mode == NetTraitsRequestMode::Navigate {
264 request.mode = NetTraitsRequestMode::SameOrigin;
265 }
266 request.referrer = global.get_referrer();
270 request.referrer_policy = MsgReferrerPolicy::EmptyString;
272 }
273
274 if let Some(init_referrer) = init.referrer.as_ref() {
276 let referrer = &init_referrer.0;
278 if referrer.is_empty() {
280 request.referrer = NetTraitsRequestReferrer::NoReferrer;
281 } else {
282 let parsed_referrer = base_url.join(referrer);
284 if parsed_referrer.is_err() {
286 return Err(Error::Type("Failed to parse referrer url".to_string()));
287 }
288 if let Ok(parsed_referrer) = parsed_referrer {
290 if (parsed_referrer.cannot_be_a_base() &&
291 parsed_referrer.scheme() == "about" &&
292 parsed_referrer.path() == "client") ||
293 parsed_referrer.origin() != origin
294 {
295 request.referrer = global.get_referrer();
296 } else {
297 request.referrer = NetTraitsRequestReferrer::ReferrerUrl(parsed_referrer);
299 }
300 }
301 }
302 }
303
304 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() {
306 let init_referrer_policy = (*init_referrerpolicy).convert();
307 request.referrer_policy = init_referrer_policy;
308 }
309
310 let mode = init.mode.as_ref().map(|m| (*m).convert()).or(fallback_mode);
312
313 if let Some(NetTraitsRequestMode::Navigate) = mode {
315 return Err(Error::Type("Request mode is Navigate".to_string()));
316 }
317
318 if let Some(m) = mode {
320 request.mode = m;
321 }
322
323 if let Some(init_credentials) = init.credentials.as_ref() {
325 let credentials = (*init_credentials).convert();
326 request.credentials_mode = credentials;
327 }
328
329 if let Some(init_cache) = init.cache.as_ref() {
331 let cache = (*init_cache).convert();
332 request.cache_mode = cache;
333 }
334
335 if request.cache_mode == NetTraitsRequestCache::OnlyIfCached &&
337 request.mode != NetTraitsRequestMode::SameOrigin
338 {
339 return Err(Error::Type(
340 "Cache is 'only-if-cached' and mode is not 'same-origin'".to_string(),
341 ));
342 }
343
344 if let Some(init_redirect) = init.redirect.as_ref() {
346 let redirect = (*init_redirect).convert();
347 request.redirect_mode = redirect;
348 }
349
350 if let Some(init_integrity) = init.integrity.as_ref() {
352 let integrity = init_integrity.clone().to_string();
353 request.integrity_metadata = integrity;
354 }
355
356 if let Some(init_method) = init.method.as_ref() {
360 if !is_method(init_method) {
361 return Err(Error::Type("Method is not a method".to_string()));
362 }
363 if is_forbidden_method(init_method) {
365 return Err(Error::Type("Method is forbidden".to_string()));
366 }
367 let method = match init_method.as_str() {
369 Some(s) => normalize_method(s)
370 .map_err(|e| Error::Type(format!("Method is not valid: {:?}", e)))?,
371 None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
372 };
373 request.method = method;
375 }
376
377 let r = Request::from_net_request(global, proto, request, can_gc);
382
383 r.headers
390 .or_init(|| Headers::for_request(&r.global(), can_gc));
391
392 let headers_copy = init
394 .headers
395 .as_ref()
396 .map(|possible_header| match possible_header {
397 HeadersInit::ByteStringSequenceSequence(init_sequence) => {
398 HeadersInit::ByteStringSequenceSequence(init_sequence.clone())
399 },
400 HeadersInit::ByteStringByteStringRecord(init_map) => {
401 HeadersInit::ByteStringByteStringRecord(init_map.clone())
402 },
403 });
404
405 if r.request.borrow().mode == NetTraitsRequestMode::NoCors {
416 let borrowed_request = r.request.borrow();
417 if !is_cors_safelisted_method(&borrowed_request.method) {
419 return Err(Error::Type(
420 "The mode is 'no-cors' but the method is not a cors-safelisted method"
421 .to_string(),
422 ));
423 }
424 r.Headers(can_gc).set_guard(Guard::RequestNoCors);
426 }
427
428 match headers_copy {
430 None => {
431 if let RequestInfo::Request(ref input_request) = input {
436 r.Headers(can_gc)
437 .copy_from_headers(input_request.Headers(can_gc))?;
438 }
439 },
440 Some(headers_copy) => r.Headers(can_gc).fill(Some(headers_copy))?,
441 }
442
443 r.request.borrow_mut().headers = r.Headers(can_gc).get_headers_list();
446
447 let mut input_body = if let RequestInfo::Request(ref mut input_request) = input {
449 let mut input_request_request = input_request.request.borrow_mut();
450 input_request_request.body.take()
451 } else {
452 None
453 };
454
455 if let Some(init_body_option) = init.body.as_ref() {
457 if init_body_option.is_some() || input_body.is_some() {
458 let req = r.request.borrow();
459 let req_method = &req.method;
460 match *req_method {
461 HttpMethod::GET => {
462 return Err(Error::Type(
463 "Init's body is non-null, and request method is GET".to_string(),
464 ));
465 },
466 HttpMethod::HEAD => {
467 return Err(Error::Type(
468 "Init's body is non-null, and request method is HEAD".to_string(),
469 ));
470 },
471 _ => {},
472 }
473 }
474 }
475
476 if let Some(Some(ref init_body)) = init.body {
478 let mut extracted_body = init_body.extract(global, can_gc)?;
482
483 if let Some(contents) = extracted_body.content_type.take() {
485 let ct_header_name = b"Content-Type";
486 if !r
487 .Headers(can_gc)
488 .Has(ByteString::new(ct_header_name.to_vec()))
489 .unwrap()
490 {
491 let ct_header_val = contents.as_bytes();
492 r.Headers(can_gc).Append(
493 ByteString::new(ct_header_name.to_vec()),
494 ByteString::new(ct_header_val.to_vec()),
495 )?;
496
497 if let Ok(v) = HeaderValue::from_bytes(ct_header_val) {
502 r.request
503 .borrow_mut()
504 .headers
505 .insert(HeaderName::from_bytes(ct_header_name).unwrap(), v);
506 }
507 }
508 }
509
510 let (net_body, stream) = extracted_body.into_net_request_body();
511 r.body_stream.set(Some(&*stream));
512 input_body = Some(net_body);
513 }
514
515 r.request.borrow_mut().body = input_body;
525
526 Ok(r)
528 }
529
530 fn Method(&self) -> ByteString {
532 let r = self.request.borrow();
533 ByteString::new(r.method.as_ref().as_bytes().into())
534 }
535
536 fn Url(&self) -> USVString {
538 let r = self.request.borrow();
539 USVString(r.url_list.first().map_or("", |u| u.as_str()).into())
540 }
541
542 fn Headers(&self, can_gc: CanGc) -> DomRoot<Headers> {
544 self.headers
545 .or_init(|| Headers::new(&self.global(), can_gc))
546 }
547
548 fn Destination(&self) -> RequestDestination {
550 self.request.borrow().destination.convert()
551 }
552
553 fn Referrer(&self) -> USVString {
555 let r = self.request.borrow();
556 USVString(match r.referrer {
557 NetTraitsRequestReferrer::NoReferrer => String::from(""),
558 NetTraitsRequestReferrer::Client(_) => String::from("about:client"),
559 NetTraitsRequestReferrer::ReferrerUrl(ref u) => {
560 let u_c = u.clone();
561 u_c.into_string()
562 },
563 })
564 }
565
566 fn ReferrerPolicy(&self) -> ReferrerPolicy {
568 self.request.borrow().referrer_policy.convert()
569 }
570
571 fn Mode(&self) -> RequestMode {
573 self.request.borrow().mode.clone().convert()
574 }
575
576 fn Credentials(&self) -> RequestCredentials {
578 let r = self.request.borrow().clone();
579 r.credentials_mode.convert()
580 }
581
582 fn Cache(&self) -> RequestCache {
584 let r = self.request.borrow().clone();
585 r.cache_mode.convert()
586 }
587
588 fn Redirect(&self) -> RequestRedirect {
590 let r = self.request.borrow().clone();
591 r.redirect_mode.convert()
592 }
593
594 fn Integrity(&self) -> DOMString {
596 let r = self.request.borrow();
597 DOMString::from_string(r.integrity_metadata.clone())
598 }
599
600 fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
602 self.body()
603 }
604
605 fn BodyUsed(&self) -> bool {
607 self.is_disturbed()
608 }
609
610 fn Clone(&self, can_gc: CanGc) -> Fallible<DomRoot<Request>> {
612 if request_is_locked(self) {
614 return Err(Error::Type("Request is locked".to_string()));
615 }
616 if request_is_disturbed(self) {
617 return Err(Error::Type("Request is disturbed".to_string()));
618 }
619
620 Request::clone_from(self, can_gc)
622 }
623
624 fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
626 consume_body(self, BodyType::Text, can_gc)
627 }
628
629 fn Blob(&self, can_gc: CanGc) -> Rc<Promise> {
631 consume_body(self, BodyType::Blob, can_gc)
632 }
633
634 fn FormData(&self, can_gc: CanGc) -> Rc<Promise> {
636 consume_body(self, BodyType::FormData, can_gc)
637 }
638
639 fn Json(&self, can_gc: CanGc) -> Rc<Promise> {
641 consume_body(self, BodyType::Json, can_gc)
642 }
643
644 fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
646 consume_body(self, BodyType::ArrayBuffer, can_gc)
647 }
648
649 fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
651 consume_body(self, BodyType::Bytes, can_gc)
652 }
653}
654
655impl BodyMixin for Request {
656 fn is_disturbed(&self) -> bool {
657 let body_stream = self.body_stream.get();
658 body_stream
659 .as_ref()
660 .is_some_and(|stream| stream.is_disturbed())
661 }
662
663 fn is_locked(&self) -> bool {
664 let body_stream = self.body_stream.get();
665 body_stream.is_some_and(|stream| stream.is_locked())
666 }
667
668 fn body(&self) -> Option<DomRoot<ReadableStream>> {
669 self.body_stream.get()
670 }
671
672 fn get_mime_type(&self, can_gc: CanGc) -> Vec<u8> {
673 let headers = self.Headers(can_gc);
674 headers.extract_mime_type()
675 }
676}
677
678impl Convert<NetTraitsRequestCache> for RequestCache {
679 fn convert(self) -> NetTraitsRequestCache {
680 match self {
681 RequestCache::Default => NetTraitsRequestCache::Default,
682 RequestCache::No_store => NetTraitsRequestCache::NoStore,
683 RequestCache::Reload => NetTraitsRequestCache::Reload,
684 RequestCache::No_cache => NetTraitsRequestCache::NoCache,
685 RequestCache::Force_cache => NetTraitsRequestCache::ForceCache,
686 RequestCache::Only_if_cached => NetTraitsRequestCache::OnlyIfCached,
687 }
688 }
689}
690
691impl Convert<RequestCache> for NetTraitsRequestCache {
692 fn convert(self) -> RequestCache {
693 match self {
694 NetTraitsRequestCache::Default => RequestCache::Default,
695 NetTraitsRequestCache::NoStore => RequestCache::No_store,
696 NetTraitsRequestCache::Reload => RequestCache::Reload,
697 NetTraitsRequestCache::NoCache => RequestCache::No_cache,
698 NetTraitsRequestCache::ForceCache => RequestCache::Force_cache,
699 NetTraitsRequestCache::OnlyIfCached => RequestCache::Only_if_cached,
700 }
701 }
702}
703
704impl Convert<NetTraitsRequestCredentials> for RequestCredentials {
705 fn convert(self) -> NetTraitsRequestCredentials {
706 match self {
707 RequestCredentials::Omit => NetTraitsRequestCredentials::Omit,
708 RequestCredentials::Same_origin => NetTraitsRequestCredentials::CredentialsSameOrigin,
709 RequestCredentials::Include => NetTraitsRequestCredentials::Include,
710 }
711 }
712}
713
714impl Convert<RequestCredentials> for NetTraitsRequestCredentials {
715 fn convert(self) -> RequestCredentials {
716 match self {
717 NetTraitsRequestCredentials::Omit => RequestCredentials::Omit,
718 NetTraitsRequestCredentials::CredentialsSameOrigin => RequestCredentials::Same_origin,
719 NetTraitsRequestCredentials::Include => RequestCredentials::Include,
720 }
721 }
722}
723
724impl Convert<NetTraitsRequestDestination> for RequestDestination {
725 fn convert(self) -> NetTraitsRequestDestination {
726 match self {
727 RequestDestination::_empty => NetTraitsRequestDestination::None,
728 RequestDestination::Audio => NetTraitsRequestDestination::Audio,
729 RequestDestination::Document => NetTraitsRequestDestination::Document,
730 RequestDestination::Embed => NetTraitsRequestDestination::Embed,
731 RequestDestination::Font => NetTraitsRequestDestination::Font,
732 RequestDestination::Frame => NetTraitsRequestDestination::Frame,
733 RequestDestination::Iframe => NetTraitsRequestDestination::IFrame,
734 RequestDestination::Image => NetTraitsRequestDestination::Image,
735 RequestDestination::Manifest => NetTraitsRequestDestination::Manifest,
736 RequestDestination::Json => NetTraitsRequestDestination::Json,
737 RequestDestination::Object => NetTraitsRequestDestination::Object,
738 RequestDestination::Report => NetTraitsRequestDestination::Report,
739 RequestDestination::Script => NetTraitsRequestDestination::Script,
740 RequestDestination::Sharedworker => NetTraitsRequestDestination::SharedWorker,
741 RequestDestination::Style => NetTraitsRequestDestination::Style,
742 RequestDestination::Track => NetTraitsRequestDestination::Track,
743 RequestDestination::Video => NetTraitsRequestDestination::Video,
744 RequestDestination::Worker => NetTraitsRequestDestination::Worker,
745 RequestDestination::Xslt => NetTraitsRequestDestination::Xslt,
746 }
747 }
748}
749
750impl Convert<RequestDestination> for NetTraitsRequestDestination {
751 fn convert(self) -> RequestDestination {
752 match self {
753 NetTraitsRequestDestination::None => RequestDestination::_empty,
754 NetTraitsRequestDestination::Audio => RequestDestination::Audio,
755 NetTraitsRequestDestination::Document => RequestDestination::Document,
756 NetTraitsRequestDestination::Embed => RequestDestination::Embed,
757 NetTraitsRequestDestination::Font => RequestDestination::Font,
758 NetTraitsRequestDestination::Frame => RequestDestination::Frame,
759 NetTraitsRequestDestination::IFrame => RequestDestination::Iframe,
760 NetTraitsRequestDestination::Image => RequestDestination::Image,
761 NetTraitsRequestDestination::Manifest => RequestDestination::Manifest,
762 NetTraitsRequestDestination::Json => RequestDestination::Json,
763 NetTraitsRequestDestination::Object => RequestDestination::Object,
764 NetTraitsRequestDestination::Report => RequestDestination::Report,
765 NetTraitsRequestDestination::Script => RequestDestination::Script,
766 NetTraitsRequestDestination::ServiceWorker |
767 NetTraitsRequestDestination::AudioWorklet |
768 NetTraitsRequestDestination::PaintWorklet => {
769 panic!("ServiceWorker request destination should not be exposed to DOM")
770 },
771 NetTraitsRequestDestination::SharedWorker => RequestDestination::Sharedworker,
772 NetTraitsRequestDestination::Style => RequestDestination::Style,
773 NetTraitsRequestDestination::Track => RequestDestination::Track,
774 NetTraitsRequestDestination::Video => RequestDestination::Video,
775 NetTraitsRequestDestination::Worker => RequestDestination::Worker,
776 NetTraitsRequestDestination::Xslt => RequestDestination::Xslt,
777 NetTraitsRequestDestination::WebIdentity => RequestDestination::_empty,
778 }
779 }
780}
781
782impl Convert<NetTraitsRequestMode> for RequestMode {
783 fn convert(self) -> NetTraitsRequestMode {
784 match self {
785 RequestMode::Navigate => NetTraitsRequestMode::Navigate,
786 RequestMode::Same_origin => NetTraitsRequestMode::SameOrigin,
787 RequestMode::No_cors => NetTraitsRequestMode::NoCors,
788 RequestMode::Cors => NetTraitsRequestMode::CorsMode,
789 }
790 }
791}
792
793impl Convert<RequestMode> for NetTraitsRequestMode {
794 fn convert(self) -> RequestMode {
795 match self {
796 NetTraitsRequestMode::Navigate => RequestMode::Navigate,
797 NetTraitsRequestMode::SameOrigin => RequestMode::Same_origin,
798 NetTraitsRequestMode::NoCors => RequestMode::No_cors,
799 NetTraitsRequestMode::CorsMode => RequestMode::Cors,
800 NetTraitsRequestMode::WebSocket { .. } => {
801 unreachable!("Websocket request mode should never be exposed to Dom")
802 },
803 }
804 }
805}
806
807impl Convert<MsgReferrerPolicy> for ReferrerPolicy {
808 fn convert(self) -> MsgReferrerPolicy {
809 match self {
810 ReferrerPolicy::_empty => MsgReferrerPolicy::EmptyString,
811 ReferrerPolicy::No_referrer => MsgReferrerPolicy::NoReferrer,
812 ReferrerPolicy::No_referrer_when_downgrade => {
813 MsgReferrerPolicy::NoReferrerWhenDowngrade
814 },
815 ReferrerPolicy::Origin => MsgReferrerPolicy::Origin,
816 ReferrerPolicy::Origin_when_cross_origin => MsgReferrerPolicy::OriginWhenCrossOrigin,
817 ReferrerPolicy::Unsafe_url => MsgReferrerPolicy::UnsafeUrl,
818 ReferrerPolicy::Same_origin => MsgReferrerPolicy::SameOrigin,
819 ReferrerPolicy::Strict_origin => MsgReferrerPolicy::StrictOrigin,
820 ReferrerPolicy::Strict_origin_when_cross_origin => {
821 MsgReferrerPolicy::StrictOriginWhenCrossOrigin
822 },
823 }
824 }
825}
826
827impl Convert<ReferrerPolicy> for MsgReferrerPolicy {
828 fn convert(self) -> ReferrerPolicy {
829 match self {
830 MsgReferrerPolicy::EmptyString => ReferrerPolicy::_empty,
831 MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer,
832 MsgReferrerPolicy::NoReferrerWhenDowngrade => {
833 ReferrerPolicy::No_referrer_when_downgrade
834 },
835 MsgReferrerPolicy::Origin => ReferrerPolicy::Origin,
836 MsgReferrerPolicy::OriginWhenCrossOrigin => ReferrerPolicy::Origin_when_cross_origin,
837 MsgReferrerPolicy::UnsafeUrl => ReferrerPolicy::Unsafe_url,
838 MsgReferrerPolicy::SameOrigin => ReferrerPolicy::Same_origin,
839 MsgReferrerPolicy::StrictOrigin => ReferrerPolicy::Strict_origin,
840 MsgReferrerPolicy::StrictOriginWhenCrossOrigin => {
841 ReferrerPolicy::Strict_origin_when_cross_origin
842 },
843 }
844 }
845}
846
847impl Convert<NetTraitsRequestRedirect> for RequestRedirect {
848 fn convert(self) -> NetTraitsRequestRedirect {
849 match self {
850 RequestRedirect::Follow => NetTraitsRequestRedirect::Follow,
851 RequestRedirect::Error => NetTraitsRequestRedirect::Error,
852 RequestRedirect::Manual => NetTraitsRequestRedirect::Manual,
853 }
854 }
855}
856
857impl Convert<RequestRedirect> for NetTraitsRequestRedirect {
858 fn convert(self) -> RequestRedirect {
859 match self {
860 NetTraitsRequestRedirect::Follow => RequestRedirect::Follow,
861 NetTraitsRequestRedirect::Error => RequestRedirect::Error,
862 NetTraitsRequestRedirect::Manual => RequestRedirect::Manual,
863 }
864 }
865}