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

Side by Side Diff: Source/core/xmlhttprequest/XMLHttpRequest.cpp

Issue 942433003: Protect XHR's wrapper while dispatching event. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 10 months 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
« no previous file with comments | « Source/core/xmlhttprequest/XMLHttpRequest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 #include "public/platform/WebURLRequest.h" 68 #include "public/platform/WebURLRequest.h"
69 #include "wtf/Assertions.h" 69 #include "wtf/Assertions.h"
70 #include "wtf/RefCountedLeakCounter.h" 70 #include "wtf/RefCountedLeakCounter.h"
71 #include "wtf/StdLibExtras.h" 71 #include "wtf/StdLibExtras.h"
72 #include "wtf/text/CString.h" 72 #include "wtf/text/CString.h"
73 73
74 namespace blink { 74 namespace blink {
75 75
76 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest")); 76 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest"));
77 77
78 static bool isSetCookieHeader(const AtomicString& name) 78 namespace {
79
80 // This class protects the wrapper of the associated XMLHttpRequest object
81 // via hasPendingActivity method which returns true if
82 // m_eventDispatchRecursionLevel is positive.
83 class ScopedEventDispatchProtect final {
84 public:
85 explicit ScopedEventDispatchProtect(int* level) : m_level(level)
86 {
87 ++*m_level;
88 }
89 ~ScopedEventDispatchProtect()
90 {
91 ASSERT(*m_level > 0);
92 --*m_level;
93 }
94
95 private:
96 int* const m_level;
97 };
98
99 bool isSetCookieHeader(const AtomicString& name)
79 { 100 {
80 return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set -cookie2"); 101 return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set -cookie2");
81 } 102 }
82 103
83 static void replaceCharsetInMediaType(String& mediaType, const String& charsetVa lue) 104 void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
84 { 105 {
85 unsigned pos = 0, len = 0; 106 unsigned pos = 0, len = 0;
86 107
87 findCharsetInMediaType(mediaType, pos, len); 108 findCharsetInMediaType(mediaType, pos, len);
88 109
89 if (!len) { 110 if (!len) {
90 // When no charset found, do nothing. 111 // When no charset found, do nothing.
91 return; 112 return;
92 } 113 }
93 114
94 // Found at least one existing charset, replace all occurrences with new cha rset. 115 // Found at least one existing charset, replace all occurrences with new cha rset.
95 while (len) { 116 while (len) {
96 mediaType.replace(pos, len, charsetValue); 117 mediaType.replace(pos, len, charsetValue);
97 unsigned start = pos + charsetValue.length(); 118 unsigned start = pos + charsetValue.length();
98 findCharsetInMediaType(mediaType, pos, len, start); 119 findCharsetInMediaType(mediaType, pos, len, start);
99 } 120 }
100 } 121 }
101 122
102 static void logConsoleError(ExecutionContext* context, const String& message) 123 void logConsoleError(ExecutionContext* context, const String& message)
103 { 124 {
104 if (!context) 125 if (!context)
105 return; 126 return;
106 // FIXME: It's not good to report the bad usage without indicating what sour ce line it came from. 127 // FIXME: It's not good to report the bad usage without indicating what sour ce line it came from.
107 // We should pass additional parameters so we can tell the console where the mistake occurred. 128 // We should pass additional parameters so we can tell the console where the mistake occurred.
108 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMess ageLevel, message)); 129 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMess ageLevel, message));
109 } 130 }
110 131
132 } // namespace
133
111 using Result = WebDataConsumerHandle::Result; 134 using Result = WebDataConsumerHandle::Result;
112 135
113 // ReadableStreamSource is the underlying source for the response stream of 136 // ReadableStreamSource is the underlying source for the response stream of
114 // XHR. The class has two modes: with and without body stream (passed to the 137 // XHR. The class has two modes: with and without body stream (passed to the
115 // constructor as the |body| argument). 138 // constructor as the |body| argument).
116 // 1) When an instance is constructed with a body stream, it receives data from 139 // 1) When an instance is constructed with a body stream, it receives data from
117 // the body stream. The data reading is originated by a |pullSource| call. 140 // the body stream. The data reading is originated by a |pullSource| call.
118 // 2) When an instance is constructed without a body stream, it receives data 141 // 2) When an instance is constructed without a body stream, it receives data
119 // from |didReceiveData| function. The associated XHR instance will push data 142 // from |didReceiveData| function. The associated XHR instance will push data
120 // via the function. 143 // via the function.
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 : ActiveDOMObject(context) 324 : ActiveDOMObject(context)
302 , m_timeoutMilliseconds(0) 325 , m_timeoutMilliseconds(0)
303 , m_loaderIdentifier(0) 326 , m_loaderIdentifier(0)
304 , m_state(UNSENT) 327 , m_state(UNSENT)
305 , m_lengthDownloadedToFile(0) 328 , m_lengthDownloadedToFile(0)
306 , m_receivedLength(0) 329 , m_receivedLength(0)
307 , m_exceptionCode(0) 330 , m_exceptionCode(0)
308 , m_progressEventThrottle(this) 331 , m_progressEventThrottle(this)
309 , m_responseTypeCode(ResponseTypeDefault) 332 , m_responseTypeCode(ResponseTypeDefault)
310 , m_securityOrigin(securityOrigin) 333 , m_securityOrigin(securityOrigin)
334 , m_eventDispatchRecursionLevel(0)
311 , m_async(true) 335 , m_async(true)
312 , m_includeCredentials(false) 336 , m_includeCredentials(false)
313 , m_parsedResponse(false) 337 , m_parsedResponse(false)
314 , m_error(false) 338 , m_error(false)
315 , m_uploadEventsAllowed(true) 339 , m_uploadEventsAllowed(true)
316 , m_uploadComplete(false) 340 , m_uploadComplete(false)
317 , m_sameOriginRequest(true) 341 , m_sameOriginRequest(true)
318 , m_downloadingToFile(false) 342 , m_downloadingToFile(false)
319 , m_responseTextOverflow(false) 343 , m_responseTextOverflow(false)
320 { 344 {
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 // 1131 //
1108 // If, window.onload contains open() and send(), m_loader will be set to 1132 // If, window.onload contains open() and send(), m_loader will be set to
1109 // non 0 value. So, we cannot continue the outer open(). In such case, 1133 // non 0 value. So, we cannot continue the outer open(). In such case,
1110 // just abort the outer open() by returning false. 1134 // just abort the outer open() by returning false.
1111 RefPtr<ThreadableLoader> loader = m_loader.release(); 1135 RefPtr<ThreadableLoader> loader = m_loader.release();
1112 loader->cancel(); 1136 loader->cancel();
1113 1137
1114 // If abort() called internalAbort() and a nested open() ended up 1138 // If abort() called internalAbort() and a nested open() ended up
1115 // clearing the error flag, but didn't send(), make sure the error 1139 // clearing the error flag, but didn't send(), make sure the error
1116 // flag is still set. 1140 // flag is still set.
1117 bool newLoadStarted = hasPendingActivity(); 1141 bool newLoadStarted = m_loader;
1118 if (!newLoadStarted) 1142 if (!newLoadStarted)
1119 m_error = true; 1143 m_error = true;
1120 1144
1121 return !newLoadStarted; 1145 return !newLoadStarted;
1122 } 1146 }
1123 1147
1124 void XMLHttpRequest::clearResponse() 1148 void XMLHttpRequest::clearResponse()
1125 { 1149 {
1126 // FIXME: when we add the support for multi-part XHR, we will have to 1150 // FIXME: when we add the support for multi-part XHR, we will have to
1127 // be careful with this initialization. 1151 // be careful with this initialization.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 } 1196 }
1173 1197
1174 void XMLHttpRequest::handleNetworkError() 1198 void XMLHttpRequest::handleNetworkError()
1175 { 1199 {
1176 WTF_LOG(Network, "XMLHttpRequest %p handleNetworkError()", this); 1200 WTF_LOG(Network, "XMLHttpRequest %p handleNetworkError()", this);
1177 1201
1178 // Response is cleared next, save needed progress event data. 1202 // Response is cleared next, save needed progress event data.
1179 long long expectedLength = m_response.expectedContentLength(); 1203 long long expectedLength = m_response.expectedContentLength();
1180 long long receivedLength = m_receivedLength; 1204 long long receivedLength = m_receivedLength;
1181 1205
1182 // Prevent the XMLHttpRequest instance from being destoryed during
1183 // |internalAbort()|.
1184 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1185
1186 if (!internalAbort()) 1206 if (!internalAbort())
1187 return; 1207 return;
1188 1208
1189 handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expe ctedLength); 1209 handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expe ctedLength);
1190 } 1210 }
1191 1211
1192 void XMLHttpRequest::handleDidCancel() 1212 void XMLHttpRequest::handleDidCancel()
1193 { 1213 {
1194 WTF_LOG(Network, "XMLHttpRequest %p handleDidCancel()", this); 1214 WTF_LOG(Network, "XMLHttpRequest %p handleDidCancel()", this);
1195 1215
1196 // Response is cleared next, save needed progress event data. 1216 // Response is cleared next, save needed progress event data.
1197 long long expectedLength = m_response.expectedContentLength(); 1217 long long expectedLength = m_response.expectedContentLength();
1198 long long receivedLength = m_receivedLength; 1218 long long receivedLength = m_receivedLength;
1199 1219
1200 // Prevent the XMLHttpRequest instance from being destoryed during
1201 // |internalAbort()|.
1202 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1203
1204 if (!internalAbort()) 1220 if (!internalAbort())
1205 return; 1221 return;
1206 1222
1207 handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expect edLength); 1223 handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expect edLength);
1208 } 1224 }
1209 1225
1210 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type, long long receivedLength, long long expectedLength) 1226 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi cString& type, long long receivedLength, long long expectedLength)
1211 { 1227 {
1212 WTF_LOG(Network, "XMLHttpRequest %p handleRequestError()", this); 1228 WTF_LOG(Network, "XMLHttpRequest %p handleRequestError()", this);
1213 1229
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 1409
1394 if (!m_response.httpStatusText().isNull()) 1410 if (!m_response.httpStatusText().isNull())
1395 return m_response.httpStatusText(); 1411 return m_response.httpStatusText();
1396 1412
1397 return String(); 1413 return String();
1398 } 1414 }
1399 1415
1400 void XMLHttpRequest::didFail(const ResourceError& error) 1416 void XMLHttpRequest::didFail(const ResourceError& error)
1401 { 1417 {
1402 WTF_LOG(Network, "XMLHttpRequest %p didFail()", this); 1418 WTF_LOG(Network, "XMLHttpRequest %p didFail()", this);
1419 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1403 1420
1404 // If we are already in an error state, for instance we called abort(), bail out early. 1421 // If we are already in an error state, for instance we called abort(), bail out early.
1405 if (m_error) 1422 if (m_error)
1406 return; 1423 return;
1407 1424
1408 if (error.isCancellation()) { 1425 if (error.isCancellation()) {
1409 handleDidCancel(); 1426 handleDidCancel();
1410 // Now the XMLHttpRequest instance may be dead. 1427 // Now the XMLHttpRequest instance may be dead.
1411 return; 1428 return;
1412 } 1429 }
1413 1430
1414 if (error.isTimeout()) { 1431 if (error.isTimeout()) {
1415 handleDidTimeout(); 1432 handleDidTimeout();
1416 // Now the XMLHttpRequest instance may be dead. 1433 // Now the XMLHttpRequest instance may be dead.
1417 return; 1434 return;
1418 } 1435 }
1419 1436
1420 // Network failures are already reported to Web Inspector by ResourceLoader. 1437 // Network failures are already reported to Web Inspector by ResourceLoader.
1421 if (error.domain() == errorDomainBlinkInternal) 1438 if (error.domain() == errorDomainBlinkInternal)
1422 logConsoleError(executionContext(), "XMLHttpRequest cannot load " + erro r.failingURL() + ". " + error.localizedDescription()); 1439 logConsoleError(executionContext(), "XMLHttpRequest cannot load " + erro r.failingURL() + ". " + error.localizedDescription());
1423 1440
1424 handleNetworkError(); 1441 handleNetworkError();
1425 // Now the XMLHttpRequest instance may be dead. 1442 // Now the XMLHttpRequest instance may be dead.
1426 } 1443 }
1427 1444
1428 void XMLHttpRequest::didFailRedirectCheck() 1445 void XMLHttpRequest::didFailRedirectCheck()
1429 { 1446 {
1430 WTF_LOG(Network, "XMLHttpRequest %p didFailRedirectCheck()", this); 1447 WTF_LOG(Network, "XMLHttpRequest %p didFailRedirectCheck()", this);
1448 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1431 1449
1432 handleNetworkError(); 1450 handleNetworkError();
1433 // Now the XMLHttpRequest instance may be dead. 1451 // Now the XMLHttpRequest instance may be dead.
1434 } 1452 }
1435 1453
1436 void XMLHttpRequest::didFinishLoading(unsigned long identifier, double) 1454 void XMLHttpRequest::didFinishLoading(unsigned long identifier, double)
1437 { 1455 {
1438 WTF_LOG(Network, "XMLHttpRequest %p didFinishLoading(%lu)", this, identifier ); 1456 WTF_LOG(Network, "XMLHttpRequest %p didFinishLoading(%lu)", this, identifier );
1457 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1439 1458
1440 if (m_error) 1459 if (m_error)
1441 return; 1460 return;
1442 1461
1443 if (m_state < HEADERS_RECEIVED) 1462 if (m_state < HEADERS_RECEIVED)
1444 changeState(HEADERS_RECEIVED); 1463 changeState(HEADERS_RECEIVED);
1445 1464
1446 m_loaderIdentifier = identifier; 1465 m_loaderIdentifier = identifier;
1447 1466
1448 if (m_downloadingToFile && m_responseTypeCode != ResponseTypeBlob && m_lengt hDownloadedToFile) { 1467 if (m_downloadingToFile && m_responseTypeCode != ResponseTypeBlob && m_lengt hDownloadedToFile) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 if (m_responseStreamSource) 1501 if (m_responseStreamSource)
1483 m_responseStreamSource->didReceiveFinishLoadingNotification(); 1502 m_responseStreamSource->didReceiveFinishLoadingNotification();
1484 1503
1485 clearVariablesForLoading(); 1504 clearVariablesForLoading();
1486 endLoading(); 1505 endLoading();
1487 } 1506 }
1488 1507
1489 void XMLHttpRequest::didFinishLoadingFromBlob() 1508 void XMLHttpRequest::didFinishLoadingFromBlob()
1490 { 1509 {
1491 WTF_LOG(Network, "XMLHttpRequest %p didFinishLoadingFromBlob", this); 1510 WTF_LOG(Network, "XMLHttpRequest %p didFinishLoadingFromBlob", this);
1511 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1492 1512
1493 didFinishLoadingInternal(); 1513 didFinishLoadingInternal();
1494 } 1514 }
1495 1515
1496 void XMLHttpRequest::didFailLoadingFromBlob() 1516 void XMLHttpRequest::didFailLoadingFromBlob()
1497 { 1517 {
1498 WTF_LOG(Network, "XMLHttpRequest %p didFailLoadingFromBlob()", this); 1518 WTF_LOG(Network, "XMLHttpRequest %p didFailLoadingFromBlob()", this);
1519 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1499 1520
1500 if (m_error) 1521 if (m_error)
1501 return; 1522 return;
1502 handleNetworkError(); 1523 handleNetworkError();
1503 } 1524 }
1504 1525
1505 PassRefPtr<BlobDataHandle> XMLHttpRequest::createBlobDataHandleFromResponse() 1526 PassRefPtr<BlobDataHandle> XMLHttpRequest::createBlobDataHandleFromResponse()
1506 { 1527 {
1507 ASSERT(m_downloadingToFile); 1528 ASSERT(m_downloadingToFile);
1508 OwnPtr<BlobData> blobData = BlobData::create(); 1529 OwnPtr<BlobData> blobData = BlobData::create();
1509 String filePath = m_response.downloadedFilePath(); 1530 String filePath = m_response.downloadedFilePath();
1510 // If we errored out or got no data, we return an empty handle. 1531 // If we errored out or got no data, we return an empty handle.
1511 if (!filePath.isEmpty() && m_lengthDownloadedToFile) { 1532 if (!filePath.isEmpty() && m_lengthDownloadedToFile) {
1512 blobData->appendFile(filePath); 1533 blobData->appendFile(filePath);
1513 // FIXME: finalResponseMIMETypeWithFallback() defaults to 1534 // FIXME: finalResponseMIMETypeWithFallback() defaults to
1514 // text/xml which may be incorrect. Replace it with 1535 // text/xml which may be incorrect. Replace it with
1515 // finalResponseMIMEType() after compatibility investigation. 1536 // finalResponseMIMEType() after compatibility investigation.
1516 blobData->setContentType(finalResponseMIMETypeWithFallback().lower()); 1537 blobData->setContentType(finalResponseMIMETypeWithFallback().lower());
1517 } 1538 }
1518 return BlobDataHandle::create(blobData.release(), m_lengthDownloadedToFile); 1539 return BlobDataHandle::create(blobData.release(), m_lengthDownloadedToFile);
1519 } 1540 }
1520 1541
1521 void XMLHttpRequest::notifyParserStopped() 1542 void XMLHttpRequest::notifyParserStopped()
1522 { 1543 {
1544 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1545
1523 // This should only be called when response document is parsed asynchronousl y. 1546 // This should only be called when response document is parsed asynchronousl y.
1524 ASSERT(m_responseDocumentParser); 1547 ASSERT(m_responseDocumentParser);
1525 ASSERT(!m_responseDocumentParser->isParsing()); 1548 ASSERT(!m_responseDocumentParser->isParsing());
1526 ASSERT(!m_responseLegacyStream); 1549 ASSERT(!m_responseLegacyStream);
1527 ASSERT(!m_responseStream); 1550 ASSERT(!m_responseStream);
1528 1551
1529 // Do nothing if we are called from |internalAbort()|. 1552 // Do nothing if we are called from |internalAbort()|.
1530 if (m_error) 1553 if (m_error)
1531 return; 1554 return;
1532 1555
(...skipping 16 matching lines...) Expand all
1549 if (m_loader) 1572 if (m_loader)
1550 m_loader = nullptr; 1573 m_loader = nullptr;
1551 m_loaderIdentifier = 0; 1574 m_loaderIdentifier = 0;
1552 1575
1553 changeState(DONE); 1576 changeState(DONE);
1554 } 1577 }
1555 1578
1556 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) 1579 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent)
1557 { 1580 {
1558 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent); 1581 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent);
1582 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1559 1583
1560 if (!m_upload) 1584 if (!m_upload)
1561 return; 1585 return;
1562 1586
1563 if (m_uploadEventsAllowed) 1587 if (m_uploadEventsAllowed)
1564 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); 1588 m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
1565 1589
1566 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { 1590 if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
1567 m_uploadComplete = true; 1591 m_uploadComplete = true;
1568 if (m_uploadEventsAllowed) 1592 if (m_uploadEventsAllowed)
1569 m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesS ent, totalBytesToBeSent); 1593 m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesS ent, totalBytesToBeSent);
1570 } 1594 }
1571 } 1595 }
1572 1596
1573 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response, PassOwnPtr<WebDataConsumerHandle> handle) 1597 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response, PassOwnPtr<WebDataConsumerHandle> handle)
1574 { 1598 {
1575 WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifi er); 1599 WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifi er);
1600 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1576 1601
1577 m_response = response; 1602 m_response = response;
1578 if (!m_mimeTypeOverride.isEmpty()) { 1603 if (!m_mimeTypeOverride.isEmpty()) {
1579 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); 1604 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride);
1580 m_finalResponseCharset = extractCharsetFromMediaType(m_mimeTypeOverride) ; 1605 m_finalResponseCharset = extractCharsetFromMediaType(m_mimeTypeOverride) ;
1581 } 1606 }
1582 1607
1583 if (m_finalResponseCharset.isEmpty()) 1608 if (m_finalResponseCharset.isEmpty())
1584 m_finalResponseCharset = response.textEncodingName(); 1609 m_finalResponseCharset = response.textEncodingName();
1585 1610
1586 if (handle) { 1611 if (handle) {
1587 ASSERT(!m_responseStream); 1612 ASSERT(!m_responseStream);
1588 ASSERT(!m_responseStreamSource); 1613 ASSERT(!m_responseStreamSource);
1589 m_responseStreamSource = new ReadableStreamSource(this, handle); 1614 m_responseStreamSource = new ReadableStreamSource(this, handle);
1590 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits< DOMArrayBuffer>>(executionContext(), m_responseStreamSource); 1615 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits< DOMArrayBuffer>>(executionContext(), m_responseStreamSource);
1591 m_responseStreamSource->startStream(m_responseStream); 1616 m_responseStreamSource->startStream(m_responseStream);
1592 1617
1593 // This protection seems needed to keep |this| alive after changeState
1594 // calling which may call event listeners.
1595 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1596 changeState(HEADERS_RECEIVED); 1618 changeState(HEADERS_RECEIVED);
1597 if (m_error) { 1619 if (m_error) {
1598 // We need to check for |m_error| because |changeState| may trigger 1620 // We need to check for |m_error| because |changeState| may trigger
1599 // readystatechange, and user javascript can cause |abort()|. 1621 // readystatechange, and user javascript can cause |abort()|.
1600 return; 1622 return;
1601 } 1623 }
1602 changeState(LOADING); 1624 changeState(LOADING);
1603 } 1625 }
1604 } 1626 }
1605 1627
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 } 1664 }
1643 1665
1644 if (responseIsHTML()) 1666 if (responseIsHTML())
1645 return TextResourceDecoder::create("text/html", "UTF-8"); 1667 return TextResourceDecoder::create("text/html", "UTF-8");
1646 1668
1647 return TextResourceDecoder::create("text/plain", "UTF-8"); 1669 return TextResourceDecoder::create("text/plain", "UTF-8");
1648 } 1670 }
1649 1671
1650 void XMLHttpRequest::didReceiveData(const char* data, unsigned len) 1672 void XMLHttpRequest::didReceiveData(const char* data, unsigned len)
1651 { 1673 {
1674 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1652 if (m_error) 1675 if (m_error)
1653 return; 1676 return;
1654 1677
1655 if (m_state < HEADERS_RECEIVED) 1678 if (m_state < HEADERS_RECEIVED)
1656 changeState(HEADERS_RECEIVED); 1679 changeState(HEADERS_RECEIVED);
1657 1680
1658 // We need to check for |m_error| again, because |changeState| may trigger 1681 // We need to check for |m_error| again, because |changeState| may trigger
1659 // readystatechange, and user javascript can cause |abort()|. 1682 // readystatechange, and user javascript can cause |abort()|.
1660 if (m_error) 1683 if (m_error)
1661 return; 1684 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 if (m_blobLoader) { 1719 if (m_blobLoader) {
1697 // In this case, the data is provided by m_blobLoader. As progress 1720 // In this case, the data is provided by m_blobLoader. As progress
1698 // events are already fired, we should return here. 1721 // events are already fired, we should return here.
1699 return; 1722 return;
1700 } 1723 }
1701 trackProgress(len); 1724 trackProgress(len);
1702 } 1725 }
1703 1726
1704 void XMLHttpRequest::didDownloadData(int dataLength) 1727 void XMLHttpRequest::didDownloadData(int dataLength)
1705 { 1728 {
1729 ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
1706 if (m_error) 1730 if (m_error)
1707 return; 1731 return;
1708 1732
1709 ASSERT(m_downloadingToFile); 1733 ASSERT(m_downloadingToFile);
1710 1734
1711 if (m_state < HEADERS_RECEIVED) 1735 if (m_state < HEADERS_RECEIVED)
1712 changeState(HEADERS_RECEIVED); 1736 changeState(HEADERS_RECEIVED);
1713 1737
1714 if (!dataLength) 1738 if (!dataLength)
1715 return; 1739 return;
1716 1740
1717 // readystatechange event handler may do something to put this XHR in error 1741 // readystatechange event handler may do something to put this XHR in error
1718 // state. We need to check m_error again here. 1742 // state. We need to check m_error again here.
1719 if (m_error) 1743 if (m_error)
1720 return; 1744 return;
1721 1745
1722 m_lengthDownloadedToFile += dataLength; 1746 m_lengthDownloadedToFile += dataLength;
1723 1747
1724 trackProgress(dataLength); 1748 trackProgress(dataLength);
1725 } 1749 }
1726 1750
1727 void XMLHttpRequest::handleDidTimeout() 1751 void XMLHttpRequest::handleDidTimeout()
1728 { 1752 {
1729 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1753 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1730 1754
1731 // Response is cleared next, save needed progress event data. 1755 // Response is cleared next, save needed progress event data.
1732 long long expectedLength = m_response.expectedContentLength(); 1756 long long expectedLength = m_response.expectedContentLength();
1733 long long receivedLength = m_receivedLength; 1757 long long receivedLength = m_receivedLength;
1734 1758
1735 // Prevent the XMLHttpRequest instance from being destoryed during
1736 // |internalAbort()|.
1737 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1738
1739 if (!internalAbort()) 1759 if (!internalAbort())
1740 return; 1760 return;
1741 1761
1742 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength); 1762 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength);
1743 } 1763 }
1744 1764
1745 void XMLHttpRequest::suspend() 1765 void XMLHttpRequest::suspend()
1746 { 1766 {
1747 m_progressEventThrottle.suspend(); 1767 m_progressEventThrottle.suspend();
1748 } 1768 }
(...skipping 13 matching lines...) Expand all
1762 // Neither this object nor the JavaScript wrapper should be deleted while 1782 // Neither this object nor the JavaScript wrapper should be deleted while
1763 // a request is in progress because we need to keep the listeners alive, 1783 // a request is in progress because we need to keep the listeners alive,
1764 // and they are referenced by the JavaScript wrapper. 1784 // and they are referenced by the JavaScript wrapper.
1765 // |m_loader| is non-null while request is active and ThreadableLoaderClient 1785 // |m_loader| is non-null while request is active and ThreadableLoaderClient
1766 // callbacks may be called, and |m_responseDocumentParser| is non-null while 1786 // callbacks may be called, and |m_responseDocumentParser| is non-null while
1767 // DocumentParserClient callbacks may be called. 1787 // DocumentParserClient callbacks may be called.
1768 if (m_loader || m_responseDocumentParser) 1788 if (m_loader || m_responseDocumentParser)
1769 return true; 1789 return true;
1770 if (m_responseStream && m_responseStream->hasPendingActivity()) 1790 if (m_responseStream && m_responseStream->hasPendingActivity())
1771 return true; 1791 return true;
1772 return false; 1792 return m_eventDispatchRecursionLevel > 0;
1773 } 1793 }
1774 1794
1775 void XMLHttpRequest::contextDestroyed() 1795 void XMLHttpRequest::contextDestroyed()
1776 { 1796 {
1777 ASSERT(!m_loader); 1797 ASSERT(!m_loader);
1778 ActiveDOMObject::contextDestroyed(); 1798 ActiveDOMObject::contextDestroyed();
1779 } 1799 }
1780 1800
1781 const AtomicString& XMLHttpRequest::interfaceName() const 1801 const AtomicString& XMLHttpRequest::interfaceName() const
1782 { 1802 {
(...skipping 15 matching lines...) Expand all
1798 visitor->trace(m_responseDocumentParser); 1818 visitor->trace(m_responseDocumentParser);
1799 visitor->trace(m_progressEventThrottle); 1819 visitor->trace(m_progressEventThrottle);
1800 visitor->trace(m_upload); 1820 visitor->trace(m_upload);
1801 visitor->trace(m_blobLoader); 1821 visitor->trace(m_blobLoader);
1802 XMLHttpRequestEventTarget::trace(visitor); 1822 XMLHttpRequestEventTarget::trace(visitor);
1803 DocumentParserClient::trace(visitor); 1823 DocumentParserClient::trace(visitor);
1804 ActiveDOMObject::trace(visitor); 1824 ActiveDOMObject::trace(visitor);
1805 } 1825 }
1806 1826
1807 } // namespace blink 1827 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/xmlhttprequest/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698