Skip to content

Commit f1c3288

Browse files
author
bors-servo
authored
Auto merge of #13597 - servo:fetch, r=jdm
Provide the fetched data to fetch() consumers. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13597) <!-- Reviewable:end -->
2 parents f719ac2 + cd47e21 commit f1c3288

File tree

105 files changed

+160
-283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+160
-283
lines changed

components/script/body.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::rc::Rc;
2424
use std::str;
2525
use url::form_urlencoded;
2626

27+
#[derive(Copy, Clone, JSTraceable, HeapSizeOf)]
2728
pub enum BodyType {
2829
Blob,
2930
FormData,
@@ -47,14 +48,32 @@ pub fn consume_body<T: BodyOperations + Reflectable>(object: &T, body_type: Body
4748
if object.get_body_used() || object.is_locked() {
4849
promise.reject_error(promise.global().r().get_cx(), Error::Type(
4950
"The response's stream is disturbed or locked".to_string()));
51+
return promise;
5052
}
5153

54+
object.set_body_promise(&promise, body_type);
55+
5256
// Steps 2-4
5357
// TODO: Body does not yet have a stream.
5458

59+
consume_body_with_promise(object, body_type, &promise);
60+
61+
promise
62+
}
63+
64+
// https://fetch.spec.whatwg.org/#concept-body-consume-body
65+
#[allow(unrooted_must_root)]
66+
pub fn consume_body_with_promise<T: BodyOperations + Reflectable>(object: &T,
67+
body_type: BodyType,
68+
promise: &Promise) {
5569
// Step 5
70+
let body = match object.take_body() {
71+
Some(body) => body,
72+
None => return,
73+
};
74+
5675
let pkg_data_results = run_package_data_algorithm(object,
57-
object.take_body(),
76+
body,
5877
body_type,
5978
object.get_mime_type());
6079

@@ -70,20 +89,15 @@ pub fn consume_body<T: BodyOperations + Reflectable>(object: &T, body_type: Body
7089
},
7190
Err(err) => promise.reject_error(cx, err),
7291
}
73-
promise
7492
}
7593

