Remove didReceiveAuthenticationChallenge() from SubresourceLoaderClient.
authorjaphet@chromium.org <japhet@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2011 01:12:38 +0000 (01:12 +0000)
committerjaphet@chromium.org <japhet@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2011 01:12:38 +0000 (01:12 +0000)
Instead, add a load-specific policy for showing the user authentication
challenge down to ResourceLoaderOptions and enforce it in ResourceLoader.
https://bugs.webkit.org/show_bug.cgi?id=65330

Reviewed by Alexey Proskuryakov.

No new tests, refactor only.

* loader/DocumentThreadableLoader.cpp:
* loader/DocumentThreadableLoader.h:
* loader/MainResourceLoader.cpp:
* loader/NetscapePlugInStreamLoader.cpp:
* loader/ResourceLoadScheduler.h:
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::didReceiveAuthenticationChallenge):
   For resource types that always send a challenge to the embedder,
   this patch doesn't change anything. For those that don't, we will
   always try to continue without credentials when they are forbidden
   and the platform supports it.
   When continuing without credentials was initially implemented in
   DocumentThreadableLoader, we sent the ThreadableLoaderClient a didFail(),
   then canceled the SubresourceLoader. This was necessary because of the
   quirks of ThreadableLoader cancellation (we sever the client/loader connections
   before the load actually cancels), but a simple didFail() should suffice at
   the ResourceLoader layer.
* loader/ResourceLoaderOptions.h:
* loader/SubresourceLoader.cpp:
* loader/SubresourceLoader.h:
* loader/SubresourceLoaderClient.h:
* loader/cache/CachedResource.cpp:
* loader/cache/CachedResourceLoader.cpp:
* loader/cache/CachedResourceLoader.h:
* loader/icon/IconLoader.cpp: The ResourceLoader implementation of
    didReceiveAuthenticationChallege means that IconLoader will now
    try to continue with credentials on platforms that support it,
    rather than just canceling outright. We still will never prompt
    for authentication for icons.
* loader/icon/IconLoader.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95768 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/loader/DocumentThreadableLoader.h
Source/WebCore/loader/MainResourceLoader.cpp
Source/WebCore/loader/NetscapePlugInStreamLoader.cpp
Source/WebCore/loader/ResourceLoadScheduler.h
Source/WebCore/loader/ResourceLoader.cpp
Source/WebCore/loader/ResourceLoaderOptions.h
Source/WebCore/loader/SubresourceLoader.cpp
Source/WebCore/loader/SubresourceLoader.h
Source/WebCore/loader/SubresourceLoaderClient.h
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/loader/cache/CachedResourceLoader.h
Source/WebCore/loader/icon/IconLoader.cpp
Source/WebCore/loader/icon/IconLoader.h

index d3a4e33..c1eb510 100644 (file)
@@ -1,3 +1,45 @@
+2011-09-22  Nate Chapin  <japhet@chromium.org>
+
+        Remove didReceiveAuthenticationChallenge() from SubresourceLoaderClient.
+        Instead, add a load-specific policy for showing the user authentication
+        challenge down to ResourceLoaderOptions and enforce it in ResourceLoader.
+        https://bugs.webkit.org/show_bug.cgi?id=65330
+
+        Reviewed by Alexey Proskuryakov.
+
+        No new tests, refactor only.
+
+        * loader/DocumentThreadableLoader.cpp:
+        * loader/DocumentThreadableLoader.h:
+        * loader/MainResourceLoader.cpp:
+        * loader/NetscapePlugInStreamLoader.cpp:
+        * loader/ResourceLoadScheduler.h:
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::didReceiveAuthenticationChallenge):
+           For resource types that always send a challenge to the embedder,
+           this patch doesn't change anything. For those that don't, we will
+           always try to continue without credentials when they are forbidden
+           and the platform supports it.
+           When continuing without credentials was initially implemented in
+           DocumentThreadableLoader, we sent the ThreadableLoaderClient a didFail(),
+           then canceled the SubresourceLoader. This was necessary because of the
+           quirks of ThreadableLoader cancellation (we sever the client/loader connections
+           before the load actually cancels), but a simple didFail() should suffice at
+           the ResourceLoader layer.
+        * loader/ResourceLoaderOptions.h:
+        * loader/SubresourceLoader.cpp:
+        * loader/SubresourceLoader.h:
+        * loader/SubresourceLoaderClient.h:
+        * loader/cache/CachedResource.cpp:
+        * loader/cache/CachedResourceLoader.cpp:
+        * loader/cache/CachedResourceLoader.h:
+        * loader/icon/IconLoader.cpp: The ResourceLoader implementation of
+            didReceiveAuthenticationChallege means that IconLoader will now
+            try to continue with credentials on platforms that support it,
+            rather than just canceling outright. We still will never prompt
+            for authentication for icons.
+        * loader/icon/IconLoader.h:
+
 2011-09-22  Dean Jackson  <dino@apple.com>
 
         Add ENABLE_CSS_FILTERS
