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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |