Index: third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp |
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp |
index 91188b57fbf107336e00b9d22827900354745acf..1149f754bd133d33461db8389108a5108f7603db 100644 |
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp |
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp |
@@ -237,8 +237,8 @@ XMLHttpRequest::XMLHttpRequest( |
m_includeCredentials(false), |
m_parsedResponse(false), |
m_error(false), |
- m_uploadEventsAllowed(true), |
- m_uploadComplete(false), |
+ m_uploadListenerFlag(false), |
+ m_uploadCompleteFlag(false), |
m_sameOriginRequest(true), |
m_downloadingToFile(false), |
m_responseTextOverflow(false) {} |
@@ -622,7 +622,7 @@ void XMLHttpRequest::open(const AtomicString& method, |
State previousState = m_state; |
m_state = kUnsent; |
m_error = false; |
- m_uploadComplete = false; |
+ m_uploadCompleteFlag = false; |
if (!ContentSecurityPolicy::shouldBypassMainWorld(getExecutionContext()) && |
!getExecutionContext()->contentSecurityPolicy()->allowConnectToSource( |
@@ -940,17 +940,18 @@ void XMLHttpRequest::createRequest(PassRefPtr<EncodedFormData> httpBody, |
DCHECK(getExecutionContext()); |
ExecutionContext& executionContext = *getExecutionContext(); |
- // The presence of upload event listeners forces us to use preflighting |
- // because POSTing to an URL that does not permit cross origin requests should |
- // look exactly like POSTing to an URL that does not respond at all. |
- // Also, only async requests support upload progress events. |
- bool uploadEvents = false; |
+ m_uploadListenerFlag = false; |
yhirano
2016/10/20 11:27:54
In the spec this flag is initialized in open funct
|
if (m_async) { |
InspectorInstrumentation::asyncTaskScheduled( |
&executionContext, "XMLHttpRequest.send", this, true); |
+ |
dispatchProgressEvent(EventTypeNames::loadstart, 0, 0); |
- if (httpBody && m_upload) { |
- uploadEvents = m_upload->hasEventListeners(); |
+ |
+ // For optimization, we set the upload listener flag only when m_async is |
+ // true unlike the spec. |
+ if (m_upload && m_upload->hasEventListeners()) { |
+ m_uploadListenerFlag = true; |
+ |
m_upload->dispatchEvent( |
ProgressEvent::create(EventTypeNames::loadstart, false, 0, 0)); |
} |
@@ -962,12 +963,6 @@ void XMLHttpRequest::createRequest(PassRefPtr<EncodedFormData> httpBody, |
UseCounter::count(&executionContext, |
UseCounter::XMLHttpRequestCrossOriginWithCredentials); |
- // We also remember whether upload events should be allowed for this request |
- // in case the upload listeners are added after the request is started. |
- m_uploadEventsAllowed = |
- m_sameOriginRequest || uploadEvents || |
- !FetchUtils::isSimpleRequest(m_method, m_requestHeaders); |
- |
ResourceRequest request(m_url); |
request.setHTTPMethod(m_method); |
request.setRequestContext(WebURLRequest::RequestContextXMLHttpRequest); |
@@ -995,7 +990,8 @@ void XMLHttpRequest::createRequest(PassRefPtr<EncodedFormData> httpBody, |
request.addHTTPHeaderFields(m_requestHeaders); |
ThreadableLoaderOptions options; |
- options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; |
+ options.preflightPolicy = |
+ m_uploadListenerFlag ? ForcePreflight : ConsiderPreflight; |
options.crossOriginRequestPolicy = UseAccessControl; |
options.initiator = FetchInitiatorTypeNames::xmlhttprequest; |
options.contentSecurityPolicyEnforcement = |
@@ -1028,7 +1024,12 @@ void XMLHttpRequest::createRequest(PassRefPtr<EncodedFormData> httpBody, |
if (m_async) { |
UseCounter::count(&executionContext, |
UseCounter::XMLHttpRequestAsynchronous); |
- if (m_upload) |
+ |
+ // The presence of upload event listeners forces us to use preflighting |
+ // because POSTing to an URL that does not permit cross origin requests |
+ // should look exactly like POSTing to an URL that does not respond at all. |
+ // Also, only async requests support upload progress events. |
+ if (m_uploadListenerFlag) |
request.setReportUploadProgress(true); |
DCHECK(!m_loader); |
@@ -1244,10 +1245,13 @@ void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, |
DCHECK(m_error); |
changeState(kDone); |
- if (!m_uploadComplete) { |
- m_uploadComplete = true; |
- if (m_upload && m_uploadEventsAllowed) |
+ if (!m_uploadCompleteFlag) { |
+ m_uploadCompleteFlag = true; |
yhirano
2016/10/20 11:27:54
Is substituting unconditionally enough?
|
+ |
+ if (m_uploadListenerFlag) { |
+ DCHECK(m_upload); |
m_upload->handleRequestError(type); |
+ } |
} |
// Note: The below event dispatch may be called while |hasPendingActivity() == |
@@ -1632,21 +1636,30 @@ void XMLHttpRequest::endLoading() { |
void XMLHttpRequest::didSendData(unsigned long long bytesSent, |
unsigned long long totalBytesToBeSent) { |
+ DCHECK(m_async); |
yhirano
2016/10/20 12:17:02
You call setReportUploadProgress only when m_uploa
|
NETWORK_DVLOG(1) << this << " didSendData(" << bytesSent << ", " |
<< totalBytesToBeSent << ")"; |
ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); |
- if (!m_upload) |
- return; |
- |
- if (m_uploadEventsAllowed) |
+ if (m_uploadListenerFlag) { |
+ DCHECK(m_upload); |
m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent); |
+ } |
+ |
yhirano
2016/10/20 12:17:02
Not related to this CL but we may need an early-re
|
+ // TODO(tyoshino): Since AsyncResourceHandler doesn't send us any |
yhirano
2016/10/20 11:27:54
"Since" is not needed?
|
+ // notification when the total size is 0. Therefore, we cannot depend on |
+ // didSendData() invocation to dispatch the progress events for "process |
+ // request end-of-body" hook as specified in the XHR spec. Fix this. |
+ if (bytesSent == totalBytesToBeSent && !m_uploadCompleteFlag) { |
+ m_uploadCompleteFlag = true; |
- if (bytesSent == totalBytesToBeSent && !m_uploadComplete) { |
- m_uploadComplete = true; |
- if (m_uploadEventsAllowed) |
+ if (m_uploadListenerFlag) { |
+ DCHECK(m_upload); |
m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesSent, |
totalBytesToBeSent); |
+ } |
+ |
+ return; |
yhirano
2016/10/20 11:27:54
This statement is redundant.
|
} |
} |