Index: Source/core/loader/DocumentThreadableLoader.cpp |
diff --git a/Source/core/loader/DocumentThreadableLoader.cpp b/Source/core/loader/DocumentThreadableLoader.cpp |
index 2f1314a8201119b4384ecdaee6c54e3af5e1113c..1d627505211aff97b1f3e735fe5a7dce5dce1821 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() + ".")); |
+ handlePreflightFailure(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); |
+ handlePreflightFailure(redirectResponse.url().string(), accessControlErrorDescription); |
} else { |
m_client->didFailRedirectCheck(); |
} |
@@ -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)); |
+ handlePreflightFailure(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,6 +529,8 @@ void DocumentThreadableLoader::loadActualRequest() |
loadRequest(*actualRequest, *actualOptions); |
} |
+// Call handlePreflightFailure() instead of didFailAccessControlCheck() |
+// from other places in DocumentThreadableLoader. |
kinuko
2015/02/03 02:35:36
nit: putting this comment in the header feels more
hiroshige
2015/02/03 08:19:44
Done.
|
void DocumentThreadableLoader::handlePreflightFailure(const String& url, const String& errorDescription) |
tyoshino (SeeGerritForStatus)
2015/02/03 06:22:02
rename this as it's no longer specific to prefligh
hiroshige
2015/02/03 08:19:43
Done.
|
{ |
ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
@@ -534,6 +538,10 @@ void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S |
// Prevent handleSuccessfulFinish() from bypassing access check. |
m_actualRequest = nullptr; |
+ // Prevent m_client->didReceiveData()/didFinishLoading() from being called |
+ // after m_client->didFailAccessControlCheck() is called here. |
+ m_accessControlCheckFailed = true; |
+ |
// FIXME: Should prevent timeout from being overridden after preflight failure, without |
// resetting m_requestStartedSeconds to 0.0 |
m_client->didFailAccessControlCheck(error); |