--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5403,18 +5403,24 @@ var OfflineApps = {
getService(Ci.nsIPermissionManager);
pm.add(aURI, "offline-app",
Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
},
// XXX: duplicated in preferences/advanced.js
_getOfflineAppUsage: function (host)
{
- // XXX Bug 442810: include offline cache usage.
- var usage = 0;
+ var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].
+ getService(Components.interfaces.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Components.interfaces.nsICache.STORE_OFFLINE,
+ true).
+ QueryInterface(Components.interfaces.nsIOfflineCacheSession);
+ var usage = cacheSession.getDomainUsage(host);
+
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
getService(Components.interfaces.nsIDOMStorageManager);
usage += storageManager.getUsage(host);
return usage;
},
_checkUsage: function(aURI) {
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -211,18 +211,23 @@ var gAdvancedPane = {
document.documentElement.openWindow("Browser:Permissions",
"chrome://browser/content/preferences/permissions.xul",
"", params);
},
// XXX: duplicated in browser.js
_getOfflineAppUsage: function (host)
{
- // XXX Bug 442710: include offline cache usage.
- var usage = 0;
+ var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].
+ getService(Components.interfaces.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Components.interfaces.nsICache.STORE_OFFLINE,
+ true).
+ QueryInterface(Components.interfaces.nsIOfflineCacheSession);
+ var usage = cacheSession.getDomainUsage(host);
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
getService(Components.interfaces.nsIDOMStorageManager);
usage += storageManager.getUsage(host);
return usage;
},
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -66,18 +66,16 @@
#include "nsIContentViewer.h"
#include "nsIAtom.h"
#include "nsGkAtoms.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPrincipal.h"
#include "nsIScriptGlobalObject.h"
#include "nsNetCID.h"
#include "nsIOfflineCacheUpdate.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheContainer.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDOMLoadStatus.h"
#include "nsICookieService.h"
#include "nsIPrompt.h"
#include "nsServiceManagerUtils.h"
#include "nsContentUtils.h"
#include "nsParserUtils.h"
#include "nsCRT.h"
@@ -878,34 +876,16 @@ nsContentSink::ProcessOfflineManifest(ns
return;
}
// Only update if the document has permission to use offline APIs.
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return;
}
- // XXX: at this point in the spec there is an algorithm for
- // confirming whether the cache that was selected at load time was
- // the proper application cache for this document. This will
- // be implemented in a separate patch; For now just assume that we
- // chose an acceptable application cache.
-
- nsCOMPtr<nsIApplicationCacheContainer> channelContainer =
- do_QueryInterface(mDocument->GetChannel());
-
- nsCOMPtr<nsIApplicationCacheContainer> docContainer =
- do_QueryInterface(mDocument);
-
- if (channelContainer && docContainer) {
- nsCOMPtr<nsIApplicationCache> appCache;
- channelContainer->GetApplicationCache(getter_AddRefs(appCache));
- docContainer->SetApplicationCache(appCache);
- }
-
nsCOMPtr<nsIURI> manifestURI;
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
manifestSpec, mDocument,
mDocumentURI);
if (!manifestURI) {
return;
}
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -799,17 +799,51 @@ nsContentUtils::GetOfflineAppManifest(ns
nsContentUtils::NewURIWithDocumentCharset(aURI, manifestSpec,
topDoc, topDoc->GetBaseURI());
}
/* static */
PRBool
nsContentUtils::OfflineAppAllowed(nsIURI *aURI)
{
- return NS_OfflineAppAllowed(aURI, sPrefBranch);
+ nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
+ if (!innerURI)
+ return PR_FALSE;
+
+ // only http and https applications can use offline APIs.
+ PRBool match;
+ nsresult rv = innerURI->SchemeIs("http", &match);
+ NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+ if (!match) {
+ rv = innerURI->SchemeIs("https", &match);
+ NS_ENSURE_SUCCESS(rv, PR_FALSE);
+ if (!match) {
+ return PR_FALSE;
+ }
+ }
+
+ nsCOMPtr<nsIPermissionManager> permissionManager =
+ do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+ if (!permissionManager) {
+ return PR_FALSE;
+ }
+
+ PRUint32 perm;
+ permissionManager->TestExactPermission(innerURI, "offline-app", &perm);
+
+ if (perm == nsIPermissionManager::UNKNOWN_ACTION) {
+ return GetBoolPref("offline-apps.allow_by_default");
+ }
+
+ if (perm == nsIPermissionManager::DENY_ACTION) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
}
// static
void
nsContentUtils::Shutdown()
{
sInitialized = PR_FALSE;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1138,17 +1138,16 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNode)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsPIDOMEventTarget)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOM3Node)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOM3Document)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsISupportsWeakReference)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNodeSelector)
- NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
// nsNodeSH::PreCreate() depends on the identity pointer being the
// same as nsINode (which nsIDocument inherits), so if you change
// the below line, make sure nsNodeSH::PreCreate() still does the
// right thing!
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsDocument, nsISupports, nsIDocument)
NS_INTERFACE_TABLE_END
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDocument)
if (aIID.Equals(NS_GET_IID(nsIDOMXPathEvaluator)) ||
@@ -1950,32 +1949,16 @@ nsDocument::GetPrincipal()
void
nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal)
{
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
}
NS_IMETHODIMP
-nsDocument::GetApplicationCache(nsIApplicationCache **aApplicationCache)
-{
- NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::SetApplicationCache(nsIApplicationCache *aApplicationCache)
-{
- mApplicationCache = aApplicationCache;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
nsDocument::GetContentType(nsAString& aContentType)
{
CopyUTF8toUTF16(mContentType, aContentType);
return NS_OK;
}
void
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -88,18 +88,16 @@
#include "nsIRequest.h"
#include "nsILoadGroup.h"
#include "nsTObserverArray.h"
#include "nsStubMutationObserver.h"
#include "nsIChannel.h"
#include "nsCycleCollectionParticipant.h"
#include "nsContentList.h"
#include "nsGkAtoms.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheContainer.h"
// Put these here so all document impls get them automatically
#include "nsHTMLStyleSheet.h"
#include "nsIHTMLCSSStyleSheet.h"
#include "nsStyleSet.h"
#include "nsXMLEventsManager.h"
#include "pldhash.h"
@@ -405,17 +403,16 @@ class nsDocument : public nsIDocument,
public nsIDOM3Document,
public nsSupportsWeakReference,
public nsIDOMEventTarget,
public nsIDOM3EventTarget,
public nsIDOMNSEventTarget,
public nsIScriptObjectPrincipal,
public nsIRadioGroupContainer,
public nsIDOMNodeSelector,
- public nsIApplicationCacheContainer,
public nsStubMutationObserver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
virtual void Reset(nsIChannel *aChannel, nsILoadGroup *aLoadGroup);
virtual void ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
nsIPrincipal* aPrincipal);
@@ -750,19 +747,16 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();
- // nsIApplicationCacheContainer
- NS_DECL_NSIAPPLICATIONCACHECONTAINER
-
virtual nsresult Init();
virtual nsresult AddXMLEventsContent(nsIContent * aXMLEventsElement);
virtual nsresult CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID,
PRBool aDocumentDefaultType,
nsIContent **aResult);
@@ -1022,20 +1016,16 @@ protected:
nsCOMPtr<nsIScriptEventManager> mScriptEventManager;
nsString mBaseTarget;
// Our update nesting level
PRUint32 mUpdateNestLevel;
- // The application cache that this document is associated with, if
- // any. This can change during the lifetime of the document.
- nsCOMPtr<nsIApplicationCache> mApplicationCache;
-
private:
friend class nsUnblockOnloadEvent;
void PostUnblockOnloadEvent();
void DoUnblockOnload();
/**
* See if aDocument is a child of this. If so, return the frame element in
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -138,19 +138,16 @@
#include "nsIHistoryEntry.h"
#include "nsISHistoryListener.h"
#include "nsIWindowWatcher.h"
#include "nsIPromptFactory.h"
#include "nsIObserver.h"
#include "nsINestedURI.h"
#include "nsITransportSecurityInfo.h"
#include "nsINSSErrorsService.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheContainer.h"
-#include "nsIPermissionManager.h"
// Editor-related
#include "nsIEditingSession.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsICachingChannel.h"
#include "nsICacheVisitor.h"
@@ -456,32 +453,16 @@ NS_IMETHODIMP nsDocShell::GetInterface(c
NS_SUCCEEDED(EnsureScriptEnvironment())) {
return mScriptGlobal->QueryInterface(aIID, aSink);
}
else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) &&
NS_SUCCEEDED(EnsureContentViewer())) {
mContentViewer->GetDOMDocument((nsIDOMDocument **) aSink);
return *aSink ? NS_OK : NS_NOINTERFACE;
}
- else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer)) &&
- NS_SUCCEEDED(EnsureContentViewer())) {
- *aSink = nsnull;
-
- // Return the toplevel document as an
- // nsIApplicationCacheContainer.
-
- nsCOMPtr<nsIDocShellTreeItem> rootItem;
- GetSameTypeRootTreeItem(getter_AddRefs(rootItem));
- nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootItem);
- NS_ASSERTION(domDoc, "Should have a document.");
- if (!domDoc)
- return NS_ERROR_NO_INTERFACE;
-
- return domDoc->QueryInterface(aIID, aSink);
- }
else if (aIID.Equals(NS_GET_IID(nsIPrompt)) &&
NS_SUCCEEDED(EnsureScriptEnvironment())) {
nsresult rv;
nsCOMPtr<nsIWindowWatcher> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(mScriptGlobal));
@@ -7289,25 +7270,16 @@ nsDocShell::DoURILoad(nsIURI * aURI,
uriLoader = do_GetService(NS_URI_LOADER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
if (aFirstParty) {
// tag first party URL loads
loadFlags |= nsIChannel::LOAD_INITIAL_DOCUMENT_URI;
-
- // Toplevel document loads in domains with the offline-app
- // permission should check for an associated application
- // cache.
- nsCOMPtr<nsIDocShellTreeItem> root;
- GetSameTypeRootTreeItem(getter_AddRefs(root));
- if (root == this && NS_OfflineAppAllowed(aURI)) {
- loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE;
- }
}
if (mLoadType == LOAD_ERROR_PAGE) {
// Error pages are LOAD_BACKGROUND
loadFlags |= nsIChannel::LOAD_BACKGROUND;
}
// open a channel for the url
--- a/dom/src/offline/Makefile.in
+++ b/dom/src/offline/Makefile.in
@@ -54,17 +54,16 @@ REQUIRES = xpcom \
thebes \
js \
layout \
locale \
necko \
nkcache \
pref \
prefetch \
- docshell \
widget \
xpconnect \
$(NULL)
CPPSRCS = \
nsDOMOfflineResourceList.cpp \
$(NULL)
--- a/dom/src/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/src/offline/nsDOMOfflineResourceList.cpp
@@ -40,26 +40,26 @@
#include "nsDOMClassInfo.h"
#include "nsDOMError.h"
#include "nsIPrefetchService.h"
#include "nsCPrefetchService.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsICacheSession.h"
#include "nsICacheService.h"
+#include "nsIOfflineCacheSession.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIDOMLoadStatus.h"
#include "nsAutoPtr.h"
#include "nsContentUtils.h"
#include "nsIJSContextStack.h"
#include "nsEventDispatcher.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIObserverService.h"
#include "nsIScriptGlobalObject.h"
-#include "nsIWebNavigation.h"
// Event names
#define CHECKING_STR "checking"
#define ERROR_STR "error"
#define NOUPDATE_STR "noupdate"
#define DOWNLOADING_STR "downloading"
#define PROGRESS_STR "progress"
@@ -68,28 +68,29 @@
// To prevent abuse of the resource list for data storage, the number
// of offline urls and their length are limited.
static const char kMaxEntriesPref[] = "offline.max_site_resources";
#define DEFAULT_MAX_ENTRIES 100
#define MAX_URI_LENGTH 2048
-static nsCAutoString gCachedManifestSpec;
+static nsCAutoString gCachedAsciiHost;
static char **gCachedKeys = nsnull;
static PRUint32 gCachedKeysCount = 0;
//
// nsDOMOfflineResourceList
//
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMOfflineResourceList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMOfflineResourceList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCacheSession)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCacheUpdate)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCheckingListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mErrorListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mNoUpdateListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mDownloadingListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mProgressListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCachedListeners)
@@ -108,16 +109,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPendingEvents[i].listener);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPendingEvents[i].listeners);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMOfflineResourceList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCacheSession)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCacheUpdate)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mCheckingListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mErrorListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mNoUpdateListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mDownloadingListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mProgressListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mCachedListeners)
@@ -174,30 +176,46 @@ nsDOMOfflineResourceList::Init()
if (mInitialized) {
return NS_OK;
}
if (!mManifestURI) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
- mManifestURI->GetAsciiSpec(mManifestSpec);
-
nsresult rv = nsContentUtils::GetSecurityManager()->
CheckSameOriginURI(mManifestURI, mDocumentURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// Dynamically-managed resources are stored as a separate ownership list
// from the manifest.
+ rv = mManifestURI->GetAsciiSpec(mDynamicOwnerSpec);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mDynamicOwnerSpec.Append("#dynamic");
+
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(mDocumentURI);
if (!innerURI)
return NS_ERROR_FAILURE;
- mApplicationCacheService =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
+ rv = innerURI->GetAsciiHost(mAsciiHost);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsICacheService> serv = do_GetService(NS_CACHESERVICE_CONTRACTID,
+ &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsICacheSession> session;
+ rv = serv->CreateSession("HTTP-offline",
+ nsICache::STORE_OFFLINE,
+ nsICache::STREAM_BASED,
+ getter_AddRefs(session));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mCacheSession = do_QueryInterface(session, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Check for in-progress cache updates
nsCOMPtr<nsIOfflineCacheUpdateService> cacheUpdateService =
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 numUpdates;
@@ -296,21 +314,16 @@ nsDOMOfflineResourceList::Add(const nsAS
{
nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv);
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
- nsCOMPtr<nsIApplicationCache> appCache = GetDocumentAppCache();
- if (!appCache) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
if (aURI.Length() > MAX_URI_LENGTH) return NS_ERROR_DOM_BAD_URI;
// this will fail if the URI is not absolute
nsCOMPtr<nsIURI> requestedURI;
rv = NS_NewURI(getter_AddRefs(requestedURI), aURI);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString scheme;
@@ -356,79 +369,59 @@ nsDOMOfflineResourceList::Remove(const n
{
nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv);
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
- nsCOMPtr<nsIApplicationCache> appCache = GetDocumentAppCache();
- if (!appCache) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
nsCAutoString key;
rv = GetCacheKey(aURI, key);
NS_ENSURE_SUCCESS(rv, rv);
ClearCachedKeys();
- // XXX: This is a race condition. remove() is specced to remove
- // from the currently associated application cache, but if this
- // happens during an update (or after an update, if we haven't
- // swapped yet), that remove() will be lost when the next update is
- // finished. Need to bring this issue up.
+ rv = mCacheSession->RemoveOwnedKey(mAsciiHost, mDynamicOwnerSpec, key);
+ NS_ENSURE_SUCCESS(rv, rv);
- rv = appCache->UnmarkEntry(key, nsIApplicationCache::ITEM_DYNAMIC);
+ rv = mCacheSession->EvictUnownedEntries();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsDOMOfflineResourceList::GetStatus(PRUint16 *aStatus)
{
nsresult rv = Init();
- // Init may fail with INVALID_STATE_ERR if there is no manifest URI.
- // The status attribute should not throw that exception, convert it
- // to an UNCACHED.
- if (rv == NS_ERROR_DOM_INVALID_STATE_ERR ||
- !nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
+ // It is OK to check the status without a manifest attribute (you'll
+ // just get "uncached").
+ if (rv == NS_ERROR_DOM_INVALID_STATE_ERR && !mManifestURI) {
*aStatus = nsIDOMOfflineResourceList::UNCACHED;
return NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
- // If there is an update in process, use its status.
if (mCacheUpdate) {
- rv = mCacheUpdate->GetStatus(aStatus);
- if (NS_SUCCEEDED(rv) && *aStatus != nsIDOMOfflineResourceList::IDLE) {
- return NS_OK;
- }
+ return mCacheUpdate->GetStatus(aStatus);
}
- // If this object is not associated with a cache, return UNCACHED
- nsCOMPtr<nsIApplicationCache> appCache = GetDocumentAppCache();
- if (!appCache) {
- *aStatus = nsIDOMOfflineResourceList::UNCACHED;
- return NS_OK;
- }
+ // XXX: the spec allows either UNCACHED or IDLE, depending on whether
+ // the application is associated with a specific offline cache. Until
+ // we have versioned application caches, the best approximation is
+ // probably IDLE if the offline-app permission is set, and UNCACHED
+ // otherwise.
- nsCOMPtr<nsIApplicationCache> activeCache;
- rv = mApplicationCacheService->GetActiveCache(mManifestSpec,
- getter_AddRefs(activeCache));
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (appCache == activeCache) {
+ if (nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
*aStatus = nsIDOMOfflineResourceList::IDLE;
} else {
- *aStatus = nsIDOMOfflineResourceList::UPDATEREADY;
+ *aStatus = nsIDOMOfflineResourceList::UNCACHED;
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMOfflineResourceList::Update()
{
@@ -456,45 +449,17 @@ nsDOMOfflineResourceList::SwapCache()
{
nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv);
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
- if (!mToplevel) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
- nsCOMPtr<nsIApplicationCacheService> serv =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIApplicationCache> currentAppCache = GetDocumentAppCache();
-
- nsCOMPtr<nsIApplicationCache> newAppCache;
- rv = serv->GetActiveCache(mManifestSpec, getter_AddRefs(newAppCache));
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!newAppCache || newAppCache == currentAppCache) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
- ClearCachedKeys();
-
- nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
- GetDocumentAppCacheContainer();
-
- if (appCacheContainer) {
- rv = appCacheContainer->SetApplicationCache(newAppCache);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
//
// nsDOMOfflineResourceList::nsIDOMEventTarget
//
NS_IMETHODIMP
nsDOMOfflineResourceList::GetOnchecking(nsIDOMEventListener **aOnchecking)
@@ -974,35 +939,30 @@ nsDOMOfflineResourceList::UpdateAdded(ns
nsresult
nsDOMOfflineResourceList::UpdateCompleted(nsIOfflineCacheUpdate *aUpdate)
{
if (aUpdate != mCacheUpdate) {
// This isn't the update we're watching.
return NS_OK;
}
- PRBool partial;
- mCacheUpdate->GetPartial(&partial);
- PRBool isUpgrade;
- mCacheUpdate->GetIsUpgrade(&isUpgrade);
-
PRBool succeeded;
nsresult rv = mCacheUpdate->GetSucceeded(&succeeded);
mCacheUpdate->RemoveObserver(this);
mCacheUpdate = nsnull;
- if (NS_SUCCEEDED(rv) && succeeded && !partial) {
- if (isUpgrade) {
- SendEvent(NS_LITERAL_STRING(UPDATEREADY_STR),
- mOnUpdateReadyListener, mUpdateReadyListeners);
- } else {
- SendEvent(NS_LITERAL_STRING(CACHED_STR),
- mOnCachedListener, mCachedListeners);
- }
+ if (NS_SUCCEEDED(rv) && succeeded) {
+ // XXX: the spec requires a "cached" event to be sent if this is a
+ // first-time cache attempt, and "updateready" if this page was loaded
+ // from an existing application cache. Since we don't have versioned
+ // application caches yet, basically each update acts like a first-time
+ // update, so we'll always fire "cached" for now.
+ SendEvent(NS_LITERAL_STRING(CACHED_STR),
+ mOnCachedListener, mCachedListeners);
}
return NS_OK;
}
nsresult
nsDOMOfflineResourceList::GetCacheKey(nsIURI *aURI, nsCString &aKey)
{
@@ -1016,79 +976,39 @@ nsDOMOfflineResourceList::GetCacheKey(ns
if (FindCharInReadable('#', specStart, specEnd)) {
aKey.BeginReading(specEnd);
aKey = Substring(specEnd, specStart);
}
return NS_OK;
}
-already_AddRefed<nsIApplicationCacheContainer>
-nsDOMOfflineResourceList::GetDocumentAppCacheContainer()
-{
- nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
- if (!window) {
- return nsnull;
- }
-
- nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(window);
- if (!webnav) {
- return nsnull;
- }
-
- nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
- do_GetInterface(webnav);
- return appCacheContainer.forget();
-}
-
-already_AddRefed<nsIApplicationCache>
-nsDOMOfflineResourceList::GetDocumentAppCache()
-{
- nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
- GetDocumentAppCacheContainer();
-
- if (appCacheContainer) {
- nsCOMPtr<nsIApplicationCache> applicationCache;
- appCacheContainer->GetApplicationCache(
- getter_AddRefs(applicationCache));
- return applicationCache.forget();
- }
-
- return nsnull;
-}
-
nsresult
nsDOMOfflineResourceList::CacheKeys()
{
- if (gCachedKeys && mManifestSpec == gCachedManifestSpec)
+ if (gCachedKeys && mAsciiHost == gCachedAsciiHost)
return NS_OK;
ClearCachedKeys();
- nsCOMPtr<nsIApplicationCache> appCache;
- mApplicationCacheService->GetActiveCache(mManifestSpec,
- getter_AddRefs(appCache));
-
- if (!appCache) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
- nsresult rv = appCache->GatherEntries(nsIApplicationCache::ITEM_DYNAMIC,
- &gCachedKeysCount, &gCachedKeys);
+ nsresult rv = mCacheSession->GetOwnedKeys(mAsciiHost, mDynamicOwnerSpec,
+ &gCachedKeysCount, &gCachedKeys);
if (NS_SUCCEEDED(rv))
- gCachedManifestSpec = mManifestSpec;
+ gCachedAsciiHost = mAsciiHost;
return rv;
}
void
nsDOMOfflineResourceList::ClearCachedKeys()
{
if (gCachedKeys) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(gCachedKeysCount, gCachedKeys);
gCachedKeys = nsnull;
gCachedKeysCount = 0;
}
- gCachedManifestSpec = "";
+ gCachedAsciiHost = "";
}
+
+
--- a/dom/src/offline/nsDOMOfflineResourceList.h
+++ b/dom/src/offline/nsDOMOfflineResourceList.h
@@ -36,19 +36,17 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDOMOfflineResourceList_h___
#define nsDOMOfflineResourceList_h___
#include "nscore.h"
#include "nsIDOMOfflineResourceList.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheContainer.h"
-#include "nsIApplicationCacheService.h"
+#include "nsIOfflineCacheSession.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsWeakReference.h"
#include "nsCOMArray.h"
#include "nsIDOMEventListener.h"
@@ -94,36 +92,31 @@ private:
nsresult SendEvent(const nsAString &aEventName,
nsIDOMEventListener *aListener,
const nsCOMArray<nsIDOMEventListener> &aListeners);
nsresult UpdateAdded(nsIOfflineCacheUpdate *aUpdate);
nsresult UpdateCompleted(nsIOfflineCacheUpdate *aUpdate);
- already_AddRefed<nsIApplicationCacheContainer> GetDocumentAppCacheContainer();
- already_AddRefed<nsIApplicationCache> GetDocumentAppCache();
-
nsresult GetCacheKey(const nsAString &aURI, nsCString &aKey);
nsresult GetCacheKey(nsIURI *aURI, nsCString &aKey);
nsresult CacheKeys();
void ClearCachedKeys();
PRBool mInitialized;
PRBool mToplevel;
-
nsCOMPtr<nsIURI> mManifestURI;
- // AsciiSpec of mManifestURI
- nsCString mManifestSpec;
-
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIWeakReference> mWindow;
- nsCOMPtr<nsIApplicationCacheService> mApplicationCacheService;
+ nsCOMPtr<nsIOfflineCacheSession> mCacheSession;
nsCOMPtr<nsIOfflineCacheUpdate> mCacheUpdate;
+ nsCAutoString mAsciiHost;
+ nsCAutoString mDynamicOwnerSpec;
nsCOMArray<nsIDOMEventListener> mCheckingListeners;
nsCOMArray<nsIDOMEventListener> mErrorListeners;
nsCOMArray<nsIDOMEventListener> mNoUpdateListeners;
nsCOMArray<nsIDOMEventListener> mDownloadingListeners;
nsCOMArray<nsIDOMEventListener> mProgressListeners;
nsCOMArray<nsIDOMEventListener> mCachedListeners;
nsCOMArray<nsIDOMEventListener> mUpdateReadyListeners;
--- a/dom/tests/mochitest/ajax/offline/offlineTests.js
+++ b/dom/tests/mochitest/ajax/offline/offlineTests.js
@@ -46,19 +46,24 @@ fetch: function(callback)
if (this.urls.length == 0) {
callback(this.contents);
return;
}
var url = this.urls.shift();
var self = this;
- var cacheSession = OfflineTest.getActiveSession();
+ var cacheService = Cc["@mozilla.org/network/cache-service;1"]
+ .getService(Ci.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Ci.nsICache.STORE_OFFLINE,
+ true);
cacheSession.asyncOpenCacheEntry(url, Ci.nsICache.ACCESS_READ, this);
}
+
};
var OfflineTest = {
_slaveWindow: null,
// The window where test results should be sent.
_masterWindow: null,
@@ -157,37 +162,57 @@ is: function(a, b, name)
isnot: function(a, b, name)
{
return this._masterWindow.SimpleTest.isnot(a, b, name);
},
clear: function()
{
- // XXX: maybe we should just wipe out the entire disk cache.
- var appCacheService = Cc["@mozilla.org/network/application-cache-service;1"]
- .getService(Ci.nsIApplicationCacheService);
- var applicationCache = this.getActiveCache();
- if (applicationCache) {
- applicationCache.discard();
- }
+ // Clear the ownership list
+ var cacheService = Cc["@mozilla.org/network/cache-service;1"]
+ .getService(Ci.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Ci.nsICache.STORE_OFFLINE,
+ true)
+ .QueryInterface(Ci.nsIOfflineCacheSession);
+
+ // Get the asciiHost from the page URL
+ var locationURI = Cc["@mozilla.org/network/standard-url;1"]
+ .createInstance(Ci.nsIURI);
+ locationURI.spec = window.location.href;
+ var asciiHost = locationURI.asciiHost;
+
+ // Clear manifest-owned urls
+ cacheSession.setOwnedKeys(asciiHost,
+ this.getManifestUrl() + "#manifest", 0, []);
+
+ // Clear dynamically-owned urls
+ cacheSession.setOwnedKeys(asciiHost,
+ this.getManifestUrl() + "#dynamic", 0, []);
+
+ cacheSession.evictUnownedEntries();
},
failEvent: function(e)
{
OfflineTest.ok(false, "Unexpected event: " + e.type);
},
// The offline API as specified has no way to watch the load of a resource
// added with applicationCache.add().
waitForAdd: function(url, onFinished) {
// Check every half second for ten seconds.
var numChecks = 20;
var waitFunc = function() {
- var cacheSession = OfflineTest.getActiveSession();
+ var cacheService = Cc["@mozilla.org/network/cache-service;1"]
+ .getService(Ci.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Ci.nsICache.STORE_OFFLINE,
+ true);
var entry;
try {
var entry = cacheSession.openCacheEntry(url, Ci.nsICache.ACCESS_READ, true);
} catch (e) {
}
if (entry) {
entry.close();
@@ -206,74 +231,48 @@ waitForAdd: function(url, onFinished) {
setTimeout(this.priv(waitFunc), 500);
},
getManifestUrl: function()
{
return window.top.document.documentElement.getAttribute("manifest");
},
-getActiveCache: function()
-{
- // Note that this is the current active cache in the cache stack, not the
- // one associated with this window.
- var serv = Cc["@mozilla.org/network/application-cache-service;1"]
- .getService(Ci.nsIApplicationCacheService);
- return serv.getActiveCache(this.getManifestUrl());
-},
-
-getActiveSession: function()
-{
- var cache = this.getActiveCache();
- if (!cache) return null;
-
- var cacheService = Cc["@mozilla.org/network/cache-service;1"]
- .getService(Ci.nsICacheService);
- return cacheService.createSession(cache.clientID,
- Ci.nsICache.STORE_OFFLINE,
- true);
-},
-
priv: function(func)
{
var self = this;
return function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
func(arguments);
}
},
checkCache: function(url, expectEntry)
{
- var cacheSession = this.getActiveSession();
- if (!cacheSession) {
- if (expectEntry) {
- this.ok(false, url + " should exist in the offline cache");
- } else {
- this.ok(true, url + " should not exist in the offline cache");
- }
- return;
- }
-
+ var cacheService = Cc["@mozilla.org/network/cache-service;1"]
+ .getService(Ci.nsICacheService);
+ var cacheSession = cacheService.createSession("HTTP-offline",
+ Ci.nsICache.STORE_OFFLINE,
+ true);
try {
var entry = cacheSession.openCacheEntry(url, Ci.nsICache.ACCESS_READ, false);
if (expectEntry) {
this.ok(true, url + " should exist in the offline cache");
} else {
this.ok(false, url + " should not exist in the offline cache");
}
entry.close();
} catch (e) {
if (e.result == NS_ERROR_CACHE_KEY_NOT_FOUND) {
if (expectEntry) {
this.ok(false, url + " should exist in the offline cache");
} else {
this.ok(true, url + " should not exist in the offline cache");
}
- } else if (e.result == NS_ERROR_CACHE_KEY_WAIT_FOR_VALIDATION) {
+ } else if (e.result == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
// There was a cache key that we couldn't access yet, that's good enough.
if (expectEntry) {
this.ok(true, url + " should exist in the offline cache");
} else {
this.ok(false, url + " should not exist in the offline cache");
}
} else {
throw e;
--- a/dom/tests/mochitest/ajax/offline/test_changingManifest.html
+++ b/dom/tests/mochitest/ajax/offline/test_changingManifest.html
@@ -46,19 +46,18 @@ function manifestUpdated()
OfflineTest.ok(gGotDownloading, "Should get a downloading event");
// Get the initial contents of the first two files.
fetcher = new OfflineCacheContents([g1SecUrl, g1HourUrl]);
fetcher.fetch(function(contents) {
gCacheContents = contents;
// Now make sure applicationCache.update() does what we expect.
- applicationCache.onupdateready = OfflineTest.priv(manifestUpdatedAgain);
+ applicationCache.oncached = OfflineTest.priv(manifestUpdatedAgain);
applicationCache.onnoupdate = failAndFinish;
- applicationCache.oncached = failAndFinish;
gGotChecking = false;
gGotDownloading = false;
// The changing versions give out a new version each second,
// make sure it has time to grab a new version, and for the
// 1-second cache timeout to pass.
window.setTimeout("applicationCache.update()", 5000);
--- a/dom/tests/mochitest/ajax/offline/test_simpleManifest.html
+++ b/dom/tests/mochitest/ajax/offline/test_simpleManifest.html
@@ -31,16 +31,36 @@ function addFinished()
// We're done
OfflineTest.teardown();
OfflineTest.finish();
}
+function secondUpdate()
+{
+ OfflineTest.ok(gGotChecking, "Should get a checking event");
+ OfflineTest.ok(gGotDownloading, "Should get a downloading event");
+
+ // The document that requested the manifest should be in the cache
+ OfflineTest.checkCache(window.location.href, true);
+
+ OfflineTest.checkCache("http://localhost:8888/tests/SimpleTest/SimpleTest.js", true);
+ OfflineTest.checkCache("http://localhost:8888/MochiKit/packed.js", true);
+ OfflineTest.checkCache("http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/offlineTests.js", true);
+
+ // Now add a file using the applicationCache API
+ applicationCache.add("http://localhost:8888/tests/SimpleTest/EventUtils.js");
+
+ // Wait for the add() to be downloaded
+ OfflineTest.waitForAdd("http://localhost:8888/tests/SimpleTest/EventUtils.js",
+ OfflineTest.priv(addFinished));
+}
+
function manifestUpdated()
{
OfflineTest.ok(gGotChecking, "Should get a checking event");
OfflineTest.ok(gGotDownloading, "Should get a downloading event");
// The manifest itself should be in the cache
OfflineTest.checkCache("http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/simpleManifest.cacheManifest", true);
@@ -51,28 +71,36 @@ function manifestUpdated()
OfflineTest.checkCache("http://localhost:8888/tests/SimpleTest/SimpleTest.js", true);
OfflineTest.checkCache("http://localhost:8888/MochiKit/packed.js", true);
OfflineTest.checkCache("http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/offlineTests.js", true);
// The bad entries from the manifest should not be in the cache
OfflineTest.checkCache("https://localhost:8888/MochiKit/packed.js", false);
OfflineTest.checkCache("bad:/uri/invalid", false);
- applicationCache.swapCache();
+ // Remove items from the cache.
+ OfflineTest.clear();
- // XXX: make sure that the previous version went away after the swapCache().
+ // Make sure OfflineTest.clear() properly removed the items
- // Now add a file using the applicationCache API
- applicationCache.add("http://localhost:8888/tests/SimpleTest/EventUtils.js");
+ OfflineTest.checkCache("http://localhost:8888/tests/SimpleTest/SimpleTest.js", false);
+ OfflineTest.checkCache("http://localhost:8888/MochiKit/packed.js", false);
+ OfflineTest.checkCache("http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/offlineTests.js", false);
+ OfflineTest.checkCache("http://localhost:8888/tests/SimpleTest/EventUtils.js",
+ false);
- // Wait for the add() to be downloaded
- OfflineTest.waitForAdd("http://localhost:8888/tests/SimpleTest/EventUtils.js",
- OfflineTest.priv(addFinished));
+ // Now make sure applicationCache.update() does what we expect.
+ applicationCache.oncached = OfflineTest.priv(secondUpdate);
+
+ gGotChecking = false;
+ gGotDownloading = false;
+ applicationCache.update();
}
+
if (OfflineTest.setup()) {
OfflineTest.ok(applicationCache instanceof EventTarget,
"applicationCache should be an event target");
applicationCache.onerror = OfflineTest.failEvent;
applicationCache.addEventListener("checking", function() {
OfflineTest.is(applicationCache.status, 2, "CHECKING state while checking");
--- a/netwerk/base/public/Makefile.in
+++ b/netwerk/base/public/Makefile.in
@@ -56,19 +56,16 @@ SDK_XPIDLSRCS = \
nsIURI.idl \
nsIURL.idl \
nsIFileURL.idl \
nsIUploadChannel.idl \
nsIUnicharStreamListener.idl \
$(NULL)
XPIDLSRCS = \
- nsIApplicationCache.idl \
- nsIApplicationCacheContainer.idl \
- nsIApplicationCacheService.idl \
nsIAuthInformation.idl \
nsIAuthPrompt.idl \
nsIAuthPrompt2.idl \
nsIAuthPromptAdapterFactory.idl \
nsIAuthPromptCallback.idl \
nsIAsyncStreamCopier.idl \
nsISafeOutputStream.idl \
nsIBufferedStreams.idl \
deleted file mode 100644
--- a/netwerk/base/public/nsIApplicationCache.idl
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is nsIApplicationCache.idl.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dave Camp <dcamp@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-/**
- * Application caches store resources for offline use. Each
- * application cache has a unique client ID for use with
- * nsICacheService::openSession() to access the cache's entries.
- *
- * Each entry in the application cache can be marked with a set of
- * types, as discussed in the WHAT-WG offline applications
- * specification.
- *
- * All application caches with the same group ID belong to a cache
- * group. Each group has one "active" cache that will service future
- * loads. Inactive caches will be removed from the cache when they are
- * no longer referenced.
- */
-[scriptable, uuid(a9cfbeef-8f8d-49c3-b899-303390383ae9)]
-interface nsIApplicationCache : nsISupports
-{
- /**
- * Entries in an application cache can be marked as one or more of
- * the following types.
- */
-
- /* This item is the application manifest. */
- const unsigned long ITEM_MANIFEST = 1 << 0;
-
- /* This item was explicitly listed in the application manifest. */
- const unsigned long ITEM_EXPLICIT = 1 << 1;
-
- /* This item was navigated in a toplevel browsing context, and
- * named this cache's group as its manifest. */
- const unsigned long ITEM_IMPLICIT = 1 << 2;
-
- /* This item was added by the dynamic scripting API */
- const unsigned long ITEM_DYNAMIC = 1 << 3;
-
- /* This item was listed in the application manifest, but named a
- * different cache group as its manifest. */
- const unsigned long ITEM_FOREIGN = 1 << 4;
-
- /* This item was listed as a fallback entry. */
- const unsigned long ITEM_FALLBACK = 1 << 5;
-
- /* This item matched an opportunistic cache namespace and was
- * cached accordingly. */
- const unsigned long ITEM_OPPORTUNISTIC = 1 << 6;
-
- /**
- * The group ID for this cache group. This is the URI of the
- * manifest file.
- **/
- readonly attribute ACString groupID;
-
- /**
- * The client ID for this application cache. Clients can open a
- * session with nsICacheService::createSession() using this client
- * ID and a storage policy of STORE_OFFLINE to access this cache.
- */
- readonly attribute ACString clientID;
-
- /**
- * TRUE if the cache is the active cache for this group.
- */
- readonly attribute boolean active;
-
- /**
- * Makes this cache the active application cache for this group.
- * Future loads associated with this group will come from this
- * cache. Other caches from this cache group will be deactivated.
- */
- void activate();
-
- /**
- * Discard this application cache. Removes all cached resources
- * for this cache. If this is the active application cache for the
- * group, the group will be removed.
- */
- void discard();
-
- /**
- * Adds item types to a given entry.
- */
- void markEntry(in ACString key, in unsigned long typeBits);
-
- /**
- * Removes types from a given entry. If the resulting entry has
- * no types left, the entry is removed.
- */
- void unmarkEntry(in ACString key, in unsigned long typeBits);
-
- /**
- * Gets the types for a given entry.
- */
- unsigned long getTypes(in ACString key);
-
- /**
- * Returns any entries in the application cache whose type matches
- * one or more of the bits in typeBits.
- */
- void gatherEntries(in PRUint32 typeBits,
- out unsigned long count,
- [array, size_is(count)] out string keys);
-};
deleted file mode 100644
--- a/netwerk/base/public/nsIApplicationCacheContainer.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is nsIApplicationCache.idl.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dave Camp <dcamp@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-interface nsIApplicationCache;
-
-/**
- * Interface used by objects that can be associated with an
- * application cache.
- */
-[scriptable, uuid(bbb80700-1f7f-4258-aff4-1743cc5a7d23)]
-interface nsIApplicationCacheContainer : nsISupports
-{
- attribute nsIApplicationCache applicationCache;
-};
deleted file mode 100644
--- a/netwerk/base/public/nsIApplicationCacheService.idl
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is nsIApplicationCache.idl.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dave Camp <dcamp@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-interface nsIApplicationCache;
-
-/**
- * The application cache service manages the set of application cache
- * groups.
- */
-[scriptable, uuid(3f411c68-0d17-420d-839a-6355eea877b9)]
-interface nsIApplicationCacheService : nsISupports
-{
- /**
- * Create a new, empty application cache for the given cache
- * group.
- */
- nsIApplicationCache createApplicationCache(in ACString group);
-
- /**
- * Get an application cache object for the given client ID.
- */
- nsIApplicationCache getApplicationCache(in ACString clientID);
-
- /**
- * Get the currently active cache object for a cache group.
- */
- nsIApplicationCache getActiveCache(in ACString group);
-
- /**
- * Try to find the best application cache to serve a resource.
- */
- nsIApplicationCache chooseApplicationCache(in ACString key);
-};
--- a/netwerk/base/public/nsINetUtil.idl
+++ b/netwerk/base/public/nsINetUtil.idl
@@ -36,17 +36,16 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIURI;
-interface nsIPrefBranch;
/**
* nsINetUtil provides various network-related utility methods.
*/
[scriptable, uuid(57322c6f-f4ec-4e46-8253-b74be220de16)]
interface nsINetUtil : nsISupports
{
/**
@@ -216,30 +215,8 @@ interface nsINetUtil : nsISupports
* cases when parseContentType would claim to have a charset, if the type
* that won out does not have a charset parameter specified.
*/
boolean extractCharsetFromContentType(in AUTF8String aTypeHeader,
out AUTF8String aCharset,
out long aCharsetStart,
out long aCharsetEnd);
};
-
-/**
- * nsINetUtil methods added in mozilla 1.9.1.
- *
- * XXX bug 451255: Merge this up in to nsINetUtil as soon as possible.
- */
-[scriptable, uuid(da76ab60-2ec5-4649-84c4-4954a08f6d37)]
-interface nsINetUtil_MOZILLA_1_9_1 : nsISupports
-{
- /**
- * Checks whether a document at the given URI should have access
- * to the offline cache.
- * @param aURI
- * The URI to check
- * @param aPrefBranch
- * The pref branch to use to check the
- * offline-apps.allow_by_default pref. If not specified,
- * the pref service will be used.
- */
- boolean OfflineAppAllowed(in nsIURI aURI,
- in nsIPrefBranch aPrefBranch);
-};
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -1436,33 +1436,9 @@ NS_GetFinalChannelURI(nsIChannel* channe
if (loadFlags & nsIChannel::LOAD_REPLACE) {
return channel->GetURI(uri);
}
return channel->GetOriginalURI(uri);
}
-/**
- * Checks whether a document at the given URI should have access
- * to the offline cache.
- * @param uri
- * The URI to check
- * @param prefBranch
- * The pref branch to use to check the
- * offline-apps.allow_by_default pref. If not specified,
- * the pref service will be used.
- */
-inline PRBool
-NS_OfflineAppAllowed(nsIURI *aURI, nsIPrefBranch *aPrefBranch = nsnull)
-{
- nsresult rv;
- nsCOMPtr<nsINetUtil_MOZILLA_1_9_1> util = do_GetIOService(&rv);
- NS_ENSURE_SUCCESS(rv, PR_FALSE);
-
- PRBool allowed;
- rv = util->OfflineAppAllowed(aURI, aPrefBranch, &allowed);
- NS_ENSURE_SUCCESS(rv, PR_FALSE);
-
- return allowed;
-}
-
#endif // !nsNetUtil_h__
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -65,17 +65,16 @@
#include "nsEscape.h"
#include "nsNetCID.h"
#include "nsIRecyclingAllocator.h"
#include "nsISocketTransport.h"
#include "nsCRT.h"
#include "nsINestedURI.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
-#include "nsIPermissionManager.h"
#if defined(XP_WIN)
#include "nsNativeConnectionHelper.h"
#endif
#define PORT_PREF_PREFIX "network.security.ports."
#define PORT_PREF(x) PORT_PREF_PREFIX x
#define AUTODIAL_PREF "network.autodial-helper.enabled"
@@ -274,23 +273,22 @@ nsIOService::GetInstance() {
return nsnull;
}
return gIOService;
}
NS_ADDREF(gIOService);
return gIOService;
}
-NS_IMPL_THREADSAFE_ISUPPORTS6(nsIOService,
+NS_IMPL_THREADSAFE_ISUPPORTS5(nsIOService,
nsIIOService,
nsIIOService2,
nsINetUtil,
nsIObserver,
- nsISupportsWeakReference,
- nsINetUtil_MOZILLA_1_9_1)
+ nsISupportsWeakReference)
////////////////////////////////////////////////////////////////////////////////
nsresult
nsIOService::OnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
PRUint32 flags)
{
nsCOMPtr<nsIChannelEventSink> sink =
@@ -980,63 +978,8 @@ nsIOService::ExtractCharsetFromContentTy
net_ParseContentType(aTypeHeader, ignored, aCharset, aHadCharset,
aCharsetStart, aCharsetEnd);
if (*aHadCharset && *aCharsetStart == *aCharsetEnd) {
*aHadCharset = PR_FALSE;
}
return NS_OK;
}
-NS_IMETHODIMP
-nsIOService::OfflineAppAllowed(nsIURI *aURI,
- nsIPrefBranch *aPrefBranch,
- PRBool *aAllowed)
-{
- *aAllowed = PR_FALSE;
-
- nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
- if (!innerURI)
- return NS_OK;
-
- // only http and https applications can use offline APIs.
- PRBool match;
- nsresult rv = innerURI->SchemeIs("http", &match);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!match) {
- rv = innerURI->SchemeIs("https", &match);
- NS_ENSURE_SUCCESS(rv, rv);
- if (!match) {
- return NS_OK;
- }
- }
-
- nsCOMPtr<nsIPermissionManager> permissionManager =
- do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
- if (!permissionManager) {
- return NS_OK;
- }
-
- PRUint32 perm;
- permissionManager->TestExactPermission(innerURI, "offline-app", &perm);
-
- if (perm == nsIPermissionManager::UNKNOWN_ACTION) {
- nsCOMPtr<nsIPrefBranch> branch = aPrefBranch;
- if (!branch) {
- branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
- }
- if (branch) {
- rv = branch->GetBoolPref("offline-apps.allow_by_default", aAllowed);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
- }
-
- if (perm == nsIPermissionManager::DENY_ACTION) {
- return NS_OK;
- }
-
- *aAllowed = PR_TRUE;
-
- return NS_OK;
-}
-
--- a/netwerk/base/src/nsIOService.h
+++ b/netwerk/base/src/nsIOService.h
@@ -72,26 +72,24 @@ static const char gScheme[][sizeof("reso
{"chrome", "file", "http", "jar", "resource"};
class nsIPrefBranch;
class nsIPrefBranch2;
class nsIOService : public nsIIOService2
, public nsIObserver
, public nsINetUtil
- , public nsINetUtil_MOZILLA_1_9_1
, public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIOSERVICE
NS_DECL_NSIIOSERVICE2
NS_DECL_NSIOBSERVER
NS_DECL_NSINETUTIL
- NS_DECL_NSINETUTIL_MOZILLA_1_9_1
// Gets the singleton instance of the IO Service, creating it as needed
// Returns nsnull on out of memory or failure to initialize.
// Returns an addrefed pointer.
static nsIOService* GetInstance();
NS_HIDDEN_(nsresult) Init();
NS_HIDDEN_(nsresult) NewURI(const char* aSpec, nsIURI* aBaseURI,
--- a/netwerk/build/Makefile.in
+++ b/netwerk/build/Makefile.in
@@ -108,21 +108,16 @@ endif
ifdef NECKO_COOKIES
SHARED_LIBRARY_LIBS += \
../cookie/src/$(LIB_PREFIX)neckocookie_s.$(LIB_SUFFIX) \
$(NULL)
LOCAL_INCLUDES += -I$(srcdir)/../cookie/src
endif
-ifdef MOZ_STORAGE
-REQUIRES += storage
-DEFINES += -DNECKO_OFFLINE_CACHE
-endif
-
EXTRA_DSO_LDOPTS = \
$(LIBS_DIR) \
$(EXTRA_DSO_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(ZLIB_LIBS) \
$(NULL)
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -460,28 +460,16 @@
#define NS_CACHESERVICE_CID \
{ /* 6c84aec9-29a5-4264-8fbc-bee8f922ea67 */ \
0x6c84aec9, \
0x29a5, \
0x4264, \
{0x8f, 0xbc, 0xbe, 0xe8, 0xf9, 0x22, 0xea, 0x67} \
}
-// service implementing nsIApplicationCacheService.
-#define NS_APPLICATIONCACHESERVICE_CLASSNAME \
- "nsApplicationCacheService"
-#define NS_APPLICATIONCACHESERVICE_CONTRACTID \
- "@mozilla.org/network/application-cache-service;1"
-#define NS_APPLICATIONCACHESERVICE_CID \
-{ /* 02bf7a2a-39d8-4a23-a50c-2cbb085ab7a5 */ \
- 0x02bf7a2a, \
- 0x39d8, \
- 0x4a23, \
- {0xa5, 0x0c, 0x2c, 0xbb, 0x08, 0x5a, 0xb7, 0xa5} \
-}
/******************************************************************************
* netwerk/protocol/http/ classes
*/
#define NS_HTTPPROTOCOLHANDLER_CID \
{ /* 4f47e42e-4d23-4dd3-bfda-eb29255e9ea3 */ \
0x4f47e42e, \
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -51,17 +51,16 @@
#include "nsLoadGroup.h"
#include "nsStreamLoader.h"
#include "nsUnicharStreamLoader.h"
#include "nsFileStreams.h"
#include "nsBufferedStreams.h"
#include "nsMIMEInputStream.h"
#include "nsSOCKSSocketProvider.h"
#include "nsCacheService.h"
-#include "nsDiskCacheDeviceSQL.h"
#include "nsMimeTypes.h"
#include "nsNetStrings.h"
#include "nsNetCID.h"
#if defined(XP_MACOSX)
#define BUILD_APPLEFILE_DECODER 1
#else
@@ -183,21 +182,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAbo
// about
#ifdef NS_BUILD_REFCNT_LOGGING
#include "nsAboutBloat.h"
#endif
#include "nsAboutCache.h"
#include "nsAboutCacheEntry.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutCacheEntry)
#endif
-
-#ifdef NECKO_OFFLINE_CACHE
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheDevice, nsOfflineCacheDevice::GetInstance)
-#endif
-
+
#ifdef NECKO_PROTOCOL_file
// file
#include "nsFileProtocolHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFileProtocolHandler, Init)
#endif
#ifdef NECKO_PROTOCOL_ftp
// ftp
@@ -1045,24 +1040,16 @@ static const nsModuleComponentInfo gNetM
},
{ NS_CACHESERVICE_CLASSNAME,
NS_CACHESERVICE_CID,
NS_CACHESERVICE_CONTRACTID,
nsCacheService::Create
},
-#ifdef NECKO_OFFLINE_CACHE
- { NS_APPLICATIONCACHESERVICE_CLASSNAME,
- NS_APPLICATIONCACHESERVICE_CID,
- NS_APPLICATIONCACHESERVICE_CONTRACTID,
- nsOfflineCacheDeviceConstructor
- },
-#endif
-
#ifdef NECKO_COOKIES
{ NS_COOKIEMANAGER_CLASSNAME,
NS_COOKIEMANAGER_CID,
NS_COOKIEMANAGER_CONTRACTID,
nsCookieServiceConstructor
},
{ NS_COOKIESERVICE_CLASSNAME,
--- a/netwerk/cache/public/Makefile.in
+++ b/netwerk/cache/public/Makefile.in
@@ -48,13 +48,14 @@ include $(DEPTH)/config/autoconf.mk
XPIDLSRCS = \
nsICache.idl \
nsICacheEntryDescriptor.idl \
nsICacheListener.idl \
nsICacheService.idl \
nsICacheSession.idl \
nsICacheVisitor.idl \
+ nsIOfflineCacheSession.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk
DEFINES += -DIMPL_NS_NET
--- a/netwerk/cache/public/nsICacheService.idl
+++ b/netwerk/cache/public/nsICacheService.idl
@@ -81,17 +81,21 @@ interface nsICacheService : nsISupports
void visitEntries(in nsICacheVisitor visitor);
/**
* Evicts all entries in all devices implied by the storage policy.
*/
void evictEntries(in nsCacheStoragePolicy storagePolicy);
/**
- * This method is deprecated and will throw NS_ERROR_NOT_IMPLEMENTED.
+ * Return a unique, temporary cache client ID.
+ *
+ * This is used by the offline cache. The offline cache lets clients
+ * accumulate entries in a temporary client and merge them in as a group
+ * using nsIOfflineCacheSession.mergeTemporaryClient().
*/
ACString createTemporaryClientID(in nsCacheStoragePolicy storagePolicy);
};
%{C++
/**
* Observer service notification that is sent when
* nsICacheService::evictEntries() or nsICacheSession::evictEntries()
new file mode 100644
--- /dev/null
+++ b/netwerk/cache/public/nsIOfflineCacheSession.idl
@@ -0,0 +1,233 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is nsIOfflineCacheSession.idl.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dave Camp <dcamp@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+#include "nsICache.idl"
+
+/**
+ * The offline cache is meant to reliably store resources for
+ * offline use. The expected semantics are:
+ *
+ * a) Once populated, the cache will not evict an application resource
+ * unless explicitly asked.
+ *
+ * b) Resources no longer in use by the application should be evicted.
+ *
+ * c) If the cache fills up, new entries should be rejected rather
+ * than throwing out old ones.
+ *
+ * The offline cache uses domains to concretely represent an
+ * application. It maintains a list of resources to be pinned for
+ * each domain. This list is separate from actual cache
+ * population - the caller is still responsible for placing items
+ * in the cache, and ownership can be declared without a
+ * corresponding entry.
+ *
+ * A key can optionally be associated with a specific URI within
+ * the domain.
+ */
+
+[scriptable, uuid(3a33e268-4175-4440-a933-89d461c86c5f)]
+interface nsIOfflineCacheSession : nsISupports
+{
+ /**
+ * Gets the list of owner domains in the cache.
+ *
+ * @param count
+ * The number of domains returned
+ * @param uris
+ * The domains that own resources in the cache
+ */
+ void getOwnerDomains(out unsigned long count,
+ [array, size_is(count)]out string domains);
+
+ /**
+ * Gets the list of owner URIs associated with a domain.
+ *
+ * @param ownerAsciiDomain
+ * The domain to query
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param count
+ * The number of uris returned
+ * @param uris
+ * The uris in this domain that own resources
+ */
+ void getOwnerURIs(in ACString ownerAsciiDomain,
+ out unsigned long count,
+ [array, size_is(count)]out string uris);
+
+ /**
+ * Sets the resources owned by a given domain/URI pair.
+ *
+ * Setting a list will remove any resources previously owned by this
+ * domain/URI pair.
+ *
+ * A key can be added while there is no associated entry. When
+ * an entry is created with this key, it will be owned by the
+ * domain/URI pair.
+ *
+ * @param ownerAsciiDomain
+ * The domain that owns the resources
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param ownerAsciiKey
+ * The specific key that owns the resources. You may use
+ * ascii encoded URI spec of the owner - nsIURI.asciiSpec.
+ * This can be empty if none specifically owns the resources.
+ * @param count
+ * The number of keys in keys.
+ * @param keys
+ * The keys that the domain/URI pair own. This can be empty to
+ * clear ownership for the domain/URI pair.
+ */
+ void setOwnedKeys(in ACString ownerAsciiDomain,
+ in ACString ownerAsciiKey,
+ in unsigned long count,
+ [array, size_is(count)]in string keys);
+
+ /**
+ * Gets the list of resources owned by a given domain/URI pair.
+ *
+ * @param ownerAsciiDomain
+ * The domain that owns the resources
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param ownerAsciiKey
+ * The specific key that owns the resources. You may use
+ * ascii encoded URI spec of the owner - nsIURI.asciiSpec.
+ * This can be empty if none specifically owns the resources.
+ * @param count
+ * The number of keys in keys.
+ * @param keys
+ * The keys that the domain/URI pair own.
+ */
+ void getOwnedKeys(in ACString ownerAsciiDomain,
+ in ACString ownerAsciiKey,
+ out unsigned long count,
+ [array, size_is(count)]out string keys);
+
+ /**
+ * Adds an owned key to a domain/URI pair.
+ *
+ * A key can be added while there is no associated entry. When
+ * an entry is created with this key, it will be owned by the
+ * domain/URI pair.
+ *
+ * @param ownerAsciiDomain
+ * The domain that owns the resources
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param ownerAsciiKey
+ * The specific key that owns the resources. You may use
+ * ascii encoded URI spec of the owner - nsIURI.asciiSpec.
+ * This can be empty if none specifically owns the resources.
+ * @param key
+ * The key to add.
+ */
+ void addOwnedKey(in ACString ownerAsciiDomain,
+ in ACString ownerAsciiKey,
+ in ACString key);
+
+ /**
+ * Removes an owned key from a domain/URI pair.
+ *
+ * If the key does not exist, an NS_ERROR_NOT_AVAILABLE exception
+ * will be thrown.
+ *
+ * @param ownerAsciiDomain
+ * The domain that owns the resources
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param ownerAsciiKey
+ * The specific key that owns the resources. You may use
+ * ascii encoded URI spec of the owner - nsIURI.asciiSpec.
+ * This can be empty if none specifically owns the resources.
+ * @param key The key to remove.
+ */
+ void removeOwnedKey(in ACString ownerAsciiDomain,
+ in ACString ownerAsciiKey,
+ in ACString key);
+
+ /**
+ * Checks whether a key is owned by a given domain/URI pair.
+ *
+ * @param ownerAsciiDomain
+ * The domain that owns the resources
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ * @param ownerAsciiKey
+ * The specific key that owns the resources. You may use
+ * ascii encoded URI spec of the owner - nsIURI.asciiSpec.
+ * This can be empty if none specifically owns the resources.
+ * @param key The key to check
+ */
+ boolean keyIsOwned(in ACString ownerAsciiDomain,
+ in ACString ownerAsciiKey,
+ in ACString key);
+
+ /**
+ * Remove all keys owned by a domain, including keys owned by
+ * a specific URI.
+ *
+ * @param ownerAsciiDomain
+ * The domain for which keys should be removed
+ * !! IMPORTANT !! : This must be ascii encoded host - nsIURI.asciiHost
+ */
+ void clearKeysOwnedByDomain(in ACString ownerAsciiDomain);
+
+ /**
+ * Get the number of bytes used in the cache by a domain.
+ *
+ * @param domain The domain to check.
+ */
+ unsigned long getDomainUsage(in ACString ownerDomain);
+
+ /**
+ * Evict all entries that are not owned by a domain.
+ */
+ void evictUnownedEntries();
+
+ /**
+ * Merge the items from a temporary clientID in to this client. This lets
+ * offline cache updates accumulate in a temporary client and be moved
+ * in all at once.
+ *
+ * Entries in the temporary client will replace any entries in this client
+ * with the same cache key.
+ *
+ * Ownership lists for a given domain/URI pair from the temporary client
+ * will replace ownership lists for the same domain/URI pair.
+ */
+ void mergeTemporaryClientID(in ACString temporaryClientID);
+};
--- a/netwerk/cache/src/nsCacheService.cpp
+++ b/netwerk/cache/src/nsCacheService.cpp
@@ -658,17 +658,18 @@ nsCacheService::Shutdown()
mMemoryDevice = nsnull;
#ifdef NECKO_DISK_CACHE
delete mDiskDevice;
mDiskDevice = nsnull;
#endif // !NECKO_DISK_CACHE
#ifdef NECKO_OFFLINE_CACHE
- NS_IF_RELEASE(mOfflineDevice);
+ delete mOfflineDevice;
+ mOfflineDevice = nsnull;
#endif // !NECKO_OFFLINE_CACHE
#if defined(NECKO_DISK_CACHE) && defined(PR_LOGGING)
LogCacheStatistics();
#endif
}
}
@@ -823,16 +824,255 @@ nsCacheService::IsStorageEnabledForPolic
if (gService->mEnableOfflineDevice &&
storagePolicy == nsICache::STORE_OFFLINE) {
return PR_TRUE;
}
return PR_FALSE;
}
+
+nsresult nsCacheService::GetOfflineOwnerDomains(nsCacheSession * session,
+ PRUint32 * count,
+ char *** domains)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->GetOwnerDomains(session->ClientID()->get(),
+ count, domains);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+
+nsresult nsCacheService::GetOfflineOwnerURIs(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ PRUint32 * count,
+ char *** uris)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->GetOwnerURIs(session->ClientID()->get(),
+ ownerDomain, count, uris);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult
+nsCacheService::SetOfflineOwnedKeys(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ PRUint32 count,
+ const char ** keys)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->SetOwnedKeys(session->ClientID()->get(),
+ ownerDomain,
+ ownerURI,
+ count,
+ keys);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::GetOfflineOwnedKeys(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ PRUint32 * count,
+ char *** keys)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->GetOwnedKeys(session->ClientID()->get(),
+ ownerDomain,
+ ownerURI,
+ count,
+ keys);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::AddOfflineOwnedKey(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->AddOwnedKey(session->ClientID()->get(),
+ ownerDomain,
+ ownerURI,
+ key);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::RemoveOfflineOwnedKey(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->RemoveOwnedKey(session->ClientID()->get(),
+ ownerDomain,
+ ownerURI,
+ key);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::OfflineKeyIsOwned(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key,
+ PRBool *isOwned)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->KeyIsOwned(session->ClientID()->get(),
+ ownerDomain,
+ ownerURI,
+ key,
+ isOwned);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::ClearOfflineKeysOwnedByDomain(nsCacheSession * session,
+ const nsACString & domain)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->ClearKeysOwnedByDomain(session->ClientID()->get(),
+ domain);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::GetOfflineDomainUsage(nsCacheSession * session,
+ const nsACString & domain,
+ PRUint32 * usage)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->GetDomainUsage(session->ClientID()->get(),
+ domain,
+ usage);
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::EvictUnownedOfflineEntries(nsCacheSession * session)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->EvictUnownedEntries(session->ClientID()->get());
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+nsresult nsCacheService::MergeTemporaryClientID(nsCacheSession * session,
+ const nsACString & clientID)
+{
+#ifdef NECKO_OFFLINE_CACHE
+ if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->MergeTemporaryClientID
+ (session->ClientID()->get(), PromiseFlatCString(clientID).get());
+#else // !NECKO_OFFLINE_CACHE
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
{
NS_ENSURE_ARG_POINTER(visitor);
nsCacheServiceAutoLock lock;
if (!(mEnableDiskDevice || mEnableMemoryDevice))
return NS_ERROR_NOT_AVAILABLE;
@@ -879,17 +1119,30 @@ NS_IMETHODIMP nsCacheService::VisitEntri
NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
{
return EvictEntriesForClient(nsnull, storagePolicy);
}
NS_IMETHODIMP nsCacheService::CreateTemporaryClientID(nsCacheStoragePolicy storagePolicy,
nsACString &clientID)
{
+#ifdef NECKO_OFFLINE_CACHE
+ // Only the offline cache device supports temporary clients
+ if (storagePolicy != nsICache::STORE_OFFLINE)
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (!gService->mOfflineDevice) {
+ nsresult rv = gService->CreateOfflineDevice();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ return gService->mOfflineDevice->CreateTemporaryClientID(clientID);
+#else // !NECKO_OFFLINE_CACHE
return NS_ERROR_NOT_IMPLEMENTED;
+#endif
}
/**
* Internal Methods
*/
nsresult
nsCacheService::CreateDiskDevice()
{
@@ -930,30 +1183,29 @@ nsCacheService::CreateOfflineDevice()
CACHE_LOG_ALWAYS(("Creating offline device"));
if (!mEnableOfflineDevice) return NS_ERROR_NOT_AVAILABLE;
if (mOfflineDevice) return NS_OK;
mOfflineDevice = new nsOfflineCacheDevice;
if (!mOfflineDevice) return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(mOfflineDevice);
-
// set the preferences
mOfflineDevice->SetCacheParentDirectory(
mObserver->OfflineCacheParentDirectory());
mOfflineDevice->SetCapacity(mObserver->OfflineCacheCapacity());
nsresult rv = mOfflineDevice->Init();
if (NS_FAILED(rv)) {
CACHE_LOG_DEBUG(("mOfflineDevice->Init() failed (0x%.8x)\n", rv));
CACHE_LOG_DEBUG((" - disabling offline cache for this session.\n"));
mEnableOfflineDevice = PR_FALSE;
- NS_RELEASE(mOfflineDevice);
+ delete mOfflineDevice;
+ mOfflineDevice = nsnull;
}
return rv;
#else // !NECKO_DISK_CACHE
NS_NOTREACHED("nsCacheService::CreateOfflineDevice");
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
--- a/netwerk/cache/src/nsCacheService.h
+++ b/netwerk/cache/src/nsCacheService.h
@@ -92,16 +92,64 @@ public:
nsICacheListener * listener,
nsICacheEntryDescriptor ** result);
static nsresult EvictEntriesForSession(nsCacheSession * session);
static nsresult IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
PRBool * result);
+
+ static nsresult GetOfflineOwnerDomains(nsCacheSession * session,
+ PRUint32 * count,
+ char *** domains);
+ static nsresult GetOfflineOwnerURIs(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ PRUint32 * count,
+ char *** uris);
+
+ static nsresult SetOfflineOwnedKeys(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerUri,
+ PRUint32 count,
+ const char ** keys);
+
+ static nsresult GetOfflineOwnedKeys(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ PRUint32 * count,
+ char *** keys);
+
+ static nsresult AddOfflineOwnedKey(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key);
+
+ static nsresult RemoveOfflineOwnedKey(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key);
+
+ static nsresult OfflineKeyIsOwned(nsCacheSession * session,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key,
+ PRBool * isOwned);
+
+ static nsresult ClearOfflineKeysOwnedByDomain(nsCacheSession * session,
+ const nsACString & domain);
+ static nsresult GetOfflineDomainUsage(nsCacheSession * session,
+ const nsACString & domain,
+ PRUint32 * usage);
+
+ static nsresult EvictUnownedOfflineEntries(nsCacheSession * session);
+
+ static nsresult MergeTemporaryClientID(nsCacheSession * session,
+ const nsACString & fromClientID);
+
/**
* Methods called by nsCacheEntryDescriptor
*/
static void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
static nsresult GetFileForEntry(nsCacheEntry * entry,
nsIFile ** result);
@@ -155,17 +203,16 @@ public:
static void SetOfflineCacheCapacity(PRInt32 capacity);
static void SetMemoryCache();
nsresult Init();
void Shutdown();
private:
friend class nsCacheServiceAutoLock;
- friend class nsOfflineCacheDevice;
/**
* Internal Methods
*/
static void Lock();
static void Unlock();
--- a/netwerk/cache/src/nsCacheSession.cpp
+++ b/netwerk/cache/src/nsCacheSession.cpp
@@ -39,17 +39,25 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCacheSession.h"
#include "nsCacheService.h"
#include "nsCRT.h"
-NS_IMPL_ISUPPORTS1(nsCacheSession, nsICacheSession)
+NS_IMPL_ADDREF(nsCacheSession)
+NS_IMPL_RELEASE(nsCacheSession)
+
+NS_INTERFACE_MAP_BEGIN(nsCacheSession)
+ NS_INTERFACE_MAP_ENTRY(nsICacheSession)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(
+ nsIOfflineCacheSession, (StoragePolicy() == nsICache::STORE_OFFLINE))
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICacheSession)
+NS_INTERFACE_MAP_END
nsCacheSession::nsCacheSession(const char * clientID,
nsCacheStoragePolicy storagePolicy,
PRBool streamBased)
: mClientID(clientID),
mInfo(0)
{
SetStoragePolicy(storagePolicy);
@@ -122,8 +130,80 @@ NS_IMETHODIMP nsCacheSession::EvictEntri
}
NS_IMETHODIMP nsCacheSession::IsStorageEnabled(PRBool *result)
{
return nsCacheService::IsStorageEnabledForPolicy(StoragePolicy(), result);
}
+
+NS_IMETHODIMP nsCacheSession::GetOwnerDomains(PRUint32 * count,
+ char *** domains)
+{
+ return nsCacheService::GetOfflineOwnerDomains(this, count, domains);
+}
+
+NS_IMETHODIMP nsCacheSession::GetOwnerURIs(const nsACString & domain,
+ PRUint32 * count,
+ char *** uris)
+{
+ return nsCacheService::GetOfflineOwnerURIs(this, domain, count, uris);
+}
+
+NS_IMETHODIMP nsCacheSession::SetOwnedKeys(const nsACString & domain,
+ const nsACString & uri,
+ PRUint32 count,
+ const char ** keys)
+{
+ return nsCacheService::SetOfflineOwnedKeys(this, domain, uri, count, keys);
+}
+
+NS_IMETHODIMP nsCacheSession::GetOwnedKeys(const nsACString & domain,
+ const nsACString & uri,
+ PRUint32 * count,
+ char *** keys)
+{
+ return nsCacheService::GetOfflineOwnedKeys(this, domain, uri, count, keys);
+}
+
+NS_IMETHODIMP nsCacheSession::AddOwnedKey(const nsACString & domain,
+ const nsACString & uri,
+ const nsACString & key)
+{
+ return nsCacheService::AddOfflineOwnedKey(this, domain, uri, key);
+}
+
+NS_IMETHODIMP nsCacheSession::RemoveOwnedKey(const nsACString & domain,
+ const nsACString & uri,
+ const nsACString & key)
+{
+ return nsCacheService::RemoveOfflineOwnedKey(this, domain, uri, key);
+}
+
+NS_IMETHODIMP nsCacheSession::KeyIsOwned(const nsACString & domain,
+ const nsACString & uri,
+ const nsACString & key,
+ PRBool * isOwned)
+{
+ return nsCacheService::OfflineKeyIsOwned(this, domain, uri, key, isOwned);
+}
+
+NS_IMETHODIMP nsCacheSession::ClearKeysOwnedByDomain(const nsACString & domain)
+{
+ return nsCacheService::ClearOfflineKeysOwnedByDomain(this, domain);
+}
+
+NS_IMETHODIMP nsCacheSession::GetDomainUsage(const nsACString & domain,
+ PRUint32 *usage)
+{
+ return nsCacheService::GetOfflineDomainUsage(this, domain, usage);
+}
+
+NS_IMETHODIMP nsCacheSession::EvictUnownedEntries()
+{
+ return nsCacheService::EvictUnownedOfflineEntries(this);
+}
+
+NS_IMETHODIMP nsCacheSession::MergeTemporaryClientID(const nsACString& fromClientID)
+{
+ return nsCacheService::MergeTemporaryClientID(this, fromClientID);
+}
--- a/netwerk/cache/src/nsCacheSession.h
+++ b/netwerk/cache/src/nsCacheSession.h
@@ -41,23 +41,26 @@
* ***** END LICENSE BLOCK ***** */
#ifndef _nsCacheSession_h_
#define _nsCacheSession_h_
#include "nspr.h"
#include "nsError.h"
#include "nsICacheSession.h"
+#include "nsIOfflineCacheSession.h"
#include "nsString.h"
class nsCacheSession : public nsICacheSession
+ , public nsIOfflineCacheSession
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICACHESESSION
+ NS_DECL_NSIOFFLINECACHESESSION
nsCacheSession(const char * clientID, nsCacheStoragePolicy storagePolicy, PRBool streamBased);
virtual ~nsCacheSession();
nsCString * ClientID() { return &mClientID; }
enum SessionInfo {
eStoragePolicyMask = 0x000000FF,
--- a/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp
@@ -38,32 +38,30 @@
#include "nsCache.h"
#include "nsDiskCache.h"
#include "nsDiskCacheDeviceSQL.h"
#include "nsCacheService.h"
#include "nsNetUtil.h"
#include "nsAutoPtr.h"
-#include "nsEscape.h"
#include "nsString.h"
#include "nsPrintfCString.h"
#include "nsCRT.h"
#include "nsIVariant.h"
#include "mozIStorageService.h"
#include "mozIStorageStatement.h"
#include "mozIStorageFunction.h"
#include "mozStorageHelper.h"
#include "nsICacheVisitor.h"
#include "nsISeekableStream.h"
static const char OFFLINE_CACHE_DEVICE_ID[] = { "offline" };
-static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
#define LOG(args) CACHE_LOG_DEBUG(args)
static PRUint32 gNextTemporaryClientID = 0;
/*****************************************************************************
* helpers
*/
@@ -538,153 +536,19 @@ NS_IMETHODIMP
nsOfflineCacheEntryInfo::GetDataSize(PRUint32 *aDataSize)
{
*aDataSize = mRec->dataSize;
return NS_OK;
}
/******************************************************************************
- * nsApplicationCache
- */
-
-class nsApplicationCache : public nsIApplicationCache
- , public nsSupportsWeakReference
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIAPPLICATIONCACHE
-
- nsApplicationCache(nsOfflineCacheDevice *device,
- const nsACString &group,
- const nsACString &clientID);
-
- virtual ~nsApplicationCache();
-
- void MarkInvalid() { mValid = PR_FALSE; }
-
-private:
- nsRefPtr<nsOfflineCacheDevice> mDevice;
- nsCString mGroup;
- nsCString mClientID;
- PRBool mValid;
-};
-
-NS_IMPL_ISUPPORTS2(nsApplicationCache,
- nsIApplicationCache,
- nsISupportsWeakReference)
-
-nsApplicationCache::nsApplicationCache(nsOfflineCacheDevice *device,
- const nsACString &group,
- const nsACString &clientID)
- : mDevice(device)
- , mGroup(group)
- , mClientID(clientID)
- , mValid(PR_TRUE)
-{
-}
-
-nsApplicationCache::~nsApplicationCache()
-{
- mDevice->mCaches.Remove(mClientID);
-
- // If this isn't an active cache anymore, it can be destroyed.
- if (mValid && !mDevice->IsActiveCache(mGroup, mClientID))
- Discard();
-}
-
-NS_IMETHODIMP
-nsApplicationCache::GetGroupID(nsACString &out)
-{
- out = mGroup;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsApplicationCache::GetClientID(nsACString &out)
-{
- out = mClientID;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsApplicationCache::GetActive(PRBool *out)
-{
- *out = mDevice->IsActiveCache(mGroup, mClientID);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsApplicationCache::Activate()
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- mDevice->ActivateCache(mGroup, mClientID);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsApplicationCache::Discard()
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- mValid = PR_FALSE;
-
- if (mDevice->IsActiveCache(mGroup, mClientID))
- {
- mDevice->DeactivateGroup(mGroup);
- }
-
- return mDevice->EvictEntries(mClientID.get());
-}
-
-NS_IMETHODIMP
-nsApplicationCache::MarkEntry(const nsACString &key,
- PRUint32 typeBits)
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- return mDevice->MarkEntry(mClientID, key, typeBits);
-}
-
-
-NS_IMETHODIMP
-nsApplicationCache::UnmarkEntry(const nsACString &key,
- PRUint32 typeBits)
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- return mDevice->UnmarkEntry(mClientID, key, typeBits);
-}
-
-NS_IMETHODIMP
-nsApplicationCache::GetTypes(const nsACString &key,
- PRUint32 *typeBits)
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- return mDevice->GetTypes(mClientID, key, typeBits);
-}
-
-NS_IMETHODIMP
-nsApplicationCache::GatherEntries(PRUint32 typeBits,
- PRUint32 * count,
- char *** keys)
-{
- NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-
- return mDevice->GatherEntries(mClientID, typeBits, count, keys);
-}
-
-/******************************************************************************
* nsOfflineCacheDevice
*/
-NS_IMPL_ISUPPORTS1(nsOfflineCacheDevice, nsIApplicationCacheService)
-
nsOfflineCacheDevice::nsOfflineCacheDevice()
: mDB(nsnull)
, mCacheCapacity(0)
, mDeltaCounter(0)
{
}
nsOfflineCacheDevice::~nsOfflineCacheDevice()
@@ -828,33 +692,16 @@ nsOfflineCacheDevice::DeleteData(nsCache
return binding->mDataFile->Remove(PR_FALSE);
}
/**
* nsCacheDevice implementation
*/
-/* static */
-nsOfflineCacheDevice *
-nsOfflineCacheDevice::GetInstance()
-{
- nsresult rv;
- nsCOMPtr<nsICacheService> serv = do_GetService(kCacheServiceCID, &rv);
- NS_ENSURE_SUCCESS(rv, nsnull);
-
- nsICacheService *iservice = static_cast<nsICacheService*>(serv.get());
- nsCacheService *cacheService = static_cast<nsCacheService*>(iservice);
- rv = cacheService->CreateOfflineDevice();
- NS_ENSURE_SUCCESS(rv, nsnull);
-
- NS_IF_ADDREF(cacheService->mOfflineDevice);
- return cacheService->mOfflineDevice;
-}
-
nsresult
nsOfflineCacheDevice::Init()
{
NS_ENSURE_TRUE(!mDB, NS_ERROR_ALREADY_INITIALIZED);
// SetCacheParentDirectory must have been called
NS_ENSURE_TRUE(mCacheDirectory, NS_ERROR_UNEXPECTED);
@@ -883,187 +730,113 @@ nsOfflineCacheDevice::Init()
// XXX in the future we may wish to verify the schema for moz_cache
// perhaps using "PRAGMA table_info" ?
// build the table
//
// "Generation" is the data file generation number.
// "Flags" is a bit-field indicating the state of the entry.
//
- rv = mDB->ExecuteSimpleSQL(
- NS_LITERAL_CSTRING("CREATE TABLE IF NOT EXISTS moz_cache (\n"
+ mDB->ExecuteSimpleSQL(
+ NS_LITERAL_CSTRING("CREATE TABLE moz_cache (\n"
" ClientID TEXT,\n"
" Key TEXT,\n"
" MetaData BLOB,\n"
" Generation INTEGER,\n"
" Flags INTEGER,\n"
" DataSize INTEGER,\n"
" FetchCount INTEGER,\n"
" LastFetched INTEGER,\n"
" LastModified INTEGER,\n"
- " ExpirationTime INTEGER,\n"
- " ItemType INTEGER DEFAULT 0\n"
+ " ExpirationTime INTEGER\n"
");\n"));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Databases from 1.9.0 don't have the ItemType column. Add the column
- // here, but don't worry about failures (the column probably already exists)
- mDB->ExecuteSimpleSQL(
- NS_LITERAL_CSTRING("ALTER TABLE moz_cache ADD ItemType INTEGER DEFAULT 0"));
+ // maybe the table already exists, so don't bother checking for errors.
- // Create the table for storing cache groups. All actions on
- // moz_cache_groups use the GroupID, so use it as the primary key.
- rv = mDB->ExecuteSimpleSQL(
- NS_LITERAL_CSTRING("CREATE TABLE IF NOT EXISTS moz_cache_groups (\n"
- " GroupID TEXT PRIMARY KEY,\n"
- " ActiveClientID TEXT\n"
+ // build the ownership table
+ mDB->ExecuteSimpleSQL(
+ NS_LITERAL_CSTRING("CREATE TABLE moz_cache_owners (\n"
+ " ClientID TEXT,\n"
+ " Domain TEXT,\n"
+ " URI TEXT,\n"
+ " Key TEXT\n"
");\n"));
- NS_ENSURE_SUCCESS(rv, rv);
+ // maybe the table already exists, so don't bother checking for errors.
- // Databases from 1.9.0 have a moz_cache_index that should be dropped
- rv = mDB->ExecuteSimpleSQL(
- NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_cache_index"));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Key/ClientID pairs should be unique in the database. All queries
- // against moz_cache use the Key (which is also the most unique), so
- // use it as the primary key for this index.
- rv = mDB->ExecuteSimpleSQL(
- NS_LITERAL_CSTRING("CREATE UNIQUE INDEX IF NOT EXISTS "
- " moz_cache_key_clientid_index"
- " ON moz_cache (Key, ClientID);"));
- NS_ENSURE_SUCCESS(rv, rv);
+ mDB->ExecuteSimpleSQL(
+ NS_LITERAL_CSTRING("CREATE UNIQUE INDEX moz_cache_index"
+ " ON moz_cache (ClientID, Key);"));
+ // maybe the index already exists, so don't bother checking for errors.
mEvictionFunction = new nsOfflineCacheEvictionFunction(this);
if (!mEvictionFunction) return NS_ERROR_OUT_OF_MEMORY;
rv = mDB->CreateFunction(NS_LITERAL_CSTRING("cache_eviction_observer"), 2, mEvictionFunction);
NS_ENSURE_SUCCESS(rv, rv);
// create all (most) of our statements up front
struct StatementSql {
nsCOMPtr<mozIStorageStatement> &statement;
const char *sql;
StatementSql (nsCOMPtr<mozIStorageStatement> &aStatement, const char *aSql):
statement (aStatement), sql (aSql) {}
} prepared[] = {
StatementSql ( mStatement_CacheSize, "SELECT Sum(DataSize) from moz_cache;" ),
- // XXX bug 442810: Restore the ability to monitor individual cache usage
- StatementSql ( mStatement_DomainSize, "SELECT 0;"),
+ StatementSql ( mStatement_DomainSize, "SELECT Sum(moz_cache.DataSize) FROM moz_cache INNER JOIN moz_cache_owners ON moz_cache.ClientID=moz_cache_owners.ClientID AND moz_cache.Key = moz_cache_owners.Key WHERE moz_cache.ClientID=? AND moz_cache_owners.Domain=?;" ),
StatementSql ( mStatement_EntryCount, "SELECT count(*) from moz_cache;" ),
StatementSql ( mStatement_UpdateEntry, "UPDATE moz_cache SET MetaData = ?, Flags = ?, DataSize = ?, FetchCount = ?, LastFetched = ?, LastModified = ?, ExpirationTime = ? WHERE ClientID = ? AND Key = ?;" ),
StatementSql ( mStatement_UpdateEntrySize, "UPDATE moz_cache SET DataSize = ? WHERE ClientID = ? AND Key = ?;" ),
StatementSql ( mStatement_UpdateEntryFlags, "UPDATE moz_cache SET Flags = ? WHERE ClientID = ? AND Key = ?;" ),
StatementSql ( mStatement_DeleteEntry, "DELETE FROM moz_cache WHERE ClientID = ? AND Key = ?;" ),
StatementSql ( mStatement_FindEntry, "SELECT MetaData, Generation, Flags, DataSize, FetchCount, LastFetched, LastModified, ExpirationTime FROM moz_cache WHERE ClientID = ? AND Key = ?;" ),
StatementSql ( mStatement_BindEntry, "INSERT INTO moz_cache (ClientID, Key, MetaData, Generation, Flags, DataSize, FetchCount, LastFetched, LastModified, ExpirationTime) VALUES(?,?,?,?,?,?,?,?,?,?);" ),
-
- StatementSql ( mStatement_MarkEntry, "UPDATE moz_cache SET ItemType = (ItemType | ?) WHERE ClientID = ? AND Key = ?;" ),
- StatementSql ( mStatement_UnmarkEntry, "UPDATE moz_cache SET ItemType = (ItemType & ~?) WHERE ClientID = ? AND Key = ?;" ),
- StatementSql ( mStatement_GetTypes, "SELECT ItemType FROM moz_cache WHERE ClientID = ? AND Key = ?;"),
- StatementSql ( mStatement_CleanupUnmarked, "DELETE FROM moz_cache WHERE ClientID = ? AND Key = ? AND ItemType = 0;" ),
- StatementSql ( mStatement_GatherEntries, "SELECT Key FROM moz_cache WHERE ClientID = ? AND (ItemType & ?) > 0;" ),
-
- StatementSql ( mStatement_ActivateClient, "INSERT OR REPLACE INTO moz_cache_groups (GroupID, ActiveClientID) VALUES (?, ?);" ),
- StatementSql ( mStatement_DeactivateGroup, "DELETE FROM moz_cache_groups WHERE GroupID = ?;" ),
- StatementSql ( mStatement_FindClient, "SELECT ClientID FROM moz_cache WHERE Key = ? ORDER BY LastFetched DESC, LastModified DESC;")
+ StatementSql ( mStatement_ClearOwnership, "DELETE FROM moz_cache_owners WHERE ClientId = ? AND Domain = ? AND URI = ?;" ),
+ StatementSql ( mStatement_RemoveOwnership, "DELETE FROM moz_cache_owners WHERE ClientID = ? AND Domain = ? AND URI = ? AND Key = ?;" ),
+ StatementSql ( mStatement_ClearDomain, "DELETE FROM moz_cache_owners WHERE ClientID = ? AND Domain = ?;" ),
+ StatementSql ( mStatement_AddOwnership, "INSERT INTO moz_cache_owners (ClientID, Domain, URI, Key) VALUES (?, ?, ?, ?);" ),
+ StatementSql ( mStatement_CheckOwnership, "SELECT Key From moz_cache_owners WHERE ClientID = ? AND Domain = ? AND URI = ? AND Key = ?;" ),
+ StatementSql ( mStatement_ListOwned, "SELECT Key FROM moz_cache_owners WHERE ClientID = ? AND Domain = ? AND URI = ?;" ),
+ StatementSql ( mStatement_ListOwners, "SELECT DISTINCT Domain, URI FROM moz_cache_owners WHERE ClientID = ?;"),
+ StatementSql ( mStatement_ListOwnerDomains, "SELECT DISTINCT Domain FROM moz_cache_owners WHERE ClientID = ?;"),
+ StatementSql ( mStatement_ListOwnerURIs, "SELECT DISTINCT URI FROM moz_cache_owners WHERE ClientID = ? AND Domain = ?;"),
+ StatementSql ( mStatement_DeleteConflicts, "DELETE FROM moz_cache WHERE rowid IN (SELECT old.rowid FROM moz_cache AS old, moz_cache AS new WHERE old.Key = new.Key AND old.ClientID = ? AND new.ClientID = ?)"),
+ StatementSql ( mStatement_DeleteUnowned, "DELETE FROM moz_cache WHERE rowid IN (SELECT moz_cache.rowid FROM moz_cache LEFT OUTER JOIN moz_cache_owners ON (moz_cache.ClientID = moz_cache_owners.ClientID AND moz_cache.Key = moz_cache_owners.Key) WHERE moz_cache.ClientID = ? AND moz_cache_owners.Domain ISNULL);" ),
+ StatementSql ( mStatement_SwapClientID, "UPDATE OR REPLACE moz_cache SET ClientID = ? WHERE ClientID = ?;")
};
- for (PRUint32 i = 0; NS_SUCCEEDED(rv) && i < NS_ARRAY_LENGTH(prepared); ++i)
+ for (PRUint32 i=0; i<NS_ARRAY_LENGTH(prepared); ++i)
{
- LOG(("Creating statement: %s\n", prepared[i].sql));
-
- rv = mDB->CreateStatement(nsDependentCString(prepared[i].sql),
- getter_AddRefs(prepared[i].statement));
- NS_ENSURE_SUCCESS(rv, rv);
+ rv |= mDB->CreateStatement(nsDependentCString(prepared[i].sql),
+ getter_AddRefs(prepared[i].statement));
}
+ NS_ENSURE_SUCCESS(rv, rv);
// Clear up any dangling active flags
rv = mDB->ExecuteSimpleSQL(
NS_LITERAL_CSTRING("UPDATE moz_cache"
" SET Flags=(Flags & ~1)"
" WHERE (Flags & 1);"));
NS_ENSURE_SUCCESS(rv, rv);
- rv = InitActiveCaches();
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-nsOfflineCacheDevice::InitActiveCaches()
-{
- NS_ENSURE_TRUE(mCaches.Init(), NS_ERROR_OUT_OF_MEMORY);
- NS_ENSURE_TRUE(mActiveCachesByGroup.Init(), NS_ERROR_OUT_OF_MEMORY);
+ // Clear up dangling temporary sessions
+ EvictionObserver evictionObserver(mDB, mEvictionFunction);
- nsresult rv = mActiveCaches.Init(5);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<mozIStorageStatement> statement;
- rv =
- mDB->CreateStatement(NS_LITERAL_CSTRING("SELECT GroupID, ActiveClientID"
- " FROM moz_cache_groups"),
- getter_AddRefs(statement));
- NS_ENSURE_SUCCESS(rv, rv);
-
- PRBool hasRows;
- rv = statement->ExecuteStep(&hasRows);
+ rv = mDB->ExecuteSimpleSQL(
+ NS_LITERAL_CSTRING("DELETE FROM moz_cache"
+ " WHERE (ClientID GLOB \"TempClient*\")"));
NS_ENSURE_SUCCESS(rv, rv);
- while (hasRows)
- {
- nsCAutoString group;
- statement->GetUTF8String(0, group);
- nsCString clientID;
- statement->GetUTF8String(1, clientID);
-
- mActiveCaches.Put(clientID);
- mActiveCachesByGroup.Put(group, new nsCString(clientID));
-
- rv = statement->ExecuteStep(&hasRows);
- NS_ENSURE_SUCCESS(rv, rv);
- }
+ evictionObserver.Apply();
return NS_OK;
}
-/* static */
-PLDHashOperator
-nsOfflineCacheDevice::ShutdownApplicationCache(const nsACString &key,
- nsIWeakReference *weakRef,
- void *ctx)
-{
- nsCOMPtr<nsIApplicationCache> obj = do_QueryReferent(weakRef);
- if (obj)
- {
- nsApplicationCache *appCache = static_cast<nsApplicationCache*>(obj.get());
- appCache->MarkInvalid();
- }
-
- return PL_DHASH_NEXT;
-}
-
nsresult
nsOfflineCacheDevice::Shutdown()
{
NS_ENSURE_TRUE(mDB, NS_ERROR_NOT_INITIALIZED);
- if (mCaches.IsInitialized())
- mCaches.EnumerateRead(ShutdownApplicationCache, this);
-
- EvictionObserver evictionObserver(mDB, mEvictionFunction);
-
- // Delete all rows whose clientID is not an active clientID.
- nsresult rv = mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE rowid IN (SELECT moz_cache.rowid FROM moz_cache LEFT OUTER JOIN moz_cache_groups ON (moz_cache.ClientID = moz_cache_groups.ActiveClientID) WHERE moz_cache_groups.GroupID ISNULL)"));
-
- if (NS_FAILED(rv))
- NS_WARNING("Failed to clean up unused application caches.");
- else
- evictionObserver.Apply();
-
mDB = 0;
mEvictionFunction = 0;
return NS_OK;
}
const char *
nsOfflineCacheDevice::GetDeviceID()
@@ -1248,16 +1021,17 @@ nsOfflineCacheDevice::BindEntry(nsCacheE
rv |= statement->BindInt64Parameter(7, rec.lastFetched);
rv |= statement->BindInt64Parameter(8, rec.lastModified);
rv |= statement->BindInt64Parameter(9, rec.expirationTime);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasRows;
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
+
NS_ASSERTION(!hasRows, "INSERT should not result in output");
entry->SetData(binding);
return NS_OK;
}
void
nsOfflineCacheDevice::DoomEntry(nsCacheEntry *entry)
@@ -1471,147 +1245,41 @@ nsOfflineCacheDevice::EvictEntries(const
clientID ? clientID : ""));
// called to evict all entries matching the given clientID.
// need trigger to fire user defined function after a row is deleted
// so we can delete the corresponding data file.
EvictionObserver evictionObserver(mDB, mEvictionFunction);
- nsCOMPtr<mozIStorageStatement> statement;
- nsresult rv;
+ const char *deleteCmd;
if (clientID)
{
- rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE ClientID=? AND Flags = 0;"),
- getter_AddRefs(statement));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = statement->BindUTF8StringParameter(0, nsDependentCString(clientID));
- NS_ENSURE_SUCCESS(rv, rv);
+ deleteCmd =
+ PR_smprintf("DELETE FROM moz_cache WHERE ClientID=%q AND Flags=0;",
+ clientID);
+ if (!deleteCmd)
+ return NS_ERROR_OUT_OF_MEMORY;
}
else
{
- rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE Flags = 0;"),
- getter_AddRefs(statement));
- NS_ENSURE_SUCCESS(rv, rv);
+ deleteCmd = "DELETE FROM moz_cache WHERE Flags = 0;";
}
- rv = statement->Execute();
+ nsresult rv = mDB->ExecuteSimpleSQL(nsDependentCString(deleteCmd));
+ if (clientID)
+ PR_smprintf_free((char *) deleteCmd);
NS_ENSURE_SUCCESS(rv, rv);
evictionObserver.Apply();
return NS_OK;
}
nsresult
-nsOfflineCacheDevice::MarkEntry(const nsCString &clientID,
- const nsACString &key,
- PRUint32 typeBits)
-{
- LOG(("nsOfflineCacheDevice::MarkEntry [cid=%s, key=%s, typeBits=%d]\n",
- clientID.get(), PromiseFlatCString(key).get(), typeBits));
-
- AutoResetStatement statement(mStatement_MarkEntry);
- nsresult rv = statement->BindInt32Parameter(0, typeBits);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(1, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(2, key);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = statement->Execute();
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-nsOfflineCacheDevice::UnmarkEntry(const nsCString &clientID,
- const nsACString &key,
- PRUint32 typeBits)
-{
- LOG(("nsOfflineCacheDevice::UnmarkEntry [cid=%s, key=%s, typeBits=%d]\n",
- clientID.get(), PromiseFlatCString(key).get(), typeBits));
-
- AutoResetStatement statement(mStatement_UnmarkEntry);
- nsresult rv = statement->BindInt32Parameter(0, typeBits);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(1, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(2, key);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = statement->Execute();
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Remove the entry if it is now empty.
-
- EvictionObserver evictionObserver(mDB, mEvictionFunction);
-
- AutoResetStatement cleanupStatement(mStatement_CleanupUnmarked);
- rv = cleanupStatement->BindUTF8StringParameter(0, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = cleanupStatement->BindUTF8StringParameter(1, key);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = cleanupStatement->Execute();
- NS_ENSURE_SUCCESS(rv, rv);
-
- evictionObserver.Apply();
-
- return NS_OK;
-}
-
-nsresult
-nsOfflineCacheDevice::GetTypes(const nsCString &clientID,
- const nsACString &key,
- PRUint32 *typeBits)
-{
- LOG(("nsOfflineCacheDevice::GetTypes [cid=%s, key=%s]\n",
- clientID.get(), PromiseFlatCString(key).get()));
-
- AutoResetStatement statement(mStatement_GetTypes);
- nsresult rv = statement->BindUTF8StringParameter(0, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(1, key);
- NS_ENSURE_SUCCESS(rv, rv);
-
- PRBool hasRows;
- rv = statement->ExecuteStep(&hasRows);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!hasRows)
- return NS_ERROR_CACHE_KEY_NOT_FOUND;
-
- *typeBits = statement->AsInt32(0);
-
- return NS_OK;
-}
-
-nsresult
-nsOfflineCacheDevice::GatherEntries(const nsCString &clientID,
- PRUint32 typeBits,
- PRUint32 *count,
- char ***keys)
-{
- LOG(("nsOfflineCacheDevice::GatherEntries [cid=%s, typeBits=%X]\n",
- clientID.get(), typeBits));
-
- AutoResetStatement statement(mStatement_GatherEntries);
- nsresult rv = statement->BindUTF8StringParameter(0, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = statement->BindInt32Parameter(1, typeBits);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return RunSimpleQuery(mStatement_GatherEntries, 0, count, keys);
-}
-
-nsresult
nsOfflineCacheDevice::RunSimpleQuery(mozIStorageStatement * statement,
PRUint32 resultIndex,
PRUint32 * count,
char *** values)
{
PRBool hasRows;
nsresult rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
@@ -1639,200 +1307,322 @@ nsOfflineCacheDevice::RunSimpleQuery(moz
}
}
*values = ret;
return NS_OK;
}
-NS_IMETHODIMP
-nsOfflineCacheDevice::CreateApplicationCache(const nsACString &group,
- nsIApplicationCache **out)
+nsresult
+nsOfflineCacheDevice::GetOwnerDomains(const char * clientID,
+ PRUint32 * count,
+ char *** domains)
{
- *out = nsnull;
+ LOG(("nsOfflineCacheDevice::GetOwnerDomains [cid=%s]\n", clientID));
+
+ AutoResetStatement statement(mStatement_ListOwnerDomains);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return RunSimpleQuery(mStatement_ListOwnerDomains, 0, count, domains);
+}
+
+nsresult
+nsOfflineCacheDevice::GetOwnerURIs(const char * clientID,
+ const nsACString & ownerDomain,
+ PRUint32 * count,
+ char *** domains)
+{
+ LOG(("nsOfflineCacheDevice::GetOwnerURIs [cid=%s]\n", clientID));
+
+ AutoResetStatement statement(mStatement_ListOwnerURIs);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv = statement->BindUTF8StringParameter(
+ 1, ownerDomain);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return RunSimpleQuery(mStatement_ListOwnerURIs, 0, count, domains);
+}
- nsCString clientID;
- // Some characters are special in the clientID. Escape the groupID
- // before putting it in to the client key.
- if (!NS_Escape(nsCString(group), clientID, url_Path)) {
- return NS_ERROR_OUT_OF_MEMORY;
+nsresult
+nsOfflineCacheDevice::SetOwnedKeys(const char * clientID,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ PRUint32 count,
+ const char ** keys)
+{
+ LOG(("nsOfflineCacheDevice::SetOwnedKeys [cid=%s]\n", clientID));
+ mozStorageTransaction transaction(mDB, PR_FALSE);
+
+ nsDependentCString clientIDStr(clientID);
+
+ AutoResetStatement clearStatement(mStatement_ClearOwnership);
+ nsresult rv = clearStatement->BindUTF8StringParameter(
+ 0, clientIDStr);
+ rv |= clearStatement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= clearStatement->BindUTF8StringParameter(2, ownerURI);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = clearStatement->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (PRUint32 i = 0; i < count; i++)
+ {
+ AutoResetStatement insertStatement(mStatement_AddOwnership);
+ rv = insertStatement->BindUTF8StringParameter(0, clientIDStr);
+ rv |= insertStatement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= insertStatement->BindUTF8StringParameter(2, ownerURI);
+ rv |= insertStatement->BindUTF8StringParameter(3, nsDependentCString(keys[i]));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = insertStatement->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
}
- PRTime now = PR_Now();
-
- // Include the timestamp to guarantee uniqueness across runs, and
- // the gNextTemporaryClientID for uniqueness within a second.
- clientID.Append(nsPrintfCString(64, "|%016lld|%d",
- now / PR_USEC_PER_SEC,
- gNextTemporaryClientID++));
+ return transaction.Commit();
+}
- nsCOMPtr<nsIApplicationCache> cache = new nsApplicationCache(this,
- group,
- clientID);
- if (!cache)
- return NS_ERROR_OUT_OF_MEMORY;
+nsresult
+nsOfflineCacheDevice::GetOwnedKeys(const char * clientID,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ PRUint32 * count,
+ char *** keys)
+{
+ LOG(("nsOfflineCacheDevice::GetOwnedKeys [cid=%s]\n", clientID));
- nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(cache);
- if (!weak)
- return NS_ERROR_OUT_OF_MEMORY;
+ AutoResetStatement statement(mStatement_ListOwned);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv |= statement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= statement->BindUTF8StringParameter(2, ownerURI);
+ NS_ENSURE_SUCCESS(rv, rv);
- mCaches.Put(clientID, weak);
-
- cache.swap(*out);
-
- return NS_OK;
+ return RunSimpleQuery(mStatement_ListOwned, 0, count, keys);
}
-NS_IMETHODIMP
-nsOfflineCacheDevice::GetApplicationCache(const nsACString &clientID,
- nsIApplicationCache **out)
+nsresult
+nsOfflineCacheDevice::AddOwnedKey(const char * clientID,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key)
{
- *out = nsnull;
+ LOG(("nsOfflineCacheDevice::AddOwnedKey [cid=%s]\n", clientID));
- nsCOMPtr<nsIApplicationCache> cache;
+ PRBool isOwned;
+ nsresult rv = KeyIsOwned(clientID, ownerDomain, ownerURI, key, &isOwned);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (isOwned) return NS_OK;
- nsWeakPtr weak;
- if (mCaches.Get(clientID, getter_AddRefs(weak)))
- cache = do_QueryReferent(weak);
+ AutoResetStatement statement(mStatement_AddOwnership);
+ rv = statement->BindUTF8StringParameter(0, nsDependentCString(clientID));
+ rv |= statement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= statement->BindUTF8StringParameter(2, ownerURI);
+ rv |= statement->BindUTF8StringParameter(3, key);
+ NS_ENSURE_SUCCESS(rv, rv);
- if (!cache)
- {
- nsCString group;
- nsresult rv = GetGroupForCache(clientID, group);
- NS_ENSURE_SUCCESS(rv, rv);
+ return statement->Execute();
+}
- if (group.IsEmpty()) {
- return NS_OK;
- }
+nsresult
+nsOfflineCacheDevice::RemoveOwnedKey(const char * clientID,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key)
+{
+ LOG(("nsOfflineCacheDevice::RemoveOwnedKey [cid=%s]\n", clientID));
- cache = new nsApplicationCache(this, group, clientID);
- weak = do_GetWeakReference(cache);
- if (!weak)
- return NS_ERROR_OUT_OF_MEMORY;
+ PRBool isOwned;
+ nsresult rv = KeyIsOwned(clientID, ownerDomain, ownerURI, key, &isOwned);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isOwned) return NS_ERROR_NOT_AVAILABLE;
- mCaches.Put(clientID, weak);
- }
+ AutoResetStatement statement(mStatement_RemoveOwnership);
+ rv = statement->BindUTF8StringParameter(0, nsDependentCString(clientID));
+ rv |= statement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= statement->BindUTF8StringParameter(2, ownerURI);
+ rv |= statement->BindUTF8StringParameter(3, key);
+ NS_ENSURE_SUCCESS(rv, rv);
- cache.swap(*out);
-
- return NS_OK;
+ return statement->Execute();
}
-NS_IMETHODIMP
-nsOfflineCacheDevice::GetActiveCache(const nsACString &group,
- nsIApplicationCache **out)
+nsresult
+nsOfflineCacheDevice::KeyIsOwned(const char * clientID,
+ const nsACString & ownerDomain,
+ const nsACString & ownerURI,
+ const nsACString & key,
+ PRBool * isOwned)
{
- *out = nsnull;
+ AutoResetStatement statement(mStatement_CheckOwnership);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv |= statement->BindUTF8StringParameter(1, ownerDomain);
+ rv |= statement->BindUTF8StringParameter(2, ownerURI);
+ rv |= statement->BindUTF8StringParameter(3, key);
+ NS_ENSURE_SUCCESS(rv, rv);
- nsCString *clientID;
- if (mActiveCachesByGroup.Get(group, &clientID))
- return GetApplicationCache(*clientID, out);
-
- return NS_OK;
+ return statement->ExecuteStep(isOwned);
}
-NS_IMETHODIMP
-nsOfflineCacheDevice::ChooseApplicationCache(const nsACString &key,
- nsIApplicationCache **out)
+nsresult
+nsOfflineCacheDevice::ClearKeysOwnedByDomain(const char *clientID,
+ const nsACString &domain)
{
- *out = nsnull;
+ LOG(("nsOfflineCacheDevice::ClearKeysOwnedByDomain [cid=%s]\n", clientID));
+
+ AutoResetStatement statement(mStatement_ClearDomain);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv |= statement->BindUTF8StringParameter(1, domain);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return statement->Execute();
+}
- AutoResetStatement statement(mStatement_FindClient);
- nsresult rv = statement->BindUTF8StringParameter(
- 0, key);
+nsresult
+nsOfflineCacheDevice::GetDomainUsage(const char *clientID,
+ const nsACString &domain,
+ PRUint32 *usage)
+{
+ LOG(("nsOfflineCacheDevice::GetDomainUsage [cid=%s]\n", clientID));
+
+ *usage = 0;
+
+ AutoResetStatement statement(mStatement_DomainSize);
+ nsresult rv;
+
+ rv = statement->BindUTF8StringParameter(0, nsDependentCString(clientID));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = statement->BindUTF8StringParameter(1, domain);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasRows;
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
- while (hasRows) {
- nsCString clientID;
- rv = statement->GetUTF8String(0, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (!hasRows)
+ return NS_OK;
- if (mActiveCaches.Contains(clientID))
- return GetApplicationCache(clientID, out);
-
- rv = statement->ExecuteStep(&hasRows);
- NS_ENSURE_SUCCESS(rv, rv);
- }
+ *usage = statement->AsInt32(0);
return NS_OK;
}
nsresult
-nsOfflineCacheDevice::ActivateCache(const nsCSubstring &group,
- const nsCSubstring &clientID)
+nsOfflineCacheDevice::EvictUnownedEntries(const char *clientID)
{
- AutoResetStatement statement(mStatement_ActivateClient);
- nsresult rv = statement->BindUTF8StringParameter(0, group);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = statement->BindUTF8StringParameter(1, clientID);
+ LOG(("nsOfflineCacheDevice::EvictUnownedEntries [cid=%s]\n", clientID));
+ EvictionObserver evictionObserver(mDB, mEvictionFunction);
+
+ AutoResetStatement statement(mStatement_DeleteUnowned);
+ nsresult rv = statement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
- nsCString *active;
- if (mActiveCachesByGroup.Get(group, &active))
- {
- mActiveCaches.Remove(*active);
- mActiveCachesByGroup.Remove(group);
- active = nsnull;
- }
-
- if (!clientID.IsEmpty())
- {
- mActiveCaches.Put(clientID);
- mActiveCachesByGroup.Put(group, new nsCString(clientID));
- }
-
+ evictionObserver.Apply();
return NS_OK;
}
-PRBool
-nsOfflineCacheDevice::IsActiveCache(const nsCSubstring &group,
- const nsCSubstring &clientID)
+nsresult
+nsOfflineCacheDevice::CreateTemporaryClientID(nsACString &clientID)
{
- nsCString *active = nsnull;
- return mActiveCachesByGroup.Get(group, &active) && *active == clientID;
-}
-
-nsresult
-nsOfflineCacheDevice::DeactivateGroup(const nsCSubstring &group)
-{
- nsCString *active = nsnull;
+ nsCAutoString str;
+ str.AssignLiteral("TempClient");
+ str.AppendInt(gNextTemporaryClientID++);
- AutoResetStatement statement(mStatement_DeactivateGroup);
- nsresult rv = statement->BindUTF8StringParameter(
- 0, group);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = statement->Execute();
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (mActiveCachesByGroup.Get(group, &active))
- {
- mActiveCaches.Remove(*active);
- mActiveCachesByGroup.Remove(group);
- active = nsnull;
- }
+ clientID.Assign(str);
return NS_OK;
}
nsresult
-nsOfflineCacheDevice::GetGroupForCache(const nsACString &clientID,
- nsCString &out)
+nsOfflineCacheDevice::MergeTemporaryClientID(const char *clientID,
+ const char *fromClientID)
{
- out.Assign(clientID);
- out.Truncate(out.FindChar('|'));
- NS_UnescapeURL(out);
+ LOG(("nsOfflineCacheDevice::MergeTemporaryClientID [cid=%s, from=%s]\n",
+ clientID, fromClientID));
+ mozStorageTransaction transaction(mDB, PR_FALSE);
+
+ // Move over ownerships
+ AutoResetStatement listOwnersStatement(mStatement_ListOwners);
+ nsresult rv = listOwnersStatement->BindUTF8StringParameter(
+ 0, nsDependentCString(fromClientID));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // List all the owners in the new session
+ nsTArray<nsCString> domainArray;
+ nsTArray<nsCString> uriArray;
+
+ PRBool hasRows;
+ rv = listOwnersStatement->ExecuteStep(&hasRows);
+ NS_ENSURE_SUCCESS(rv, rv);
+ while (hasRows)
+ {
+ PRUint32 length;
+ domainArray.AppendElement(
+ nsDependentCString(listOwnersStatement->AsSharedUTF8String(0, &length)));
+ uriArray.AppendElement(
+ nsDependentCString(listOwnersStatement->AsSharedUTF8String(1, &length)));
+
+ rv = listOwnersStatement->ExecuteStep(&hasRows);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // Now move over each ownership set
+ for (PRUint32 i = 0; i < domainArray.Length(); i++) {
+ PRUint32 count;
+ char **keys;
+ rv = GetOwnedKeys(fromClientID, domainArray[i], uriArray[i],
+ &count, &keys);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = SetOwnedKeys(clientID, domainArray[i], uriArray[i],
+ count, const_cast<const char **>(keys));
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, keys);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Now clear out the temporary session's copy
+ rv = SetOwnedKeys(fromClientID, domainArray[i], uriArray[i], 0, 0);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ EvictionObserver evictionObserver(mDB, mEvictionFunction);
+
+ AutoResetStatement deleteStatement(mStatement_DeleteConflicts);
+ rv = deleteStatement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv |= deleteStatement->BindUTF8StringParameter(
+ 1, nsDependentCString(fromClientID));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = deleteStatement->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ AutoResetStatement swapStatement(mStatement_SwapClientID);
+ rv = swapStatement->BindUTF8StringParameter(
+ 0, nsDependentCString(clientID));
+ rv |= swapStatement->BindUTF8StringParameter(
+ 1, nsDependentCString(fromClientID));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = swapStatement->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = transaction.Commit();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ evictionObserver.Apply();
return NS_OK;
}
/**
* Preference accessors
*/
--- a/netwerk/cache/src/nsDiskCacheDeviceSQL.h
+++ b/netwerk/cache/src/nsDiskCacheDeviceSQL.h
@@ -34,31 +34,25 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsOfflineCacheDevice_h__
#define nsOfflineCacheDevice_h__
#include "nsCacheDevice.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheService.h"
#include "nsILocalFile.h"
#include "nsIObserver.h"
#include "mozIStorageConnection.h"
#include "mozIStorageFunction.h"
#include "nsIFile.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsVoidArray.h"
-#include "nsInterfaceHashtable.h"
-#include "nsClassHashtable.h"
-#include "nsHashSets.h"
-#include "nsWeakReference.h"
class nsOfflineCacheDevice;
class nsOfflineCacheEvictionFunction : public mozIStorageFunction {
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISTORAGEFUNCTION
@@ -71,32 +65,26 @@ public:
private:
nsOfflineCacheDevice *mDevice;
nsCOMArray<nsIFile> mItems;
};
class nsOfflineCacheDevice : public nsCacheDevice
- , public nsIApplicationCacheService
{
public:
nsOfflineCacheDevice();
- NS_DECL_ISUPPORTS
- NS_DECL_NSIAPPLICATIONCACHESERVICE
-
/**
* nsCacheDevice methods
*/
virtual ~nsOfflineCacheDevice();
- static nsOfflineCacheDevice *GetInstance();
-
virtual nsresult Init();
virtual nsresult Shutdown();
virtual const char * GetDeviceID(void);
virtual nsCacheEntry * FindEntry(nsCString * key, PRBool *collision);
virtual nsresult DeactivateEntry(nsCacheEntry * entry);
virtual nsresult BindEntry(nsCacheEntry * entry);
virtual void DoomEntry( nsCacheEntry * entry );
@@ -150,69 +138,46 @@ public:
nsresult KeyIsOwned(const char * clientID,
const nsACString & ownerDomain,
const nsACString & ownerURI,
const nsACString & key,
PRBool * isOwned);
nsresult ClearKeysOwnedByDomain(const char *clientID,
const nsACString &ownerDomain);
+ nsresult GetDomainUsage(const char *clientID,
+ const nsACString &ownerDomain,
+ PRUint32 *usage);
nsresult EvictUnownedEntries(const char *clientID);
- nsresult ActivateCache(const nsCSubstring &group,
- const nsCSubstring &clientID);
- PRBool IsActiveCache(const nsCSubstring &group,
- const nsCSubstring &clientID);
- nsresult DeactivateGroup(const nsCSubstring &group);
- nsresult GetGroupForCache(const nsCSubstring &clientID,
- nsCString &out);
+ nsresult CreateTemporaryClientID(nsACString &clientID);
+ nsresult MergeTemporaryClientID(const char *clientID,
+ const char *fromClientID);
+
/**
* Preference accessors
*/
void SetCacheParentDirectory(nsILocalFile * parentDir);
void SetCapacity(PRUint32 capacity);
nsILocalFile * CacheDirectory() { return mCacheDirectory; }
PRUint32 CacheCapacity() { return mCacheCapacity; }
PRUint32 CacheSize();
PRUint32 EntryCount();
private:
- friend class nsApplicationCache;
-
- static PLDHashOperator ShutdownApplicationCache(const nsACString &key,
- nsIWeakReference *weakRef,
- void *ctx);
-
PRBool Initialized() { return mDB != nsnull; }
-
- nsresult InitActiveCaches();
nsresult UpdateEntry(nsCacheEntry *entry);
nsresult UpdateEntrySize(nsCacheEntry *entry, PRUint32 newSize);
nsresult DeleteEntry(nsCacheEntry *entry, PRBool deleteData);
nsresult DeleteData(nsCacheEntry *entry);
nsresult EnableEvictionObserver();
nsresult DisableEvictionObserver();
-
- nsresult MarkEntry(const nsCString &clientID,
- const nsACString &key,
- PRUint32 typeBits);
- nsresult UnmarkEntry(const nsCString &clientID,
- const nsACString &key,
- PRUint32 typeBits);
- nsresult GetTypes(const nsCString &clientID,
- const nsACString &key,
- PRUint32 *typeBits);
- nsresult GatherEntries(const nsCString &clientID,
- PRUint32 typeBits,
- PRUint32 *count,
- char *** values);
-
nsresult RunSimpleQuery(mozIStorageStatement *statment,
PRUint32 resultIndex,
PRUint32 * count,
char *** values);
nsCOMPtr<mozIStorageConnection> mDB;
nsRefPtr<nsOfflineCacheEvictionFunction> mEvictionFunction;
@@ -220,28 +185,27 @@ private:
nsCOMPtr<mozIStorageStatement> mStatement_DomainSize;
nsCOMPtr<mozIStorageStatement> mStatement_EntryCount;
nsCOMPtr<mozIStorageStatement> mStatement_UpdateEntry;
nsCOMPtr<mozIStorageStatement> mStatement_UpdateEntrySize;
nsCOMPtr<mozIStorageStatement> mStatement_UpdateEntryFlags;
nsCOMPtr<mozIStorageStatement> mStatement_DeleteEntry;
nsCOMPtr<mozIStorageStatement> mStatement_FindEntry;
nsCOMPtr<mozIStorageStatement> mStatement_BindEntry;
+ nsCOMPtr<mozIStorageStatement> mStatement_ClearOwnership;
+ nsCOMPtr<mozIStorageStatement> mStatement_RemoveOwnership;
nsCOMPtr<mozIStorageStatement> mStatement_ClearDomain;
- nsCOMPtr<mozIStorageStatement> mStatement_MarkEntry;
- nsCOMPtr<mozIStorageStatement> mStatement_UnmarkEntry;
- nsCOMPtr<mozIStorageStatement> mStatement_GetTypes;
- nsCOMPtr<mozIStorageStatement> mStatement_CleanupUnmarked;
- nsCOMPtr<mozIStorageStatement> mStatement_GatherEntries;
- nsCOMPtr<mozIStorageStatement> mStatement_ActivateClient;
- nsCOMPtr<mozIStorageStatement> mStatement_DeactivateGroup;
- nsCOMPtr<mozIStorageStatement> mStatement_FindClient;
+ nsCOMPtr<mozIStorageStatement> mStatement_AddOwnership;
+ nsCOMPtr<mozIStorageStatement> mStatement_CheckOwnership;
+ nsCOMPtr<mozIStorageStatement> mStatement_DeleteConflicts;
+ nsCOMPtr<mozIStorageStatement> mStatement_DeleteUnowned;
+ nsCOMPtr<mozIStorageStatement> mStatement_ListOwned;
+ nsCOMPtr<mozIStorageStatement> mStatement_ListOwners;
+ nsCOMPtr<mozIStorageStatement> mStatement_ListOwnerDomains;
+ nsCOMPtr<mozIStorageStatement> mStatement_ListOwnerURIs;
+ nsCOMPtr<mozIStorageStatement> mStatement_SwapClientID;
nsCOMPtr<nsILocalFile> mCacheDirectory;
PRUint32 mCacheCapacity;
PRInt32 mDeltaCounter;
-
- nsInterfaceHashtable<nsCStringHashKey, nsIWeakReference> mCaches;
- nsClassHashtable<nsCStringHashKey, nsCString> mActiveCachesByGroup;
- nsCStringHashSet mActiveCaches;
};
#endif // nsOfflineCacheDevice_h__
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -42,17 +42,16 @@
#include "nsHttpChannel.h"
#include "nsHttpTransaction.h"
#include "nsHttpConnection.h"
#include "nsHttpHandler.h"
#include "nsHttpAuthCache.h"
#include "nsHttpResponseHead.h"
#include "nsHttp.h"
#include "nsIHttpAuthenticator.h"
-#include "nsIApplicationCacheService.h"
#include "nsIAuthInformation.h"
#include "nsIAuthPrompt2.h"
#include "nsIAuthPromptProvider.h"
#include "nsIStringBundle.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIURL.h"
#include "nsIIDNService.h"
@@ -1367,71 +1366,36 @@ nsHttpChannel::OpenCacheEntry(PRBool off
return NS_ERROR_NOT_AVAILABLE;
accessRequested = nsICache::ACCESS_READ;
}
else if (BYPASS_LOCAL_CACHE(mLoadFlags))
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
else
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
- if (!mApplicationCache) {
- // Pick up an application cache from the load group if available
- nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer;
- GetCallback(appCacheContainer);
-
- if (appCacheContainer) {
- appCacheContainer->GetApplicationCache(getter_AddRefs(mApplicationCache));
- }
-
- if ((mLoadFlags & LOAD_CHECK_OFFLINE_CACHE) && !mApplicationCache) {
- // We're supposed to load from an application cache, but
- // one was not supplied by the load group. Ask the
- // application cache service to choose one for us.
- nsCOMPtr<nsIApplicationCacheService> appCacheService =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
- if (appCacheService) {
- nsresult rv = appCacheService->ChooseApplicationCache
- (cacheKey, getter_AddRefs(mApplicationCache));
- NS_ENSURE_SUCCESS(rv, rv);
- }
- }
- }
-
nsCOMPtr<nsICacheSession> session;
-
- // If we have an application cache, we check it first.
- if (mApplicationCache) {
- nsCAutoString appCacheClientID;
- mApplicationCache->GetClientID(appCacheClientID);
-
- nsCOMPtr<nsICacheService> serv =
- do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = serv->CreateSession(appCacheClientID.get(),
- nsICache::STORE_OFFLINE,
- nsICache::STREAM_BASED,
- getter_AddRefs(session));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // we'll try to synchronously open the cache entry... however,
- // it may be in use and not yet validated, in which case we'll
- // try asynchronously opening the cache entry.
+ if (mLoadFlags & LOAD_CHECK_OFFLINE_CACHE) {
+ // when LOAD_CHECK_OFFLINE_CACHE set prefer the offline cache
+ rv = gHttpHandler->GetCacheSession(nsICache::STORE_OFFLINE,
+ getter_AddRefs(session));
+ if (NS_FAILED(rv)) return rv;
+
+ // we'll try to synchronously open the cache entry... however, it may be
+ // in use and not yet validated, in which case we'll try asynchronously
+ // opening the cache entry.
//
- // we need open in ACCESS_READ only because we don't want to
- // overwrite the offline cache entry non-atomically so
- // ACCESS_READ will prevent us from writing to the
- // HTTP-offline cache as a normal cache entry. XXX: this
- // needs to be checked.
- rv = session->OpenCacheEntry(cacheKey,
- nsICache::ACCESS_READ, PR_FALSE,
+ // we need open in ACCESS_READ only because we don't want to overwrite
+ // the offline cache entry non-atomically so ACCESS_READ
+ // will prevent us from writing to the HTTP-offline cache as a
+ // normal cache entry.
+ rv = session->OpenCacheEntry(cacheKey, nsICache::ACCESS_READ, PR_FALSE,
getter_AddRefs(mCacheEntry));
}
- if (!mApplicationCache ||
+ if (!(mLoadFlags & LOAD_CHECK_OFFLINE_CACHE) ||
(NS_FAILED(rv) && rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION))
{
rv = gHttpHandler->GetCacheSession(storagePolicy,
getter_AddRefs(session));
if (NS_FAILED(rv)) return rv;
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
getter_AddRefs(mCacheEntry));
@@ -1488,28 +1452,30 @@ nsHttpChannel::OpenOfflineCacheEntryForW
// don't use the cache if our consumer is making a conditional request
// (see bug 331825).
return NS_OK;
}
nsCAutoString cacheKey;
GenerateCacheKey(cacheKey);
- NS_ENSURE_TRUE(!mOfflineCacheClientID.IsEmpty(),
- NS_ERROR_NOT_AVAILABLE);
-
nsCOMPtr<nsICacheSession> session;
- nsCOMPtr<nsICacheService> serv =
- do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
- if (NS_FAILED(rv)) return rv;
-
- rv = serv->CreateSession(mOfflineCacheClientID.get(),
- nsICache::STORE_OFFLINE,
- nsICache::STREAM_BASED,
- getter_AddRefs(session));
+ if (!mOfflineCacheClientID.IsEmpty()) {
+ nsCOMPtr<nsICacheService> serv =
+ do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = serv->CreateSession(mOfflineCacheClientID.get(),
+ nsICache::STORE_OFFLINE,
+ nsICache::STREAM_BASED,
+ getter_AddRefs(session));
+ } else {
+ rv = gHttpHandler->GetCacheSession(nsICache::STORE_OFFLINE,
+ getter_AddRefs(session));
+ }
if (NS_FAILED(rv)) return rv;
rv = session->OpenCacheEntry(cacheKey, nsICache::ACCESS_READ_WRITE,
PR_FALSE, getter_AddRefs(mOfflineCacheEntry));
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
// access to the cache entry has been denied (because the cache entry
// is probably in use by another channel). Either the cache is being
@@ -3416,17 +3382,16 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)
NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyCallback)
NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel)
- NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIRequest
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::GetName(nsACString &aName)
@@ -4907,34 +4872,16 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnec
rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
if (NS_FAILED(rv)) return rv;
return mTransactionPump->AsyncRead(this, nsnull);
}
//-----------------------------------------------------------------------------
-// nsHttpChannel::nsIApplicationCacheContainer
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-nsHttpChannel::GetApplicationCache(nsIApplicationCache **out)
-{
- NS_IF_ADDREF(*out = mApplicationCache);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHttpChannel::SetApplicationCache(nsIApplicationCache *appCache)
-{
- mApplicationCache = appCache;
- return NS_OK;
-}
-
-
-//-----------------------------------------------------------------------------
// nsHttpChannel::nsContentEncodings <public>
//-----------------------------------------------------------------------------
nsHttpChannel::nsContentEncodings::nsContentEncodings(nsIHttpChannel* aChannel,
const char* aEncodingHeader) :
mEncodingHeader(aEncodingHeader), mChannel(aChannel), mReady(PR_FALSE)
{
mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
--- a/netwerk/protocol/http/src/nsHttpChannel.h
+++ b/netwerk/protocol/http/src/nsHttpChannel.h
@@ -61,21 +61,18 @@
#include "nsIIOService.h"
#include "nsIURI.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIInputStream.h"
#include "nsIProgressEventSink.h"
#include "nsICachingChannel.h"
-#include "nsICacheSession.h"
#include "nsICacheEntryDescriptor.h"
#include "nsICacheListener.h"
-#include "nsIApplicationCache.h"
-#include "nsIApplicationCacheContainer.h"
#include "nsIEncodedChannel.h"
#include "nsITransport.h"
#include "nsIUploadChannel.h"
#include "nsIStringEnumerator.h"
#include "nsIOutputStream.h"
#include "nsIAsyncInputStream.h"
#include "nsIPrompt.h"
#include "nsIResumableChannel.h"
@@ -101,17 +98,16 @@ class nsHttpChannel : public nsHashPrope
, public nsIUploadChannel
, public nsICacheListener
, public nsIEncodedChannel
, public nsITransportEventSink
, public nsIResumableChannel
, public nsISupportsPriority
, public nsIProtocolProxyCallback
, public nsIProxiedChannel
- , public nsIApplicationCacheContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIHTTPCHANNEL
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
@@ -120,17 +116,16 @@ public:
NS_DECL_NSICACHELISTENER
NS_DECL_NSIENCODEDCHANNEL
NS_DECL_NSIHTTPCHANNELINTERNAL
NS_DECL_NSITRANSPORTEVENTSINK
NS_DECL_NSIRESUMABLECHANNEL
NS_DECL_NSISUPPORTSPRIORITY
NS_DECL_NSIPROTOCOLPROXYCALLBACK
NS_DECL_NSIPROXIEDCHANNEL
- NS_DECL_NSIAPPLICATIONCACHECONTAINER
nsHttpChannel();
virtual ~nsHttpChannel();
nsresult Init(nsIURI *uri,
PRUint8 capabilities,
nsProxyInfo* proxyInfo);
@@ -263,18 +258,16 @@ private:
nsCacheAccessMode mCacheAccess;
PRUint32 mPostID;
PRUint32 mRequestTime;
nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
nsCacheAccessMode mOfflineCacheAccess;
nsCString mOfflineCacheClientID;
- nsCOMPtr<nsIApplicationCache> mApplicationCache;
-
// auth specific data
nsISupports *mProxyAuthContinuationState;
nsCString mProxyAuthType;
nsISupports *mAuthContinuationState;
nsCString mAuthType;
nsHttpAuthIdentity mIdent;
nsHttpAuthIdentity mProxyIdent;
--- a/uriloader/prefetch/nsIOfflineCacheUpdate.idl
+++ b/uriloader/prefetch/nsIOfflineCacheUpdate.idl
@@ -110,37 +110,31 @@ interface nsIOfflineCacheUpdateObserver
* Each update object maintains a list of nsIDOMLoadStatus items for the
* resources it is updating. The list of these items will be available
* after the object is scheduled.
*
* One update object will be updating at a time. The active object will
* load its items one by one, sending itemCompleted() to any registered
* observers.
*/
-[scriptable, uuid(4b206247-82ee-46cf-a8b7-f7284e753bc2)]
+[scriptable, uuid(7dc06ede-1098-4384-b95e-65525ab254c9)]
interface nsIOfflineCacheUpdate : nsISupports {
/**
* Fetch the status of the running update. This will return a value
* defined in nsIDOMOfflineResourceList.
*/
readonly attribute unsigned short status;
/**
* TRUE if the update is being used to add specific resources.
* FALSE if the complete cache update process is happening.
*/
readonly attribute boolean partial;
/**
- * TRUE if this is an upgrade attempt, FALSE if it is a new cache
- * attempt.
- */
- readonly attribute boolean isUpgrade;
-
- /**
* The domain being updated, and the domain that will own any URIs added
* with this update.
*/
readonly attribute ACString updateDomain;
/**
* The manifest for the offline application being updated.
*/
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -35,26 +35,24 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsOfflineCacheUpdate.h"
#include "nsCPrefetchService.h"
#include "nsCURILoader.h"
-#include "nsIApplicationCacheContainer.h"
-#include "nsIApplicationCacheService.h"
#include "nsICache.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsICachingChannel.h"
#include "nsIDOMWindow.h"
#include "nsIDOMOfflineResourceList.h"
#include "nsIObserverService.h"
-#include "nsIURL.h"
+#include "nsIOfflineCacheSession.h"
#include "nsIWebProgress.h"
#include "nsICryptoHash.h"
#include "nsICacheEntryDescriptor.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsStreamUtils.h"
#include "nsThreadUtils.h"
@@ -101,65 +99,40 @@ NS_IMPL_ISUPPORTS6(nsOfflineCacheUpdateI
//-----------------------------------------------------------------------------
// nsOfflineCacheUpdateItem <public>
//-----------------------------------------------------------------------------
nsOfflineCacheUpdateItem::nsOfflineCacheUpdateItem(nsOfflineCacheUpdate *aUpdate,
nsIURI *aURI,
nsIURI *aReferrerURI,
- nsIApplicationCache *aPreviousApplicationCache,
- const nsACString &aClientID,
- PRUint32 type)
+ const nsACString &aClientID)
: mURI(aURI)
, mReferrerURI(aReferrerURI)
- , mPreviousApplicationCache(aPreviousApplicationCache)
, mClientID(aClientID)
- , mItemType(type)
, mUpdate(aUpdate)
, mChannel(nsnull)
, mState(nsIDOMLoadStatus::UNINITIALIZED)
, mBytesRead(0)
{
}
nsOfflineCacheUpdateItem::~nsOfflineCacheUpdateItem()
{
}
nsresult
nsOfflineCacheUpdateItem::OpenChannel()
{
-#if defined(PR_LOGGING)
- if (LOG_ENABLED()) {
- nsCAutoString spec;
- mURI->GetSpec(spec);
- LOG(("%p: Opening channel for %s", this, spec.get()));
- }
-#endif
-
- nsresult rv = nsOfflineCacheUpdate::GetCacheKey(mURI, mCacheKey);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = NS_NewChannel(getter_AddRefs(mChannel),
- mURI,
- nsnull, nsnull, this,
- nsIRequest::LOAD_BACKGROUND |
- nsICachingChannel::LOAD_ONLY_IF_MODIFIED |
- nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
- do_QueryInterface(mChannel, &rv);
-
- // Support for nsIApplicationCacheContainer is required.
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Use the existing application cache as the cache to check.
- rv = appCacheContainer->SetApplicationCache(mPreviousApplicationCache);
+ nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
+ mURI,
+ nsnull, nsnull, this,
+ nsIRequest::LOAD_BACKGROUND |
+ nsICachingChannel::LOAD_ONLY_IF_MODIFIED |
+ nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE);
NS_ENSURE_SUCCESS(rv, rv);
// configure HTTP specific stuff
nsCOMPtr<nsIHttpChannel> httpChannel =
do_QueryInterface(mChannel);
if (httpChannel) {
httpChannel->SetReferrer(mReferrerURI);
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("X-Moz"),
@@ -414,21 +387,18 @@ nsOfflineCacheUpdateItem::GetStatus(PRUi
//-----------------------------------------------------------------------------
// nsOfflineManifestItem <public>
//-----------------------------------------------------------------------------
nsOfflineManifestItem::nsOfflineManifestItem(nsOfflineCacheUpdate *aUpdate,
nsIURI *aURI,
nsIURI *aReferrerURI,
- nsIApplicationCache *aPreviousApplicationCache,
const nsACString &aClientID)
- : nsOfflineCacheUpdateItem(aUpdate, aURI, aReferrerURI,
- aPreviousApplicationCache, aClientID,
- nsIApplicationCache::ITEM_MANIFEST)
+ : nsOfflineCacheUpdateItem(aUpdate, aURI, aReferrerURI, aClientID)
, mParserState(PARSE_INIT)
, mNeedsUpdate(PR_TRUE)
, mManifestHashInitialized(PR_FALSE)
{
}
nsOfflineManifestItem::~nsOfflineManifestItem()
{
@@ -782,52 +752,30 @@ nsOfflineCacheUpdate::nsOfflineCacheUpda
{
}
nsOfflineCacheUpdate::~nsOfflineCacheUpdate()
{
LOG(("nsOfflineCacheUpdate::~nsOfflineCacheUpdate [%p]", this));
}
-/* static */
-nsresult
-nsOfflineCacheUpdate::GetCacheKey(nsIURI *aURI, nsACString &aKey)
-{
- aKey.Truncate();
-
- nsCOMPtr<nsIURI> newURI;
- nsresult rv = aURI->Clone(getter_AddRefs(newURI));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIURL> newURL;
- newURL = do_QueryInterface(newURI);
- if (newURL) {
- newURL->SetRef(EmptyCString());
- }
-
- rv = newURI->GetAsciiSpec(aKey);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
nsresult
nsOfflineCacheUpdate::Init(PRBool aPartialUpdate,
nsIURI *aManifestURI,
nsIURI *aDocumentURI)
{
nsresult rv;
// Make sure the service has been initialized
nsOfflineCacheUpdateService* service =
nsOfflineCacheUpdateService::EnsureService();
if (!service)
return NS_ERROR_FAILURE;
- LOG(("nsOfflineCacheUpdate::Init [%p, %d]", this, aPartialUpdate));
+ LOG(("nsOfflineCacheUpdate::Init [%p]", this));
mPartialUpdate = aPartialUpdate;
// Only http and https applications are supported.
PRBool match;
rv = aManifestURI->SchemeIs("http", &match);
NS_ENSURE_SUCCESS(rv, rv);
@@ -840,41 +788,68 @@ nsOfflineCacheUpdate::Init(PRBool aParti
mManifestURI = aManifestURI;
rv = mManifestURI->GetAsciiHost(mUpdateDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString manifestSpec;
- rv = GetCacheKey(mManifestURI, manifestSpec);
+ rv = mManifestURI->GetAsciiSpec(manifestSpec);
NS_ENSURE_SUCCESS(rv, rv);
+ PRInt32 ref = manifestSpec.FindChar('#');
+ if (ref != kNotFound)
+ manifestSpec.Truncate(ref);
+
+ mManifestOwnerSpec = manifestSpec;
+ mManifestOwnerSpec.AppendLiteral("#manifest");
+
+ mDynamicOwnerSpec = manifestSpec;
+ mDynamicOwnerSpec.AppendLiteral("#dynamic");
+
mDocumentURI = aDocumentURI;
- nsCOMPtr<nsIApplicationCacheService> cacheService =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
+ nsCOMPtr<nsICacheService> cacheService =
+ do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- rv = cacheService->GetActiveCache(manifestSpec,
- getter_AddRefs(mPreviousApplicationCache));
+ nsCOMPtr<nsICacheSession> session;
+ rv = cacheService->CreateSession("HTTP-offline",
+ nsICache::STORE_OFFLINE,
+ nsICache::STREAM_BASED,
+ getter_AddRefs(session));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mMainCacheSession = do_QueryInterface(session, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- // Partial updates to existing application caches don't need a new cache.
- if (aPartialUpdate && mPreviousApplicationCache) {
- mApplicationCache = mPreviousApplicationCache;
+ // Partial updates don't use temporary cache sessions
+ if (aPartialUpdate) {
+ mCacheSession = mMainCacheSession;
} else {
- rv = cacheService->CreateApplicationCache(manifestSpec,
- getter_AddRefs(mApplicationCache));
+ rv = cacheService->CreateTemporaryClientID(nsICache::STORE_OFFLINE,
+ mClientID);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = cacheService->CreateSession(mClientID.get(),
+ nsICache::STORE_OFFLINE,
+ nsICache::STREAM_BASED,
+ getter_AddRefs(session));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mCacheSession = do_QueryInterface(session, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // The manifest implicitly owns itself.
+ rv = mCacheSession->AddOwnedKey(mUpdateDomain, mManifestOwnerSpec,
+ manifestSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
- rv = mApplicationCache->GetClientID(mClientID);
- NS_ENSURE_SUCCESS(rv, rv);
-
mState = STATE_INITIALIZED;
return NS_OK;
}
nsresult
nsOfflineCacheUpdate::HandleManifest(PRBool *aDoUpdate)
{
@@ -891,31 +866,27 @@ nsOfflineCacheUpdate::HandleManifest(PRB
if (!mManifestItem->NeedsUpdate()) {
return NS_OK;
}
// Add items requested by the manifest.
const nsCOMArray<nsIURI> &manifestURIs = mManifestItem->GetExplicitURIs();
for (PRInt32 i = 0; i < manifestURIs.Count(); i++) {
- rv = AddURI(manifestURIs[i], nsIApplicationCache::ITEM_EXPLICIT);
+ rv = AddURI(manifestURIs[i], mManifestOwnerSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
// The document that requested the manifest is implicitly included
// as part of that manifest update.
- rv = AddURI(mDocumentURI, nsIApplicationCache::ITEM_IMPLICIT);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Add items previously cached implicitly
- rv = AddExistingItems(nsIApplicationCache::ITEM_IMPLICIT);
+ rv = AddURI(mDocumentURI, mManifestOwnerSpec);
NS_ENSURE_SUCCESS(rv, rv);
// Add items requested by the script API
- rv = AddExistingItems(nsIApplicationCache::ITEM_DYNAMIC);
+ rv = AddOwnedItems(mDynamicOwnerSpec);
NS_ENSURE_SUCCESS(rv, rv);
*aDoUpdate = PR_TRUE;
return NS_OK;
}
void
@@ -946,25 +917,16 @@ nsOfflineCacheUpdate::LoadCompleted()
if (!doUpdate) {
mSucceeded = PR_FALSE;
NotifyNoUpdate();
Finish();
return;
}
- rv = mApplicationCache->MarkEntry(mManifestItem->mCacheKey,
- mManifestItem->mItemType);
- if (NS_FAILED(rv)) {
- mSucceeded = PR_FALSE;
- NotifyError();
- Finish();
- return;
- }
-
mState = STATE_DOWNLOADING;
NotifyDownloading();
// Start fetching resources.
ProcessNextURI();
return;
}
@@ -980,24 +942,16 @@ nsOfflineCacheUpdate::LoadCompleted()
// Check for failures. 4XX and 5XX errors will cause the update to fail.
if (NS_FAILED(rv) || status == 0 || status >= 400) {
mSucceeded = PR_FALSE;
NotifyError();
Finish();
return;
}
- rv = mApplicationCache->MarkEntry(item->mCacheKey, item->mItemType);
- if (NS_FAILED(rv)) {
- mSucceeded = PR_FALSE;
- NotifyError();
- Finish();
- return;
- }
-
rv = NotifyCompleted(item);
if (NS_FAILED(rv)) return;
ProcessNextURI();
}
nsresult
nsOfflineCacheUpdate::Begin()
@@ -1012,19 +966,17 @@ nsOfflineCacheUpdate::Begin()
ProcessNextURI();
return NS_OK;
}
// Start checking the manifest.
nsCOMPtr<nsIURI> uri;
mManifestItem = new nsOfflineManifestItem(this, mManifestURI,
- mDocumentURI,
- mPreviousApplicationCache,
- mClientID);
+ mDocumentURI, mClientID);
if (!mManifestItem) {
return NS_ERROR_OUT_OF_MEMORY;
}
mState = STATE_CHECKING;
NotifyChecking();
nsresult rv = mManifestItem->OpenChannel();
@@ -1052,35 +1004,35 @@ nsOfflineCacheUpdate::Cancel()
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsOfflineCacheUpdate <private>
//-----------------------------------------------------------------------------
nsresult
-nsOfflineCacheUpdate::AddExistingItems(PRUint32 aType)
+nsOfflineCacheUpdate::AddOwnedItems(const nsACString &aOwnerURI)
{
- if (!mPreviousApplicationCache) {
- return NS_OK;
- }
-
- PRUint32 count = 0;
- char **keys = nsnull;
- nsresult rv = mPreviousApplicationCache->GatherEntries(aType,
- &count, &keys);
+ PRUint32 count;
+ char **keys;
+ nsresult rv = mMainCacheSession->GetOwnedKeys(mUpdateDomain, aOwnerURI,
+ &count, &keys);
NS_ENSURE_SUCCESS(rv, rv);
AutoFreeArray autoFree(count, keys);
for (PRUint32 i = 0; i < count; i++) {
nsCOMPtr<nsIURI> uri;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), keys[i]))) {
- rv = AddURI(uri, aType);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsRefPtr<nsOfflineCacheUpdateItem> item =
+ new nsOfflineCacheUpdateItem(this, uri, mDocumentURI,
+ mClientID);
+ if (!item) return NS_ERROR_OUT_OF_MEMORY;
+
+ mItems.AppendElement(item);
}
}
return NS_OK;
}
nsresult
nsOfflineCacheUpdate::ProcessNextURI()
@@ -1133,18 +1085,16 @@ nsOfflineCacheUpdate::GatherObservers(ns
return NS_OK;
}
nsresult
nsOfflineCacheUpdate::NotifyError()
{
LOG(("nsOfflineCacheUpdate::NotifyError [%p]", this));
- mState = STATE_FINISHED;
-
nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
nsresult rv = GatherObservers(observers);
NS_ENSURE_SUCCESS(rv, rv);
for (PRInt32 i = 0; i < observers.Count(); i++) {
observers[i]->Error(this);
}
@@ -1167,18 +1117,16 @@ nsOfflineCacheUpdate::NotifyChecking()
return NS_OK;
}
nsresult
nsOfflineCacheUpdate::NotifyNoUpdate()
{
LOG(("nsOfflineCacheUpdate::NotifyNoUpdate [%p]", this));
- mState = STATE_FINISHED;
-
nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
nsresult rv = GatherObservers(observers);
NS_ENSURE_SUCCESS(rv, rv);
for (PRInt32 i = 0; i < observers.Count(); i++) {
observers[i]->NoUpdate(this);
}
@@ -1243,30 +1191,28 @@ nsOfflineCacheUpdate::Finish()
nsOfflineCacheUpdateService* service =
nsOfflineCacheUpdateService::EnsureService();
if (!service)
return NS_ERROR_FAILURE;
if (!mPartialUpdate) {
if (mSucceeded) {
- nsresult rv = mApplicationCache->Activate();
+ nsresult rv = mMainCacheSession->MergeTemporaryClientID(mClientID);
if (NS_FAILED(rv)) {
NotifyError();
mSucceeded = PR_FALSE;
}
}
if (!mSucceeded) {
// Update was not merged, mark all the loads as failures
for (PRUint32 i = 0; i < mItems.Length(); i++) {
mItems[i]->Cancel();
}
-
- mApplicationCache->Discard();
}
}
return service->UpdateFinished(this);
}
//-----------------------------------------------------------------------------
// nsOfflineCacheUpdate::nsIOfflineCacheUpdate
@@ -1320,85 +1266,73 @@ nsOfflineCacheUpdate::GetSucceeded(PRBoo
{
NS_ENSURE_TRUE(mState == STATE_FINISHED, NS_ERROR_NOT_AVAILABLE);
*aSucceeded = mSucceeded;
return NS_OK;
}
-NS_IMETHODIMP
-nsOfflineCacheUpdate::GetIsUpgrade(PRBool *aIsUpgrade)
-{
- NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
-
- *aIsUpgrade = (mPreviousApplicationCache != nsnull);
-
- return NS_OK;
-}
-
nsresult
-nsOfflineCacheUpdate::AddURI(nsIURI *aURI, PRUint32 aType)
+nsOfflineCacheUpdate::AddURI(nsIURI *aURI, const nsACString &aOwnerSpec)
{
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
if (mState >= STATE_DOWNLOADING)
return NS_ERROR_NOT_AVAILABLE;
- // Resource URIs must have the same scheme as the manifest.
+ // Manifest URIs must have the same scheme as the manifest.
nsCAutoString scheme;
aURI->GetScheme(scheme);
PRBool match;
if (NS_FAILED(mManifestURI->SchemeIs(scheme.get(), &match)) || !match)
return NS_ERROR_FAILURE;
+ // Save the cache key as an owned URI
+ nsCAutoString spec;
+ nsresult rv = aURI->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // url fragments aren't used in cache keys
+ nsCAutoString::const_iterator specStart, specEnd;
+ spec.BeginReading(specStart);
+ spec.EndReading(specEnd);
+ if (FindCharInReadable('#', specStart, specEnd)) {
+ spec.BeginReading(specEnd);
+ rv = mCacheSession->AddOwnedKey(mUpdateDomain, aOwnerSpec,
+ Substring(specEnd, specStart));
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ rv = mCacheSession->AddOwnedKey(mUpdateDomain, aOwnerSpec, spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
// Don't fetch the same URI twice.
for (PRUint32 i = 0; i < mItems.Length(); i++) {
PRBool equals;
if (NS_SUCCEEDED(mItems[i]->mURI->Equals(aURI, &equals)) && equals) {
- // retain both types.
- mItems[i]->mItemType |= aType;
return NS_OK;
}
}
nsRefPtr<nsOfflineCacheUpdateItem> item =
- new nsOfflineCacheUpdateItem(this, aURI, mDocumentURI,
- mPreviousApplicationCache, mClientID,
- aType);
+ new nsOfflineCacheUpdateItem(this, aURI, mDocumentURI, mClientID);
if (!item) return NS_ERROR_OUT_OF_MEMORY;
mItems.AppendElement(item);
mAddedItems = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsOfflineCacheUpdate::AddDynamicURI(nsIURI *aURI)
{
- // If this is a partial update and the resource is already in the
- // cache, we should only mark the entry, not fetch it again.
- if (mPartialUpdate) {
- nsCAutoString key;
- GetCacheKey(aURI, key);
-
- PRUint32 types;
- nsresult rv = mApplicationCache->GetTypes(key, &types);
- if (NS_SUCCEEDED(rv)) {
- if (!(types & nsIApplicationCache::ITEM_DYNAMIC)) {
- mApplicationCache->MarkEntry
- (key, nsIApplicationCache::ITEM_DYNAMIC);
- }
- return NS_OK;
- }
- }
-
- return AddURI(aURI, nsIApplicationCache::ITEM_DYNAMIC);
+ return AddURI(aURI, mDynamicOwnerSpec);
}
NS_IMETHODIMP
nsOfflineCacheUpdate::GetCount(PRUint32 *aNumItems)
{
LOG(("nsOfflineCacheUpdate::GetNumItems [%p, num=%d]",
this, mItems.Length()));
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -47,17 +47,18 @@
#include "nsICacheService.h"
#include "nsIChannelEventSink.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNode.h"
#include "nsIDOMLoadStatus.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
-#include "nsIApplicationCache.h"
+#include "nsIOfflineCacheSession.h"
+#include "nsIPrefetchService.h"
#include "nsIRequestObserver.h"
#include "nsIRunnable.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
#include "nsIWebProgressListener.h"
#include "nsClassHashtable.h"
#include "nsString.h"
#include "nsTArray.h"
@@ -81,27 +82,22 @@ public:
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIRUNNABLE
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
nsOfflineCacheUpdateItem(nsOfflineCacheUpdate *aUpdate,
nsIURI *aURI,
nsIURI *aReferrerURI,
- nsIApplicationCache *aPreviousApplicationCache,
- const nsACString &aClientID,
- PRUint32 aType);
+ const nsACString &aClientID);
virtual ~nsOfflineCacheUpdateItem();
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mReferrerURI;
- nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
nsCString mClientID;
- nsCString mCacheKey;
- PRUint32 mItemType;
nsresult OpenChannel();
nsresult Cancel();
private:
nsOfflineCacheUpdate* mUpdate;
nsCOMPtr<nsIChannel> mChannel;
PRUint16 mState;
@@ -115,17 +111,16 @@ class nsOfflineManifestItem : public nsO
{
public:
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
nsOfflineManifestItem(nsOfflineCacheUpdate *aUpdate,
nsIURI *aURI,
nsIURI *aReferrerURI,
- nsIApplicationCache *aPreviousApplicationCache,
const nsACString &aClientID);
virtual ~nsOfflineManifestItem();
nsCOMArray<nsIURI> &GetExplicitURIs() { return mExplicitURIs; }
PRBool ParseSucceeded()
{ return (mParserState != PARSE_INIT && mParserState != PARSE_ERROR); }
PRBool NeedsUpdate() { return mParserState != PARSE_INIT && mNeedsUpdate; }
@@ -177,32 +172,29 @@ class nsOfflineCacheUpdate : public nsIO
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOFFLINECACHEUPDATE
nsOfflineCacheUpdate();
~nsOfflineCacheUpdate();
- static nsresult GetCacheKey(nsIURI *aURI, nsACString &aKey);
-
nsresult Init();
nsresult Begin();
nsresult Cancel();
void LoadCompleted();
-
private:
nsresult HandleManifest(PRBool *aDoUpdate);
- nsresult AddURI(nsIURI *aURI, PRUint32 aItemType);
+ nsresult AddURI(nsIURI *aURI, const nsACString &aOwnerSpec);
nsresult ProcessNextURI();
- nsresult AddExistingItems(PRUint32 aType);
+ nsresult AddOwnedItems(const nsACString &aOwnerURI);
nsresult GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
nsresult NotifyError();
nsresult NotifyChecking();
nsresult NotifyNoUpdate();
nsresult NotifyDownloading();
nsresult NotifyStarted(nsOfflineCacheUpdateItem *aItem);
nsresult NotifyCompleted(nsOfflineCacheUpdateItem *aItem);
@@ -217,22 +209,24 @@ private:
STATE_FINISHED
} mState;
PRBool mAddedItems;
PRBool mPartialUpdate;
PRBool mSucceeded;
nsCString mUpdateDomain;
nsCOMPtr<nsIURI> mManifestURI;
+ nsCString mManifestOwnerSpec;
+ nsCString mDynamicOwnerSpec;
nsCOMPtr<nsIURI> mDocumentURI;
nsCString mClientID;
- nsCOMPtr<nsIApplicationCache> mApplicationCache;
- nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
+ nsCOMPtr<nsIOfflineCacheSession> mCacheSession;
+ nsCOMPtr<nsIOfflineCacheSession> mMainCacheSession;
nsCOMPtr<nsIObserverService> mObserverService;
nsRefPtr<nsOfflineManifestItem> mManifestItem;
/* Items being updated */
PRInt32 mCurrentItem;
nsTArray<nsRefPtr<nsOfflineCacheUpdateItem> > mItems;