Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / fetch / CrossOriginAccessControl.cpp
index 98d2b1a..4ebc1ab 100644 (file)
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/StringBuilder.h"
 
-namespace WebCore {
-
-bool isOnAccessControlSimpleRequestMethodWhitelist(const String& method)
-{
-    return method == "GET" || method == "HEAD" || method == "POST";
-}
-
-bool isOnAccessControlSimpleRequestHeaderWhitelist(const AtomicString& name, const AtomicString& value)
-{
-    if (equalIgnoringCase(name, "accept")
-        || equalIgnoringCase(name, "accept-language")
-        || equalIgnoringCase(name, "content-language")
-        || equalIgnoringCase(name, "origin")
-        || equalIgnoringCase(name, "referer"))
-        return true;
-
-    // Preflight is required for MIME types that can not be sent via form submission.
-    if (equalIgnoringCase(name, "content-type")) {
-        AtomicString mimeType = extractMIMETypeFromMediaType(value);
-        return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded")
-            || equalIgnoringCase(mimeType, "multipart/form-data")
-            || equalIgnoringCase(mimeType, "text/plain");
-    }
-
-    return false;
-}
-
-bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap& headerMap)
-{
-    if (!isOnAccessControlSimpleRequestMethodWhitelist(method))
-        return false;
-
-    HTTPHeaderMap::const_iterator end = headerMap.end();
-    for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
-        if (!isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value))
-            return false;
-    }
-
-    return true;
-}
+namespace blink {
 
 static PassOwnPtr<HTTPHeaderSet> createAllowedCrossOriginResponseHeadersSet()
 {
@@ -103,7 +64,8 @@ bool isOnAccessControlResponseHeaderWhitelist(const String& name)
 void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
 {
     request.removeCredentials();
-    request.setAllowCookies(allowCredentials == AllowStoredCredentials);
+    request.setAllowStoredCredentials(allowCredentials == AllowStoredCredentials);
+    request.setFetchCredentialsMode(allowCredentials == AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRequest::FetchCredentialsModeOmit);
 
     if (securityOrigin)
         request.setHTTPOrigin(securityOrigin->toAtomicString());
@@ -116,6 +78,7 @@ ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& reque
     preflightRequest.setHTTPMethod("OPTIONS");
     preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
     preflightRequest.setPriority(request.priority());
+    preflightRequest.setRequestContext(request.requestContext());
 
     const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
 
@@ -142,6 +105,14 @@ static bool isOriginSeparator(UChar ch)
     return isASCIISpace(ch) || ch == ',';
 }
 
+static bool isInterestingStatusCode(int statusCode)
+{
+    // Predicate that gates what status codes should be included in
+    // console error messages for responses containing no access
+    // control headers.
+    return statusCode >= 400;
+}
+
 bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
 {
     AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new AtomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral));
@@ -152,17 +123,22 @@ bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential
         return false;
     }
 
-    // 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.
     const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin);
-    if (accessControlOriginString == starAtom && includeCredentials == DoNotAllowStoredCredentials)
-        return true;
-
-    if (accessControlOriginString != securityOrigin->toAtomicString()) {
-        if (accessControlOriginString == starAtom) {
+    if (accessControlOriginString == 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.";
-        } else if (accessControlOriginString.isEmpty()) {
+            return false;
+        }
+    } 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.";
+
+            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 {
@@ -240,7 +216,7 @@ bool CrossOriginAccessControl::handleRedirect(Resource* resource, SecurityOrigin
         bool allowRedirect = isLegalRedirectLocation(requestURL, errorDescription);
         if (allowRedirect) {
             // Step 5: perform resource sharing access check.
-            StoredCredentials withCredentials = resource->resourceRequest().allowCookies() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+            StoredCredentials withCredentials = resource->lastResourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
             allowRedirect = passesAccessControlCheck(redirectResponse, withCredentials, securityOrigin, errorDescription);
             if (allowRedirect) {
                 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(originalURL);
@@ -270,4 +246,4 @@ bool CrossOriginAccessControl::handleRedirect(Resource* resource, SecurityOrigin
     return true;
 }
 
-} // namespace WebCore
+} // namespace blink