| 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 , m_downloadedBlobLength(0) | 171 , m_downloadedBlobLength(0) |
| 172 , m_error(false) | 172 , m_error(false) |
| 173 , m_uploadEventsAllowed(true) | 173 , m_uploadEventsAllowed(true) |
| 174 , m_uploadComplete(false) | 174 , m_uploadComplete(false) |
| 175 , m_sameOriginRequest(true) | 175 , m_sameOriginRequest(true) |
| 176 , m_receivedLength(0) | 176 , m_receivedLength(0) |
| 177 , m_lastSendLineNumber(0) | 177 , m_lastSendLineNumber(0) |
| 178 , m_exceptionCode(0) | 178 , m_exceptionCode(0) |
| 179 , m_progressEventThrottle(this) | 179 , m_progressEventThrottle(this) |
| 180 , m_responseTypeCode(ResponseTypeDefault) | 180 , m_responseTypeCode(ResponseTypeDefault) |
| 181 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection) | |
| 182 , m_securityOrigin(securityOrigin) | 181 , m_securityOrigin(securityOrigin) |
| 183 { | 182 { |
| 184 initializeXMLHttpRequestStaticData(); | 183 initializeXMLHttpRequestStaticData(); |
| 185 #ifndef NDEBUG | 184 #ifndef NDEBUG |
| 186 xmlHttpRequestCounter.increment(); | 185 xmlHttpRequestCounter.increment(); |
| 187 #endif | 186 #endif |
| 188 ScriptWrappable::init(this); | 187 ScriptWrappable::init(this); |
| 189 } | 188 } |
| 190 | 189 |
| 191 XMLHttpRequest::~XMLHttpRequest() | 190 XMLHttpRequest::~XMLHttpRequest() |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 if (m_async) { | 841 if (m_async) { |
| 843 if (m_upload) | 842 if (m_upload) |
| 844 request.setReportUploadProgress(true); | 843 request.setReportUploadProgress(true); |
| 845 | 844 |
| 846 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. | 845 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. |
| 847 // This is true while running onunload handlers. | 846 // This is true while running onunload handlers. |
| 848 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 847 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. |
| 849 // FIXME: Maybe create() can return null for other reasons too? | 848 // FIXME: Maybe create() can return null for other reasons too? |
| 850 ASSERT(!m_loader); | 849 ASSERT(!m_loader); |
| 851 m_loader = ThreadableLoader::create(executionContext(), this, request, o
ptions); | 850 m_loader = ThreadableLoader::create(executionContext(), this, request, o
ptions); |
| 852 if (m_loader) { | |
| 853 // Neither this object nor the JavaScript wrapper should be deleted
while | |
| 854 // a request is in progress because we need to keep the listeners al
ive, | |
| 855 // and they are referenced by the JavaScript wrapper. | |
| 856 setPendingActivity(this); | |
| 857 } | |
| 858 } else { | 851 } else { |
| 859 ThreadableLoader::loadResourceSynchronously(executionContext(), request,
*this, options); | 852 ThreadableLoader::loadResourceSynchronously(executionContext(), request,
*this, options); |
| 860 } | 853 } |
| 861 | 854 |
| 862 if (!m_exceptionCode && m_error) | 855 if (!m_exceptionCode && m_error) |
| 863 m_exceptionCode = NetworkError; | 856 m_exceptionCode = NetworkError; |
| 864 if (m_exceptionCode) | 857 if (m_exceptionCode) |
| 865 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode)
; | 858 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode)
; |
| 866 } | 859 } |
| 867 | 860 |
| 868 void XMLHttpRequest::abort() | 861 void XMLHttpRequest::abort() |
| 869 { | 862 { |
| 870 WTF_LOG(Network, "XMLHttpRequest %p abort()", this); | 863 WTF_LOG(Network, "XMLHttpRequest %p abort()", this); |
| 871 | 864 |
| 872 // internalAbort() calls dropProtection(), which may release the last refere
nce. | |
| 873 RefPtr<XMLHttpRequest> protect(this); | |
| 874 | |
| 875 bool sendFlag = m_loader; | 865 bool sendFlag = m_loader; |
| 876 | 866 |
| 877 // Response is cleared next, save needed progress event data. | 867 // Response is cleared next, save needed progress event data. |
| 878 long long expectedLength = m_response.expectedContentLength(); | 868 long long expectedLength = m_response.expectedContentLength(); |
| 879 long long receivedLength = m_receivedLength; | 869 long long receivedLength = m_receivedLength; |
| 880 | 870 |
| 871 // internalAbort() clears m_loader. hasPendingActivity() returns false when |
| 872 // m_loader is 0. So, if window.onload is dispatched (see comments in |
| 873 // internalAbort()), it's possible that the wrapper gets GC-ed during |
| 874 // execution of the event. So, we need to keep this object alive to |
| 875 // continue the rest of this method. |
| 876 RefPtr<XMLHttpRequest> protect(this); |
| 877 |
| 881 if (!internalAbort()) | 878 if (!internalAbort()) |
| 882 return; | 879 return; |
| 883 | 880 |
| 884 clearResponse(); | 881 clearResponse(); |
| 885 | 882 |
| 886 // Clear headers as required by the spec | 883 // Clear headers as required by the spec |
| 887 m_requestHeaders.clear(); | 884 m_requestHeaders.clear(); |
| 888 | 885 |
| 889 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) { | 886 if (!((m_state <= OPENED && !sendFlag) || m_state == DONE)) { |
| 890 ASSERT(!m_loader); | 887 ASSERT(!m_loader); |
| 891 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen
gth); | 888 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen
gth); |
| 892 } | 889 } |
| 893 m_state = UNSENT; | 890 m_state = UNSENT; |
| 894 } | 891 } |
| 895 | 892 |
| 896 void XMLHttpRequest::clearVariablesForLoading() | 893 void XMLHttpRequest::clearVariablesForLoading() |
| 897 { | 894 { |
| 898 m_decoder.clear(); | 895 m_decoder.clear(); |
| 899 | 896 |
| 900 m_responseEncoding = String(); | 897 m_responseEncoding = String(); |
| 901 } | 898 } |
| 902 | 899 |
| 903 bool XMLHttpRequest::internalAbort(DropProtection async) | 900 bool XMLHttpRequest::internalAbort() |
| 904 { | 901 { |
| 905 m_error = true; | 902 m_error = true; |
| 906 | 903 |
| 907 clearVariablesForLoading(); | 904 clearVariablesForLoading(); |
| 908 | 905 |
| 909 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); | 906 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); |
| 910 | 907 |
| 911 if (m_responseStream && m_state != DONE) | 908 if (m_responseStream && m_state != DONE) |
| 912 m_responseStream->abort(); | 909 m_responseStream->abort(); |
| 913 | 910 |
| 914 if (!m_loader) | 911 if (!m_loader) |
| 915 return true; | 912 return true; |
| 916 | 913 |
| 917 // Cancelling the ThreadableLoader m_loader may result in calling | 914 // Cancelling the ThreadableLoader m_loader may result in calling |
| 918 // window.onload synchronously. If such an onload handler contains open() | 915 // window.onload synchronously. If such an onload handler contains open() |
| 919 // call on the same XMLHttpRequest object, reentry happens. If m_loader | 916 // call on the same XMLHttpRequest object, reentry happens. If m_loader |
| 920 // is left to be non 0, internalAbort() call for the inner open() makes | 917 // is left to be non 0, internalAbort() for the inner open() repeats the |
| 921 // an extra dropProtection() call (when we're back to the outer open(), | 918 // the same work. To avoid that, clears m_loader before calling cancel(). |
| 922 // we'll call dropProtection()). To avoid that, clears m_loader before | 919 RefPtr<ThreadableLoader> loader = m_loader.release(); |
| 923 // calling cancel. | 920 loader->cancel(); |
| 924 // | 921 |
| 925 // If, window.onload contains open() and send(), m_loader will be set to | 922 // If, window.onload contains open() and send(), m_loader will be set to |
| 926 // non 0 value. So, we cannot continue the outer open(). In such case, | 923 // non 0 value. So, we cannot continue the outer open(). In such case, |
| 927 // just abort the outer open() by returning false. | 924 // just abort the outer open() by returning false. |
| 928 RefPtr<ThreadableLoader> loader = m_loader.release(); | 925 if (m_loader) |
| 929 loader->cancel(); | 926 return false; |
| 930 | |
| 931 // Save to a local variable since we're going to drop protection. | |
| 932 bool newLoadStarted = m_loader; | |
| 933 | 927 |
| 934 // If abort() called internalAbort() and a nested open() ended up | 928 // If abort() called internalAbort() and a nested open() ended up |
| 935 // clearing the error flag, but didn't send(), make sure the error | 929 // clearing the error flag, but didn't send(), make sure the error |
| 936 // flag is still set. | 930 // flag is still set. |
| 937 if (!newLoadStarted) | 931 m_error = true; |
| 938 m_error = true; | |
| 939 | 932 |
| 940 if (async == DropProtectionAsync) | 933 return true; |
| 941 dropProtectionSoon(); | |
| 942 else | |
| 943 dropProtection(); | |
| 944 | |
| 945 return !newLoadStarted; | |
| 946 } | 934 } |
| 947 | 935 |
| 948 void XMLHttpRequest::clearResponse() | 936 void XMLHttpRequest::clearResponse() |
| 949 { | 937 { |
| 950 // FIXME: when we add the support for multi-part XHR, we will have to | 938 // FIXME: when we add the support for multi-part XHR, we will have to |
| 951 // be careful with this initialization. | 939 // be careful with this initialization. |
| 952 m_receivedLength = 0; | 940 m_receivedLength = 0; |
| 953 | 941 |
| 954 m_response = ResourceResponse(); | 942 m_response = ResourceResponse(); |
| 955 | 943 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 if (!m_uploadComplete) { | 1042 if (!m_uploadComplete) { |
| 1055 m_uploadComplete = true; | 1043 m_uploadComplete = true; |
| 1056 if (m_upload && m_uploadEventsAllowed) | 1044 if (m_upload && m_uploadEventsAllowed) |
| 1057 m_upload->handleRequestError(type); | 1045 m_upload->handleRequestError(type); |
| 1058 } | 1046 } |
| 1059 | 1047 |
| 1060 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp
ectedLength); | 1048 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp
ectedLength); |
| 1061 dispatchEventAndLoadEnd(type, receivedLength, expectedLength); | 1049 dispatchEventAndLoadEnd(type, receivedLength, expectedLength); |
| 1062 } | 1050 } |
| 1063 | 1051 |
| 1064 void XMLHttpRequest::dropProtectionSoon() | |
| 1065 { | |
| 1066 m_dropProtectionRunner.runAsync(); | |
| 1067 } | |
| 1068 | |
| 1069 void XMLHttpRequest::dropProtection() | |
| 1070 { | |
| 1071 unsetPendingActivity(this); | |
| 1072 } | |
| 1073 | |
| 1074 void XMLHttpRequest::overrideMimeType(const AtomicString& override) | 1052 void XMLHttpRequest::overrideMimeType(const AtomicString& override) |
| 1075 { | 1053 { |
| 1076 m_mimeTypeOverride = override; | 1054 m_mimeTypeOverride = override; |
| 1077 } | 1055 } |
| 1078 | 1056 |
| 1079 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri
ng& value, ExceptionState& exceptionState) | 1057 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri
ng& value, ExceptionState& exceptionState) |
| 1080 { | 1058 { |
| 1081 if (m_state != OPENED || m_loader) { | 1059 if (m_state != OPENED || m_loader) { |
| 1082 exceptionState.throwDOMException(InvalidStateError, "The object's state
must be OPENED."); | 1060 exceptionState.throwDOMException(InvalidStateError, "The object's state
must be OPENED."); |
| 1083 return; | 1061 return; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 if (m_decoder) | 1234 if (m_decoder) |
| 1257 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); | 1235 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); |
| 1258 | 1236 |
| 1259 if (m_responseStream) | 1237 if (m_responseStream) |
| 1260 m_responseStream->finalize(); | 1238 m_responseStream->finalize(); |
| 1261 | 1239 |
| 1262 clearVariablesForLoading(); | 1240 clearVariablesForLoading(); |
| 1263 | 1241 |
| 1264 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this
, identifier, m_responseText, m_method, m_url, m_lastSendURL, m_lastSendLineNumb
er); | 1242 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this
, identifier, m_responseText, m_method, m_url, m_lastSendURL, m_lastSendLineNumb
er); |
| 1265 | 1243 |
| 1266 // Prevent dropProtection releasing the last reference, and retain |this| un
til the end of this method. | 1244 // hasPendingActivity() returns false when m_loader is 0. So, it's possible |
| 1245 // that the wrapper gets GC-ed during execution of the event. So, we need |
| 1246 // to keep this object alive to continue the rest of this method. |
| 1267 RefPtr<XMLHttpRequest> protect(this); | 1247 RefPtr<XMLHttpRequest> protect(this); |
| 1268 | 1248 |
| 1269 if (m_loader) { | 1249 if (m_loader) |
| 1270 m_loader = 0; | 1250 m_loader = 0; |
| 1271 dropProtection(); | |
| 1272 } | |
| 1273 | 1251 |
| 1274 changeState(DONE); | 1252 changeState(DONE); |
| 1275 } | 1253 } |
| 1276 | 1254 |
| 1277 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
g totalBytesToBeSent) | 1255 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
g totalBytesToBeSent) |
| 1278 { | 1256 { |
| 1279 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen
t, totalBytesToBeSent); | 1257 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen
t, totalBytesToBeSent); |
| 1280 | 1258 |
| 1281 if (!m_upload) | 1259 if (!m_upload) |
| 1282 return; | 1260 return; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 return; | 1353 return; |
| 1376 | 1354 |
| 1377 m_downloadedBlobLength += dataLength; | 1355 m_downloadedBlobLength += dataLength; |
| 1378 trackProgress(dataLength); | 1356 trackProgress(dataLength); |
| 1379 } | 1357 } |
| 1380 | 1358 |
| 1381 void XMLHttpRequest::handleDidTimeout() | 1359 void XMLHttpRequest::handleDidTimeout() |
| 1382 { | 1360 { |
| 1383 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); | 1361 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); |
| 1384 | 1362 |
| 1385 // internalAbort() calls dropProtection(), which may release the last refere
nce. | |
| 1386 RefPtr<XMLHttpRequest> protect(this); | |
| 1387 | |
| 1388 // Response is cleared next, save needed progress event data. | 1363 // Response is cleared next, save needed progress event data. |
| 1389 long long expectedLength = m_response.expectedContentLength(); | 1364 long long expectedLength = m_response.expectedContentLength(); |
| 1390 long long receivedLength = m_receivedLength; | 1365 long long receivedLength = m_receivedLength; |
| 1391 | 1366 |
| 1392 if (!internalAbort()) | 1367 if (!internalAbort()) |
| 1393 return; | 1368 return; |
| 1394 | 1369 |
| 1395 handleDidFailGeneric(); | 1370 handleDidFailGeneric(); |
| 1396 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex
pectedLength); | 1371 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex
pectedLength); |
| 1397 } | 1372 } |
| 1398 | 1373 |
| 1399 void XMLHttpRequest::suspend() | 1374 void XMLHttpRequest::suspend() |
| 1400 { | 1375 { |
| 1401 m_progressEventThrottle.suspend(); | 1376 m_progressEventThrottle.suspend(); |
| 1402 } | 1377 } |
| 1403 | 1378 |
| 1404 void XMLHttpRequest::resume() | 1379 void XMLHttpRequest::resume() |
| 1405 { | 1380 { |
| 1406 m_progressEventThrottle.resume(); | 1381 m_progressEventThrottle.resume(); |
| 1407 } | 1382 } |
| 1408 | 1383 |
| 1409 void XMLHttpRequest::stop() | 1384 void XMLHttpRequest::stop() |
| 1410 { | 1385 { |
| 1411 internalAbort(DropProtectionAsync); | 1386 internalAbort(); |
| 1387 } |
| 1388 |
| 1389 bool XMLHttpRequest::hasPendingActivity() const |
| 1390 { |
| 1391 return m_loader; |
| 1412 } | 1392 } |
| 1413 | 1393 |
| 1414 void XMLHttpRequest::contextDestroyed() | 1394 void XMLHttpRequest::contextDestroyed() |
| 1415 { | 1395 { |
| 1416 ASSERT(!m_loader); | 1396 ASSERT(!m_loader); |
| 1417 ActiveDOMObject::contextDestroyed(); | 1397 ActiveDOMObject::contextDestroyed(); |
| 1418 } | 1398 } |
| 1419 | 1399 |
| 1420 const AtomicString& XMLHttpRequest::interfaceName() const | 1400 const AtomicString& XMLHttpRequest::interfaceName() const |
| 1421 { | 1401 { |
| 1422 return EventTargetNames::XMLHttpRequest; | 1402 return EventTargetNames::XMLHttpRequest; |
| 1423 } | 1403 } |
| 1424 | 1404 |
| 1425 ExecutionContext* XMLHttpRequest::executionContext() const | 1405 ExecutionContext* XMLHttpRequest::executionContext() const |
| 1426 { | 1406 { |
| 1427 return ActiveDOMObject::executionContext(); | 1407 return ActiveDOMObject::executionContext(); |
| 1428 } | 1408 } |
| 1429 | 1409 |
| 1430 } // namespace WebCore | 1410 } // namespace WebCore |
| OLD | NEW |