index 73ef31b..0c5afa9 100644 (file)
@@ -288,23 +288,6 @@ void DocumentThreadableLoader::didFail(SubresourceLoader* loader, const Resource
     m_client->didFail(error);
 }
 
-void DocumentThreadableLoader::didReceiveAuthenticationChallenge(SubresourceLoader* loader, const AuthenticationChallenge& challenge)
-{
-    ASSERT(loader == m_loader);
-    // Users are not prompted for credentials for cross-origin requests.
-    if (!m_sameOriginRequest) {
-#if PLATFORM(MAC) || USE(CFNETWORK) || USE(CURL)
-        loader->handle()->receivedRequestToContinueWithoutCredential(challenge);
-#else
-        // These platforms don't provide a way to continue without credentials, cancel the load altogether.
-        UNUSED_PARAM(challenge);
-        RefPtr<DocumentThreadableLoader> protect(this);
-        m_client->didFail(loader->blockedError());
-        cancel();
-#endif
-    }
-}
-
 void DocumentThreadableLoader::preflightSuccess()
 {
     OwnPtr<ResourceRequest> actualRequest;
@@ -331,6 +314,7 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
 
     if (m_async) {
         ThreadableLoaderOptions options = m_options;
+        options.crossOriginCredentialPolicy = DoNotAskClientForCrossOriginCredentials;
         if (m_actualRequest) {
             // Don't sniff content or send load callbacks for the preflight request.
             options.sendLoadCallbacks = DoNotSendCallbacks;
index ef0e96e..31d8dcf 100644 (file)
@@ -82,8 +82,6 @@ namespace WebCore {
         virtual void didFinishLoading(SubresourceLoader*, double);
         virtual void didFail(SubresourceLoader*, const ResourceError&);
 
-        virtual void didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&);
-
 #if PLATFORM(CHROMIUM)
         virtual void didDownloadData(SubresourceLoader*, int dataLength);
 #endif
index 87c5bae..06e0547 100644 (file)
@@ -60,7 +60,7 @@
 namespace WebCore {
 
 MainResourceLoader::MainResourceLoader(Frame* frame)
-    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials))
+    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials))
     , m_dataLoadTimer(this, &MainResourceLoader::handleDataLoadNow)
     , m_loadingMultipartContent(false)
     , m_waitingForContentPolicy(false)
index a1672e9..77f855f 100644 (file)
@@ -36,7 +36,7 @@
 namespace WebCore {
 
 NetscapePlugInStreamLoader::NetscapePlugInStreamLoader(Frame* frame, NetscapePlugInStreamLoaderClient* client)
-    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials))
+    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials))
     , m_client(client)
 {
 }
index 371c7c8..ddeaffd 100644 (file)
@@ -51,7 +51,7 @@ class ResourceLoadScheduler {
 public:
     friend ResourceLoadScheduler* resourceLoadScheduler();
 
-    PassRefPtr<SubresourceLoader> scheduleSubresourceLoad(Frame*, SubresourceLoaderClient*, const ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityLow, SecurityCheckPolicy = DoSecurityCheck, const ResourceLoaderOptions& = ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials));
+    PassRefPtr<SubresourceLoader> scheduleSubresourceLoad(Frame*, SubresourceLoaderClient*, const ResourceRequest&, ResourceLoadPriority, SecurityCheckPolicy, const ResourceLoaderOptions&);
     PassRefPtr<NetscapePlugInStreamLoader> schedulePluginStreamLoad(Frame*, NetscapePlugInStreamLoaderClient*, const ResourceRequest&);
     void addMainResourceLoad(ResourceLoader*);
     void remove(ResourceLoader*);
