1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 use body::{BodyOperations, BodyType, consume_body};
6 use dom::bindings::cell::DomRefCell;
7 use dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
8 use dom::bindings::codegen::Bindings::RequestBinding;
9 use dom::bindings::codegen::Bindings::RequestBinding::ReferrerPolicy;
10 use dom::bindings::codegen::Bindings::RequestBinding::RequestCache;
11 use dom::bindings::codegen::Bindings::RequestBinding::RequestCredentials;
12 use dom::bindings::codegen::Bindings::RequestBinding::RequestDestination;
13 use dom::bindings::codegen::Bindings::RequestBinding::RequestInfo;
14 use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
15 use dom::bindings::codegen::Bindings::RequestBinding::RequestMethods;
16 use dom::bindings::codegen::Bindings::RequestBinding::RequestMode;
17 use dom::bindings::codegen::Bindings::RequestBinding::RequestRedirect;
18 use dom::bindings::error::{Error, Fallible};
19 use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
20 use dom::bindings::root::{DomRoot, MutNullableDom};
21 use dom::bindings::str::{ByteString, DOMString, USVString};
22 use dom::bindings::trace::RootedTraceableBox;
23 use dom::globalscope::GlobalScope;
24 use dom::headers::{Guard, Headers};
25 use dom::promise::Promise;
26 use dom::xmlhttprequest::Extractable;
27 use dom_struct::dom_struct;
28 use hyper::method::Method as HttpMethod;
29 use net_traits::ReferrerPolicy as MsgReferrerPolicy;
30 use net_traits::request::{Origin, Window};
31 use net_traits::request::CacheMode as NetTraitsRequestCache;
32 use net_traits::request::CredentialsMode as NetTraitsRequestCredentials;
33 use net_traits::request::Destination as NetTraitsRequestDestination;
34 use net_traits::request::RedirectMode as NetTraitsRequestRedirect;
35 use net_traits::request::Referrer as NetTraitsRequestReferrer;
36 use net_traits::request::Request as NetTraitsRequest;
37 use net_traits::request::RequestMode as NetTraitsRequestMode;
38 use servo_url::ServoUrl;
39 use std::cell::{Cell, Ref};
40 use std::rc::Rc;
41
42 #[dom_struct]
43 pub struct Request {
44 reflector_: Reflector,
45 request: DomRefCell<NetTraitsRequest>,
46 body_used: Cell<bool>,
47 headers: MutNullableDom<Headers>,
48 mime_type: DomRefCell<Vec<u8>>,
49 #[ignore_malloc_size_of = "Rc"]
50 body_promise: DomRefCell<Option<(Rc<Promise>, BodyType)>>,
51 }
52
53 impl Request {
new_inherited(global: &GlobalScope, url: ServoUrl) -> Request54 fn new_inherited(global: &GlobalScope,
55 url: ServoUrl) -> Request {
56 Request {
57 reflector_: Reflector::new(),
58 request: DomRefCell::new(
59 net_request_from_global(global, url)),
60 body_used: Cell::new(false),
61 headers: Default::default(),
62 mime_type: DomRefCell::new("".to_string().into_bytes()),
63 body_promise: DomRefCell::new(None),
64 }
65 }
66
new(global: &GlobalScope, url: ServoUrl) -> DomRoot<Request>67 pub fn new(global: &GlobalScope,
68 url: ServoUrl) -> DomRoot<Request> {
69 reflect_dom_object(Box::new(Request::new_inherited(global, url)),
70 global, RequestBinding::Wrap)
71 }
72
73 // https://fetch.spec.whatwg.org/#dom-request
Constructor(global: &GlobalScope, input: RequestInfo, init: RootedTraceableBox<RequestInit>) -> Fallible<DomRoot<Request>>74 pub fn Constructor(global: &GlobalScope,
75 input: RequestInfo,
76 init: RootedTraceableBox<RequestInit>)
77 -> Fallible<DomRoot<Request>> {
78 // Step 1
79 let temporary_request: NetTraitsRequest;
80
81 // Step 2
82 let mut fallback_mode: Option<NetTraitsRequestMode> = None;
83
84 // Step 3
85 let mut fallback_credentials: Option<NetTraitsRequestCredentials> = None;
86
87 // Step 4
88 let base_url = global.api_base_url();
89
90 match input {
91 // Step 5
92 RequestInfo::USVString(USVString(ref usv_string)) => {
93 // Step 5.1
94 let parsed_url = base_url.join(&usv_string);
95 // Step 5.2
96 if parsed_url.is_err() {
97 return Err(Error::Type("Url could not be parsed".to_string()))
98 }
99 // Step 5.3
100 let url = parsed_url.unwrap();
101 if includes_credentials(&url) {
102 return Err(Error::Type("Url includes credentials".to_string()))
103 }
104 // Step 5.4
105 temporary_request = net_request_from_global(global, url);
106 // Step 5.5
107 fallback_mode = Some(NetTraitsRequestMode::CorsMode);
108 // Step 5.6
109 fallback_credentials = Some(NetTraitsRequestCredentials::Omit);
110 }
111 // Step 6
112 RequestInfo::Request(ref input_request) => {
113 // Step 6.1
114 if request_is_disturbed(input_request) || request_is_locked(input_request) {
115 return Err(Error::Type("Input is disturbed or locked".to_string()))
116 }
117 // Step 6.2
118 temporary_request = input_request.request.borrow().clone();
119 }
120 }
121
122 // Step 7
123 // TODO: `entry settings object` is not implemented yet.
124 let origin = base_url.origin();
125
126 // Step 8
127 let mut window = Window::Client;
128
129 // Step 9
130 // TODO: `environment settings object` is not implemented in Servo yet.
131
132 // Step 10
133 if !init.window.handle().is_null_or_undefined() {
134 return Err(Error::Type("Window is present and is not null".to_string()))
135 }
136
137 // Step 11
138 if !init.window.handle().is_undefined() {
139 window = Window::NoWindow;
140 }
141
142 // Step 12
143 let mut request: NetTraitsRequest;
144 request = net_request_from_global(global, temporary_request.current_url());
145 request.method = temporary_request.method;
146 request.headers = temporary_request.headers.clone();
147 request.unsafe_request = true;
148 request.window = window;
149 // TODO: `entry settings object` is not implemented in Servo yet.
150 request.origin = Origin::Client;
151 request.referrer = temporary_request.referrer;
152 request.referrer_policy = temporary_request.referrer_policy;
153 request.mode = temporary_request.mode;
154 request.credentials_mode = temporary_request.credentials_mode;
155 request.cache_mode = temporary_request.cache_mode;
156 request.redirect_mode = temporary_request.redirect_mode;
157 request.integrity_metadata = temporary_request.integrity_metadata;
158
159 // Step 13
160 if init.body.is_some() ||
161 init.cache.is_some() ||
162 init.credentials.is_some() ||
163 init.integrity.is_some() ||
164 init.headers.is_some() ||
165 init.method.is_some() ||
166 init.mode.is_some() ||
167 init.redirect.is_some() ||
168 init.referrer.is_some() ||
169 init.referrerPolicy.is_some() ||
170 !init.window.handle().is_undefined() {
171 // Step 13.1
172 if request.mode == NetTraitsRequestMode::Navigate {
173 request.mode = NetTraitsRequestMode::SameOrigin;
174 }
175 // Step 13.2
176 request.referrer = NetTraitsRequestReferrer::Client;
177 // Step 13.3
178 request.referrer_policy = None;
179 }
180
181 // Step 14
182 if let Some(init_referrer) = init.referrer.as_ref() {
183 // Step 14.1
184 let ref referrer = init_referrer.0;
185 // Step 14.2
186 if referrer.is_empty() {
187 request.referrer = NetTraitsRequestReferrer::NoReferrer;
188 } else {
189 // Step 14.3
190 let parsed_referrer = base_url.join(referrer);
191 // Step 14.4
192 if parsed_referrer.is_err() {
193 return Err(Error::Type(
194 "Failed to parse referrer url".to_string()));
195 }
196 // Step 14.5
197 if let Ok(parsed_referrer) = parsed_referrer {
198 if (parsed_referrer.cannot_be_a_base() &&
199 parsed_referrer.scheme() == "about" &&
200 parsed_referrer.path() == "client") ||
201 parsed_referrer.origin() != origin {
202 request.referrer = NetTraitsRequestReferrer::Client;
203 } else {
204 // Step 14.6
205 request.referrer = NetTraitsRequestReferrer::ReferrerUrl(parsed_referrer);
206 }
207 }
208 }
209 }
210
211 // Step 15
212 if let Some(init_referrerpolicy) = init.referrerPolicy.as_ref() {
213 let init_referrer_policy = init_referrerpolicy.clone().into();
214 request.referrer_policy = Some(init_referrer_policy);
215 }
216
217 // Step 16
218 let mode = init.mode.as_ref().map(|m| m.clone().into()).or(fallback_mode);
219
220 // Step 17
221 if let Some(NetTraitsRequestMode::Navigate) = mode {
222 return Err(Error::Type("Request mode is Navigate".to_string()));
223 }
224
225 // Step 18
226 if let Some(m) = mode {
227 request.mode = m;
228 }
229
230 // Step 19
231 let credentials = init.credentials.as_ref().map(|m| m.clone().into()).or(fallback_credentials);
232
233 // Step 20
234 if let Some(c) = credentials {
235 request.credentials_mode = c;
236 }
237
238 // Step 21
239 if let Some(init_cache) = init.cache.as_ref() {
240 let cache = init_cache.clone().into();
241 request.cache_mode = cache;
242 }
243
244 // Step 22
245 if request.cache_mode == NetTraitsRequestCache::OnlyIfCached {
246 if request.mode != NetTraitsRequestMode::SameOrigin {
247 return Err(Error::Type(
248 "Cache is 'only-if-cached' and mode is not 'same-origin'".to_string()));
249 }
250 }
251
252 // Step 23
253 if let Some(init_redirect) = init.redirect.as_ref() {
254 let redirect = init_redirect.clone().into();
255 request.redirect_mode = redirect;
256 }
257
258 // Step 24
259 if let Some(init_integrity) = init.integrity.as_ref() {
260 let integrity = init_integrity.clone().to_string();
261 request.integrity_metadata = integrity;
262 }
263
264 // Step 25
265 if let Some(init_method) = init.method.as_ref() {
266 // Step 25.1
267 if !is_method(&init_method) {
268 return Err(Error::Type("Method is not a method".to_string()));
269 }
270 if is_forbidden_method(&init_method) {
271 return Err(Error::Type("Method is forbidden".to_string()));
272 }
273 // Step 25.2
274 let method = match init_method.as_str() {
275 Some(s) => normalize_method(s),
276 None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
277 };
278 // Step 25.3
279 request.method = method;
280 }
281
282 // Step 26
283 let r = Request::from_net_request(global, request);
284 r.headers.or_init(|| Headers::for_request(&r.global()));
285
286 // Step 27
287 let mut headers_copy = r.Headers();
288
289 // Step 28
290 if let Some(possible_header) = init.headers.as_ref() {
291 match possible_header {
292 &HeadersInit::Headers(ref init_headers) => {
293 headers_copy = DomRoot::from_ref(&*init_headers);
294 }
295 &HeadersInit::ByteStringSequenceSequence(ref init_sequence) => {
296 headers_copy.fill(Some(
297 HeadersInit::ByteStringSequenceSequence(init_sequence.clone())))?;
298 },
299 &HeadersInit::StringByteStringRecord(ref init_map) => {
300 headers_copy.fill(Some(
301 HeadersInit::StringByteStringRecord(init_map.clone())))?;
302 },
303 }
304 }
305
306 // Step 29
307 // We cannot empty `r.Headers().header_list` because
308 // we would undo the Step 27 above. One alternative is to set
309 // `headers_copy` as a deep copy of `r.Headers()`. However,
310 // `r.Headers()` is a `DomRoot<T>`, and therefore it is difficult
311 // to obtain a mutable reference to `r.Headers()`. Without the
312 // mutable reference, we cannot mutate `r.Headers()` to be the
313 // deep copied headers in Step 27.
314
315 // Step 30
316 if r.request.borrow().mode == NetTraitsRequestMode::NoCors {
317 let borrowed_request = r.request.borrow();
318 // Step 30.1
319 if !is_cors_safelisted_method(&borrowed_request.method) {
320 return Err(Error::Type(
321 "The mode is 'no-cors' but the method is not a cors-safelisted method".to_string()));
322 }
323 // Step 30.2
324 r.Headers().set_guard(Guard::RequestNoCors);
325 }
326
327 // Step 31
328 match init.headers {
329 None => {
330 // This is equivalent to the specification's concept of
331 // "associated headers list". If an init headers is not given,
332 // but an input with headers is given, set request's
333 // headers as the input's Headers.
334 if let RequestInfo::Request(ref input_request) = input {
335 r.Headers().fill(Some(HeadersInit::Headers(input_request.Headers())))?;
336 }
337 },
338 Some(HeadersInit::Headers(_)) => r.Headers().fill(Some(HeadersInit::Headers(headers_copy)))?,
339 _ => {},
340 }
341
342 // Copy the headers list onto the headers of net_traits::Request
343 r.request.borrow_mut().headers = r.Headers().get_headers_list();
344
345 // Step 32
346 let mut input_body = if let RequestInfo::Request(ref input_request) = input {
347 let input_request_request = input_request.request.borrow();
348 input_request_request.body.clone()
349 } else {
350 None
351 };
352
353 // Step 33
354 if let Some(init_body_option) = init.body.as_ref() {
355 if init_body_option.is_some() || input_body.is_some() {
356 let req = r.request.borrow();
357 let req_method = &req.method;
358 match *req_method {
359 HttpMethod::Get => return Err(Error::Type(
360 "Init's body is non-null, and request method is GET".to_string())),
361 HttpMethod::Head => return Err(Error::Type(
362 "Init's body is non-null, and request method is HEAD".to_string())),
363 _ => {},
364 }
365 }
366 }
367
368 // Step 34
369 if let Some(Some(ref init_body)) = init.body {
370 // Step 34.2
371 let extracted_body_tmp = init_body.extract();
372 input_body = Some(extracted_body_tmp.0);
373 let content_type = extracted_body_tmp.1;
374
375 // Step 34.3
376 if let Some(contents) = content_type {
377 if !r.Headers().Has(ByteString::new(b"Content-Type".to_vec())).unwrap() {
378 r.Headers().Append(ByteString::new(b"Content-Type".to_vec()),
379 ByteString::new(contents.as_bytes().to_vec()))?;
380 }
381 }
382 }
383
384 // Step 35
385 r.request.borrow_mut().body = input_body;
386
387 // Step 36
388 let extracted_mime_type = r.Headers().extract_mime_type();
389 *r.mime_type.borrow_mut() = extracted_mime_type;
390
391 // Step 37
392 // TODO: `ReadableStream` object is not implemented in Servo yet.
393
394 // Step 38
395 Ok(r)
396 }
397
398 // https://fetch.spec.whatwg.org/#concept-body-locked
locked(&self) -> bool399 fn locked(&self) -> bool {
400 // TODO: ReadableStream is unimplemented. Just return false
401 // for now.
402 false
403 }
404 }
405
406 impl Request {
from_net_request(global: &GlobalScope, net_request: NetTraitsRequest) -> DomRoot<Request>407 fn from_net_request(global: &GlobalScope,
408 net_request: NetTraitsRequest) -> DomRoot<Request> {
409 let r = Request::new(global,
410 net_request.current_url());
411 *r.request.borrow_mut() = net_request;
412 r
413 }
414
clone_from(r: &Request) -> Fallible<DomRoot<Request>>415 fn clone_from(r: &Request) -> Fallible<DomRoot<Request>> {
416 let req = r.request.borrow();
417 let url = req.url();
418 let body_used = r.body_used.get();
419 let mime_type = r.mime_type.borrow().clone();
420 let headers_guard = r.Headers().get_guard();
421 let r_clone = Request::new(&r.global(), url);
422 r_clone.request.borrow_mut().pipeline_id = req.pipeline_id;
423 {
424 let mut borrowed_r_request = r_clone.request.borrow_mut();
425 borrowed_r_request.origin = req.origin.clone();
426 }
427 *r_clone.request.borrow_mut() = req.clone();
428 r_clone.body_used.set(body_used);
429 *r_clone.mime_type.borrow_mut() = mime_type;
430 r_clone.Headers().fill(Some(HeadersInit::Headers(r.Headers())))?;
431 r_clone.Headers().set_guard(headers_guard);
432 Ok(r_clone)
433 }
434
get_request(&self) -> NetTraitsRequest435 pub fn get_request(&self) -> NetTraitsRequest {
436 self.request.borrow().clone()
437 }
438 }
439
net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequest440 fn net_request_from_global(global: &GlobalScope,
441 url: ServoUrl) -> NetTraitsRequest {
442 let origin = Origin::Origin(global.get_url().origin());
443 let pipeline_id = global.pipeline_id();
444 NetTraitsRequest::new(url,
445 Some(origin),
446 Some(pipeline_id))
447 }
448
449 // https://fetch.spec.whatwg.org/#concept-method-normalize
normalize_method(m: &str) -> HttpMethod450 fn normalize_method(m: &str) -> HttpMethod {
451 match_ignore_ascii_case! { m,
452 "delete" => return HttpMethod::Delete,
453 "get" => return HttpMethod::Get,
454 "head" => return HttpMethod::Head,
455 "options" => return HttpMethod::Options,
456 "post" => return HttpMethod::Post,
457 "put" => return HttpMethod::Put,
458 _ => (),
459 }
460 HttpMethod::Extension(m.to_string())
461 }
462
463 // https://fetch.spec.whatwg.org/#concept-method
is_method(m: &ByteString) -> bool464 fn is_method(m: &ByteString) -> bool {
465 m.as_str().is_some()
466 }
467
468 // https://fetch.spec.whatwg.org/#forbidden-method
is_forbidden_method(m: &ByteString) -> bool469 fn is_forbidden_method(m: &ByteString) -> bool {
470 match m.to_lower().as_str() {
471 Some("connect") => true,
472 Some("trace") => true,
473 Some("track") => true,
474 _ => false,
475 }
476 }
477
478 // https://fetch.spec.whatwg.org/#cors-safelisted-method
is_cors_safelisted_method(m: &HttpMethod) -> bool479 fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
480 m == &HttpMethod::Get ||
481 m == &HttpMethod::Head ||
482 m == &HttpMethod::Post
483 }
484
485 // https://url.spec.whatwg.org/#include-credentials
includes_credentials(input: &ServoUrl) -> bool486 fn includes_credentials(input: &ServoUrl) -> bool {
487 !input.username().is_empty() || input.password().is_some()
488 }
489
490 // TODO: `Readable Stream` object is not implemented in Servo yet.
491 // https://fetch.spec.whatwg.org/#concept-body-disturbed
request_is_disturbed(_input: &Request) -> bool492 fn request_is_disturbed(_input: &Request) -> bool {
493 false
494 }
495
496 // TODO: `Readable Stream` object is not implemented in Servo yet.
497 // https://fetch.spec.whatwg.org/#concept-body-locked
request_is_locked(_input: &Request) -> bool498 fn request_is_locked(_input: &Request) -> bool {
499 false
500 }
501
502 impl RequestMethods for Request {
503 // https://fetch.spec.whatwg.org/#dom-request-method
Method(&self) -> ByteString504 fn Method(&self) -> ByteString {
505 let r = self.request.borrow();
506 ByteString::new(r.method.as_ref().as_bytes().into())
507 }
508
509 // https://fetch.spec.whatwg.org/#dom-request-url
Url(&self) -> USVString510 fn Url(&self) -> USVString {
511 let r = self.request.borrow();
512 USVString(r.url_list.get(0).map_or("", |u| u.as_str()).into())
513 }
514
515 // https://fetch.spec.whatwg.org/#dom-request-headers
Headers(&self) -> DomRoot<Headers>516 fn Headers(&self) -> DomRoot<Headers> {
517 self.headers.or_init(|| Headers::new(&self.global()))
518 }
519
520 // https://fetch.spec.whatwg.org/#dom-request-destination
Destination(&self) -> RequestDestination521 fn Destination(&self) -> RequestDestination {
522 self.request.borrow().destination.into()
523 }
524
525 // https://fetch.spec.whatwg.org/#dom-request-referrer
Referrer(&self) -> USVString526 fn Referrer(&self) -> USVString {
527 let r = self.request.borrow();
528 USVString(match r.referrer {
529 NetTraitsRequestReferrer::NoReferrer => String::from("no-referrer"),
530 NetTraitsRequestReferrer::Client => String::from("about:client"),
531 NetTraitsRequestReferrer::ReferrerUrl(ref u) => {
532 let u_c = u.clone();
533 u_c.into_string()
534 }
535 })
536 }
537
538 // https://fetch.spec.whatwg.org/#dom-request-referrerpolicy
ReferrerPolicy(&self) -> ReferrerPolicy539 fn ReferrerPolicy(&self) -> ReferrerPolicy {
540 self.request.borrow().referrer_policy.map(|m| m.into()).unwrap_or(ReferrerPolicy::_empty)
541 }
542
543 // https://fetch.spec.whatwg.org/#dom-request-mode
Mode(&self) -> RequestMode544 fn Mode(&self) -> RequestMode {
545 self.request.borrow().mode.clone().into()
546 }
547
548 // https://fetch.spec.whatwg.org/#dom-request-credentials
Credentials(&self) -> RequestCredentials549 fn Credentials(&self) -> RequestCredentials {
550 let r = self.request.borrow().clone();
551 r.credentials_mode.into()
552 }
553
554 // https://fetch.spec.whatwg.org/#dom-request-cache
Cache(&self) -> RequestCache555 fn Cache(&self) -> RequestCache {
556 let r = self.request.borrow().clone();
557 r.cache_mode.into()
558 }
559
560 // https://fetch.spec.whatwg.org/#dom-request-redirect
Redirect(&self) -> RequestRedirect561 fn Redirect(&self) -> RequestRedirect {
562 let r = self.request.borrow().clone();
563 r.redirect_mode.into()
564 }
565
566 // https://fetch.spec.whatwg.org/#dom-request-integrity
Integrity(&self) -> DOMString567 fn Integrity(&self) -> DOMString {
568 let r = self.request.borrow();
569 DOMString::from_string(r.integrity_metadata.clone())
570 }
571
572 // https://fetch.spec.whatwg.org/#dom-body-bodyused
BodyUsed(&self) -> bool573 fn BodyUsed(&self) -> bool {
574 self.body_used.get()
575 }
576
577 // https://fetch.spec.whatwg.org/#dom-request-clone
Clone(&self) -> Fallible<DomRoot<Request>>578 fn Clone(&self) -> Fallible<DomRoot<Request>> {
579 // Step 1
580 if request_is_locked(self) {
581 return Err(Error::Type("Request is locked".to_string()));
582 }
583 if request_is_disturbed(self) {
584 return Err(Error::Type("Request is disturbed".to_string()));
585 }
586
587 // Step 2
588 Request::clone_from(self)
589 }
590
591 #[allow(unrooted_must_root)]
592 // https://fetch.spec.whatwg.org/#dom-body-text
Text(&self) -> Rc<Promise>593 fn Text(&self) -> Rc<Promise> {
594 consume_body(self, BodyType::Text)
595 }
596
597 #[allow(unrooted_must_root)]
598 // https://fetch.spec.whatwg.org/#dom-body-blob
Blob(&self) -> Rc<Promise>599 fn Blob(&self) -> Rc<Promise> {
600 consume_body(self, BodyType::Blob)
601 }
602
603 #[allow(unrooted_must_root)]
604 // https://fetch.spec.whatwg.org/#dom-body-formdata
FormData(&self) -> Rc<Promise>605 fn FormData(&self) -> Rc<Promise> {
606 consume_body(self, BodyType::FormData)
607 }
608
609 #[allow(unrooted_must_root)]
610 // https://fetch.spec.whatwg.org/#dom-body-json
Json(&self) -> Rc<Promise>611 fn Json(&self) -> Rc<Promise> {
612 consume_body(self, BodyType::Json)
613 }
614 }
615
616 impl BodyOperations for Request {
get_body_used(&self) -> bool617 fn get_body_used(&self) -> bool {
618 self.BodyUsed()
619 }
620
set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType)621 fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType) {
622 assert!(self.body_promise.borrow().is_none());
623 self.body_used.set(true);
624 *self.body_promise.borrow_mut() = Some((p.clone(), body_type));
625 }
626
is_locked(&self) -> bool627 fn is_locked(&self) -> bool {
628 self.locked()
629 }
630
take_body(&self) -> Option<Vec<u8>>631 fn take_body(&self) -> Option<Vec<u8>> {
632 let mut request = self.request.borrow_mut();
633 let body = request.body.take();
634 Some(body.unwrap_or(vec![]))
635 }
636
get_mime_type(&self) -> Ref<Vec<u8>>637 fn get_mime_type(&self) -> Ref<Vec<u8>> {
638 self.mime_type.borrow()
639 }
640 }
641
642 impl Into<NetTraitsRequestCache> for RequestCache {
into(self) -> NetTraitsRequestCache643 fn into(self) -> NetTraitsRequestCache {
644 match self {
645 RequestCache::Default => NetTraitsRequestCache::Default,
646 RequestCache::No_store => NetTraitsRequestCache::NoStore,
647 RequestCache::Reload => NetTraitsRequestCache::Reload,
648 RequestCache::No_cache => NetTraitsRequestCache::NoCache,
649 RequestCache::Force_cache => NetTraitsRequestCache::ForceCache,
650 RequestCache::Only_if_cached => NetTraitsRequestCache::OnlyIfCached,
651 }
652 }
653 }
654
655 impl Into<RequestCache> for NetTraitsRequestCache {
into(self) -> RequestCache656 fn into(self) -> RequestCache {
657 match self {
658 NetTraitsRequestCache::Default => RequestCache::Default,
659 NetTraitsRequestCache::NoStore => RequestCache::No_store,
660 NetTraitsRequestCache::Reload => RequestCache::Reload,
661 NetTraitsRequestCache::NoCache => RequestCache::No_cache,
662 NetTraitsRequestCache::ForceCache => RequestCache::Force_cache,
663 NetTraitsRequestCache::OnlyIfCached => RequestCache::Only_if_cached,
664 }
665 }
666 }
667
668 impl Into<NetTraitsRequestCredentials> for RequestCredentials {
into(self) -> NetTraitsRequestCredentials669 fn into(self) -> NetTraitsRequestCredentials {
670 match self {
671 RequestCredentials::Omit => NetTraitsRequestCredentials::Omit,
672 RequestCredentials::Same_origin => NetTraitsRequestCredentials::CredentialsSameOrigin,
673 RequestCredentials::Include => NetTraitsRequestCredentials::Include,
674 }
675 }
676 }
677
678 impl Into<RequestCredentials> for NetTraitsRequestCredentials {
into(self) -> RequestCredentials679 fn into(self) -> RequestCredentials {
680 match self {
681 NetTraitsRequestCredentials::Omit => RequestCredentials::Omit,
682 NetTraitsRequestCredentials::CredentialsSameOrigin => RequestCredentials::Same_origin,
683 NetTraitsRequestCredentials::Include => RequestCredentials::Include,
684 }
685 }
686 }
687
688 impl Into<NetTraitsRequestDestination> for RequestDestination {
into(self) -> NetTraitsRequestDestination689 fn into(self) -> NetTraitsRequestDestination {
690 match self {
691 RequestDestination::_empty => NetTraitsRequestDestination::None,
692 RequestDestination::Audio => NetTraitsRequestDestination::Audio,
693 RequestDestination::Document => NetTraitsRequestDestination::Document,
694 RequestDestination::Embed => NetTraitsRequestDestination::Embed,
695 RequestDestination::Font => NetTraitsRequestDestination::Font,
696 RequestDestination::Image => NetTraitsRequestDestination::Image,
697 RequestDestination::Manifest => NetTraitsRequestDestination::Manifest,
698 RequestDestination::Object => NetTraitsRequestDestination::Object,
699 RequestDestination::Report => NetTraitsRequestDestination::Report,
700 RequestDestination::Script => NetTraitsRequestDestination::Script,
701 RequestDestination::Sharedworker => NetTraitsRequestDestination::SharedWorker,
702 RequestDestination::Style => NetTraitsRequestDestination::Style,
703 RequestDestination::Track => NetTraitsRequestDestination::Track,
704 RequestDestination::Video => NetTraitsRequestDestination::Video,
705 RequestDestination::Worker => NetTraitsRequestDestination::Worker,
706 RequestDestination::Xslt => NetTraitsRequestDestination::Xslt,
707 }
708 }
709 }
710
711 impl Into<RequestDestination> for NetTraitsRequestDestination {
into(self) -> RequestDestination712 fn into(self) -> RequestDestination {
713 match self {
714 NetTraitsRequestDestination::None => RequestDestination::_empty,
715 NetTraitsRequestDestination::Audio => RequestDestination::Audio,
716 NetTraitsRequestDestination::Document => RequestDestination::Document,
717 NetTraitsRequestDestination::Embed => RequestDestination::Embed,
718 NetTraitsRequestDestination::Font => RequestDestination::Font,
719 NetTraitsRequestDestination::Image => RequestDestination::Image,
720 NetTraitsRequestDestination::Manifest => RequestDestination::Manifest,
721 NetTraitsRequestDestination::Object => RequestDestination::Object,
722 NetTraitsRequestDestination::Report => RequestDestination::Report,
723 NetTraitsRequestDestination::Script => RequestDestination::Script,
724 NetTraitsRequestDestination::ServiceWorker
725 => panic!("ServiceWorker request destination should not be exposed to DOM"),
726 NetTraitsRequestDestination::SharedWorker => RequestDestination::Sharedworker,
727 NetTraitsRequestDestination::Style => RequestDestination::Style,
728 NetTraitsRequestDestination::Track => RequestDestination::Track,
729 NetTraitsRequestDestination::Video => RequestDestination::Video,
730 NetTraitsRequestDestination::Worker => RequestDestination::Worker,
731 NetTraitsRequestDestination::Xslt => RequestDestination::Xslt,
732 }
733 }
734 }
735
736 impl Into<NetTraitsRequestMode> for RequestMode {
into(self) -> NetTraitsRequestMode737 fn into(self) -> NetTraitsRequestMode {
738 match self {
739 RequestMode::Navigate => NetTraitsRequestMode::Navigate,
740 RequestMode::Same_origin => NetTraitsRequestMode::SameOrigin,
741 RequestMode::No_cors => NetTraitsRequestMode::NoCors,
742 RequestMode::Cors => NetTraitsRequestMode::CorsMode,
743 }
744 }
745 }
746
747 impl Into<RequestMode> for NetTraitsRequestMode {
into(self) -> RequestMode748 fn into(self) -> RequestMode {
749 match self {
750 NetTraitsRequestMode::Navigate => RequestMode::Navigate,
751 NetTraitsRequestMode::SameOrigin => RequestMode::Same_origin,
752 NetTraitsRequestMode::NoCors => RequestMode::No_cors,
753 NetTraitsRequestMode::CorsMode => RequestMode::Cors,
754 NetTraitsRequestMode::WebSocket { .. } =>
755 unreachable!("Websocket request mode should never be exposed to Dom"),
756 }
757 }
758 }
759
760 // TODO
761 // When whatwg/fetch PR #346 is merged, fix this.
762 impl Into<MsgReferrerPolicy> for ReferrerPolicy {
into(self) -> MsgReferrerPolicy763 fn into(self) -> MsgReferrerPolicy {
764 match self {
765 ReferrerPolicy::_empty => MsgReferrerPolicy::NoReferrer,
766 ReferrerPolicy::No_referrer => MsgReferrerPolicy::NoReferrer,
767 ReferrerPolicy::No_referrer_when_downgrade =>
768 MsgReferrerPolicy::NoReferrerWhenDowngrade,
769 ReferrerPolicy::Origin => MsgReferrerPolicy::Origin,
770 ReferrerPolicy::Origin_when_cross_origin => MsgReferrerPolicy::OriginWhenCrossOrigin,
771 ReferrerPolicy::Unsafe_url => MsgReferrerPolicy::UnsafeUrl,
772 ReferrerPolicy::Strict_origin => MsgReferrerPolicy::StrictOrigin,
773 ReferrerPolicy::Strict_origin_when_cross_origin =>
774 MsgReferrerPolicy::StrictOriginWhenCrossOrigin,
775 }
776 }
777 }
778
779 impl Into<ReferrerPolicy> for MsgReferrerPolicy {
into(self) -> ReferrerPolicy780 fn into(self) -> ReferrerPolicy {
781 match self {
782 MsgReferrerPolicy::NoReferrer => ReferrerPolicy::No_referrer,
783 MsgReferrerPolicy::NoReferrerWhenDowngrade =>
784 ReferrerPolicy::No_referrer_when_downgrade,
785 MsgReferrerPolicy::Origin => ReferrerPolicy::Origin,
786 MsgReferrerPolicy::SameOrigin => ReferrerPolicy::Origin,
787 MsgReferrerPolicy::OriginWhenCrossOrigin => ReferrerPolicy::Origin_when_cross_origin,
788 MsgReferrerPolicy::UnsafeUrl => ReferrerPolicy::Unsafe_url,
789 MsgReferrerPolicy::StrictOrigin => ReferrerPolicy::Strict_origin,
790 MsgReferrerPolicy::StrictOriginWhenCrossOrigin =>
791 ReferrerPolicy::Strict_origin_when_cross_origin,
792 }
793 }
794 }
795
796 impl Into<NetTraitsRequestRedirect> for RequestRedirect {
into(self) -> NetTraitsRequestRedirect797 fn into(self) -> NetTraitsRequestRedirect {
798 match self {
799 RequestRedirect::Follow => NetTraitsRequestRedirect::Follow,
800 RequestRedirect::Error => NetTraitsRequestRedirect::Error,
801 RequestRedirect::Manual => NetTraitsRequestRedirect::Manual,
802 }
803 }
804 }
805
806 impl Into<RequestRedirect> for NetTraitsRequestRedirect {
into(self) -> RequestRedirect807 fn into(self) -> RequestRedirect {
808 match self {
809 NetTraitsRequestRedirect::Follow => RequestRedirect::Follow,
810 NetTraitsRequestRedirect::Error => RequestRedirect::Error,
811 NetTraitsRequestRedirect::Manual => RequestRedirect::Manual,
812 }
813 }
814 }
815
816 impl Clone for HeadersInit {
clone(&self) -> HeadersInit817 fn clone(&self) -> HeadersInit {
818 match self {
819 &HeadersInit::Headers(ref h) =>
820 HeadersInit::Headers(h.clone()),
821 &HeadersInit::ByteStringSequenceSequence(ref b) =>
822 HeadersInit::ByteStringSequenceSequence(b.clone()),
823 &HeadersInit::StringByteStringRecord(ref m) =>
824 HeadersInit::StringByteStringRecord(m.clone()),
825 }
826 }
827 }
828