Chromium Code Reviews| 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 m_isolatedWorldSecurityOrigin(isolatedWorldSecurityOrigin), | 239 m_isolatedWorldSecurityOrigin(isolatedWorldSecurityOrigin), |
| 240 m_eventDispatchRecursionLevel(0), | 240 m_eventDispatchRecursionLevel(0), |
| 241 m_async(true), | 241 m_async(true), |
| 242 m_includeCredentials(false), | 242 m_includeCredentials(false), |
| 243 m_parsedResponse(false), | 243 m_parsedResponse(false), |
| 244 m_error(false), | 244 m_error(false), |
| 245 m_uploadEventsAllowed(true), | 245 m_uploadEventsAllowed(true), |
| 246 m_uploadComplete(false), | 246 m_uploadComplete(false), |
| 247 m_sameOriginRequest(true), | 247 m_sameOriginRequest(true), |
| 248 m_downloadingToFile(false), | 248 m_downloadingToFile(false), |
| 249 m_responseTextOverflow(false) {} | 249 m_responseTextOverflow(false) {} |
|
yhirano
2016/11/15 02:26:08
Please initialize the flag.
sof
2016/11/15 06:48:46
oops, thanks - done.
| |
| 250 | 250 |
| 251 XMLHttpRequest::~XMLHttpRequest() {} | 251 XMLHttpRequest::~XMLHttpRequest() {} |
| 252 | 252 |
| 253 Document* XMLHttpRequest::document() const { | 253 Document* XMLHttpRequest::document() const { |
| 254 DCHECK(getExecutionContext()->isDocument()); | 254 DCHECK(getExecutionContext()->isDocument()); |
| 255 return toDocument(getExecutionContext()); | 255 return toDocument(getExecutionContext()); |
| 256 } | 256 } |
| 257 | 257 |
| 258 SecurityOrigin* XMLHttpRequest::getSecurityOrigin() const { | 258 SecurityOrigin* XMLHttpRequest::getSecurityOrigin() const { |
| 259 return m_isolatedWorldSecurityOrigin | 259 return m_isolatedWorldSecurityOrigin |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 dispatchProgressEventFromSnapshot(EventTypeNames::load); | 545 dispatchProgressEventFromSnapshot(EventTypeNames::load); |
| 546 dispatchProgressEventFromSnapshot(EventTypeNames::loadend); | 546 dispatchProgressEventFromSnapshot(EventTypeNames::loadend); |
| 547 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), | 547 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), |
| 548 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", | 548 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", |
| 549 InspectorUpdateCountersEvent::data()); | 549 InspectorUpdateCountersEvent::data()); |
| 550 } | 550 } |
| 551 } | 551 } |
| 552 | 552 |
| 553 void XMLHttpRequest::setWithCredentials(bool value, | 553 void XMLHttpRequest::setWithCredentials(bool value, |
| 554 ExceptionState& exceptionState) { | 554 ExceptionState& exceptionState) { |
| 555 if (m_state > kOpened || m_loader) { | 555 if (m_state > kOpened || m_sendFlag) { |
| 556 exceptionState.throwDOMException( | 556 exceptionState.throwDOMException( |
| 557 InvalidStateError, | 557 InvalidStateError, |
| 558 "The value may only be set if the object's state is UNSENT or OPENED."); | 558 "The value may only be set if the object's state is UNSENT or OPENED."); |
| 559 return; | 559 return; |
| 560 } | 560 } |
| 561 | 561 |
| 562 m_includeCredentials = value; | 562 m_includeCredentials = value; |
| 563 } | 563 } |
| 564 | 564 |
| 565 void XMLHttpRequest::open(const AtomicString& method, | 565 void XMLHttpRequest::open(const AtomicString& method, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); | 661 UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); |
| 662 } | 662 } |
| 663 | 663 |
| 664 m_method = FetchUtils::normalizeMethod(method); | 664 m_method = FetchUtils::normalizeMethod(method); |
| 665 | 665 |
| 666 m_url = url; | 666 m_url = url; |
| 667 | 667 |
| 668 m_async = async; | 668 m_async = async; |
| 669 | 669 |
| 670 DCHECK(!m_loader); | 670 DCHECK(!m_loader); |
| 671 m_sendFlag = false; | |
| 671 | 672 |
| 672 // Check previous state to avoid dispatching readyState event | 673 // Check previous state to avoid dispatching readyState event |
| 673 // when calling open several times in a row. | 674 // when calling open several times in a row. |
| 674 if (previousState != kOpened) | 675 if (previousState != kOpened) |
| 675 changeState(kOpened); | 676 changeState(kOpened); |
| 676 else | 677 else |
| 677 m_state = kOpened; | 678 m_state = kOpened; |
| 678 } | 679 } |
| 679 | 680 |
| 680 bool XMLHttpRequest::initSend(ExceptionState& exceptionState) { | 681 bool XMLHttpRequest::initSend(ExceptionState& exceptionState) { |
| 681 if (!getExecutionContext()) { | 682 if (!getExecutionContext()) { |
| 682 handleNetworkError(); | 683 handleNetworkError(); |
| 683 throwForLoadFailureIfNeeded(exceptionState, | 684 throwForLoadFailureIfNeeded(exceptionState, |
| 684 "Document is already detached."); | 685 "Document is already detached."); |
| 685 return false; | 686 return false; |
| 686 } | 687 } |
| 687 | 688 |
| 688 if (m_state != kOpened || m_loader) { | 689 if (m_state != kOpened || m_sendFlag) { |
| 689 exceptionState.throwDOMException(InvalidStateError, | 690 exceptionState.throwDOMException(InvalidStateError, |
| 690 "The object's state must be OPENED."); | 691 "The object's state must be OPENED."); |
| 691 return false; | 692 return false; |
| 692 } | 693 } |
| 693 | 694 |
| 694 if (!m_async) { | 695 if (!m_async) { |
| 695 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 696 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 696 if (isolate && v8::MicrotasksScope::IsRunningMicrotasks(isolate)) { | 697 if (isolate && v8::MicrotasksScope::IsRunningMicrotasks(isolate)) { |
| 697 UseCounter::count(getExecutionContext(), | 698 UseCounter::count(getExecutionContext(), |
| 698 UseCounter::During_Microtask_SyncXHR); | 699 UseCounter::During_Microtask_SyncXHR); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 if (!m_async) { | 923 if (!m_async) { |
| 923 throwForLoadFailureIfNeeded( | 924 throwForLoadFailureIfNeeded( |
| 924 exceptionState, "'GET' is the only method allowed for 'blob:' URLs."); | 925 exceptionState, "'GET' is the only method allowed for 'blob:' URLs."); |
| 925 } | 926 } |
| 926 return; | 927 return; |
| 927 } | 928 } |
| 928 | 929 |
| 929 DCHECK(getExecutionContext()); | 930 DCHECK(getExecutionContext()); |
| 930 ExecutionContext& executionContext = *getExecutionContext(); | 931 ExecutionContext& executionContext = *getExecutionContext(); |
| 931 | 932 |
| 933 m_sendFlag = true; | |
| 932 // The presence of upload event listeners forces us to use preflighting | 934 // The presence of upload event listeners forces us to use preflighting |
| 933 // because POSTing to an URL that does not permit cross origin requests should | 935 // because POSTing to an URL that does not permit cross origin requests should |
| 934 // look exactly like POSTing to an URL that does not respond at all. | 936 // look exactly like POSTing to an URL that does not respond at all. |
| 935 // Also, only async requests support upload progress events. | 937 // Also, only async requests support upload progress events. |
| 936 bool uploadEvents = false; | 938 bool uploadEvents = false; |
| 937 if (m_async) { | 939 if (m_async) { |
| 938 InspectorInstrumentation::asyncTaskScheduled( | 940 InspectorInstrumentation::asyncTaskScheduled( |
| 939 &executionContext, "XMLHttpRequest.send", this, true); | 941 &executionContext, "XMLHttpRequest.send", this, true); |
| 940 dispatchProgressEvent(EventTypeNames::loadstart, 0, 0); | 942 dispatchProgressEvent(EventTypeNames::loadstart, 0, 0); |
| 941 if (httpBody && m_upload) { | 943 if (httpBody && m_upload) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 m_exceptionCode = 0; | 1027 m_exceptionCode = 0; |
| 1026 m_error = false; | 1028 m_error = false; |
| 1027 | 1029 |
| 1028 if (m_async) { | 1030 if (m_async) { |
| 1029 UseCounter::count(&executionContext, | 1031 UseCounter::count(&executionContext, |
| 1030 UseCounter::XMLHttpRequestAsynchronous); | 1032 UseCounter::XMLHttpRequestAsynchronous); |
| 1031 if (m_upload) | 1033 if (m_upload) |
| 1032 request.setReportUploadProgress(true); | 1034 request.setReportUploadProgress(true); |
| 1033 | 1035 |
| 1034 DCHECK(!m_loader); | 1036 DCHECK(!m_loader); |
| 1037 DCHECK(m_sendFlag); | |
| 1035 m_loader = ThreadableLoader::create(executionContext, this, options, | 1038 m_loader = ThreadableLoader::create(executionContext, this, options, |
| 1036 resourceLoaderOptions); | 1039 resourceLoaderOptions); |
| 1037 m_loader->start(request); | 1040 m_loader->start(request); |
| 1038 | 1041 |
| 1039 return; | 1042 return; |
| 1040 } | 1043 } |
| 1041 | 1044 |
| 1042 // Use count for XHR synchronous requests. | 1045 // Use count for XHR synchronous requests. |
| 1043 UseCounter::count(&executionContext, UseCounter::XMLHttpRequestSynchronous); | 1046 UseCounter::count(&executionContext, UseCounter::XMLHttpRequestSynchronous); |
| 1044 ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, | 1047 ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, |
| 1045 options, resourceLoaderOptions); | 1048 options, resourceLoaderOptions); |
| 1046 | 1049 |
| 1047 throwForLoadFailureIfNeeded(exceptionState, String()); | 1050 throwForLoadFailureIfNeeded(exceptionState, String()); |
| 1048 } | 1051 } |
| 1049 | 1052 |
| 1050 void XMLHttpRequest::abort() { | 1053 void XMLHttpRequest::abort() { |
| 1051 NETWORK_DVLOG(1) << this << " abort()"; | 1054 NETWORK_DVLOG(1) << this << " abort()"; |
| 1052 | 1055 |
| 1053 // internalAbort() clears |m_loader|. Compute |sendFlag| now. | |
| 1054 // | |
| 1055 // |sendFlag| corresponds to "the send() flag" defined in the XHR spec. | |
| 1056 // | |
| 1057 // |sendFlag| is only set when we have an active, asynchronous loader. | |
| 1058 // Don't use it as "the send() flag" when the XHR is in sync mode. | |
| 1059 bool sendFlag = m_loader.get(); | |
| 1060 | |
| 1061 // internalAbort() clears the response. Save the data needed for | 1056 // internalAbort() clears the response. Save the data needed for |
| 1062 // dispatching ProgressEvents. | 1057 // dispatching ProgressEvents. |
| 1063 long long expectedLength = m_response.expectedContentLength(); | 1058 long long expectedLength = m_response.expectedContentLength(); |
| 1064 long long receivedLength = m_receivedLength; | 1059 long long receivedLength = m_receivedLength; |
| 1065 | 1060 |
| 1066 if (!internalAbort()) | 1061 if (!internalAbort()) |
| 1067 return; | 1062 return; |
| 1068 | 1063 |
| 1069 // The script never gets any chance to call abort() on a sync XHR between | 1064 // The script never gets any chance to call abort() on a sync XHR between |
| 1070 // send() call and transition to the DONE state. It's because a sync XHR | 1065 // send() call and transition to the DONE state. It's because a sync XHR |
| 1071 // doesn't dispatch any event between them. So, if |m_async| is false, we | 1066 // doesn't dispatch any event between them. So, if |m_async| is false, we |
| 1072 // can skip the "request error steps" (defined in the XHR spec) without any | 1067 // can skip the "request error steps" (defined in the XHR spec) without any |
| 1073 // state check. | 1068 // state check. |
| 1074 // | 1069 // |
| 1075 // FIXME: It's possible open() is invoked in internalAbort() and |m_async| | 1070 // FIXME: It's possible open() is invoked in internalAbort() and |m_async| |
| 1076 // becomes true by that. We should implement more reliable treatment for | 1071 // becomes true by that. We should implement more reliable treatment for |
| 1077 // nested method invocations at some point. | 1072 // nested method invocations at some point. |
| 1078 if (m_async) { | 1073 if (m_async) { |
| 1079 if ((m_state == kOpened && sendFlag) || m_state == kHeadersReceived || | 1074 if ((m_state == kOpened && m_sendFlag) || m_state == kHeadersReceived || |
| 1080 m_state == kLoading) { | 1075 m_state == kLoading) { |
| 1081 DCHECK(!m_loader); | 1076 DCHECK(!m_loader); |
| 1082 handleRequestError(0, EventTypeNames::abort, receivedLength, | 1077 handleRequestError(0, EventTypeNames::abort, receivedLength, |
| 1083 expectedLength); | 1078 expectedLength); |
| 1084 } | 1079 } |
| 1085 } | 1080 } |
| 1086 m_state = kUnsent; | 1081 m_state = kUnsent; |
| 1087 } | 1082 } |
| 1088 | 1083 |
| 1089 void XMLHttpRequest::clearVariablesForLoading() { | 1084 void XMLHttpRequest::clearVariablesForLoading() { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 | 1213 |
| 1219 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, | 1214 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, |
| 1220 const AtomicString& type, | 1215 const AtomicString& type, |
| 1221 long long receivedLength, | 1216 long long receivedLength, |
| 1222 long long expectedLength) { | 1217 long long expectedLength) { |
| 1223 NETWORK_DVLOG(1) << this << " handleRequestError()"; | 1218 NETWORK_DVLOG(1) << this << " handleRequestError()"; |
| 1224 | 1219 |
| 1225 InspectorInstrumentation::didFailXHRLoading(getExecutionContext(), this, this, | 1220 InspectorInstrumentation::didFailXHRLoading(getExecutionContext(), this, this, |
| 1226 m_method, m_url); | 1221 m_method, m_url); |
| 1227 | 1222 |
| 1223 m_sendFlag = false; | |
| 1228 if (!m_async) { | 1224 if (!m_async) { |
| 1229 DCHECK(exceptionCode); | 1225 DCHECK(exceptionCode); |
| 1230 m_state = kDone; | 1226 m_state = kDone; |
| 1231 m_exceptionCode = exceptionCode; | 1227 m_exceptionCode = exceptionCode; |
| 1232 return; | 1228 return; |
| 1233 } | 1229 } |
| 1234 | 1230 |
| 1235 // With m_error set, the state change steps are minimal: any pending | 1231 // With m_error set, the state change steps are minimal: any pending |
| 1236 // progress event is flushed + a readystatechange is dispatched. | 1232 // progress event is flushed + a readystatechange is dispatched. |
| 1237 // No new progress events dispatched; as required, that happens at | 1233 // No new progress events dispatched; as required, that happens at |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1264 "MimeType cannot be overridden when the state is LOADING or DONE."); | 1260 "MimeType cannot be overridden when the state is LOADING or DONE."); |
| 1265 return; | 1261 return; |
| 1266 } | 1262 } |
| 1267 | 1263 |
| 1268 m_mimeTypeOverride = mimeType; | 1264 m_mimeTypeOverride = mimeType; |
| 1269 } | 1265 } |
| 1270 | 1266 |
| 1271 void XMLHttpRequest::setRequestHeader(const AtomicString& name, | 1267 void XMLHttpRequest::setRequestHeader(const AtomicString& name, |
| 1272 const AtomicString& value, | 1268 const AtomicString& value, |
| 1273 ExceptionState& exceptionState) { | 1269 ExceptionState& exceptionState) { |
| 1274 if (m_state != kOpened || m_loader) { | 1270 if (m_state != kOpened || m_sendFlag) { |
| 1275 exceptionState.throwDOMException(InvalidStateError, | 1271 exceptionState.throwDOMException(InvalidStateError, |
| 1276 "The object's state must be OPENED."); | 1272 "The object's state must be OPENED."); |
| 1277 return; | 1273 return; |
| 1278 } | 1274 } |
| 1279 | 1275 |
| 1280 if (!isValidHTTPToken(name)) { | 1276 if (!isValidHTTPToken(name)) { |
| 1281 exceptionState.throwDOMException( | 1277 exceptionState.throwDOMException( |
| 1282 SyntaxError, "'" + name + "' is not a valid HTTP header field name."); | 1278 SyntaxError, "'" + name + "' is not a valid HTTP header field name."); |
| 1283 return; | 1279 return; |
| 1284 } | 1280 } |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1602 if (m_loader) { | 1598 if (m_loader) { |
| 1603 const bool hasError = m_error; | 1599 const bool hasError = m_error; |
| 1604 // Set |m_error| in order to suppress the cancel notification (see | 1600 // Set |m_error| in order to suppress the cancel notification (see |
| 1605 // XMLHttpRequest::didFail). | 1601 // XMLHttpRequest::didFail). |
| 1606 m_error = true; | 1602 m_error = true; |
| 1607 m_loader->cancel(); | 1603 m_loader->cancel(); |
| 1608 m_error = hasError; | 1604 m_error = hasError; |
| 1609 m_loader = nullptr; | 1605 m_loader = nullptr; |
| 1610 } | 1606 } |
| 1611 | 1607 |
| 1608 m_sendFlag = false; | |
| 1612 changeState(kDone); | 1609 changeState(kDone); |
| 1613 | 1610 |
| 1614 if (!getExecutionContext() || !getExecutionContext()->isDocument() || | 1611 if (!getExecutionContext() || !getExecutionContext()->isDocument() || |
| 1615 !document() || !document()->frame() || !document()->frame()->page()) | 1612 !document() || !document()->frame() || !document()->frame()->page()) |
| 1616 return; | 1613 return; |
| 1617 | 1614 |
| 1618 if (status() >= 200 && status() < 300) { | 1615 if (status() >= 200 && status() < 300) { |
| 1619 document()->frame()->page()->chromeClient().ajaxSucceeded( | 1616 document()->frame()->page()->chromeClient().ajaxSucceeded( |
| 1620 document()->frame()); | 1617 document()->frame()); |
| 1621 } | 1618 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1841 visitor->traceWrappers(m_responseDocument); | 1838 visitor->traceWrappers(m_responseDocument); |
| 1842 visitor->traceWrappers(m_responseArrayBuffer); | 1839 visitor->traceWrappers(m_responseArrayBuffer); |
| 1843 XMLHttpRequestEventTarget::traceWrappers(visitor); | 1840 XMLHttpRequestEventTarget::traceWrappers(visitor); |
| 1844 } | 1841 } |
| 1845 | 1842 |
| 1846 std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) { | 1843 std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) { |
| 1847 return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr); | 1844 return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr); |
| 1848 } | 1845 } |
| 1849 | 1846 |
| 1850 } // namespace blink | 1847 } // namespace blink |
| OLD | NEW |