Index: Source/core/fetch/CrossOriginAccessControl.cpp |
diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp |
index 349d498bb3f45d0c7d2fb6b59717d9b776ba368e..1c62352cf4376777aefbc6ce14ce7467f5efa7cb 100644 |
--- a/Source/core/fetch/CrossOriginAccessControl.cpp |
+++ b/Source/core/fetch/CrossOriginAccessControl.cpp |
@@ -30,6 +30,7 @@ |
#include "core/fetch/Resource.h" |
#include "core/fetch/ResourceLoaderOptions.h" |
#include "core/frame/UseCounter.h" |
+#include "platform/RuntimeEnabledFeatures.h" |
#include "platform/network/HTTPParsers.h" |
#include "platform/network/ResourceRequest.h" |
#include "platform/network/ResourceResponse.h" |
@@ -124,10 +125,16 @@ static bool isInterestingStatusCode(int statusCode) |
return statusCode >= 400; |
} |
+String formatACError(const char* formatString, const char* suboriginsDisabledString, const char* suboriginsEnabledString) |
+{ |
+ return String::format(formatString, RuntimeEnabledFeatures::suboriginsEnabled() ? suboriginsEnabledString : suboriginsDisabledString); |
+} |
+ |
bool passesAccessControlCheck(ExecutionContext* context, const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription) |
{ |
AtomicallyInitializedStaticReference(AtomicString, accessControlAllowOrigin, (new AtomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral))); |
AtomicallyInitializedStaticReference(AtomicString, accessControlAllowCredentials, (new AtomicString("access-control-allow-credentials", AtomicString::ConstructFromLiteral))); |
+ AtomicallyInitializedStaticReference(AtomicString, accessControlAllowFinerOrigin, (new AtomicString("access-control-allow-finer-origin", AtomicString::ConstructFromLiteral))); |
if (!response.httpStatusCode()) { |
errorDescription = "Received an invalid response. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
@@ -135,29 +142,30 @@ bool passesAccessControlCheck(ExecutionContext* context, const ResourceResponse& |
} |
const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin); |
- if (accessControlOriginString == starAtom) { |
+ const AtomicString& accessControlFinerOriginString = response.httpHeaderField(accessControlAllowFinerOrigin); |
+ if (accessControlOriginString == starAtom || accessControlAllowFinerOrigin == starAtom) { |
// A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent, |
// even with Access-Control-Allow-Credentials set to true. |
if (includeCredentials == DoNotAllowStoredCredentials) |
return true; |
if (response.isHTTP()) { |
- errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
- return false; |
+ errorDescription = formatACError(String("A wildcard '*' cannot be used in the %s when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.").ascii().data(), "'Access-Control-Allow-Origin' header", "'Access-Control-Allow-Origin' headers"); |
} |
- } else if (accessControlOriginString != securityOrigin->toAtomicString()) { |
- if (accessControlOriginString.isNull()) { |
- errorDescription = "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
- |
+ } else if (accessControlOriginString != securityOrigin->toAtomicString() && accessControlFinerOriginString != securityOrigin->toAtomicString()) { |
+ if (accessControlOriginString.isNull() && accessControlFinerOriginString.isNull()) { |
+ errorDescription = formatACError(String("No %s is present on the requested resource. Origin '" + securityOrigin->toString() + "' therefore not allowed access.").ascii().data(), "'Access-Control-Allow-Origin' header is", "'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' headers are"); |
if (isInterestingStatusCode(response.httpStatusCode())) |
errorDescription.append(" The response had HTTP status code " + String::number(response.httpStatusCode()) + "."); |
- } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound) { |
- errorDescription = "The 'Access-Control-Allow-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound || accessControlFinerOriginString.string().find(isOriginSeparator, 0) != kNotFound) { |
+ errorDescription = formatACError(String("The %s multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.").ascii().data(), "'Access-Control-Allow-Origin' header contains", "'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' headers contain"); |
} else { |
KURL headerOrigin(KURL(), accessControlOriginString); |
- if (!headerOrigin.isValid()) |
- errorDescription = "The 'Access-Control-Allow-Origin' header contains the invalid value '" + accessControlOriginString + "'. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
- else |
- errorDescription = "The 'Access-Control-Allow-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the supplied origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ KURL headerFinerOrigin(KURL(), accessControlFinerOriginString); |
+ if (!headerOrigin.isValid()) { |
+ errorDescription = formatACError(String("The %s header contains the invalid value '" + accessControlOriginString + "'. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.").ascii().data(), "'Access-Control-Allow-Origin'", "'Access-Control-Allow-Finer-Origin'"); |
+ } else { |
+ errorDescription = formatACError(String("The %s a value '" + accessControlOriginString + "' that is not equal to the supplied origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.").ascii().data(), "'Access-Control-Allow-Origin' header has", "The 'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' headers have"); |
+ } |
} |
return false; |
} |