Index: Source/core/loader/DocumentThreadableLoader.cpp |
diff --git a/Source/core/loader/DocumentThreadableLoader.cpp b/Source/core/loader/DocumentThreadableLoader.cpp |
index 2f1314a8201119b4384ecdaee6c54e3af5e1113c..95be338695dc62a13911c4bc773a2417c465c130 100644 |
--- a/Source/core/loader/DocumentThreadableLoader.cpp |
+++ b/Source/core/loader/DocumentThreadableLoader.cpp |
@@ -92,6 +92,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl |
, m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
, m_requestStartedSeconds(0.0) |
, m_corsRedirectLimit(kMaxCORSRedirects) |
+ , m_accessControlCheckFailed(false) |
{ |
ASSERT(client); |
// Setting an outgoing referer is only supported in the async code path. |
@@ -162,7 +163,7 @@ void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques |
// is no reason to send a request, preflighted or not, that's guaranteed |
// to be denied. |
if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { |
- m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); |
+ handleAccessControlCheckFailure(request.url().string(), "Cross origin requests are only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + "."); |
return; |
} |
@@ -335,8 +336,7 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ |
return; |
} |
- ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url().string(), accessControlErrorDescription); |
- m_client->didFailAccessControlCheck(error); |
+ handleAccessControlCheckFailure(redirectResponse.url().string(), accessControlErrorDescription); |
} else { |
m_client->didFailRedirectCheck(); |
} |
@@ -379,12 +379,12 @@ void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r |
String accessControlErrorDescription; |
if (!passesAccessControlCheck(&m_document, response, effectiveAllowCredentials(), securityOrigin(), accessControlErrorDescription)) { |
- handlePreflightFailure(response.url().string(), accessControlErrorDescription); |
+ handleAccessControlCheckFailure(response.url().string(), accessControlErrorDescription); |
return; |
} |
if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { |
- handlePreflightFailure(response.url().string(), accessControlErrorDescription); |
+ handleAccessControlCheckFailure(response.url().string(), accessControlErrorDescription); |
return; |
} |
@@ -392,7 +392,7 @@ void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r |
if (!preflightResult->parse(response, accessControlErrorDescription) |
|| !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod(), accessControlErrorDescription) |
|| !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeaderFields(), accessControlErrorDescription)) { |
- handlePreflightFailure(response.url().string(), accessControlErrorDescription); |
+ handleAccessControlCheckFailure(response.url().string(), accessControlErrorDescription); |
return; |
} |
@@ -436,7 +436,7 @@ void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re |
String accessControlErrorDescription; |
if (!passesAccessControlCheck(&m_document, response, effectiveAllowCredentials(), securityOrigin(), accessControlErrorDescription)) { |
reportResponseReceived(identifier, response); |
- m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().string(), accessControlErrorDescription)); |
+ handleAccessControlCheckFailure(response.url().string(), accessControlErrorDescription); |
return; |
} |
} |
@@ -462,7 +462,8 @@ void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat |
ASSERT(!m_fallbackRequestForServiceWorker); |
- m_client->didReceiveData(data, dataLength); |
+ if (!m_accessControlCheckFailed) |
+ m_client->didReceiveData(data, dataLength); |
} |
void DocumentThreadableLoader::notifyFinished(Resource* resource) |
@@ -490,7 +491,8 @@ void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, |
} else { |
// FIXME: Should prevent timeout from being overridden after finished loading, without |
// resetting m_requestStartedSeconds to 0.0 |
- m_client->didFinishLoading(identifier, finishTime); |
+ if (!m_accessControlCheckFailed) |
+ m_client->didFinishLoading(identifier, finishTime); |
} |
} |
@@ -527,13 +529,19 @@ void DocumentThreadableLoader::loadActualRequest() |
loadRequest(*actualRequest, *actualOptions); |
} |
-void DocumentThreadableLoader::handlePreflightFailure(const String& url, const String& errorDescription) |
+void DocumentThreadableLoader::handleAccessControlCheckFailure(const String& url, const String& errorDescription) |
{ |
ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
// Prevent handleSuccessfulFinish() from bypassing access check. |
m_actualRequest = nullptr; |
+ // Prevent m_client->didReceiveData()/didFinishLoading() from being called |
+ // after m_client->didFailAccessControlCheck() is called here. |
+ // FIXME: It is cleaner to call clearResource() etc. where we should not |
+ // proceed any more. |
+ m_accessControlCheckFailed = true; |
+ |
// FIXME: Should prevent timeout from being overridden after preflight failure, without |
// resetting m_requestStartedSeconds to 0.0 |
m_client->didFailAccessControlCheck(error); |