OSDN Git Service

Notify WebKit of redirects in the Chrome HTTP stack.
authorIain Merrick <husky@google.com>
Fri, 29 Oct 2010 11:42:54 +0000 (12:42 +0100)
committerIain Merrick <husky@google.com>
Fri, 29 Oct 2010 14:34:19 +0000 (15:34 +0100)
In this CL we just defer the redirect until WebKit has had a chance
to check it, and potentially cancel it.

There's a comment in the old code asking what to do if we're given
a bad request. Looks like this should never happen; it's a DCHECK in
Chrome so I've turned it into an ASSERT here.

We only follow redirects if WebKit does not modify the URL (this is
the same behaviour as Chrome).

Change-Id: I0c8b8cd61c501527a29dda5aca521a7df4a3ccef

WebKit/android/WebCoreSupport/WebRequest.cpp
WebKit/android/WebCoreSupport/WebRequest.h
WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp

index 307a007..ef09ff7 100644 (file)
@@ -295,20 +295,15 @@ void WebRequest::handleBrowserURL(GURL url)
 void WebRequest::OnReceivedRedirect(URLRequest* newRequest, const GURL& newUrl, bool* deferRedirect)
 {
     ASSERT(m_loadState < Response, "Redirect after receiving response");
+    ASSERT(newRequest && newRequest->status().is_success(), "Invalid redirect");
 
-    if (newRequest && newRequest->status().is_success()) {
-        OwnPtr<WebResponse> webResponse(new WebResponse(newRequest));
-        webResponse->setUrl(newUrl.spec());
-        m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
-                m_urlLoader.get(), &WebUrlLoaderClient::willSendRequest, webResponse.release()));
-    } else {
-        // why would this happen? And what to do?
-    }
+    OwnPtr<WebResponse> webResponse(new WebResponse(newRequest));
+    webResponse->setUrl(newUrl.spec());
+    m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+            m_urlLoader.get(), &WebUrlLoaderClient::willSendRequest, webResponse.release()));
 
-    // Here we should check if the url we get back from webkit is the same
-    // as newUrl, but since we are on a different thread that is not
-    // possible. Look into later.
-    return;
+    // Defer the redirect until followDeferredRedirect() is called.
+    *deferRedirect = true;
 }
 
 // Called when we receive an authentication failure.  The delegate should
@@ -362,6 +357,13 @@ void WebRequest::cancelAuth()
     m_request->CancelAuth();
 }
 
+void WebRequest::followDeferredRedirect()
+{
+    ASSERT(m_loadState < Response, "Redirect after receiving response");
+
+    m_request->FollowDeferredRedirect();
+}
+
 void WebRequest::startReading()
 {
     ASSERT(m_loadState == Response || m_loadState == GotData, "StartReading in state other than RESPONSE and GOTDATA");
index eff39d8..1f73d2a 100644 (file)
@@ -74,6 +74,7 @@ public:
     // Methods called during a request by the UI code (via WebUrlLoaderClient).
     void setAuth(const string16& username, const string16& password);
     void cancelAuth();
+    void followDeferredRedirect();
 
     const std::string& getUrl() const;
     const std::string& getUserAgent() const;
index bd116c6..8925fbc 100644 (file)
@@ -302,8 +302,20 @@ void WebUrlLoaderClient::willSendRequest(PassOwnPtr<WebResponse> webResponse)
     if (!isActive())
         return;
 
-    OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(webResponse->createKurl()));
+    KURL url = webResponse->createKurl();
+    OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(url));
     m_resourceHandle->client()->willSendRequest(m_resourceHandle.get(), *resourceRequest, webResponse->createResourceResponse());
+
+    // WebKit may have killed the request.
+    if (!isActive())
+        return;
+
+    // Like Chrome, we only follow the redirect if WebKit left the URL unmodified.
+    if (url == resourceRequest->url()) {
+        ioThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::followDeferredRedirect));
+    } else {
+        cancel();
+    }
 }
 
 void WebUrlLoaderClient::didFinishLoading()