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

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: Avoid using default arguments Created 7 years 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 dispatchThrottledProgressEventSnapshot(EventTypeNames::load);
445 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie); 445 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
446 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(EventTypeNames::loadend)); 446 dispatchThrottledProgressEventSnapshot(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)
962 { 966 {
963 if (!m_uploadComplete) { 967 bool lengthComputable = expectedLength > 0 && receivedLength <= expectedLeng th;
964 m_uploadComplete = true; 968 unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
965 if (m_upload && m_uploadEventsAllowed) 969 unsigned long long total = lengthComputable ? static_cast<unsigned long long >(expectedLength) : 0;
966 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(type)); 970
967 } 971 m_progressEventThrottle.dispatchEventAndLoadEnd(type, lengthComputable, load ed, total);
968 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type));
969 } 972 }
970 973
971 void XMLHttpRequest::dispatchThrottledProgressEvent() 974 void XMLHttpRequest::dispatchThrottledProgressEvent(const AtomicString& type, lo ng long receivedLength, long long expectedLength)
972 { 975 {
973 long long expectedLength = m_response.expectedContentLength(); 976 if (!receivedLength)
977 receivedLength = m_receivedLength;
978 if (!expectedLength)
979 expectedLength = m_response.expectedContentLength();
tyoshino (SeeGerritForStatus) 2013/11/25 07:46:53 so now we can remove this
sof 2013/11/25 08:10:37 Done.
980
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 loaded = m_receivedLength >= 0 ? static_cast<unsigned lon g long>(m_receivedLength) : 0;
983 unsigned long long total = lengthComputable ? static_cast<unsigned long long >(expectedLength) : 0;
976 984
977 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_receivedLe ngth, total); 985 if (type == EventTypeNames::progress)
986 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, loaded, total);
987 else
988 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(type, lengthComputable, loaded, total));
989 }
990
991 void XMLHttpRequest::dispatchThrottledProgressEventSnapshot(const AtomicString& type)
992 {
993 return dispatchThrottledProgressEvent(type, m_receivedLength, m_response.exp ectedContentLength());
978 } 994 }
979 995
980 void XMLHttpRequest::handleNetworkError() 996 void XMLHttpRequest::handleNetworkError()
981 { 997 {
982 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this); 998 LOG(Network, "XMLHttpRequest %p handleNetworkError()", this);
983 999
1000 // Response is cleared next, save needed progress event data.
1001 long long expectedLength = m_response.expectedContentLength();
1002 long long receivedLength = m_receivedLength;
1003
984 handleDidFailGeneric(); 1004 handleDidFailGeneric();
985 handleRequestError(NetworkError, EventTypeNames::error); 1005 handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expe ctedLength);
986 internalAbort(); 1006 internalAbort();
987 } 1007 }
988 1008
989 void XMLHttpRequest::handleDidCancel() 1009 void XMLHttpRequest::handleDidCancel()
990 { 1010 {
991 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this); 1011 LOG(Network, "XMLHttpRequest %p handleDidCancel()", this);
992 1012
1013 // Response is cleared next, save needed progress event data.
1014 long long expectedLength = m_response.expectedContentLength();
1015 long long receivedLength = m_receivedLength;
1016
993 handleDidFailGeneric(); 1017 handleDidFailGeneric();
994 handleRequestError(AbortError, EventTypeNames::abort); 1018 handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expect edLength);
995 } 1019 }
996 1020
997 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type) 1021 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type, long long receivedLength, long long expectedLength)
998 { 1022 {
999 LOG(Network, "XMLHttpRequest %p handleRequestError()", this); 1023 LOG(Network, "XMLHttpRequest %p handleRequestError()", this);
1000 1024
1001 // The request error steps for event 'type' and exception 'exceptionCode'. 1025 // The request error steps for event 'type' and exception 'exceptionCode'.
1002 1026
1003 if (!m_async && exceptionCode) { 1027 if (!m_async && exceptionCode) {
1004 m_state = DONE; 1028 m_state = DONE;
1005 m_exceptionCode = exceptionCode; 1029 m_exceptionCode = exceptionCode;
1006 return; 1030 return;
1007 } 1031 }
1008 // With m_error set, the state change steps are minimal: any pending 1032 // With m_error set, the state change steps are minimal: any pending
1009 // progress event is flushed + a readystatechange is dispatched. 1033 // progress event is flushed + a readystatechange is dispatched.
1010 // No new progress events dispatched; as required, that happens at 1034 // No new progress events dispatched; as required, that happens at
1011 // the end here. 1035 // the end here.
1012 ASSERT(m_error); 1036 ASSERT(m_error);
1013 changeState(DONE); 1037 changeState(DONE);
1014 1038
1015 if (!m_uploadComplete) { 1039 if (!m_uploadComplete) {
1016 m_uploadComplete = true; 1040 m_uploadComplete = true;
1017 if (m_upload && m_uploadEventsAllowed) 1041 if (m_upload && m_uploadEventsAllowed)
1018 m_upload->handleRequestError(type); 1042 m_upload->handleRequestError(type);
1019 } 1043 }
1020 1044
1021 dispatchThrottledProgressEvent(); 1045 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp ectedLength);
1022 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent: :create(type)); 1046 dispatchEventAndLoadEnd(type, receivedLength, expectedLength);
1023 } 1047 }
1024 1048
1025 void XMLHttpRequest::dropProtectionSoon() 1049 void XMLHttpRequest::dropProtectionSoon()
1026 { 1050 {
1027 m_dropProtectionRunner.runAsync(); 1051 m_dropProtectionRunner.runAsync();
1028 } 1052 }
1029 1053
1030 void XMLHttpRequest::dropProtection() 1054 void XMLHttpRequest::dropProtection()
1031 { 1055 {
1032 unsetPendingActivity(this); 1056 unsetPendingActivity(this);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1236
1213 if (m_error) 1237 if (m_error)
1214 return; 1238 return;
1215 1239
1216 if (m_state < HEADERS_RECEIVED) 1240 if (m_state < HEADERS_RECEIVED)
1217 changeState(HEADERS_RECEIVED); 1241 changeState(HEADERS_RECEIVED);
1218 1242
1219 if (m_decoder) 1243 if (m_decoder)
1220 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1244 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1221 1245
1222 clearVariablesForLoading();
1223
1224 if (m_responseStream) 1246 if (m_responseStream)
1225 m_responseStream->finalize(); 1247 m_responseStream->finalize();
1226 1248
1227 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1249 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, iden tifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1228 1250
1229 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. 1251 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method.
1230 RefPtr<XMLHttpRequest> protect(this); 1252 RefPtr<XMLHttpRequest> protect(this);
1231 1253
1232 if (m_loader) { 1254 if (m_loader) {
1233 m_loader = 0; 1255 m_loader = 0;
1234 dropProtection(); 1256 dropProtection();
1235 } 1257 }
1236 1258
1237 changeState(DONE); 1259 changeState(DONE);
1260
1261 clearVariablesForLoading();
1238 } 1262 }
1239 1263
1240 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) 1264 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent)
1241 { 1265 {
1242 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent); 1266 LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, t otalBytesToBeSent);
1243 1267
1244 if (!m_upload) 1268 if (!m_upload)
1245 return; 1269 return;
1246 1270
1247 if (m_uploadEventsAllowed) 1271 if (m_uploadEventsAllowed)
1248 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); 1272 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
1249 1273
1250 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { 1274 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
1251 m_uploadComplete = true; 1275 m_uploadComplete = true;
1252 if (m_uploadEventsAllowed) 1276 if (m_uploadEventsAllowed)
1253 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat e(EventTypeNames::load)); 1277 m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesS ent, totalBytesToBeSent);
1254 } 1278 }
1255 } 1279 }
1256 1280
1257 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response) 1281 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response)
1258 { 1282 {
1259 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier); 1283 LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier);
1260 1284
1261 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er); 1285 InspectorInstrumentation::didReceiveXHRResponse(executionContext(), identifi er);
1262 1286
1263 m_response = response; 1287 m_response = response;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 m_responseStream = Stream::create(executionContext(), responseMIMETy pe()); 1338 m_responseStream = Stream::create(executionContext(), responseMIMETy pe());
1315 m_responseStream->addData(data, len); 1339 m_responseStream->addData(data, len);
1316 } 1340 }
1317 1341
1318 if (m_error) 1342 if (m_error)
1319 return; 1343 return;
1320 1344
1321 m_receivedLength += len; 1345 m_receivedLength += len;
1322 1346
1323 if (m_async) 1347 if (m_async)
1324 dispatchThrottledProgressEvent(); 1348 dispatchThrottledProgressEventSnapshot(EventTypeNames::progress);
1325 1349
1326 if (m_state != LOADING) { 1350 if (m_state != LOADING) {
1327 changeState(LOADING); 1351 changeState(LOADING);
1328 } else { 1352 } else {
1329 // Firefox calls readyStateChanged every time it receives data. Do 1353 // Firefox calls readyStateChanged every time it receives data. Do
1330 // the same to align with Firefox. 1354 // the same to align with Firefox.
1331 // 1355 //
1332 // FIXME: Make our implementation and the spec consistent. This 1356 // FIXME: Make our implementation and the spec consistent. This
1333 // behavior was needed when the progress event was not available. 1357 // behavior was needed when the progress event was not available.
1334 dispatchReadyStateChangeEvent(); 1358 dispatchReadyStateChangeEvent();
1335 } 1359 }
1336 } 1360 }
1337 1361
1338 void XMLHttpRequest::handleDidTimeout() 1362 void XMLHttpRequest::handleDidTimeout()
1339 { 1363 {
1340 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1364 LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1341 1365
1342 // internalAbort() calls dropProtection(), which may release the last refere nce. 1366 // internalAbort() calls dropProtection(), which may release the last refere nce.
1343 RefPtr<XMLHttpRequest> protect(this); 1367 RefPtr<XMLHttpRequest> protect(this);
1344 1368
1369 // Response is cleared next, save needed progress event data.
1370 long long expectedLength = m_response.expectedContentLength();
1371 long long receivedLength = m_receivedLength;
1372
1345 if (!internalAbort()) 1373 if (!internalAbort())
1346 return; 1374 return;
1347 1375
1348 handleDidFailGeneric(); 1376 handleDidFailGeneric();
1349 handleRequestError(TimeoutError, EventTypeNames::timeout); 1377 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength);
1350 } 1378 }
1351 1379
1352 void XMLHttpRequest::suspend() 1380 void XMLHttpRequest::suspend()
1353 { 1381 {
1354 m_progressEventThrottle.suspend(); 1382 m_progressEventThrottle.suspend();
1355 } 1383 }
1356 1384
1357 void XMLHttpRequest::resume() 1385 void XMLHttpRequest::resume()
1358 { 1386 {
1359 m_progressEventThrottle.resume(); 1387 m_progressEventThrottle.resume();
(...skipping 14 matching lines...) Expand all
1374 { 1402 {
1375 return EventTargetNames::XMLHttpRequest; 1403 return EventTargetNames::XMLHttpRequest;
1376 } 1404 }
1377 1405
1378 ExecutionContext* XMLHttpRequest::executionContext() const 1406 ExecutionContext* XMLHttpRequest::executionContext() const
1379 { 1407 {
1380 return ActiveDOMObject::executionContext(); 1408 return ActiveDOMObject::executionContext();
1381 } 1409 }
1382 1410
1383 } // namespace WebCore 1411 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698