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 |