| 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;
|
| }
|
|
|