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

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: 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
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 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 } 848 }
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
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 comment that we save these variables here since th
sof 2013/11/22 07:17:05 Done.
859 long long expectedLength = m_response.expectedContentLength();
860 unsigned long long receivedLength = m_receivedLength;
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 i think we can change m_receivedLength to unsigned
sof 2013/11/22 07:17:05 Done; but I'd vote for moving to unsigned long lon
861
859 if (!internalAbort()) 862 if (!internalAbort())
860 return; 863 return;
861 864
862 clearResponse(); 865 clearResponse();
863 866
864 // Clear headers as required by the spec 867 // Clear headers as required by the spec
865 m_requestHeaders.clear(); 868 m_requestHeaders.clear();
866 869
867 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) { 870 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) {
868 ASSERT(!m_loader); 871 ASSERT(!m_loader);
869 handleRequestError(0, EventTypeNames::abort); 872 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen gth);
870 } 873 }
871 m_state = UNSENT; 874 m_state = UNSENT;
872 } 875 }
873 876
874 void XMLHttpRequest::clearVariablesForLoading() 877 void XMLHttpRequest::clearVariablesForLoading()
875 { 878 {
876 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. 879 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization.
877 m_receivedLength = 0; 880 m_receivedLength = 0;
878 m_decoder.clear(); 881 m_decoder.clear();
879 882
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 } 954 }
952 955
953 void XMLHttpRequest::handleDidFailGeneric() 956 void XMLHttpRequest::handleDidFailGeneric()
954 { 957 {
955 clearResponse(); 958 clearResponse();
956 clearRequest(); 959 clearRequest();
957 960
958 m_error = true; 961 m_error = true;
959 } 962 }
960 963
961 void XMLHttpRequest::dispatchEventAndLoadEnd(const AtomicString& type) 964 void XMLHttpRequest::dispatchEventAndLoadEnd(const AtomicString& type, long long receivedLength, unsigned long long expectedLength)
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 long long expectedLength
962 { 965 {
963 if (!m_uploadComplete) { 966 if (!m_uploadComplete) {
964 m_uploadComplete = true; 967 m_uploadComplete = true;
965 if (m_upload && m_uploadEventsAllowed) 968 if (m_upload && m_uploadEventsAllowed)
966 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(type)); 969 m_upload->dispatchEventAndLoadEnd(type);
967 } 970 }
968 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type)); 971 unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 nice. please add this code also between L979 and 9
sof 2013/11/22 07:17:05 Done.
972 bool lengthComputable = expectedLength > 0 && loaded <= expectedLength;
973 unsigned long long total = lengthComputable ? expectedLength : 0;
974
975 m_progressEventThrottle.dispatchEventAndLoadEnd(type, lengthComputable, load ed, total);
969 } 976 }
970 977
971 void XMLHttpRequest::dispatchThrottledProgressEvent() 978 void XMLHttpRequest::dispatchThrottledProgressEvent(const AtomicString& type)
972 { 979 {
973 long long expectedLength = m_response.expectedContentLength(); 980 long long expectedLength = m_response.expectedContentLength();
974 bool lengthComputable = expectedLength > 0 && m_receivedLength <= expectedLe ngth; 981 bool lengthComputable = expectedLength > 0 && m_receivedLength <= expectedLe ngth;
975 unsigned long long total = lengthComputable ? expectedLength : 0; 982 unsigned long long total = lengthComputable ? expectedLength : 0;
976 983
977 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_receivedLe ngth, total); 984 if (type == EventTypeNames::progress)
985 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_receiv edLength, total);
986 else
987 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(type, lengthComputable, m_receivedLength, total));
978 } 988 }
979 989
980 void XMLHttpRequest::handleNetworkError() 990 void XMLHttpRequest::handleNetworkError()
981 { 991 {
982 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this); 992 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this);
983 993
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 comment the reason why we save them here
994 long long expectedLength = m_response.expectedContentLength();
995 unsigned long long receivedLength = m_receivedLength;
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 long long
996
984 handleDidFailGeneric(); 997 handleDidFailGeneric();
985 handleRequestError(NetworkError, EventTypeNames::error); 998 handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expe ctedLength);
986 internalAbort(); 999 internalAbort();
987 } 1000 }
988 1001
989 void XMLHttpRequest::handleDidCancel() 1002 void XMLHttpRequest::handleDidCancel()
990 { 1003 {
991 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this); 1004 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this);
992 1005
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 comment the reason why we save them here
1006 long long expectedLength = m_response.expectedContentLength();
1007 unsigned long long receivedLength = m_receivedLength;
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 long long
1008
993 handleDidFailGeneric(); 1009 handleDidFailGeneric();
994 handleRequestError(AbortError, EventTypeNames::abort); 1010 handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expect edLength);
995 } 1011 }
996 1012
997 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type) 1013 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type, long long receivedLength, unsigned long long expectedLength)
tyoshino (SeeGerritForStatus) 2013/11/22 04:48:21 long long expectedLength
998 { 1014 {
999 LOG(Network, "XMLHttpRequest %p handleRequestError()", this); 1015 LOG(Network, "XMLHttpRequest %p handleRequestError()", this);
1000 1016
1001 // The request error steps for event 'type' and exception 'exceptionCode'. 1017 // The request error steps for event 'type' and exception 'exceptionCode'.
1002 1018
1003 if (!m_async && exceptionCode) { 1019 if (!m_async && exceptionCode) {
1004 m_state = DONE; 1020 m_state = DONE;
1005 m_exceptionCode = exceptionCode; 1021 m_exceptionCode = exceptionCode;
1006 return; 1022 return;
1007 } 1023 }
1008 // With m_error set, the state change steps are minimal: any pending 1024 // With m_error set, the state change steps are minimal: any pending
1009 // progress event is flushed + a readystatechange is dispatched. 1025 // progress event is flushed + a readystatechange is dispatched.
1010 // No new progress events dispatched; as required, that happens at 1026 // No new progress events dispatched; as required, that happens at
1011 // the end here. 1027 // the end here.
1012 ASSERT(m_error); 1028 ASSERT(m_error);
1013 changeState(DONE); 1029 changeState(DONE);
1014 1030
1015 if (!m_uploadComplete) { 1031 if (!m_uploadComplete) {
1016 m_uploadComplete = true; 1032 m_uploadComplete = true;
1017 if (m_upload && m_uploadEventsAllowed) 1033 if (m_upload && m_uploadEventsAllowed)
1018 m_upload->handleRequestError(type); 1034 m_upload->handleRequestError(type);
1019 } 1035 }
1020 1036
1021 dispatchThrottledProgressEvent(); 1037 dispatchThrottledProgressEvent(EventTypeNames::progress);
1022 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type)); 1038 dispatchEventAndLoadEnd(type, receivedLength, expectedLength);
1023 } 1039 }
1024 1040
1025 void XMLHttpRequest::dropProtectionSoon() 1041 void XMLHttpRequest::dropProtectionSoon()
1026 { 1042 {
1027 m_dropProtectionRunner.runAsync(); 1043 m_dropProtectionRunner.runAsync();
1028 } 1044 }
1029 1045
1030 void XMLHttpRequest::dropProtection() 1046 void XMLHttpRequest::dropProtection()
1031 { 1047 {
1032 unsetPendingActivity(this); 1048 unsetPendingActivity(this);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1228
1213 if (m_error) 1229 if (m_error)
1214 return; 1230 return;
1215 1231
1216 if (m_state < HEADERS_RECEIVED) 1232 if (m_state < HEADERS_RECEIVED)
1217 changeState(HEADERS_RECEIVED); 1233 changeState(HEADERS_RECEIVED);
1218 1234
1219 if (m_decoder) 1235 if (m_decoder)
1220 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1236 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1221 1237
1222 clearVariablesForLoading();
1223
1224 if (m_responseStream) 1238 if (m_responseStream)
1225 m_responseStream->finalize(); 1239 m_responseStream->finalize();
1226 1240
1227 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1241 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1228 1242
1229 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. 1243 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method.
1230 RefPtr<XMLHttpRequest> protect(this); 1244 RefPtr<XMLHttpRequest> protect(this);
1231 1245
1232 if (m_loader) { 1246 if (m_loader) {
1233 m_loader = 0; 1247 m_loader = 0;
1234 dropProtection(); 1248 dropProtection();
1235 } 1249 }
1236 1250
1237 changeState(DONE); 1251 changeState(DONE);
1252
1253 clearVariablesForLoading();
1238 } 1254 }
1239 1255
1240 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) 1256 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent)
1241 { 1257 {
1242 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent); 1258 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent);
1243 1259
1244 if (!m_upload) 1260 if (!m_upload)
1245 return; 1261 return;
1246 1262
1247 if (m_uploadEventsAllowed) 1263 if (m_uploadEventsAllowed)
1248 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); 1264 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
1249 1265
1250 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { 1266 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
1251 m_uploadComplete = true; 1267 m_uploadComplete = true;
1252 if (m_uploadEventsAllowed) 1268 if (m_uploadEventsAllowed)
1253 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(EventTypeNames::load)); 1269 m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesS ent, totalBytesToBeSent);
1254 } 1270 }
1255 } 1271 }
1256 1272
1257 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response) 1273 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response)
1258 { 1274 {
1259 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier); 1275 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier);
1260 1276
1261 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er); 1277 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er);
1262 1278
1263 m_response = response; 1279 m_response = response;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 m_responseStream = Stream::create(executionContext(), responseMIMETy pe()); 1330 m_responseStream = Stream::create(executionContext(), responseMIMETy pe());
1315 m_responseStream->addData(data, len); 1331 m_responseStream->addData(data, len);
1316 } 1332 }
1317 1333
1318 if (m_error) 1334 if (m_error)
1319 return; 1335 return;
1320 1336
1321 m_receivedLength += len; 1337 m_receivedLength += len;
1322 1338
1323 if (m_async) 1339 if (m_async)
1324 dispatchThrottledProgressEvent(); 1340 dispatchThrottledProgressEvent(EventTypeNames::progress);
1325 1341
1326 if (m_state != LOADING) { 1342 if (m_state != LOADING) {
1327 changeState(LOADING); 1343 changeState(LOADING);
1328 } else { 1344 } else {
1329 // Firefox calls readyStateChanged every time it receives data. Do 1345 // Firefox calls readyStateChanged every time it receives data. Do
1330 // the same to align with Firefox. 1346 // the same to align with Firefox.
1331 // 1347 //
1332 // FIXME: Make our implementation and the spec consistent. This 1348 // FIXME: Make our implementation and the spec consistent. This
1333 // behavior was needed when the progress event was not available. 1349 // behavior was needed when the progress event was not available.
1334 dispatchReadyStateChangeEvent(); 1350 dispatchReadyStateChangeEvent();
1335 } 1351 }
1336 } 1352 }
1337 1353
1338 void XMLHttpRequest::handleDidTimeout() 1354 void XMLHttpRequest::handleDidTimeout()
1339 { 1355 {
1340 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1356 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1341 1357
1342 // internalAbort() calls dropProtection(), which may release the last refere nce. 1358 // internalAbort() calls dropProtection(), which may release the last refere nce.
1343 RefPtr<XMLHttpRequest> protect(this); 1359 RefPtr<XMLHttpRequest> protect(this);
1344 1360
1361 long long expectedLength = m_response.expectedContentLength();
1362 unsigned long long receivedLength = m_receivedLength;
1363
1345 if (!internalAbort()) 1364 if (!internalAbort())
1346 return; 1365 return;
1347 1366
1348 handleDidFailGeneric(); 1367 handleDidFailGeneric();
1349 handleRequestError(TimeoutError, EventTypeNames::timeout); 1368 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength);
1350 } 1369 }
1351 1370
1352 void XMLHttpRequest::suspend() 1371 void XMLHttpRequest::suspend()
1353 { 1372 {
1354 m_progressEventThrottle.suspend(); 1373 m_progressEventThrottle.suspend();
1355 } 1374 }
1356 1375
1357 void XMLHttpRequest::resume() 1376 void XMLHttpRequest::resume()
1358 { 1377 {
1359 m_progressEventThrottle.resume(); 1378 m_progressEventThrottle.resume();
(...skipping 14 matching lines...) Expand all
1374 { 1393 {
1375 return EventTargetNames::XMLHttpRequest; 1394 return EventTargetNames::XMLHttpRequest;
1376 } 1395 }
1377 1396
1378 ExecutionContext* XMLHttpRequest::executionContext() const 1397 ExecutionContext* XMLHttpRequest::executionContext() const
1379 { 1398 {
1380 return ActiveDOMObject::executionContext(); 1399 return ActiveDOMObject::executionContext();
1381 } 1400 }
1382 1401
1383 } // namespace WebCore 1402 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698