Title: [88466] trunk/Source/WebKit/chromium
Revision
88466
Author
[email protected]
Date
2011-06-09 11:21:48 -0700 (Thu, 09 Jun 2011)

Log Message

2011-06-09  Bill Budge  <[email protected]>

        Reviewed by Adam Barth.

        The AssociatedURLLoader returns URL access errors synchronously. Use a timer to return such errors asynchronously. Also add unit tests for successful loads, same-origin restriction by default, and successful cross-origin loads.
        https://bugs.webkit.org/show_bug.cgi?id=60059

        * WebKit.gyp:
        * WebKit.gypi:
        * src/AssociatedURLLoader.cpp:
        (WebKit::AssociatedURLLoader::ClientAdapter::clearClient):
        (WebKit::AssociatedURLLoader::ClientAdapter::ClientAdapter):
        (WebKit::AssociatedURLLoader::ClientAdapter::didFinishLoading):
        (WebKit::AssociatedURLLoader::ClientAdapter::didFail):
        (WebKit::AssociatedURLLoader::ClientAdapter::enableErrorNotifications):
        (WebKit::AssociatedURLLoader::ClientAdapter::notifyError):
        (WebKit::AssociatedURLLoader::loadAsynchronously):
        * tests/AssociatedURLLoaderTest.cpp: Added.
        (WebKit::TestWebFrameClient::cancelledError):
        (WebKit::AssociatedURLLoaderTest::AssociatedURLLoaderTest):
        (WebKit::AssociatedURLLoaderTest::SetUp):
        (WebKit::AssociatedURLLoaderTest::TearDown):
        (WebKit::AssociatedURLLoaderTest::serveRequests):
        (WebKit::AssociatedURLLoaderTest::createAssociatedURLLoader):
        (WebKit::AssociatedURLLoaderTest::willSendRequest):
        (WebKit::AssociatedURLLoaderTest::didSendData):
        (WebKit::AssociatedURLLoaderTest::didReceiveResponse):
        (WebKit::AssociatedURLLoaderTest::didDownloadData):
        (WebKit::AssociatedURLLoaderTest::didReceiveData):
        (WebKit::AssociatedURLLoaderTest::didReceiveCachedMetadata):
        (WebKit::AssociatedURLLoaderTest::didFinishLoading):
        (WebKit::AssociatedURLLoaderTest::didFail):
        (WebKit::TEST_F):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/chromium/ChangeLog (88465 => 88466)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-06-09 18:21:23 UTC (rev 88465)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-06-09 18:21:48 UTC (rev 88466)
@@ -1,3 +1,37 @@
+2011-06-09  Bill Budge  <[email protected]>
+
+        Reviewed by Adam Barth.
+
+        The AssociatedURLLoader returns URL access errors synchronously. Use a timer to return such errors asynchronously. Also add unit tests for successful loads, same-origin restriction by default, and successful cross-origin loads.
+        https://bugs.webkit.org/show_bug.cgi?id=60059
+
+        * WebKit.gyp:
+        * WebKit.gypi:
+        * src/AssociatedURLLoader.cpp:
+        (WebKit::AssociatedURLLoader::ClientAdapter::clearClient):
+        (WebKit::AssociatedURLLoader::ClientAdapter::ClientAdapter):
+        (WebKit::AssociatedURLLoader::ClientAdapter::didFinishLoading):
+        (WebKit::AssociatedURLLoader::ClientAdapter::didFail):
+        (WebKit::AssociatedURLLoader::ClientAdapter::enableErrorNotifications):
+        (WebKit::AssociatedURLLoader::ClientAdapter::notifyError):
+        (WebKit::AssociatedURLLoader::loadAsynchronously):
+        * tests/AssociatedURLLoaderTest.cpp: Added.
+        (WebKit::TestWebFrameClient::cancelledError):
+        (WebKit::AssociatedURLLoaderTest::AssociatedURLLoaderTest):
+        (WebKit::AssociatedURLLoaderTest::SetUp):
+        (WebKit::AssociatedURLLoaderTest::TearDown):
+        (WebKit::AssociatedURLLoaderTest::serveRequests):
+        (WebKit::AssociatedURLLoaderTest::createAssociatedURLLoader):
+        (WebKit::AssociatedURLLoaderTest::willSendRequest):
+        (WebKit::AssociatedURLLoaderTest::didSendData):
+        (WebKit::AssociatedURLLoaderTest::didReceiveResponse):
+        (WebKit::AssociatedURLLoaderTest::didDownloadData):
+        (WebKit::AssociatedURLLoaderTest::didReceiveData):
+        (WebKit::AssociatedURLLoaderTest::didReceiveCachedMetadata):
+        (WebKit::AssociatedURLLoaderTest::didFinishLoading):
+        (WebKit::AssociatedURLLoaderTest::didFail):
+        (WebKit::TEST_F):
+
 2011-06-09  Nico Weber  <[email protected]>
 
         Reviewed by Darin Fisher.