index 1f058eb..26bf651 100644 (file)
@@ -42,6 +42,7 @@
 #include "ResourceError.h"
 #include "ResourceHandle.h"
 #include "ResourceLoadScheduler.h"
+#include "SecurityOrigin.h"
 #include "Settings.h"
 #include "SharedBuffer.h"
 
@@ -515,10 +516,25 @@ bool ResourceLoader::shouldUseCredentialStorage()
 
 void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
 {
+    ASSERT(handle()->hasAuthenticationChallenge());
     // Protect this in this delegate method since the additional processing can do
     // anything including possibly derefing this; one example of this is Radar 3266216.
     RefPtr<ResourceLoader> protector(this);
-    frameLoader()->notifier()->didReceiveAuthenticationChallenge(this, challenge);
+
+    if (m_options.allowCredentials == AllowStoredCredentials) {
+        if (m_options.crossOriginCredentialPolicy == AskClientForCrossOriginCredentials || m_frame->document()->securityOrigin()->canRequest(originalRequest().url())) {
+            frameLoader()->notifier()->didReceiveAuthenticationChallenge(this, challenge);
+            return;
+        }
+    }
+    // Only these platforms provide a way to continue without credentials.
+    // If we can't continue with credentials, we need to cancel the load altogether.
+#if PLATFORM(MAC) || USE(CFNETWORK) || USE(CURL)
+    handle()->receivedRequestToContinueWithoutCredential(challenge);
+    ASSERT(!handle()->hasAuthenticationChallenge());
+#else
+    didFail(blockedError());
+#endif
 }
 
 void ResourceLoader::didCancelAuthenticationChallenge(const AuthenticationChallenge& challenge)
index d6adeb1..c28abe7 100644 (file)
@@ -49,14 +49,27 @@ enum DataBufferingPolicy {
     BufferData,
     DoNotBufferData
 };
+    
+enum ClientCrossOriginCredentialPolicy {
+    AskClientForCrossOriginCredentials,
+    DoNotAskClientForCrossOriginCredentials
+};
 
 struct ResourceLoaderOptions {
-    ResourceLoaderOptions() : sendLoadCallbacks(DoNotSendCallbacks), sniffContent(DoNotSniffContent), shouldBufferData(BufferData), allowCredentials(DoNotAllowStoredCredentials) { }
-    ResourceLoaderOptions(SendCallbackPolicy sendLoadCallbacksArg, ContentSniffingPolicy sniffContentArg, DataBufferingPolicy shouldBufferDataArg, StoredCredentials allowCredentialsArg) : sendLoadCallbacks(sendLoadCallbacksArg), sniffContent(sniffContentArg), shouldBufferData(shouldBufferDataArg), allowCredentials(allowCredentialsArg) { }
+    ResourceLoaderOptions() : sendLoadCallbacks(DoNotSendCallbacks), sniffContent(DoNotSniffContent), shouldBufferData(BufferData), allowCredentials(DoNotAllowStoredCredentials), crossOriginCredentialPolicy(DoNotAskClientForCrossOriginCredentials) { }
+    ResourceLoaderOptions(SendCallbackPolicy sendLoadCallbacks, ContentSniffingPolicy sniffContent, DataBufferingPolicy shouldBufferData, StoredCredentials allowCredentials, ClientCrossOriginCredentialPolicy crossOriginCredentialPolicy)
+        : sendLoadCallbacks(sendLoadCallbacks)
+        , sniffContent(sniffContent)
+        , shouldBufferData(shouldBufferData)
+        , allowCredentials(allowCredentials)
+        , crossOriginCredentialPolicy(crossOriginCredentialPolicy)
+    {
+    }
     SendCallbackPolicy sendLoadCallbacks;
     ContentSniffingPolicy sniffContent;
     DataBufferingPolicy shouldBufferData;
     StoredCredentials allowCredentials; // Whether HTTP credentials and cookies are sent with the request.
+    ClientCrossOriginCredentialPolicy crossOriginCredentialPolicy; // Whether we will ask the client for credentials (if we allow credentials at all).
 };
 
 } // namespace WebCore    
index 8fe5d27..a74f256 100644 (file)
@@ -234,25 +234,4 @@ void SubresourceLoader::didCancel(const ResourceError&)
     m_documentLoader->removeSubresourceLoader(this);
 }
 
