Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 79953004: Improve fidelity of XHR progress events. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Tidy up handling of the signed m_receivedLength Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequestProgressEventThrottle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> 3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org>
4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> 4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org>
5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. 5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved.
6 * Copyright (C) 2012 Intel Corporation 6 * Copyright (C) 2012 Intel Corporation
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 flushAction = FlushDeferredProgressEvent; 434 flushAction = FlushDeferredProgressEvent;
435 else 435 else
436 flushAction = FlushProgressEvent; 436 flushAction = FlushProgressEvent;
437 } 437 }
438 m_progressEventThrottle.dispatchReadyStateChangeEvent(XMLHttpRequestProg ressEvent::create(EventTypeNames::readystatechange), flushAction); 438 m_progressEventThrottle.dispatchReadyStateChangeEvent(XMLHttpRequestProg ressEvent::create(EventTypeNames::readystatechange), flushAction);
439 } 439 }
440 440
441 InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(cookie); 441 InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(cookie);
442 if (m_state == DONE && !m_error) { 442 if (m_state == DONE && !m_error) {
443 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi spatchXHRLoadEvent(executionContext(), this); 443 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi spatchXHRLoadEvent(executionContext(), this);
444 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(EventTypeNames::load)); 444 dispatchThrottledProgressEvent(EventTypeNames::load);
445 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie); 445 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
446 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(EventTypeNames::loadend)); 446 dispatchThrottledProgressEvent(EventTypeNames::loadend);
447 } 447 }
448 } 448 }
449 449
450 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionSta te) 450 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionSta te)
451 { 451 {
452 if (m_state > OPENED || m_loader) { 452 if (m_state > OPENED || m_loader) {
453 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("withCredentials", "XMLHttpRequest", "the value may only be set if th e object's state is UNSENT or OPENED.")); 453 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("withCredentials", "XMLHttpRequest", "the value may only be set if th e object's state is UNSENT or OPENED."));
454 return; 454 return;
455 } 455 }
456 456
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 849
850 void XMLHttpRequest::abort() 850 void XMLHttpRequest::abort()
851 { 851 {
852 LOG(Network, "XMLHttpRequest %p abort()", this); 852 LOG(Network, "XMLHttpRequest %p abort()", this);
853 853
854 // internalAbort() calls dropProtection(), which may release the last refere nce. 854 // internalAbort() calls dropProtection(), which may release the last refere nce.
855 RefPtr<XMLHttpRequest> protect(this); 855 RefPtr<XMLHttpRequest> protect(this);
856 856
857 bool sendFlag = m_loader; 857 bool sendFlag = m_loader;
858 858
859 // Response is cleared next, save needed progress event data.
860 long long expectedLength = m_response.expectedContentLength();
861 long long receivedLength = m_receivedLength;
862
859 if (!internalAbort()) 863 if (!internalAbort())
860 return; 864 return;
861 865
862 clearResponse(); 866 clearResponse();
863 867
864 // Clear headers as required by the spec 868 // Clear headers as required by the spec
865 m_requestHeaders.clear(); 869 m_requestHeaders.clear();
866 870
867 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) { 871 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) {
868 ASSERT(!m_loader); 872 ASSERT(!m_loader);
869 handleRequestError(0, EventTypeNames::abort); 873 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen gth);
870 } 874 }
871 m_state = UNSENT; 875 m_state = UNSENT;
872 } 876 }
873 877
874 void XMLHttpRequest::clearVariablesForLoading() 878 void XMLHttpRequest::clearVariablesForLoading()
875 { 879 {
876 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. 880 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization.
877 m_receivedLength = 0; 881 m_receivedLength = 0;
878 m_decoder.clear(); 882 m_decoder.clear();
879 883
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 } 955 }
952 956
953 void XMLHttpRequest::handleDidFailGeneric() 957 void XMLHttpRequest::handleDidFailGeneric()
954 { 958 {
955 clearResponse(); 959 clearResponse();
956 clearRequest(); 960 clearRequest();
957 961
958 m_error = true; 962 m_error = true;
959 } 963 }
960 964
961 void XMLHttpRequest::dispatchEventAndLoadEnd(const AtomicString& type) 965 void XMLHttpRequest::dispatchEventAndLoadEnd(const AtomicString& type, long long receivedLength, long long expectedLength)
tyoshino (SeeGerritForStatus) 2013/11/22 07:39:23 oh, this method was not used by anyone. we've made
962 { 966 {
963 if (!m_uploadComplete) { 967 if (!m_uploadComplete) {
964 m_uploadComplete = true; 968 m_uploadComplete = true;
965 if (m_upload && m_uploadEventsAllowed) 969 if (m_upload && m_uploadEventsAllowed)
966 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(type)); 970 m_upload->dispatchEventAndLoadEnd(type);
967 } 971 }
968 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type)); 972 bool lengthComputable = expectedLength > 0 && receivedLength <= expectedLeng th;
973 unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
974 unsigned long long total = lengthComputable ? static_cast<unsigned long long >(expectedLength) : 0;
975
976 m_progressEventThrottle.dispatchEventAndLoadEnd(type, lengthComputable, load ed, total);
969 } 977 }
970 978
971 void XMLHttpRequest::dispatchThrottledProgressEvent() 979 void XMLHttpRequest::dispatchThrottledProgressEvent(const AtomicString& type)
972 { 980 {
973 long long expectedLength = m_response.expectedContentLength(); 981 long long expectedLength = m_response.expectedContentLength();
982
974 bool lengthComputable = expectedLength > 0 && m_receivedLength <= expectedLe ngth; 983 bool lengthComputable = expectedLength > 0 && m_receivedLength <= expectedLe ngth;
975 unsigned long long total = lengthComputable ? expectedLength : 0; 984 unsigned long long loaded = m_receivedLength >= 0 ? static_cast<unsigned lon g long>(m_receivedLength) : 0;
985 unsigned long long total = lengthComputable ? static_cast<unsigned long long >(expectedLength) : 0;
976 986
977 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_receivedLe ngth, total); 987 if (type == EventTypeNames::progress)
988 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, loaded, total);
989 else
990 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(type, lengthComputable, loaded, total));
978 } 991 }
979 992
980 void XMLHttpRequest::handleNetworkError() 993 void XMLHttpRequest::handleNetworkError()
981 { 994 {
982 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this); 995 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this);
983 996
997 // Response is cleared next, save needed progress event data.
998 long long expectedLength = m_response.expectedContentLength();
999 long long receivedLength = m_receivedLength;
1000
984 handleDidFailGeneric(); 1001 handleDidFailGeneric();
985 handleRequestError(NetworkError, EventTypeNames::error); 1002 handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expe ctedLength);
986 internalAbort(); 1003 internalAbort();
987 } 1004 }
988 1005
989 void XMLHttpRequest::handleDidCancel() 1006 void XMLHttpRequest::handleDidCancel()
990 { 1007 {
991 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this); 1008 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this);
992 1009
1010 // Response is cleared next, save needed progress event data.
1011 long long expectedLength = m_response.expectedContentLength();
1012 long long receivedLength = m_receivedLength;
1013
993 handleDidFailGeneric(); 1014 handleDidFailGeneric();
994 handleRequestError(AbortError, EventTypeNames::abort); 1015 handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expect edLength);
995 } 1016 }
996 1017
997 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type) 1018 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type, long long receivedLength, long long expectedLength)
998 { 1019 {
999 LOG(Network, "XMLHttpRequest %p handleRequestError()", this); 1020 LOG(Network, "XMLHttpRequest %p handleRequestError()", this);
1000 1021
1001 // The request error steps for event 'type' and exception 'exceptionCode'. 1022 // The request error steps for event 'type' and exception 'exceptionCode'.
1002 1023
1003 if (!m_async && exceptionCode) { 1024 if (!m_async && exceptionCode) {
1004 m_state = DONE; 1025 m_state = DONE;
1005 m_exceptionCode = exceptionCode; 1026 m_exceptionCode = exceptionCode;
1006 return; 1027 return;
1007 } 1028 }
1008 // With m_error set, the state change steps are minimal: any pending 1029 // With m_error set, the state change steps are minimal: any pending
1009 // progress event is flushed + a readystatechange is dispatched. 1030 // progress event is flushed + a readystatechange is dispatched.
1010 // No new progress events dispatched; as required, that happens at 1031 // No new progress events dispatched; as required, that happens at
1011 // the end here. 1032 // the end here.
1012 ASSERT(m_error); 1033 ASSERT(m_error);
1013 changeState(DONE); 1034 changeState(DONE);
1014 1035
1015 if (!m_uploadComplete) { 1036 if (!m_uploadComplete) {
1016 m_uploadComplete = true; 1037 m_uploadComplete = true;
1017 if (m_upload && m_uploadEventsAllowed) 1038 if (m_upload && m_uploadEventsAllowed)
1018 m_upload->handleRequestError(type); 1039 m_upload->handleRequestError(type);
1019 } 1040 }
1020 1041
1021 dispatchThrottledProgressEvent(); 1042 dispatchThrottledProgressEvent(EventTypeNames::progress);
tyoshino (SeeGerritForStatus) 2013/11/22 09:48:32 this method should also take saved receivedLength
sof 2013/11/22 11:22:42 Done.
1022 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type)); 1043 dispatchEventAndLoadEnd(type, receivedLength, expectedLength);
1023 } 1044 }
1024 1045
1025 void XMLHttpRequest::dropProtectionSoon() 1046 void XMLHttpRequest::dropProtectionSoon()
1026 { 1047 {
1027 m_dropProtectionRunner.runAsync(); 1048 m_dropProtectionRunner.runAsync();
1028 } 1049 }
1029 1050
1030 void XMLHttpRequest::dropProtection() 1051 void XMLHttpRequest::dropProtection()
1031 { 1052 {
1032 unsetPendingActivity(this); 1053 unsetPendingActivity(this);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1233
1213 if (m_error) 1234 if (m_error)
1214 return; 1235 return;
1215 1236
1216 if (m_state < HEADERS_RECEIVED) 1237 if (m_state < HEADERS_RECEIVED)
1217 changeState(HEADERS_RECEIVED); 1238 changeState(HEADERS_RECEIVED);
1218 1239
1219 if (m_decoder) 1240 if (m_decoder)
1220 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1241 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1221 1242
1222 clearVariablesForLoading();
1223
1224 if (m_responseStream) 1243 if (m_responseStream)
1225 m_responseStream->finalize(); 1244 m_responseStream->finalize();
1226 1245
1227 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1246 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1228 1247
1229 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. 1248 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method.
1230 RefPtr<XMLHttpRequest> protect(this); 1249 RefPtr<XMLHttpRequest> protect(this);
1231 1250
1232 if (m_loader) { 1251 if (m_loader) {
1233 m_loader = 0; 1252 m_loader = 0;
1234 dropProtection(); 1253 dropProtection();
1235 } 1254 }
1236 1255
1237 changeState(DONE); 1256 changeState(DONE);
1257
1258 clearVariablesForLoading();
1238 } 1259 }
1239 1260
1240 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) 1261 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent)
1241 { 1262 {
1242 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent); 1263 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent);
1243 1264
1244 if (!m_upload) 1265 if (!m_upload)
1245 return; 1266 return;
1246 1267
1247 if (m_uploadEventsAllowed) 1268 if (m_uploadEventsAllowed)
1248 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); 1269 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
1249 1270
1250 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { 1271 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
1251 m_uploadComplete = true; 1272 m_uploadComplete = true;
1252 if (m_uploadEventsAllowed) 1273 if (m_uploadEventsAllowed)
1253 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(EventTypeNames::load)); 1274 m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesS ent, totalBytesToBeSent);
1254 } 1275 }
1255 } 1276 }
1256 1277
1257 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response) 1278 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response)
1258 { 1279 {
1259 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier); 1280 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier);
1260 1281
1261 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er); 1282 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er);
1262 1283
1263 m_response = response; 1284 m_response = response;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 m_responseStream = Stream::create(executionContext(), responseMIMETy pe()); 1335 m_responseStream = Stream::create(executionContext(), responseMIMETy pe());
1315 m_responseStream->addData(data, len); 1336 m_responseStream->addData(data, len);
1316 } 1337 }
1317 1338
1318 if (m_error) 1339 if (m_error)
1319 return; 1340 return;
1320 1341
1321 m_receivedLength += len; 1342 m_receivedLength += len;
1322 1343
1323 if (m_async) 1344 if (m_async)
1324 dispatchThrottledProgressEvent(); 1345 dispatchThrottledProgressEvent(EventTypeNames::progress);
1325 1346
1326 if (m_state != LOADING) { 1347 if (m_state != LOADING) {
1327 changeState(LOADING); 1348 changeState(LOADING);
1328 } else { 1349 } else {
1329 // Firefox calls readyStateChanged every time it receives data. Do 1350 // Firefox calls readyStateChanged every time it receives data. Do
1330 // the same to align with Firefox. 1351 // the same to align with Firefox.
1331 // 1352 //
1332 // FIXME: Make our implementation and the spec consistent. This 1353 // FIXME: Make our implementation and the spec consistent. This
1333 // behavior was needed when the progress event was not available. 1354 // behavior was needed when the progress event was not available.
1334 dispatchReadyStateChangeEvent(); 1355 dispatchReadyStateChangeEvent();
1335 } 1356 }
1336 } 1357 }
1337 1358
1338 void XMLHttpRequest::handleDidTimeout() 1359 void XMLHttpRequest::handleDidTimeout()
1339 { 1360 {
1340 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1361 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1341 1362
1342 // internalAbort() calls dropProtection(), which may release the last refere nce. 1363 // internalAbort() calls dropProtection(), which may release the last refere nce.
1343 RefPtr<XMLHttpRequest> protect(this); 1364 RefPtr<XMLHttpRequest> protect(this);
1344 1365
1366 // Response is cleared next, save needed progress event data.
1367 long long expectedLength = m_response.expectedContentLength();
1368 long long receivedLength = m_receivedLength;
1369
1345 if (!internalAbort()) 1370 if (!internalAbort())
1346 return; 1371 return;
1347 1372
1348 handleDidFailGeneric(); 1373 handleDidFailGeneric();
1349 handleRequestError(TimeoutError, EventTypeNames::timeout); 1374 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength);
1350 } 1375 }
1351 1376
1352 void XMLHttpRequest::suspend() 1377 void XMLHttpRequest::suspend()
1353 { 1378 {
1354 m_progressEventThrottle.suspend(); 1379 m_progressEventThrottle.suspend();
1355 } 1380 }
1356 1381
1357 void XMLHttpRequest::resume() 1382 void XMLHttpRequest::resume()
1358 { 1383 {
1359 m_progressEventThrottle.resume(); 1384 m_progressEventThrottle.resume();
(...skipping 14 matching lines...) Expand all
1374 { 1399 {
1375 return EventTargetNames::XMLHttpRequest; 1400 return EventTargetNames::XMLHttpRequest;
1376 } 1401 }
1377 1402
1378 ExecutionContext* XMLHttpRequest::executionContext() const 1403 ExecutionContext* XMLHttpRequest::executionContext() const
1379 { 1404 {
1380 return ActiveDOMObject::executionContext(); 1405 return ActiveDOMObject::executionContext();
1381 } 1406 }
1382 1407
1383 } // namespace WebCore 1408 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequestProgressEventThrottle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698