Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 , m_createdDocument(false) | 172 , m_createdDocument(false) |
| 173 , m_error(false) | 173 , m_error(false) |
| 174 , m_uploadEventsAllowed(true) | 174 , m_uploadEventsAllowed(true) |
| 175 , m_uploadComplete(false) | 175 , m_uploadComplete(false) |
| 176 , m_sameOriginRequest(true) | 176 , m_sameOriginRequest(true) |
| 177 , m_receivedLength(0) | 177 , m_receivedLength(0) |
| 178 , m_lastSendLineNumber(0) | 178 , m_lastSendLineNumber(0) |
| 179 , m_exceptionCode(0) | 179 , m_exceptionCode(0) |
| 180 , m_progressEventThrottle(this) | 180 , m_progressEventThrottle(this) |
| 181 , m_responseTypeCode(ResponseTypeDefault) | 181 , m_responseTypeCode(ResponseTypeDefault) |
| 182 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection) | |
| 183 , m_securityOrigin(securityOrigin) | 182 , m_securityOrigin(securityOrigin) |
| 184 { | 183 { |
| 185 initializeXMLHttpRequestStaticData(); | 184 initializeXMLHttpRequestStaticData(); |
| 186 #ifndef NDEBUG | 185 #ifndef NDEBUG |
| 187 xmlHttpRequestCounter.increment(); | 186 xmlHttpRequestCounter.increment(); |
| 188 #endif | 187 #endif |
| 189 ScriptWrappable::init(this); | 188 ScriptWrappable::init(this); |
| 190 } | 189 } |
| 191 | 190 |
| 192 XMLHttpRequest::~XMLHttpRequest() | 191 XMLHttpRequest::~XMLHttpRequest() |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 820 if (m_async) { | 819 if (m_async) { |
| 821 if (m_upload) | 820 if (m_upload) |
| 822 request.setReportUploadProgress(true); | 821 request.setReportUploadProgress(true); |
| 823 | 822 |
| 824 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. | 823 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. |
| 825 // This is true while running onunload handlers. | 824 // This is true while running onunload handlers. |
| 826 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 825 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. |
| 827 // FIXME: Maybe create() can return null for other reasons too? | 826 // FIXME: Maybe create() can return null for other reasons too? |
| 828 ASSERT(!m_loader); | 827 ASSERT(!m_loader); |
| 829 m_loader = ThreadableLoader::create(executionContext(), this, request, o ptions); | 828 m_loader = ThreadableLoader::create(executionContext(), this, request, o ptions); |
| 830 if (m_loader) { | |
| 831 // Neither this object nor the JavaScript wrapper should be deleted while | |
| 832 // a request is in progress because we need to keep the listeners al ive, | |
| 833 // and they are referenced by the JavaScript wrapper. | |
| 834 setPendingActivity(this); | |
| 835 } | |
| 836 } else { | 829 } else { |
| 837 ThreadableLoader::loadResourceSynchronously(executionContext(), request, *this, options); | 830 ThreadableLoader::loadResourceSynchronously(executionContext(), request, *this, options); |
| 838 } | 831 } |
| 839 | 832 |
| 840 if (!m_exceptionCode && m_error) | 833 if (!m_exceptionCode && m_error) |
| 841 m_exceptionCode = NetworkError; | 834 m_exceptionCode = NetworkError; |
| 842 if (m_exceptionCode) | 835 if (m_exceptionCode) |
| 843 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode) ; | 836 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode) ; |
| 844 } | 837 } |
| 845 | 838 |
| 846 void XMLHttpRequest::abort() | 839 void XMLHttpRequest::abort() |
| 847 { | 840 { |
| 848 WTF_LOG(Network, "XMLHttpRequest %p abort()", this); | 841 WTF_LOG(Network, "XMLHttpRequest %p abort()", this); |
| 849 | 842 |
| 850 // internalAbort() calls dropProtection(), which may release the last refere nce. | |
| 851 RefPtr<XMLHttpRequest> protect(this); | |
|
abarth-chromium
2013/12/05 04:17:24
Don't we still need this? Won't internalAbort rem
tyoshino (SeeGerritForStatus)
2013/12/05 04:32:10
oh right! I still didn't understand correctly when
| |
| 852 | |
| 853 bool sendFlag = m_loader; | 843 bool sendFlag = m_loader; |
| 854 | 844 |
| 855 // Response is cleared next, save needed progress event data. | 845 // Response is cleared next, save needed progress event data. |
| 856 long long expectedLength = m_response.expectedContentLength(); | 846 long long expectedLength = m_response.expectedContentLength(); |
| 857 long long receivedLength = m_receivedLength; | 847 long long receivedLength = m_receivedLength; |
| 858 | 848 |
| 859 if (!internalAbort()) | 849 if (!internalAbort()) |
| 860 return; | 850 return; |
| 861 | 851 |
| 862 clearResponse(); | 852 clearResponse(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 873 | 863 |
| 874 void XMLHttpRequest::clearVariablesForLoading() | 864 void XMLHttpRequest::clearVariablesForLoading() |
| 875 { | 865 { |
| 876 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. | 866 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. |
| 877 m_receivedLength = 0; | 867 m_receivedLength = 0; |
| 878 m_decoder.clear(); | 868 m_decoder.clear(); |
| 879 | 869 |
| 880 m_responseEncoding = String(); | 870 m_responseEncoding = String(); |
| 881 } | 871 } |
| 882 | 872 |
| 883 bool XMLHttpRequest::internalAbort(DropProtection async) | 873 bool XMLHttpRequest::internalAbort() |
| 884 { | 874 { |
| 885 m_error = true; | 875 m_error = true; |
| 886 | 876 |
| 887 clearVariablesForLoading(); | 877 clearVariablesForLoading(); |
| 888 | 878 |
| 889 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); | 879 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); |
| 890 | 880 |
| 891 if (m_responseStream && m_state != DONE) | 881 if (m_responseStream && m_state != DONE) |
| 892 m_responseStream->abort(); | 882 m_responseStream->abort(); |
| 893 | 883 |
| 894 if (!m_loader) | 884 if (!m_loader) |
| 895 return true; | 885 return true; |
| 896 | 886 |
| 897 // Cancelling the ThreadableLoader m_loader may result in calling | 887 // Cancelling the ThreadableLoader m_loader may result in calling |
| 898 // window.onload synchronously. If such an onload handler contains open() | 888 // window.onload synchronously. If such an onload handler contains open() |
| 899 // call on the same XMLHttpRequest object, reentry happens. If m_loader | 889 // call on the same XMLHttpRequest object, reentry happens. If m_loader |
| 900 // is left to be non 0, internalAbort() call for the inner open() makes | 890 // is left to be non 0, internalAbort() for the inner open() repeats the |
| 901 // an extra dropProtection() call (when we're back to the outer open(), | 891 // the same work. To avoid that, clears m_loader before calling cancel(). |
| 902 // we'll call dropProtection()). To avoid that, clears m_loader before | 892 RefPtr<ThreadableLoader> loader = m_loader.release(); |
| 903 // calling cancel. | 893 loader->cancel(); |
| 904 // | 894 |
| 905 // If, window.onload contains open() and send(), m_loader will be set to | 895 // If, window.onload contains open() and send(), m_loader will be set to |
| 906 // non 0 value. So, we cannot continue the outer open(). In such case, | 896 // non 0 value. So, we cannot continue the outer open(). In such case, |
| 907 // just abort the outer open() by returning false. | 897 // just abort the outer open() by returning false. |
| 908 RefPtr<ThreadableLoader> loader = m_loader.release(); | 898 if (m_loader) |
| 909 loader->cancel(); | 899 return false; |
| 910 | |
| 911 // Save to a local variable since we're going to drop protection. | |
| 912 bool newLoadStarted = m_loader; | |
| 913 | 900 |
| 914 // If abort() called internalAbort() and a nested open() ended up | 901 // If abort() called internalAbort() and a nested open() ended up |
| 915 // clearing the error flag, but didn't send(), make sure the error | 902 // clearing the error flag, but didn't send(), make sure the error |
| 916 // flag is still set. | 903 // flag is still set. |
| 917 if (!newLoadStarted) | 904 m_error = true; |
|
abarth-chromium
2013/12/05 04:17:24
For example, on this line of code, m_loader is 0,
| |
| 918 m_error = true; | |
| 919 | 905 |
| 920 if (async == DropProtectionAsync) | 906 return true; |
| 921 dropProtectionSoon(); | |
| 922 else | |
| 923 dropProtection(); | |
| 924 | |
| 925 return !newLoadStarted; | |
| 926 } | 907 } |
| 927 | 908 |
| 928 void XMLHttpRequest::clearResponse() | 909 void XMLHttpRequest::clearResponse() |
| 929 { | 910 { |
| 930 m_response = ResourceResponse(); | 911 m_response = ResourceResponse(); |
| 931 | 912 |
| 932 m_responseText.clear(); | 913 m_responseText.clear(); |
| 933 | 914 |
| 934 m_createdDocument = false; | 915 m_createdDocument = false; |
| 935 m_responseDocument = 0; | 916 m_responseDocument = 0; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1030 if (!m_uploadComplete) { | 1011 if (!m_uploadComplete) { |
| 1031 m_uploadComplete = true; | 1012 m_uploadComplete = true; |
| 1032 if (m_upload && m_uploadEventsAllowed) | 1013 if (m_upload && m_uploadEventsAllowed) |
| 1033 m_upload->handleRequestError(type); | 1014 m_upload->handleRequestError(type); |
| 1034 } | 1015 } |
| 1035 | 1016 |
| 1036 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp ectedLength); | 1017 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp ectedLength); |
| 1037 dispatchEventAndLoadEnd(type, receivedLength, expectedLength); | 1018 dispatchEventAndLoadEnd(type, receivedLength, expectedLength); |
| 1038 } | 1019 } |
| 1039 | 1020 |
| 1040 void XMLHttpRequest::dropProtectionSoon() | |
| 1041 { | |
| 1042 m_dropProtectionRunner.runAsync(); | |
| 1043 } | |
| 1044 | |
| 1045 void XMLHttpRequest::dropProtection() | |
| 1046 { | |
| 1047 unsetPendingActivity(this); | |
| 1048 } | |
| 1049 | |
| 1050 void XMLHttpRequest::overrideMimeType(const AtomicString& override) | 1021 void XMLHttpRequest::overrideMimeType(const AtomicString& override) |
| 1051 { | 1022 { |
| 1052 m_mimeTypeOverride = override; | 1023 m_mimeTypeOverride = override; |
| 1053 } | 1024 } |
| 1054 | 1025 |
| 1055 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState) | 1026 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState) |
| 1056 { | 1027 { |
| 1057 if (m_state != OPENED || m_loader) { | 1028 if (m_state != OPENED || m_loader) { |
| 1058 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be OPENED.")); | 1029 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be OPENED.")); |
| 1059 return; | 1030 return; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1232 changeState(HEADERS_RECEIVED); | 1203 changeState(HEADERS_RECEIVED); |
| 1233 | 1204 |
| 1234 if (m_decoder) | 1205 if (m_decoder) |
| 1235 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); | 1206 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); |
| 1236 | 1207 |
| 1237 if (m_responseStream) | 1208 if (m_responseStream) |
| 1238 m_responseStream->finalize(); | 1209 m_responseStream->finalize(); |
| 1239 | 1210 |
| 1240 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); | 1211 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); |
| 1241 | 1212 |
| 1242 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. | 1213 if (m_loader) |
| 1243 RefPtr<XMLHttpRequest> protect(this); | |
| 1244 | |
| 1245 if (m_loader) { | |
| 1246 m_loader = 0; | 1214 m_loader = 0; |
| 1247 dropProtection(); | |
| 1248 } | |
| 1249 | 1215 |
| 1250 changeState(DONE); | 1216 changeState(DONE); |
| 1251 | 1217 |
| 1252 clearVariablesForLoading(); | 1218 clearVariablesForLoading(); |
| 1253 } | 1219 } |
| 1254 | 1220 |
| 1255 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) | 1221 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) |
| 1256 { | 1222 { |
| 1257 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent); | 1223 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent); |
| 1258 | 1224 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 // FIXME: Make our implementation and the spec consistent. This | 1313 // FIXME: Make our implementation and the spec consistent. This |
| 1348 // behavior was needed when the progress event was not available. | 1314 // behavior was needed when the progress event was not available. |
| 1349 dispatchReadyStateChangeEvent(); | 1315 dispatchReadyStateChangeEvent(); |
| 1350 } | 1316 } |
| 1351 } | 1317 } |
| 1352 | 1318 |
| 1353 void XMLHttpRequest::handleDidTimeout() | 1319 void XMLHttpRequest::handleDidTimeout() |
| 1354 { | 1320 { |
| 1355 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); | 1321 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); |
| 1356 | 1322 |
| 1357 // internalAbort() calls dropProtection(), which may release the last refere nce. | |
| 1358 RefPtr<XMLHttpRequest> protect(this); | |
| 1359 | |
| 1360 // Response is cleared next, save needed progress event data. | 1323 // Response is cleared next, save needed progress event data. |
| 1361 long long expectedLength = m_response.expectedContentLength(); | 1324 long long expectedLength = m_response.expectedContentLength(); |
| 1362 long long receivedLength = m_receivedLength; | 1325 long long receivedLength = m_receivedLength; |
| 1363 | 1326 |
| 1364 if (!internalAbort()) | 1327 if (!internalAbort()) |
| 1365 return; | 1328 return; |
| 1366 | 1329 |
| 1367 handleDidFailGeneric(); | 1330 handleDidFailGeneric(); |
| 1368 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength); | 1331 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength); |
| 1369 } | 1332 } |
| 1370 | 1333 |
| 1371 void XMLHttpRequest::suspend() | 1334 void XMLHttpRequest::suspend() |
| 1372 { | 1335 { |
| 1373 m_progressEventThrottle.suspend(); | 1336 m_progressEventThrottle.suspend(); |
| 1374 } | 1337 } |
| 1375 | 1338 |
| 1376 void XMLHttpRequest::resume() | 1339 void XMLHttpRequest::resume() |
| 1377 { | 1340 { |
| 1378 m_progressEventThrottle.resume(); | 1341 m_progressEventThrottle.resume(); |
| 1379 } | 1342 } |
| 1380 | 1343 |
| 1381 void XMLHttpRequest::stop() | 1344 void XMLHttpRequest::stop() |
| 1382 { | 1345 { |
| 1383 internalAbort(DropProtectionAsync); | 1346 internalAbort(); |
|
abarth-chromium
2013/12/05 04:14:03
Don't we need to set some sort of flag here to pre
tyoshino (SeeGerritForStatus)
2013/12/05 04:26:20
Good catch! We don't want it to start a new loadin
| |
| 1347 } | |
| 1348 | |
| 1349 bool XMLHttpRequest::hasPendingActivity() const | |
| 1350 { | |
| 1351 return m_loader; | |
|
abarth-chromium
2013/12/05 04:14:03
Is there something that stops m_loader from being
tyoshino (SeeGerritForStatus)
2013/12/05 04:26:20
I once tried to add a boolean member, say "m_abort
| |
| 1384 } | 1352 } |
| 1385 | 1353 |
| 1386 void XMLHttpRequest::contextDestroyed() | 1354 void XMLHttpRequest::contextDestroyed() |
| 1387 { | 1355 { |
| 1388 ASSERT(!m_loader); | 1356 ASSERT(!m_loader); |
| 1389 ActiveDOMObject::contextDestroyed(); | 1357 ActiveDOMObject::contextDestroyed(); |
| 1390 } | 1358 } |
| 1391 | 1359 |
| 1392 const AtomicString& XMLHttpRequest::interfaceName() const | 1360 const AtomicString& XMLHttpRequest::interfaceName() const |
| 1393 { | 1361 { |
| 1394 return EventTargetNames::XMLHttpRequest; | 1362 return EventTargetNames::XMLHttpRequest; |
| 1395 } | 1363 } |
| 1396 | 1364 |
| 1397 ExecutionContext* XMLHttpRequest::executionContext() const | 1365 ExecutionContext* XMLHttpRequest::executionContext() const |
| 1398 { | 1366 { |
| 1399 return ActiveDOMObject::executionContext(); | 1367 return ActiveDOMObject::executionContext(); |
| 1400 } | 1368 } |
| 1401 | 1369 |
| 1402 } // namespace WebCore | 1370 } // namespace WebCore |
| OLD | NEW |