Title: [112997] trunk
Revision
112997
Author
[email protected]
Date
2012-04-03 01:45:26 -0700 (Tue, 03 Apr 2012)

Log Message

REGRESSION (r112217): H&R Block tax site won't load
https://bugs.webkit.org/show_bug.cgi?id=82964

Source/WebCore:

Modifies the redirect checking code to first check if the security origin can
request the redirect URL before invoking the CORS check.

Reviewed by Adam Barth.

http/tests/xmlhttprequest/access-control-and-redirects-async.html

* loader/DocumentThreadableLoader.cpp:
* loader/DocumentThreadableLoader.h:

LayoutTests:

Add a test case for a same origin request with a custom header that receives a
same origin redirect, and therefore should pass the redirect check.

Reviewed by Adam Barth.

* http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt:
* http/tests/xmlhttprequest/access-control-and-redirects-async.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112996 => 112997)


--- trunk/LayoutTests/ChangeLog	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/LayoutTests/ChangeLog	2012-04-03 08:45:26 UTC (rev 112997)
@@ -1,3 +1,16 @@
+2012-04-03  Bill Budge  <[email protected]>
+
+        REGRESSION (r112217): H&R Block tax site won't load
+        https://bugs.webkit.org/show_bug.cgi?id=82964
+
+        Add a test case for a same origin request with a custom header that receives a
+        same origin redirect, and therefore should pass the redirect check.
+
+        Reviewed by Adam Barth.
+
+        * http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt:
+        * http/tests/xmlhttprequest/access-control-and-redirects-async.html:
+
 2012-04-03  Philippe Normand  <[email protected]>
 
         Unreviewed, baseline update for new test.

Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt (112996 => 112997)


--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt	2012-04-03 08:45:26 UTC (rev 112997)
@@ -1,30 +1,33 @@
 Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard.
 
-Testing resources/redirect-cors.php?url=""
+Testing resources/redirect-cors.php?url=""
 Expecting success: false
 PASS: 0
-Testing resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000&  access-control-allow-credentials=true
+Testing resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000&  access-control-allow-credentials=true
 Expecting success: false
 PASS: 0
-Testing resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000&  access-control-allow-credentials=true
+Testing resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000&  access-control-allow-credentials=true
 Expecting success: false
 PASS: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""
 Expecting success: false
 PASS: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
 Expecting success: true
 FAIL: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
 Expecting success: false
 PASS: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""  access-control-allow-origin=http://localhost:8000
 Expecting success: false
 PASS: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&  url=""  access-control-allow-origin=*
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&  url=""  access-control-allow-origin=*
 Expecting success: false
 PASS: 0
-Testing http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false&  url=""  access-control-allow-origin=*&  access-control-allow-headers=x-webkit
+Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false&  url=""  access-control-allow-origin=*&  access-control-allow-headers=x-webkit
 Expecting success: false
 PASS: 0
+Testing resources/redirect-cors.php?url=""
+Expecting success: true
+PASS: PASS
 

Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html (112996 => 112997)


--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html	2012-04-03 08:45:26 UTC (rev 112997)
@@ -12,13 +12,13 @@
     document.getElementById('console').appendChild(document.createTextNode(message + '\n'));
 }
 
-function runTestAsync(url, forcePreflight, expectSuccess) {
+function runTestAsync(url, addCustomHeader, expectSuccess) {
     log("Testing " + url);
     log("Expecting success: " + expectSuccess);
 
     xhr = new XMLHttpRequest();
     xhr.open("GET", url, true);
-    if (forcePreflight)
+    if (addCustomHeader)
         xhr.setRequestHeader("x-webkit", "foo");
 
     xhr._onload_ = function() {
@@ -32,8 +32,8 @@
     xhr.send(null);
 }
 
-var simple = false;
-var preflight = true;
+var noCustomHeader = false;
+var addCustomHeader = true;
 var succeeds = true;
 var fails = false;
 
@@ -41,59 +41,63 @@
 // 1) Test simple same origin requests that receive cross origin redirects.
 
 // Request receives a cross-origin redirect response without CORS headers. The redirect response fails the access check.
-["resources/redirect-cors.php?url=""
-  simple, fails],
+["resources/redirect-cors.php?url=""
+  noCustomHeader, fails],
 
 // Request receives a cross-origin redirect response with CORS headers. The redirect response passes the access check,
 // but  the resource response fails its access check because the security origin is a globally unique identifier after
 // the redirect and the same origin XHR has 'allowCredentials' true.
-["resources/redirect-cors.php?url=""
+["resources/redirect-cors.php?url=""
   access-control-allow-origin=http://localhost:8000&\
   access-control-allow-credentials=true",
-  simple, fails],
+  noCustomHeader, fails],
 
 // Same as above, but to a less permissive resource that only allows the requesting origin.
-["resources/redirect-cors.php?url=""
+["resources/redirect-cors.php?url=""
   access-control-allow-origin=http://localhost:8000&\
   access-control-allow-credentials=true",
-  simple, fails],
+  noCustomHeader, fails],
 
 // 2) Test simple cross origin requests that receive redirects.
 
 // Receives a redirect response without CORS headers. The redirect response fails the access check.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""
-  simple, fails],
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""
+  noCustomHeader, fails],
 
 // Receives a redirect response with CORS headers. The redirect response passes the access check and the resource response
 // passes the access check.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""
   access-control-allow-origin=http://localhost:8000",
-  simple, succeeds],
+  noCustomHeader, succeeds],
 
 // Receives a redirect response with a URL containing the userinfo production.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""
   access-control-allow-origin=http://localhost:8000",
-  simple, fails],
+  noCustomHeader, fails],
 
 // Receives a redirect response with a URL with an unsupported scheme.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?url=""
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=""
   access-control-allow-origin=http://localhost:8000",
