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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 && !name.startsWith(staticData->m_secHeaderPrefix, false); | 474 && !name.startsWith(staticData->m_secHeaderPrefix, false); |
475 } | 475 } |
476 | 476 |
477 void XMLHttpRequest::open(const String& method, const KURL& url, ExceptionState&
es) | 477 void XMLHttpRequest::open(const String& method, const KURL& url, ExceptionState&
es) |
478 { | 478 { |
479 open(method, url, true, es); | 479 open(method, url, true, es); |
480 } | 480 } |
481 | 481 |
482 void XMLHttpRequest::open(const String& method, const KURL& url, bool async, Exc
eptionState& es) | 482 void XMLHttpRequest::open(const String& method, const KURL& url, bool async, Exc
eptionState& es) |
483 { | 483 { |
484 internalAbort(); | 484 if (!internalAbort()) |
| 485 return; |
| 486 |
485 State previousState = m_state; | 487 State previousState = m_state; |
486 m_state = UNSENT; | 488 m_state = UNSENT; |
487 m_error = false; | 489 m_error = false; |
488 m_uploadComplete = false; | 490 m_uploadComplete = false; |
489 | 491 |
490 // clear stuff from possible previous load | 492 // clear stuff from possible previous load |
491 clearResponse(); | 493 clearResponse(); |
492 clearRequest(); | 494 clearRequest(); |
493 | 495 |
494 ASSERT(m_state == UNSENT); | 496 ASSERT(m_state == UNSENT); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. | 787 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. |
786 // This is true while running onunload handlers. | 788 // This is true while running onunload handlers. |
787 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 789 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. |
788 // FIXME: Maybe create() can return null for other reasons too? | 790 // FIXME: Maybe create() can return null for other reasons too? |
789 ASSERT(!m_loader); | 791 ASSERT(!m_loader); |
790 m_loader = ThreadableLoader::create(scriptExecutionContext(), this, requ
est, options); | 792 m_loader = ThreadableLoader::create(scriptExecutionContext(), this, requ
est, options); |
791 if (m_loader) { | 793 if (m_loader) { |
792 // Neither this object nor the JavaScript wrapper should be deleted
while | 794 // Neither this object nor the JavaScript wrapper should be deleted
while |
793 // a request is in progress because we need to keep the listeners al
ive, | 795 // a request is in progress because we need to keep the listeners al
ive, |
794 // and they are referenced by the JavaScript wrapper. | 796 // and they are referenced by the JavaScript wrapper. |
795 | |
796 // m_loader was null, so there should be no pending activity at this
point. | |
797 ASSERT(!hasPendingActivity()); | |
798 setPendingActivity(this); | 797 setPendingActivity(this); |
799 } | 798 } |
800 } else { | 799 } else { |
801 ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), re
quest, *this, options); | 800 ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), re
quest, *this, options); |
802 } | 801 } |
803 | 802 |
804 if (!m_exceptionCode && m_error) | 803 if (!m_exceptionCode && m_error) |
805 m_exceptionCode = NetworkError; | 804 m_exceptionCode = NetworkError; |
806 if (m_exceptionCode) | 805 if (m_exceptionCode) |
807 es.throwDOMException(m_exceptionCode); | 806 es.throwDOMException(m_exceptionCode); |
808 } | 807 } |
809 | 808 |
810 void XMLHttpRequest::abort() | 809 void XMLHttpRequest::abort() |
811 { | 810 { |
812 // internalAbort() calls dropProtection(), which may release the last refere
nce. | 811 // internalAbort() calls dropProtection(), which may release the last refere
nce. |
813 RefPtr<XMLHttpRequest> protect(this); | 812 RefPtr<XMLHttpRequest> protect(this); |
814 | 813 |
815 bool sendFlag = m_loader; | 814 bool sendFlag = m_loader; |
816 | 815 |
817 internalAbort(); | 816 if (!internalAbort()) |
| 817 return; |
818 | 818 |
819 clearResponseBuffers(); | 819 clearResponseBuffers(); |
820 | 820 |
821 // Clear headers as required by the spec | 821 // Clear headers as required by the spec |
822 m_requestHeaders.clear(); | 822 m_requestHeaders.clear(); |
823 | 823 |
824 if ((m_state <= OPENED && !sendFlag) || m_state == DONE) | 824 if ((m_state <= OPENED && !sendFlag) || m_state == DONE) |
825 m_state = UNSENT; | 825 m_state = UNSENT; |
826 else { | 826 else { |
827 ASSERT(!m_loader); | 827 ASSERT(!m_loader); |
828 changeState(DONE); | 828 changeState(DONE); |
829 m_state = UNSENT; | 829 m_state = UNSENT; |
830 } | 830 } |
831 | 831 |
832 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent:
:create(eventNames().abortEvent)); | 832 m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent:
:create(eventNames().abortEvent)); |
833 if (!m_uploadComplete) { | 833 if (!m_uploadComplete) { |
834 m_uploadComplete = true; | 834 m_uploadComplete = true; |
835 if (m_upload && m_uploadEventsAllowed) | 835 if (m_upload && m_uploadEventsAllowed) |
836 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat
e(eventNames().abortEvent)); | 836 m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::creat
e(eventNames().abortEvent)); |
837 } | 837 } |
838 } | 838 } |
839 | 839 |
840 void XMLHttpRequest::internalAbort(DropProtection async) | 840 bool XMLHttpRequest::internalAbort(DropProtection async) |
841 { | 841 { |
842 m_error = true; | 842 m_error = true; |
843 | 843 |
844 // FIXME: when we add the support for multi-part XHR, we will have to think
be careful with this initialization. | 844 // FIXME: when we add the support for multi-part XHR, we will have to think
be careful with this initialization. |
845 m_receivedLength = 0; | 845 m_receivedLength = 0; |
846 m_decoder = 0; | 846 m_decoder = 0; |
847 | 847 |
848 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this); | 848 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this); |
849 | 849 |
850 if (m_responseStream && m_state != DONE) | 850 if (m_responseStream && m_state != DONE) |
851 m_responseStream->abort(); | 851 m_responseStream->abort(); |
852 | 852 |
853 if (!m_loader) | 853 if (!m_loader) |
854 return; | 854 return true; |
855 | 855 |
856 m_loader->cancel(); | 856 // Cancelling the ThreadableLoader m_loader may result in calling |
857 m_loader = 0; | 857 // window.onload synchronously. If such an onload handler contains open() |
| 858 // call on the same XMLHttpRequest object, reentry happens. If m_loader |
| 859 // is left to be non 0, internalAbort() call for the inner open() makes |
| 860 // an extra dropProtection() call (when we're back to the outer open(), |
| 861 // we'll call dropProtection()). To avoid that, clears m_loader before |
| 862 // calling cancel. |
| 863 // |
| 864 // If, window.onload contains open() and send(), m_loader will be set to |
| 865 // non 0 value. So, we cannot continue the outer open(). In such case, |
| 866 // just abort the outer open() by returning false. |
| 867 RefPtr<ThreadableLoader> loader = m_loader.release(); |
| 868 loader->cancel(); |
| 869 |
| 870 // Save to a local variable since we're going to drop protection. |
| 871 bool newLoadStarted = m_loader; |
858 | 872 |
859 if (async == DropProtectionAsync) | 873 if (async == DropProtectionAsync) |
860 dropProtectionSoon(); | 874 dropProtectionSoon(); |
861 else | 875 else |
862 dropProtection(); | 876 dropProtection(); |
| 877 |
| 878 return !newLoadStarted; |
863 } | 879 } |
864 | 880 |
865 void XMLHttpRequest::clearResponse() | 881 void XMLHttpRequest::clearResponse() |
866 { | 882 { |
867 m_response = ResourceResponse(); | 883 m_response = ResourceResponse(); |
868 clearResponseBuffers(); | 884 clearResponseBuffers(); |
869 } | 885 } |
870 | 886 |
871 void XMLHttpRequest::clearResponseBuffers() | 887 void XMLHttpRequest::clearResponseBuffers() |
872 { | 888 { |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 else | 1260 else |
1245 // Firefox calls readyStateChanged every time it receives data, 4449
442 | 1261 // Firefox calls readyStateChanged every time it receives data, 4449
442 |
1246 callReadyStateChangeListener(); | 1262 callReadyStateChangeListener(); |
1247 } | 1263 } |
1248 } | 1264 } |
1249 | 1265 |
1250 void XMLHttpRequest::handleDidTimeout() | 1266 void XMLHttpRequest::handleDidTimeout() |
1251 { | 1267 { |
1252 // internalAbort() calls dropProtection(), which may release the last refere
nce. | 1268 // internalAbort() calls dropProtection(), which may release the last refere
nce. |
1253 RefPtr<XMLHttpRequest> protect(this); | 1269 RefPtr<XMLHttpRequest> protect(this); |
1254 internalAbort(); | 1270 |
| 1271 if (!internalAbort()) |
| 1272 return; |
1255 | 1273 |
1256 m_exceptionCode = TimeoutError; | 1274 m_exceptionCode = TimeoutError; |
1257 | 1275 |
1258 handleDidFailGeneric(); | 1276 handleDidFailGeneric(); |
1259 | 1277 |
1260 if (!m_async) { | 1278 if (!m_async) { |
1261 m_state = DONE; | 1279 m_state = DONE; |
1262 return; | 1280 return; |
1263 } | 1281 } |
1264 changeState(DONE); | 1282 changeState(DONE); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 { | 1314 { |
1297 return eventNames().interfaceForXMLHttpRequest; | 1315 return eventNames().interfaceForXMLHttpRequest; |
1298 } | 1316 } |
1299 | 1317 |
1300 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const | 1318 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const |
1301 { | 1319 { |
1302 return ActiveDOMObject::scriptExecutionContext(); | 1320 return ActiveDOMObject::scriptExecutionContext(); |
1303 } | 1321 } |
1304 | 1322 |
1305 } // namespace WebCore | 1323 } // namespace WebCore |
OLD | NEW |