summaryrefslogtreecommitdiffstats
path: root/WebCore/loader
diff options
context:
space:
mode:
authorLeon Clarke <leonclarke@google.com>2010-03-09 14:12:21 +0000
committerLeon Clarke <leonclarke@google.com>2010-05-04 10:59:37 +0100
commitf91ac8eab3399adb5325701bebe0590a77e49df7 (patch)
tree04ff055963cf2bfe147998ca3396134b243be38d /WebCore/loader
parentb97e8541004c77ec0c85f74b896b9d3bdb6de6b4 (diff)
downloadexternal_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.zip
external_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.tar.gz
external_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.tar.bz2
Link prefetch support
http://b/issue?id=2268353
Diffstat (limited to 'WebCore/loader')
-rw-r--r--WebCore/loader/Cache.cpp7
-rw-r--r--WebCore/loader/CachedCSSStyleSheet.cpp8
-rw-r--r--WebCore/loader/CachedLinkPrefetch.h67
-rw-r--r--WebCore/loader/CachedResource.h4
-rw-r--r--WebCore/loader/DocLoader.cpp26
-rw-r--r--WebCore/loader/DocLoader.h10
-rw-r--r--WebCore/loader/loader.cpp31
-rw-r--r--WebCore/loader/loader.h6
8 files changed, 143 insertions, 16 deletions
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index fdd9b25..5f4d0e7 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -38,6 +38,9 @@
#include "SecurityOrigin.h"
#include <stdio.h>
#include <wtf/CurrentTime.h>
+#if ENABLE(LINK_PREFETCH)
+#include "CachedLinkPrefetch.h"
+#endif
using namespace std;
@@ -86,6 +89,10 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url
case CachedResource::XBLStyleSheet:
return new CachedXBLDocument(url.string());
#endif
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+ return new CachedLinkPrefetch(url.string());
+#endif
default:
break;
}
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp
index b2e03b9..3fc28ff 100644
--- a/WebCore/loader/CachedCSSStyleSheet.cpp
+++ b/WebCore/loader/CachedCSSStyleSheet.cpp
@@ -51,8 +51,10 @@ CachedCSSStyleSheet::~CachedCSSStyleSheet()
void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c)
{
- if (!m_loading)
+ if (!m_loading) {
c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this);
+ c->notifyFinished(this);
+ }
}
void CachedCSSStyleSheet::allClientsRemoved()
@@ -103,6 +105,10 @@ void CachedCSSStyleSheet::data(PassRefPtr<SharedBuffer> data, bool allDataReceiv
checkNotify();
// Clear the decoded text as it is unlikely to be needed immediately again and is cheap to regenerate.
m_decodedSheetText = String();
+
+ CachedResourceClientWalker w(m_clients);
+ while (CachedResourceClient* c = w.next())
+ c->notifyFinished(this);
}
void CachedCSSStyleSheet::checkNotify()
diff --git a/WebCore/loader/CachedLinkPrefetch.h b/WebCore/loader/CachedLinkPrefetch.h
new file mode 100644
index 0000000..4ffa5fe
--- /dev/null
+++ b/WebCore/loader/CachedLinkPrefetch.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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.
+
+*/
+
+#ifndef CachedLinkPrefetch_h
+#define CachedLinkPrefetch_h
+
+#include "CachedResource.h"
+#include "CachedResourceClient.h"
+#include "CachedResourceClientWalker.h"
+
+namespace WebCore {
+
+class DocLoader;
+
+class CachedLinkPrefetch : public CachedResource {
+public:
+ CachedLinkPrefetch(const String& URL) : CachedResource(URL, LinkPrefetch) { };
+ virtual ~CachedLinkPrefetch() { };
+
+ virtual void didAddClient(CachedResourceClient* c) {
+ if (!m_loading)
+ c->notifyFinished(this);
+ };
+
+ virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived) {
+ if (!allDataReceived)
+ return;
+
+ m_data = data;
+
+ CachedResourceClientWalker w(m_clients);
+ while (CachedResourceClient* c = w.next())
+ c->notifyFinished(this);
+ };
+ virtual void error() { };
+
+ virtual bool schedule() const { return true; }
+
+ virtual bool isPrefetch() const { return true; }
+};
+}
+
+#endif
+
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h
index 0f46a62..bad632b 100644
--- a/WebCore/loader/CachedResource.h
+++ b/WebCore/loader/CachedResource.h
@@ -63,6 +63,9 @@ public:
#if ENABLE(XBL)
, XBL
#endif
+#if ENABLE(LINK_PREFETCH)
+ , LinkPrefetch
+#endif
};
enum Status {
@@ -118,6 +121,7 @@ public:
void setLoading(bool b) { m_loading = b; }
virtual bool isImage() const { return false; }
+ virtual bool isPrefetch() const { return false; }
unsigned accessCount() const { return m_accessCount; }
void increaseAccessCount() { m_accessCount++; }
diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp
index 8c0a1b2..08dfa33 100644
--- a/WebCore/loader/DocLoader.cpp
+++ b/WebCore/loader/DocLoader.cpp
@@ -44,6 +44,9 @@
#include "loader.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#if ENABLE(LINK_PREFETCH)
+#include "CachedLinkPrefetch.h"
+#endif
#define PRELOAD_DEBUG 0
@@ -176,6 +179,13 @@ CachedXBLDocument* DocLoader::requestXBLDocument(const String& url)
}
#endif
+#if ENABLE(LINK_PREFETCH)
+CachedLinkPrefetch* DocLoader::requestLinkPrefetch(const String& url)
+{
+ return static_cast<CachedLinkPrefetch*>(requestResource(CachedResource::LinkPrefetch, url, String()));
+}
+#endif
+
bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
{
// Some types of resources can be loaded only from the same origin. Other
@@ -186,6 +196,9 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
case CachedResource::CSSStyleSheet:
case CachedResource::Script:
case CachedResource::FontResource:
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+#endif
// These types of resources can be loaded from any origin.
// FIXME: Are we sure about CachedResource::FontResource?
break;
@@ -228,6 +241,9 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
break;
case CachedResource::ImageResource:
case CachedResource::CSSStyleSheet:
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+#endif
case CachedResource::FontResource: {
// These resources can corrupt only the frame's pixels.
if (Frame* f = frame()) {
@@ -402,13 +418,19 @@ void DocLoader::checkCacheObjectStatus(CachedResource* resource)
frame()->loader()->loadedResourceFromMemoryCache(resource);
}
-void DocLoader::incrementRequestCount()
+void DocLoader::incrementRequestCount(const CachedResource* res)
{
+ if (res->isPrefetch())
+ return;
+
++m_requestCount;
}
-void DocLoader::decrementRequestCount()
+void DocLoader::decrementRequestCount(const CachedResource* res)
{
+ if (res->isPrefetch())
+ return;
+
--m_requestCount;
ASSERT(m_requestCount > -1);
}
diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h
index 06d8a47..2f8f639 100644
--- a/WebCore/loader/DocLoader.h
+++ b/WebCore/loader/DocLoader.h
@@ -45,6 +45,9 @@ class Document;
class Frame;
class ImageLoader;
class KURL;
+#if ENABLE(LINK_PREFETCH)
+class CachedLinkPrefetch;
+#endif
// The DocLoader manages the loading of scripts/images/stylesheets for a single document.
class DocLoader : public Noncopyable
@@ -68,6 +71,9 @@ public:
#if ENABLE(XBL)
CachedXBLDocument* requestXBLDocument(const String &url);
#endif
+#if ENABLE(LINK_PREFETCH)
+ CachedLinkPrefetch* requestLinkPrefetch(const String &url);
+#endif
// Logs an access denied message to the console for the specified URL.
void printAccessDeniedMessage(const KURL& url) const;
@@ -98,8 +104,8 @@ public:
void setAllowStaleResources(bool allowStaleResources) { m_allowStaleResources = allowStaleResources; }
- void incrementRequestCount();
- void decrementRequestCount();
+ void incrementRequestCount(const CachedResource*);
+ void decrementRequestCount(const CachedResource*);
int requestCount();
void clearPreloads();
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index 4d2b474..24f141f 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -88,7 +88,12 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
return ResourceRequest::TargetIsFontResource;
case CachedResource::ImageResource:
return ResourceRequest::TargetIsImage;
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+ return ResourceRequest::TargetIsSubresource;
+#endif
}
+ ASSERT_NOT_REACHED();
return ResourceRequest::TargetIsSubresource;
}
@@ -109,6 +114,10 @@ Loader::Priority Loader::determinePriority(const CachedResource* resource) const
return Medium;
case CachedResource::ImageResource:
return Low;
+#if ENABLE(LINK_PREFETCH)
+ case CachedResource::LinkPrefetch:
+ return VeryLow;
+#endif
}
ASSERT_NOT_REACHED();
return Low;
@@ -138,9 +147,9 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment
bool hadRequests = host->hasRequests();
Priority priority = determinePriority(resource);
host->addRequest(request, priority);
- docLoader->incrementRequestCount();
+ docLoader->incrementRequestCount(request->cachedResource());
- if (priority > Low || !url.protocolInHTTPFamily() || !hadRequests) {
+ if (priority > Low || !url.protocolInHTTPFamily() || (priority == Low && !hadRequests)) {
// Try to request important resources immediately
host->servePendingRequests(priority);
} else {
@@ -352,6 +361,12 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
}
}
+#if ENABLE(LINK_PREFETCH)
+ if (request->cachedResource()->type() == CachedResource::LinkPrefetch) {
+ resourceRequest.setHTTPHeaderField("X-Moz", "prefetch");
+ }
+#endif
+
RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
if (loader) {
@@ -361,7 +376,7 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
} else {
- docLoader->decrementRequestCount();
+ docLoader->decrementRequestCount(request->cachedResource());
docLoader->setLoadInProgress(true);
request->cachedResource()->error();
docLoader->setLoadInProgress(false);
@@ -385,7 +400,7 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
// the docLoader that it will delete when the document gets deleted.
RefPtr<Document> protector(docLoader->doc());
if (!request->isMultipart())
- docLoader->decrementRequestCount();
+ docLoader->decrementRequestCount(request->cachedResource());
CachedResource* resource = request->cachedResource();
ASSERT(!resource->resourceToRevalidate());
@@ -433,7 +448,7 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
// the docLoader that it will delete when the document gets deleted.
RefPtr<Document> protector(docLoader->doc());
if (!request->isMultipart())
- docLoader->decrementRequestCount();
+ docLoader->decrementRequestCount(request->cachedResource());
CachedResource* resource = request->cachedResource();
@@ -478,7 +493,7 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
// 304 Not modified / Use local copy
m_requestsLoading.remove(loader);
loader->clearClient();
- request->docLoader()->decrementRequestCount();
+ request->docLoader()->decrementRequestCount(request->cachedResource());
// Existing resource is ok, just use it updating the expiration time.
cache()->revalidationSucceeded(resource, response);
@@ -510,7 +525,7 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
request->setIsMultipart(true);
// We don't count multiParts in a DocLoader's request count
- request->docLoader()->decrementRequestCount();
+ request->docLoader()->decrementRequestCount(request->cachedResource());
// If we get a multipart response, we must have a handle
ASSERT(loader->handle());
@@ -559,7 +574,7 @@ void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoade
if (request->docLoader() == docLoader) {
cache()->remove(request->cachedResource());
delete request;
- docLoader->decrementRequestCount();
+ docLoader->decrementRequestCount(request->cachedResource());
} else
remaining.append(request);
}
diff --git a/WebCore/loader/loader.h b/WebCore/loader/loader.h
index a9de032..9393a60 100644
--- a/WebCore/loader/loader.h
+++ b/WebCore/loader/loader.h
@@ -48,8 +48,8 @@ namespace WebCore {
void cancelRequests(DocLoader*);
- enum Priority { Low, Medium, High };
- void servePendingRequests(Priority minimumPriority = Low);
+ enum Priority { VeryLow, Low, Medium, High };
+ void servePendingRequests(Priority minimumPriority = VeryLow);
bool isSuspendingPendingRequests() { return m_isSuspendingPendingRequests; }
void suspendPendingRequests();
@@ -76,7 +76,7 @@ namespace WebCore {
void addRequest(Request*, Priority);
void nonCacheRequestInFlight();
void nonCacheRequestComplete();
- void servePendingRequests(Priority minimumPriority = Low);
+ void servePendingRequests(Priority minimumPriority = VeryLow);
void cancelRequests(DocLoader*);
bool hasRequests() const;