-  simple, fails],
+  noCustomHeader, fails],
 
 // 3) Test preflighted cross origin requests that receive redirects.
 
 // Receives a redirect response to the preflight request and fails.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&\
-  url=""
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&\
+  url=""
   access-control-allow-origin=*",
-  preflight, fails],
+  addCustomHeader, fails],
 
 // Successful preflight and receives a redirect response to the actual request and fails.
-["http://127.0.0.1:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false&\
-  url=""
+["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false&\
+  url=""
   access-control-allow-origin=*&\
   access-control-allow-headers=x-webkit",
-  preflight, fails],
+  addCustomHeader, fails],
+
+// 4) Test same origin requests with a custom header that receive a same origin redirect.
+["resources/redirect-cors.php?url=""
+  addCustomHeader, succeeds],
 ]
 
 var currentTest = 0;

Modified: trunk/Source/WebCore/ChangeLog (112996 => 112997)


--- trunk/Source/WebCore/ChangeLog	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/Source/WebCore/ChangeLog	2012-04-03 08:45:26 UTC (rev 112997)
@@ -1,3 +1,18 @@
+2012-04-03  Bill Budge  <[email protected]>
+
+        REGRESSION (r112217): H&R Block tax site won't load
+        https://bugs.webkit.org/show_bug.cgi?id=82964
+
+        Modifies the redirect checking code to first check if the security origin can
+        request the redirect URL before invoking the CORS check.
+
+        Reviewed by Adam Barth.
+
+        http/tests/xmlhttprequest/access-control-and-redirects-async.html
+
+        * loader/DocumentThreadableLoader.cpp:
+        * loader/DocumentThreadableLoader.h:
+
 2012-04-03  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r112994.

Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (112996 => 112997)


--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp	2012-04-03 08:45:26 UTC (rev 112997)
@@ -85,11 +85,6 @@
     // Setting an outgoing referer is only supported in the async code path.
     ASSERT(m_async || request.httpReferrer().isEmpty());
 
-    makeRequest(request);
-}
-
-void DocumentThreadableLoader::makeRequest(const ResourceRequest& request)
-{
     if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) {
         loadRequest(request, DoSecurityCheck);
         return;
@@ -100,6 +95,11 @@
         return;
     }
 
+    makeCrossOriginAccessRequest(request);
+}
+
+void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceRequest& request)
+{
     ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
 
     OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
@@ -175,10 +175,17 @@
     ASSERT_UNUSED(resource, resource == m_resource);
 
     RefPtr<DocumentThreadableLoader> protect(this);
-    bool allowRedirect = false;
+    // Allow same origin requests to continue after allowing clients to audit the redirect.
+    if (isAllowedRedirect(request.url())) {
+        if (m_client->isDocumentThreadableLoaderClient())
+            static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequest(request, redirectResponse);
+        return;
+    }
+
+    // When using access control, only simple cross origin requests are allowed to redirect. The new request URL must have a supported
+    // scheme and not contain the userinfo production. In addition, the redirect response must pass the access control check.
     if (m_options.crossOriginRequestPolicy == UseAccessControl) {
-        // When using access control, only simple cross origin requests are allowed to redirect. The new request URL must have a supported
-        // scheme and not contain the userinfo production. In addition, the redirect response must pass the access control check.
+        bool allowRedirect = false;
         if (m_simpleRequest) {
             String accessControlErrorDescription;
             allowRedirect = SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())
@@ -186,11 +193,8 @@
                             && request.url().pass().isEmpty()
                             && passesAccessControlCheck(redirectResponse, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription);
         }
-    } else
-        allowRedirect = isAllowedRedirect(request.url());
 
-    if (allowRedirect) {
-        if (m_options.crossOriginRequestPolicy == UseAccessControl) {
+        if (allowRedirect) {
             if (m_resource)
                 clearResource();
 
@@ -199,7 +203,8 @@
             // If the request URL origin is not same origin with the original URL origin, set source origin to a globally unique identifier.
             if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get()))
                 m_options.securityOrigin = SecurityOrigin::createUnique();
-            m_sameOriginRequest = securityOrigin()->canRequest(request.url());
+            // Force any subsequent requests to use these checks.
+            m_sameOriginRequest = false;
 
             // Remove any headers that may have been added by the network layer that cause access control to fail.
             request.clearHTTPContentType();
@@ -207,16 +212,13 @@
             request.clearHTTPOrigin();
             request.clearHTTPUserAgent();
             request.clearHTTPAccept();
-            makeRequest(request);
-        } else {
-            // If not using access control, allow clients to audit the redirect.
-            if (m_client->isDocumentThreadableLoaderClient())
-                static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequest(request, redirectResponse);
+            makeCrossOriginAccessRequest(request);
+            return;
         }
-    } else {
-        m_client->didFailRedirectCheck();
-        request = ResourceRequest();
     }
+
+    m_client->didFailRedirectCheck();
+    request = ResourceRequest();
 }
 
 void DocumentThreadableLoader::dataSent(CachedResource* resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)

Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.h (112996 => 112997)


--- trunk/Source/WebCore/loader/DocumentThreadableLoader.h	2012-04-03 08:36:12 UTC (rev 112996)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.h	2012-04-03 08:45:26 UTC (rev 112997)
@@ -89,7 +89,7 @@
         void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
         void didFinishLoading(unsigned long identifier, double finishTime);
         void didFail(const ResourceError&);
-        void makeRequest(const ResourceRequest&);
+        void makeCrossOriginAccessRequest(const ResourceRequest&);
         void makeSimpleCrossOriginAccessRequest(const ResourceRequest& request);
         void makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request);
         void preflightSuccess();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to