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 |