Modified: trunk/Source/WebKit/chromium/WebKit.gyp (88465 => 88466)


--- trunk/Source/WebKit/chromium/WebKit.gyp	2011-06-09 18:21:23 UTC (rev 88465)
+++ trunk/Source/WebKit/chromium/WebKit.gyp	2011-06-09 18:21:48 UTC (rev 88466)
@@ -644,6 +644,7 @@
                                 'tests/CCThreadTest.cpp',
                                 # These tests depend on webkit_support and
                                 # functions defined only in !WEBKIT_IMPLEMENTATION.
+                                'tests/AssociatedURLLoaderTest.cpp',
                                 'tests/WebFrameTest.cpp',
                                 'tests/WebPageNewSerializerTest.cpp',
                                 'tests/WebPageSerializerTest.cpp',

Modified: trunk/Source/WebKit/chromium/WebKit.gypi (88465 => 88466)


--- trunk/Source/WebKit/chromium/WebKit.gypi	2011-06-09 18:21:23 UTC (rev 88465)
+++ trunk/Source/WebKit/chromium/WebKit.gypi	2011-06-09 18:21:48 UTC (rev 88466)
@@ -53,6 +53,7 @@
         ],
         'webkit_unittest_files': [
             'tests/ArenaTestHelpers.h',
+            'tests/AssociatedURLLoaderTest.cpp',
             'tests/InnerGestureRecognizerTest.cpp',
             'tests/CCThreadTaskTest.cpp',
             'tests/CCThreadTest.cpp',

Modified: trunk/Source/WebKit/chromium/src/AssociatedURLLoader.cpp (88465 => 88466)


--- trunk/Source/WebKit/chromium/src/AssociatedURLLoader.cpp	2011-06-09 18:21:23 UTC (rev 88465)
+++ trunk/Source/WebKit/chromium/src/AssociatedURLLoader.cpp	2011-06-09 18:21:48 UTC (rev 88466)
@@ -34,6 +34,7 @@
 #include "DocumentThreadableLoader.h"
 #include "DocumentThreadableLoaderClient.h"
 #include "SubresourceLoader.h"
+#include "Timer.h"
 #include "WebApplicationCacheHost.h"
 #include "WebDataSource.h"
 #include "WebFrameImpl.h"
@@ -54,6 +55,7 @@
 // This class bridges the interface differences between WebCore and WebKit loader clients.
 // It forwards its ThreadableLoaderClient notifications to a WebURLLoaderClient.
 class AssociatedURLLoader::ClientAdapter : public DocumentThreadableLoaderClient {
+    WTF_MAKE_NONCOPYABLE(ClientAdapter);
 public:
     static PassOwnPtr<ClientAdapter> create(AssociatedURLLoader*, WebURLLoaderClient*, bool /*downloadToFile*/);
 
@@ -68,16 +70,27 @@
 
     virtual bool isDocumentThreadableLoaderClient() { return true; }
 
-    // This method stops loading and releases the DocumentThreadableLoader as early as possible.
-    void clearClient() { m_client = 0; }
+    // Enables forwarding of error notifications to the WebURLLoaderClient. These must be
+    // deferred until after the call to AssociatedURLLoader::loadAsynchronously() completes.
+    void enableErrorNotifications();
 
+    // Stops loading and releases the DocumentThreadableLoader as early as possible.
+    void clearClient() { m_client = 0; } 
+
 private:
     ClientAdapter(AssociatedURLLoader*, WebURLLoaderClient*, bool /*downloadToFile*/);
 
+    void notifyError(Timer<ClientAdapter>*);
+
     AssociatedURLLoader* m_loader;
     WebURLLoaderClient* m_client;
+    WebURLError m_error;
+
+    Timer<ClientAdapter> m_errorTimer;
     unsigned long m_downloadLength;
     bool m_downloadToFile;
+    bool m_enableErrorNotifications;
+    bool m_didFail;
 };
 
 PassOwnPtr<AssociatedURLLoader::ClientAdapter> AssociatedURLLoader::ClientAdapter::create(AssociatedURLLoader* loader, WebURLLoaderClient* client, bool downloadToFile)
@@ -88,8 +101,11 @@
 AssociatedURLLoader::ClientAdapter::ClientAdapter(AssociatedURLLoader* loader, WebURLLoaderClient* client, bool downloadToFile)
     : m_loader(loader)
     , m_client(client)
+    , m_errorTimer(this, &ClientAdapter::notifyError)
     , m_downloadLength(0)
     , m_downloadToFile(downloadToFile)
+    , m_enableErrorNotifications(false)
+    , m_didFail(false)
 {
     ASSERT(m_loader);
     ASSERT(m_client);
@@ -144,7 +160,7 @@
     if (m_downloadToFile) {
         int downloadLength = m_downloadLength <= INT_MAX ? m_downloadLength : INT_MAX;
         m_client->didDownloadData(m_loader, downloadLength);
-        // While the client could have cancelled, continue, since the load finished. 
+        // While the client could have canceled, continue, since the load finished.
     }
 
     m_client->didFinishLoading(m_loader, finishTime);
@@ -155,10 +171,28 @@
     if (!m_client)
         return;
 
-    WebURLError webError(error);
-    m_client->didFail(m_loader, webError);
+    m_didFail = true;
+    m_error = WebURLError(error);
+    if (m_enableErrorNotifications)
+        notifyError(&m_errorTimer);
 }
 
+void AssociatedURLLoader::ClientAdapter::enableErrorNotifications()
+{
+    m_enableErrorNotifications = true;
+    // If an error has already been received, start a timer to report it to the client
+    // after AssociatedURLLoader::loadAsynchronously has returned to the caller.
+    if (m_didFail)
+        m_errorTimer.startOneShot(0);
+}
+
+void AssociatedURLLoader::ClientAdapter::notifyError(Timer<ClientAdapter>* timer)
+{
+    ASSERT_UNUSED(timer, timer == &m_errorTimer);
+
+    m_client->didFail(m_loader, m_error);
+}
+
 AssociatedURLLoader::AssociatedURLLoader(PassRefPtr<WebFrameImpl> frameImpl)
     : m_frameImpl(frameImpl)
     , m_client(0)
@@ -215,8 +249,8 @@
     const ResourceRequest& webcoreRequest = request.toResourceRequest();
     Document* webcoreDocument = m_frameImpl->frame()->document();
     m_clientAdapter = ClientAdapter::create(this, m_client, request.downloadToFile());
-
     m_loader = DocumentThreadableLoader::create(webcoreDocument, m_clientAdapter.get(), webcoreRequest, options);
+    m_clientAdapter->enableErrorNotifications();
 }
 
 void AssociatedURLLoader::cancel()

