servo: Merge #15455 - Implement XHR progress event changes (from charlesvdv:xhr-process-event); r=KiChjang
authorCharles Vandevoorde <charles.vandevoorde@hotmail.be>
Fri, 03 Mar 2017 01:05:11 -0800
changeset 374866 ed6fe97d40718fcaef9ca36bd207e4e7be46ae32
parent 374865 a600cecf698c94d6ef63e56b3cea90bc33eab48d
child 374867 29c16c3ec59b309787730d3059b1df86e0bb3b6b
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersKiChjang
milestone54.0a1
servo: Merge #15455 - Implement XHR progress event changes (from charlesvdv:xhr-process-event); r=KiChjang <!-- Please describe your changes on the following line: --> This PR implements change in the specs in XHR. Unfortunatelly, @jdm the test are not passing. It looks like the fetch module send more bytes that we should according the ```Content-Length```. This [lines](https://github.com/servo/servo/blob/master/tests/wpt/web-platform-tests/XMLHttpRequest/progress-events-response-data-gzip.htm#L70) make the test fail. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #13276 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 0294a474b802a87ce7788e603203a1ad526d18a7
servo/components/script/dom/xmlhttprequest.rs
--- a/servo/components/script/dom/xmlhttprequest.rs
+++ b/servo/components/script/dom/xmlhttprequest.rs
@@ -38,17 +38,17 @@ use dom::xmlhttprequesteventtarget::XMLH
 use dom::xmlhttprequestupload::XMLHttpRequestUpload;
 use dom_struct::dom_struct;
 use encoding::all::UTF_8;
 use encoding::label::encoding_from_whatwg_label;
 use encoding::types::{DecoderTrap, EncoderTrap, Encoding, EncodingRef};
 use euclid::length::Length;
 use html5ever::serialize;
 use html5ever::serialize::SerializeOpts;
-use hyper::header::{ContentLength, ContentType};
+use hyper::header::{ContentLength, ContentType, ContentEncoding};
 use hyper::header::Headers;
 use hyper::method::Method;
 use hyper::mime::{self, Attr as MimeAttr, Mime, Value as MimeValue};
 use hyper_serde::Serde;
 use ipc_channel::ipc;
 use ipc_channel::router::ROUTER;
 use js::jsapi::{JSContext, JS_ParseJSON};
 use js::jsapi::JS_ClearPendingException;
@@ -975,24 +975,22 @@ impl XMLHttpRequest {
                         self.ready_state.get() == XMLHttpRequestState::Loading ||
                         self.sync.get());
 
                 self.cancel_timeout();
 
                 // Part of step 11, send() (processing response end of file)
                 // XXXManishearth handle errors, if any (substep 2)
 
-                // Subsubsteps 5-7
+                // Subsubsteps 6-8
                 self.send_flag.set(false);
 
                 self.change_ready_state(XMLHttpRequestState::Done);
                 return_if_fetch_was_terminated!();
-                // Subsubsteps 10-12
-                self.dispatch_response_progress_event(atom!("progress"));
-                return_if_fetch_was_terminated!();
+                // Subsubsteps 11-12
                 self.dispatch_response_progress_event(atom!("load"));
                 return_if_fetch_was_terminated!();
                 self.dispatch_response_progress_event(atom!("loadend"));
             },
             XHRProgress::Errored(_, e) => {
                 self.cancel_timeout();
 
                 self.discard_subsequent_responses();
@@ -1005,45 +1003,46 @@ impl XMLHttpRequest {
                     Error::Abort => "abort",
                     Error::Timeout => "timeout",
                     _ => "error",
                 };
 
                 let upload_complete = &self.upload_complete;
                 if !upload_complete.get() {
                     upload_complete.set(true);
-                    self.dispatch_upload_progress_event(atom!("progress"), None);
-                    return_if_fetch_was_terminated!();
                     self.dispatch_upload_progress_event(Atom::from(errormsg), None);
                     return_if_fetch_was_terminated!();
                     self.dispatch_upload_progress_event(atom!("loadend"), None);
                     return_if_fetch_was_terminated!();
                 }
-                self.dispatch_response_progress_event(atom!("progress"));
-                return_if_fetch_was_terminated!();
                 self.dispatch_response_progress_event(Atom::from(errormsg));
                 return_if_fetch_was_terminated!();
                 self.dispatch_response_progress_event(atom!("loadend"));
             }
         }
     }
 
     fn terminate_ongoing_fetch(&self) {
         let GenerationId(prev_id) = self.generation_id.get();
         self.generation_id.set(GenerationId(prev_id + 1));
         self.response_status.set(Ok(()));
     }
 
     fn dispatch_progress_event(&self, upload: bool, type_: Atom, loaded: u64, total: Option<u64>) {
+        let (total_length, length_computable) = if self.response_headers.borrow().has::<ContentEncoding>() {
+            (0, false)
+        } else {
+            (total.unwrap_or(0), total.is_some())
+        };
         let progressevent = ProgressEvent::new(&self.global(),
                                                type_,
                                                EventBubbles::DoesNotBubble,
                                                EventCancelable::NotCancelable,
-                                               total.is_some(), loaded,
-                                               total.unwrap_or(0));
+                                               length_computable, loaded,
+                                               total_length);
         let target = if upload {
             self.upload.upcast()
         } else {
             self.upcast()
         };
         progressevent.upcast::<Event>().fire(target);
     }