-void SubresourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
-{
-    RefPtr<SubresourceLoader> protect(this);
-
-    ASSERT(handle()->hasAuthenticationChallenge());
-
-    if (m_client)
-        m_client->didReceiveAuthenticationChallenge(this, challenge);
-    
-    // The SubResourceLoaderClient may have cancelled this ResourceLoader in response to the challenge.  
-    // If that's the case, don't call didReceiveAuthenticationChallenge.
-    if (reachedTerminalState())
-        return;
-
-    // It may have also handled authentication on its own.
-    if (!handle()->hasAuthenticationChallenge())
-        return;
-
-    ResourceLoader::didReceiveAuthenticationChallenge(challenge);
-}
-
 }
index 86d1528..d9ca5e2 100644 (file)
@@ -56,7 +56,6 @@ namespace WebCore {
         virtual void didReceiveCachedMetadata(const char*, int);
         virtual void didFinishLoading(double finishTime);
         virtual void didFail(const ResourceError&);
-        virtual void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
         virtual void willCancel(const ResourceError&);
         virtual void didCancel(const ResourceError&);
 
index 0de63a1..9528ab8 100644 (file)
@@ -50,8 +50,6 @@ public:
     virtual void didReceiveCachedMetadata(SubresourceLoader*, const char*, int /*dataLength*/) { }
     virtual void didFinishLoading(SubresourceLoader*, double /*finishTime*/) { }
     virtual void didFail(SubresourceLoader*, const ResourceError&) { }
-    
-    virtual void didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&) { }
 
 #if PLATFORM(CHROMIUM)
     virtual void didDownloadData(SubresourceLoader*, int /*dataLength*/) { }
index 1212a7b..65918e0 100644 (file)
@@ -96,7 +96,7 @@ CachedResource::CachedResource(const ResourceRequest& request, Type type)
     , m_loading(false)
     , m_type(type)
     , m_status(Pending)
-    , m_options(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials)
+    , m_options(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials)
 #ifndef NDEBUG
     , m_deleted(false)
     , m_lruIndex(0)
index 6944622..863fd3d 100644 (file)
@@ -167,7 +167,7 @@ CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequ
     if (!inCache)
         userSheet->setInCache(true);
 
-    userSheet->setResourceLoaderOptions(ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials));
+    userSheet->setResourceLoaderOptions(ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials));
     userSheet->load(this, /*incremental*/ false, SkipSecurityCheck);
 
     if (!inCache)
index 0cda4ad..f4094bb 100644 (file)
@@ -109,7 +109,7 @@ public:
 private:
     // FIXME: The default value for ResourceLoaderOptions will always be used currently.
     // It is plumbed for http://bugs.webkit.org/show_bug.cgi?id=61225 .
-    CachedResource* requestResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false, const ResourceLoaderOptions& = ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials));
+    CachedResource* requestResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false, const ResourceLoaderOptions& = ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials));
     CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority);
     CachedResource* loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority, const ResourceLoaderOptions&);
     void requestPreload(CachedResource::Type, ResourceRequest&, const String& charset);
index bede65c..0eb7a80 100644 (file)
@@ -72,7 +72,7 @@ void IconLoader::startLoading()
     ResourceRequest resourceRequest(m_frame->loader()->icon()->url());
     resourceRequest.setPriority(ResourceLoadPriorityLow);
 
-    RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_frame, this, resourceRequest);
+    RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_frame, this, resourceRequest, ResourceLoadPriorityLow, DoSecurityCheck, ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials));
     if (!loader)
         LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->icon()->url().string().ascii().data());
 
@@ -124,13 +124,6 @@ void IconLoader::didFail(SubresourceLoader* resourceLoader, const ResourceError&
     }
 }
 
-void IconLoader::didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&)
-{
-    // We don't ever want to prompt for authentication just for a site icon, so
-    // implement this method to cancel the resource load
-    m_resourceLoader->cancel();
-}
-
 void IconLoader::didFinishLoading(SubresourceLoader* resourceLoader, double)
 {
     LOG(IconDatabase, "IconLoader::didFinishLoading() - Loader %p", resourceLoader);
index f6d5b81..49b812d 100644 (file)
@@ -54,8 +54,6 @@ private:
     virtual void didFinishLoading(SubresourceLoader*, double);
     virtual void didFail(SubresourceLoader*, const ResourceError&);
 
-    virtual void didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&);
-
     void finishLoading(const KURL&, PassRefPtr<SharedBuffer> data);
     void clearLoadingState();