Added: trunk/Source/WebKit/chromium/tests/AssociatedURLLoaderTest.cpp (0 => 88466)


--- trunk/Source/WebKit/chromium/tests/AssociatedURLLoaderTest.cpp	                        (rev 0)
+++ trunk/Source/WebKit/chromium/tests/AssociatedURLLoaderTest.cpp	2011-06-09 18:21:48 UTC (rev 88466)
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "WebFrame.h"
+#include "WebFrameClient.h"
+#include "WebString.h"
+#include "WebURL.h"
+#include "WebURLLoader.h"
+#include "WebURLLoaderClient.h"
+#include "WebURLLoaderOptions.h"
+#include "WebURLRequest.h"
+#include "WebURLResponse.h"
+#include "WebView.h"
+
+#include <googleurl/src/gurl.h>
+#include <gtest/gtest.h>
+#include <webkit/support/webkit_support.h>
+
+using namespace WebKit;
+
+namespace {
+
+class TestWebFrameClient : public WebFrameClient {
+    // Return a non-null cancellation error so the WebFrame loaders can shut down without asserting.
+    // Make 'reason' non-zero so WebURLError isn't considered null.
+    WebURLError cancelledError(WebFrame*, const WebURLRequest& request)
+    {
+        WebURLError error;
+        error.reason = 1;
+        error.unreachableURL = request.url();
+        return error;
+    }
+};
+
+class AssociatedURLLoaderTest : public testing::Test,
+                                public WebURLLoaderClient {
+public:
+    AssociatedURLLoaderTest()
+        :  m_willSendRequest(false)
+        ,  m_didSendData(false)
+        ,  m_didReceiveResponse(false)
+        ,  m_didReceiveData(false)
+        ,  m_didReceiveCachedMetadata(false)
+        ,  m_didFinishLoading(false)
+        ,  m_didFail(false)
+    {
+        // Reuse one of the test files from WebFrameTest.
+        std::string filePath = webkit_support::GetWebKitRootDir().utf8();
+        filePath += "/Source/WebKit/chromium/tests/data/iframes_test.html";
+        m_frameFilePath = WebString::fromUTF8(filePath);
+    }
+
+    void SetUp()
+    {
+        m_webView = WebView::create(0);
+        m_webView->initializeMainFrame(&m_webFrameClient);
+
+        // Load the frame before trying to load resources.
+        GURL url = ""
+        WebURLResponse response;
+        response.initialize();
+        response.setMIMEType("text/html");
+        webkit_support::RegisterMockedURL(url, response, m_frameFilePath);
+
+        WebURLRequest request;
+        request.initialize();
+        request.setURL(url);
+        m_webView->mainFrame()->loadRequest(request);
+        serveRequests();
+
+        webkit_support::UnregisterMockedURL(url);
+    }
+
+    void TearDown()
+    {
+        webkit_support::UnregisterAllMockedURLs();
+        m_webView->close();
+    }
+
+    void serveRequests()
+    {
+        webkit_support::ServeAsynchronousMockedRequests();
+    }
+
+    WebURLLoader* createAssociatedURLLoader(const WebURLLoaderOptions options = WebURLLoaderOptions())
+    {
+        return m_webView->mainFrame()->createAssociatedURLLoader(options);
+    }
+
+    // WebURLLoaderClient implementation.
+    void willSendRequest(WebURLLoader* loader, WebURLRequest& newRequest, const WebURLResponse& redirectResponse)
+    {
+        m_willSendRequest = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+        EXPECT_EQ(m_expectedNewRequest.url(), newRequest.url());
+        EXPECT_EQ(m_expectedRedirectResponse.url(), redirectResponse.url());
+        EXPECT_EQ(m_expectedRedirectResponse.mimeType(), redirectResponse.mimeType());
+        EXPECT_EQ(m_expectedRedirectResponse.httpStatusCode(), redirectResponse.httpStatusCode());
+    }
+
+    void didSendData(WebURLLoader* loader, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+    {
+        m_didSendData = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+    }
+
+    void didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response)
+    {
+        m_didReceiveResponse = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+        EXPECT_EQ(m_expectedResponse.url(), response.url());
+        EXPECT_EQ(m_expectedResponse.httpStatusCode(), response.httpStatusCode());
+    }
+
+    void didDownloadData(WebURLLoader* loader, int dataLength)
+    {
+        m_didDownloadData = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+    }
+
+    void didReceiveData(WebURLLoader* loader, const char* data, int dataLength, int encodedDataLength)
+    {
+        m_didReceiveData = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+        EXPECT_TRUE(data);
+        EXPECT_GT(dataLength, 0);
+    }
+
+    void didReceiveCachedMetadata(WebURLLoader* loader, const char* data, int dataLength)
+    {
+        m_didReceiveCachedMetadata = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+    }
+
+    void didFinishLoading(WebURLLoader* loader, double finishTime)
+    {
+        m_didFinishLoading = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+    }
+
+    void didFail(WebURLLoader* loader, const WebURLError& error)
+    {
+        m_didFail = true;
+        EXPECT_EQ(m_expectedLoader, loader);
+        webkit_support::QuitMessageLoop();
+    }
+
+protected:
+    WebString m_frameFilePath;
+    TestWebFrameClient m_webFrameClient;
+    WebView* m_webView;
+
+    WebURLLoader* m_expectedLoader;
+    WebURLResponse m_expectedResponse;
+    WebURLRequest m_expectedNewRequest;
+    WebURLResponse m_expectedRedirectResponse;
+    bool m_willSendRequest;
+    bool m_didSendData;
+    bool m_didReceiveResponse;
+    bool m_didDownloadData;
+    bool m_didReceiveData;
+    bool m_didReceiveCachedMetadata;
+    bool m_didFinishLoading;
+    bool m_didFail;
+};
+
+// Test a successful URL load.
+TEST_F(AssociatedURLLoaderTest, Success)
+{
+    GURL url = ""
+    WebURLRequest request;
+    request.initialize();
+    request.setURL(url);
+
+    m_expectedResponse = WebURLResponse();
+    m_expectedResponse.initialize();
+    m_expectedResponse.setMIMEType("text/html");
+    webkit_support::RegisterMockedURL(url, m_expectedResponse, m_frameFilePath);
+
+    m_expectedLoader = createAssociatedURLLoader();
+    EXPECT_TRUE(m_expectedLoader);
+    m_expectedLoader->loadAsynchronously(request, this);
+    serveRequests();
+    EXPECT_TRUE(m_didReceiveResponse);
+    EXPECT_TRUE(m_didReceiveData);
+    EXPECT_TRUE(m_didFinishLoading);
+}
+
+// Test that the same-origin restriction is the default.
+TEST_F(AssociatedURLLoaderTest, SameOriginRestriction)
+{
+    // This is cross-origin since the frame was loaded from www.test.com.
+    GURL url = ""
+    WebURLRequest request;
+    request.initialize();
+    request.setURL(url);
+
+    m_expectedLoader = createAssociatedURLLoader();
+    EXPECT_TRUE(m_expectedLoader);
+    m_expectedLoader->loadAsynchronously(request, this);
+    // Failure should not be reported synchronously.
+    EXPECT_FALSE(m_didFail);
+    // Allow the loader to return the error.
+    webkit_support::RunMessageLoop();
+    EXPECT_TRUE(m_didFail);
+}
+
+// Test a successful cross-origin load.
+TEST_F(AssociatedURLLoaderTest, CrossOriginSuccess)
+{
+    // This is cross-origin since the frame was loaded from www.test.com.
+    GURL url = ""
+    WebURLRequest request;
+    request.initialize();
+    request.setURL(url);
+
+    m_expectedResponse = WebURLResponse();
+    m_expectedResponse.initialize();
+    m_expectedResponse.setMIMEType("text/html");
+    webkit_support::RegisterMockedURL(url, m_expectedResponse, m_frameFilePath);
+
+    WebURLLoaderOptions options;
+    options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
+    m_expectedLoader = createAssociatedURLLoader(options);
+    EXPECT_TRUE(m_expectedLoader);
+    m_expectedLoader->loadAsynchronously(request, this);
+    serveRequests();
+    EXPECT_TRUE(m_didReceiveResponse);
+    EXPECT_TRUE(m_didReceiveData);
+    EXPECT_TRUE(m_didFinishLoading);
+}
+
+}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to