7694
// https://fetch.spec.whatwg.org/#concept-body-package-data
7795
#[allow(unsafe_code)]
7896
fn run_package_data_algorithm<T: BodyOperations + Reflectable>(object: &T,
79-
bytes: Option<Vec<u8>>,
97+
bytes: Vec<u8>,
8098
body_type: BodyType,
8199
mime_type: Ref<Vec<u8>>)
82100
-> Fallible<FetchedData> {
83-
let bytes = match bytes {
84-
Some(b) => b,
85-
_ => vec![],
86-
};
87101
let cx = object.global().r().get_cx();
88102
let mime = &*mime_type;
89103
match body_type {
@@ -156,6 +170,9 @@ fn run_form_data_algorithm(root: GlobalRef, bytes: Vec<u8>, mime: &[u8]) -> Fall
156170

157171
pub trait BodyOperations {
158172
fn get_body_used(&self) -> bool;
173+
fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType);
174+
/// Returns `Some(_)` if the body is complete, `None` if there is more to
175+
/// come.
159176
fn take_body(&self) -> Option<Vec<u8>>;
160177
fn is_locked(&self) -> bool;
161178
fn get_mime_type(&self) -> Ref<Vec<u8>>;

components/script/dom/request.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use net_traits::request::Request as NetTraitsRequest;
3636
use net_traits::request::RequestMode as NetTraitsRequestMode;
3737
use net_traits::request::Type as NetTraitsRequestType;
3838
use std::cell::{Cell, Ref};
39-
use std::mem;
4039
use std::rc::Rc;
4140
use url::Url;
4241

@@ -47,6 +46,8 @@ pub struct Request {
4746
body_used: Cell<bool>,
4847
headers: MutNullableHeap<JS<Headers>>,
4948
mime_type: DOMRefCell<Vec<u8>>,
49+
#[ignore_heap_size_of = "Rc"]
50+
body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>,
5051
}
5152

5253
impl Request {
@@ -62,6 +63,7 @@ impl Request {
6263
body_used: Cell::new(false),
6364
headers: Default::default(),
6465
mime_type: DOMRefCell::new("".to_string().into_bytes()),
66+
body_promise: DOMRefCell::new(None),
6567
}
6668
}
6769

@@ -662,20 +664,20 @@ impl BodyOperations for Request {
662664
self.BodyUsed()
663665
}
664666

667+
fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType) {
668+
assert!(self.body_promise.borrow().is_none());
669+
self.body_used.set(true);
670+
*self.body_promise.borrow_mut() = Some((p.clone(), body_type));
671+
}
672+
665673
fn is_locked(&self) -> bool {
666674
self.locked()
667675
}
668676

669677
fn take_body(&self) -> Option<Vec<u8>> {
670-
let ref mut net_traits_req = *self.request.borrow_mut();
671-
let body: Option<Vec<u8>> = mem::replace(&mut *net_traits_req.body.borrow_mut(), None);
672-
match body {
673-
Some(_) => {
674-
self.body_used.set(true);
675-
body
676-
},
677-
_ => None,
678-
}
678+
let request = self.request.borrow_mut();
679+
let body = request.body.borrow_mut().take();
680+
Some(body.unwrap_or(vec![]))
679681
}
680682

681683
fn get_mime_type(&self) -> Ref<Vec<u8>> {

components/script/dom/response.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
use body::{BodyOperations, BodyType, consume_body};
5+
use body::{BodyOperations, BodyType, consume_body, consume_body_with_promise};
66
use core::cell::Cell;
77
use dom::bindings::cell::DOMRefCell;
88
use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods;
@@ -44,6 +44,8 @@ pub struct Response {
4444
url_list: DOMRefCell<Vec<Url>>,
4545
// For now use the existing NetTraitsResponseBody enum
4646
body: DOMRefCell<NetTraitsResponseBody>,
47+
#[ignore_heap_size_of = "Rc"]
48+
body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>,
4749
}
4850

4951
impl Response {
@@ -59,6 +61,7 @@ impl Response {
5961
url: DOMRefCell::new(None),
6062
url_list: DOMRefCell::new(vec![]),
6163
body: DOMRefCell::new(NetTraitsResponseBody::Empty),
64+
body_promise: DOMRefCell::new(None),
6265
}
6366
}
6467

@@ -194,18 +197,26 @@ impl BodyOperations for Response {
194197
self.BodyUsed()
195198
}
196199

200+
fn set_body_promise(&self, p: &Rc<Promise>, body_type: BodyType) {
201+
assert!(self.body_promise.borrow().is_none());
202+
self.body_used.set(true);
203+
*self.body_promise.borrow_mut() = Some((p.clone(), body_type));
204+
}
205+
197206
fn is_locked(&self) -> bool {
198207
self.locked()
199208
}
200209

201210
fn take_body(&self) -> Option<Vec<u8>> {
202-
let body: NetTraitsResponseBody = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty);
211+
let body = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty);
203212
match body {
204-
NetTraitsResponseBody::Done(bytes) | NetTraitsResponseBody::Receiving(bytes) => {
205-
self.body_used.set(true);
213+
NetTraitsResponseBody::Done(bytes) => {
206214
Some(bytes)
207215
},
208-
_ => None,
216+
body => {
217+
mem::replace(&mut *self.body.borrow_mut(), body);
218+
None
219+
},
209220
}
210221
}
211222

@@ -366,4 +377,12 @@ impl Response {
366377
pub fn set_final_url(&self, final_url: Url) {
367378
*self.url.borrow_mut() = Some(final_url);
368379
}
380+
381+
#[allow(unrooted_must_root)]
382+
pub fn finish(&self, body: Vec<u8>) {
383+
*self.body.borrow_mut() = NetTraitsResponseBody::Done(body);
384+
if let Some((p, body_type)) = self.body_promise.borrow_mut().take() {
385+
consume_body_with_promise(self, body_type, &p);
386+
}
387+
}
369388
}

components/script/fetch.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ use net_traits::CoreResourceMsg::Fetch as NetTraitsFetch;
2424
use net_traits::request::Request as NetTraitsRequest;
2525
use net_traits::request::RequestInit as NetTraitsRequestInit;
2626
use network_listener::{NetworkListener, PreInvoke};
27+
use std::mem;
2728
use std::rc::Rc;
2829
use std::sync::{Arc, Mutex};
2930
use url::Url;
3031

3132
struct FetchContext {
3233
fetch_promise: Option<TrustedPromise>,
3334
response_object: Trusted<Response>,
35+
body: Vec<u8>,
3436
}
3537

3638
fn from_referrer_to_referrer_url(request: &NetTraitsRequest) -> Option<Url> {
@@ -89,6 +91,7 @@ pub fn Fetch(global: GlobalRef, input: RequestOrUSVString, init: &RequestInit) -
8991
let fetch_context = Arc::new(Mutex::new(FetchContext {
9092
fetch_promise: Some(TrustedPromise::new(promise.clone())),
9193
response_object: Trusted::new(&*response),
94+
body: vec![],
9295
}));
9396
let listener = NetworkListener {
9497
context: fetch_context,
@@ -153,12 +156,16 @@ impl FetchResponseListener for FetchContext {
153156
self.fetch_promise = Some(TrustedPromise::new(promise));
154157
}
155158

156-
fn process_response_chunk(&mut self, _chunk: Vec<u8>) {
157-
// TODO when body is implemented
158-
// ... this will append the chunk to Response's body.
159+
fn process_response_chunk(&mut self, mut chunk: Vec<u8>) {
160+
self.body.append(&mut chunk);
159161
}
160162

161163
fn process_response_eof(&mut self, _response: Result<(), NetworkError>) {
164+
let response = self.response_object.root();
165+
let global = response.global();
166+
let cx = global.r().get_cx();
167+
let _ac = JSAutoCompartment::new(cx, global.r().reflector().get_jsobject().get());
168+
response.finish(mem::replace(&mut self.body, vec![]));
162169
// TODO
163170
// ... trailerObject is not supported in Servo yet.
164171
}

tests/wpt/metadata/fetch/api/basic/text-utf8.html.ini

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,45 +18,21 @@
1818
[UTF-8 without BOM with Response.text()]
1919
expected: FAIL
2020

21-
[UTF-8 without BOM with fetched data (UTF-8 charset)]
22-
expected: FAIL
23-
24-
[UTF-8 without BOM with fetched data (UTF-16 charset)]
25-
expected: FAIL
26-
2721
[UTF-16BE with BOM decoded as UTF-8 with Request.text()]
2822
expected: FAIL
2923

3024
[UTF-16BE with BOM decoded as UTF-8 with Response.text()]
3125
expected: FAIL
3226

33-
[UTF-16BE with BOM decoded as UTF-8 with fetched data (UTF-8 charset)]
34-
expected: FAIL
35-
36-
[UTF-16BE with BOM decoded as UTF-8 with fetched data (UTF-16 charset)]
37-
expected: FAIL
38-
3927
[UTF-16LE with BOM decoded as UTF-8 with Request.text()]
4028
expected: FAIL
4129

4230
[UTF-16LE with BOM decoded as UTF-8 with Response.text()]
4331
expected: FAIL
4432

45-
[UTF-16LE with BOM decoded as UTF-8 with fetched data (UTF-8 charset)]
46-
expected: FAIL
47-
48-
[UTF-16LE with BOM decoded as UTF-8 with fetched data (UTF-16 charset)]
49-
expected: FAIL
50-
5133
[UTF-16 without BOM decoded as UTF-8 with Request.text()]
5234
expected: FAIL
5335

5436
[UTF-16 without BOM decoded as UTF-8 with Response.text()]
5537
expected: FAIL
5638

57-
[UTF-16 without BOM decoded as UTF-8 with fetched data (UTF-8 charset)]
58-
expected: FAIL
59-
60-
[UTF-16 without BOM decoded as UTF-8 with fetched data (UTF-16 charset)]
61-
expected: FAIL
62-

tests/wpt/metadata/fetch/api/request/request-consume-empty.html.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,12 @@
1212
[Consume empty text request body as arrayBuffer]
1313
expected: FAIL
1414

15+
[Consume request's body as text]
16+
expected: FAIL
17+
18+
[Consume request's body as blob]
19+
expected: FAIL
20+
21+
[Consume request's body as json]
22+
expected: FAIL
23+

tests/wpt/metadata/fetch/api/request/request-disturbed.html.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212
[Request construction failure should not set "bodyUsed"]
1313
expected: FAIL
1414

15+
[Request without body cannot be disturbed]
16+
expected: FAIL
17+
Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
[response-consume-empty.html]
22
type: testharness
3+
expected: TIMEOUT
34
[Consume response's body as arrayBuffer]
4-
expected: FAIL
5+
expected: NOTRUN
56
67
[Consume response's body as formData]
7-
expected: FAIL
8+
expected: NOTRUN
89

910
[Consume empty blob response body as arrayBuffer]
10-
expected: FAIL
11+
expected: NOTRUN
1112

1213
[Consume empty text response body as arrayBuffer]
13-
expected: FAIL
14+
expected: NOTRUN
15+
16+
[Consume response's body as text]
17+
expected: TIMEOUT
18+
19+
[Consume response's body as blob]
20+
expected: NOTRUN
21+
22+
[Consume response's body as json]
23+
expected: NOTRUN
24+
25+
[Consume empty blob response body as text]
26+
expected: NOTRUN
27+
28+
[Consume empty text response body as text]
29+
expected: NOTRUN
1430

tests/wpt/metadata/fetch/api/response/response-consume.html.ini

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@
2121
[Consume stream response's body as arrayBuffer]
2222
expected: FAIL
2323
24-
[Consume fetched response's body as blob]
25-
expected: FAIL
26-
27-
[Consume fetched response's body as text]
28-
expected: FAIL
29-
3024
[Consume fetched response's body as arrayBuffer]
3125
expected: FAIL
3226

tests/wpt/metadata/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-http/fetch-request/__dir__.ini

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)