зеркало из https://github.com/mozilla/gecko-dev.git
Bug 649778 - document.write may cause a document to be written to disk cache even when the page has Cache-Control: no-store
This commit is contained in:
Родитель
b3f1940949
Коммит
7302ff3ce0
|
@ -300,5 +300,14 @@ _TEST_FILES = \
|
|||
test_bug694503.html \
|
||||
$(NULL)
|
||||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_bug649778.js \
|
||||
file_bug649778.html \
|
||||
file_bug649778.html^headers^ \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// Test for bug 649778 - document.write may cause a document to be written to disk cache even when the page has Cache-Control: no-store
|
||||
|
||||
// Globals
|
||||
var testPath = "http://mochi.test:8888/browser/content/html/content/test/";
|
||||
var popup;
|
||||
|
||||
function checkCache(url, policy, shouldExist)
|
||||
{
|
||||
var cache = Components.classes["@mozilla.org/network/cache-service;1"].
|
||||
getService(Components.interfaces.nsICacheService);
|
||||
var session = cache.createSession(
|
||||
"wyciwyg", policy,
|
||||
Components.interfaces.nsICache.STREAM_BASED);
|
||||
try {
|
||||
var cacheEntry = session.openCacheEntry(
|
||||
url, Components.interfaces.nsICache.ACCESS_READ, true);
|
||||
is(shouldExist, true, "Entry found");
|
||||
}
|
||||
catch (e) {
|
||||
is(shouldExist, false, "Entry not found");
|
||||
is(e.result, Components.results.NS_ERROR_CACHE_KEY_NOT_FOUND,
|
||||
"Invalid error");
|
||||
}
|
||||
}
|
||||
|
||||
function getPopupURL() {
|
||||
var sh = popup.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.sessionHistory;
|
||||
|
||||
return sh.getEntryAtIndex(sh.index, false).URI.spec;
|
||||
}
|
||||
|
||||
function testContinue() {
|
||||
var wyciwygURL = getPopupURL();
|
||||
is(wyciwygURL.substring(0, 10), "wyciwyg://", "Unexpected URL.");
|
||||
popup.close()
|
||||
|
||||
checkCache(wyciwygURL, Components.interfaces.nsICache.STORE_ON_DISK, false);
|
||||
checkCache(wyciwygURL, Components.interfaces.nsICache.STORE_IN_MEMORY, true);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function waitForWyciwygDocument() {
|
||||
try {
|
||||
var url = getPopupURL();
|
||||
if (url.substring(0, 10) == "wyciwyg://") {
|
||||
setTimeout(testContinue, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
setTimeout(waitForWyciwygDocument, 100);
|
||||
}
|
||||
|
||||
// Entry point from Mochikit
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
popup = window.open(testPath + "file_bug649778.html", "popup 0",
|
||||
"height=200,width=200,location=yes," +
|
||||
"menubar=yes,status=yes,toolbar=yes,dependent=yes");
|
||||
|
||||
waitForWyciwygDocument();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<script>
|
||||
function test() {
|
||||
document.open();
|
||||
document.write('<html><body>WYCIWYG DOCUMENT</body></html>');
|
||||
document.close();
|
||||
}
|
||||
</script>
|
||||
<body onload="setTimeout(test, 0);">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Cache-Control: no-store
|
|
@ -136,6 +136,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIRequest.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -1419,6 +1420,7 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
|
|||
nsCOMPtr<nsIURI> uri = callerDoc->GetDocumentURI();
|
||||
nsCOMPtr<nsIURI> baseURI = callerDoc->GetBaseURI();
|
||||
nsCOMPtr<nsIPrincipal> callerPrincipal = callerDoc->NodePrincipal();
|
||||
nsCOMPtr<nsIChannel> callerChannel = callerDoc->GetChannel();
|
||||
|
||||
// We're called from script. Make sure the script is from the same
|
||||
// origin, not just that the caller can access the document. This is
|
||||
|
@ -1490,6 +1492,21 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
|
|||
rv = channel->SetOwner(callerPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (callerChannel) {
|
||||
nsLoadFlags callerLoadFlags;
|
||||
rv = callerChannel->GetLoadFlags(&callerLoadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsLoadFlags loadFlags;
|
||||
rv = channel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
loadFlags |= callerLoadFlags & nsIRequest::INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
rv = channel->SetLoadFlags(loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Before we reset the doc notify the globalwindow of the change,
|
||||
// but only if we still have a window (i.e. our window object the
|
||||
// current inner window in our outer window).
|
||||
|
|
|
@ -978,6 +978,8 @@ nsHttpChannel::ProcessResponse()
|
|||
LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
|
||||
this, httpStatus));
|
||||
|
||||
UpdateInhibitPersistentCachingFlag();
|
||||
|
||||
if (mTransaction->SSLConnectFailed()) {
|
||||
if (!ShouldSSLProxyResponseContinue(httpStatus))
|
||||
return ProcessFailedSSLConnect(httpStatus);
|
||||
|
@ -1783,6 +1785,8 @@ nsHttpChannel::ProcessPartialContent()
|
|||
// make the cached response be the current response
|
||||
mResponseHead = mCachedResponseHead;
|
||||
|
||||
UpdateInhibitPersistentCachingFlag();
|
||||
|
||||
rv = UpdateExpirationTime();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -1864,6 +1868,8 @@ nsHttpChannel::ProcessNotModified()
|
|||
// make the cached response be the current response
|
||||
mResponseHead = mCachedResponseHead;
|
||||
|
||||
UpdateInhibitPersistentCachingFlag();
|
||||
|
||||
rv = UpdateExpirationTime();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -2848,6 +2854,8 @@ nsHttpChannel::ReadFromCache()
|
|||
if (mCachedResponseHead)
|
||||
mResponseHead = mCachedResponseHead;
|
||||
|
||||
UpdateInhibitPersistentCachingFlag();
|
||||
|
||||
// if we don't already have security info, try to get it from the cache
|
||||
// entry. there are two cases to consider here: 1) we are just reading
|
||||
// from the cache, or 2) this may be due to a 304 not modified response,
|
||||
|
@ -3002,16 +3010,6 @@ nsHttpChannel::InitCacheEntry()
|
|||
LOG(("nsHttpChannel::InitCacheEntry [this=%p entry=%p]\n",
|
||||
this, mCacheEntry.get()));
|
||||
|
||||
// The no-store directive within the 'Cache-Control:' header indicates
|
||||
// that we must not store the response in a persistent cache.
|
||||
if (mResponseHead->NoStore())
|
||||
mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
// Only cache SSL content on disk if the pref is set
|
||||
if (!gHttpHandler->IsPersistentHttpsCachingEnabled() &&
|
||||
mConnectionInfo->UsingSSL())
|
||||
mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
|
||||
rv = mCacheEntry->SetStoragePolicy(nsICache::STORE_IN_MEMORY);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -3028,6 +3026,19 @@ nsHttpChannel::InitCacheEntry()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::UpdateInhibitPersistentCachingFlag()
|
||||
{
|
||||
// The no-store directive within the 'Cache-Control:' header indicates
|
||||
// that we must not store the response in a persistent cache.
|
||||
if (mResponseHead->NoStore())
|
||||
mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
// Only cache SSL content on disk if the pref is set
|
||||
if (!gHttpHandler->IsPersistentHttpsCachingEnabled() &&
|
||||
mConnectionInfo->UsingSSL())
|
||||
mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::InitOfflineCacheEntry()
|
||||
|
|
|
@ -224,6 +224,7 @@ private:
|
|||
void CloseCacheEntry(bool doomOnFailure);
|
||||
void CloseOfflineCacheEntry();
|
||||
nsresult InitCacheEntry();
|
||||
void UpdateInhibitPersistentCachingFlag();
|
||||
nsresult InitOfflineCacheEntry();
|
||||
nsresult AddCacheEntryHeaders(nsICacheEntryDescriptor *entry);
|
||||
nsresult StoreAuthorizationMetaData(nsICacheEntryDescriptor *entry);
|
||||
|
|
|
@ -446,6 +446,11 @@ nsWyciwygChannel::WriteToCacheEntryInternal(const nsAString &aData, const nsACSt
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
|
||||
rv = mCacheEntry->SetMetaDataElement("inhibit-persistent-caching", "1");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
if (mSecurityInfo) {
|
||||
mCacheEntry->SetSecurityInfo(mSecurityInfo);
|
||||
}
|
||||
|
@ -720,6 +725,12 @@ nsWyciwygChannel::ReadFromCache()
|
|||
// Get the stored security info
|
||||
mCacheEntry->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
|
||||
nsCAutoString tmpStr;
|
||||
rv = mCacheEntry->GetMetaDataElement("inhibit-persistent-caching",
|
||||
getter_Copies(tmpStr));
|
||||
if (NS_SUCCEEDED(rv) && tmpStr == NS_LITERAL_CSTRING("1"))
|
||||
mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
// Get a transport to the cached data...
|
||||
rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
|
||||
if (NS_FAILED(rv))
|
||||
|
|
Загрузка…
Ссылка в новой задаче