зеркало из https://github.com/mozilla/pjs.git
Bug 648429: HTTP cache: compress all compressible files; r=michal.novotny
This commit is contained in:
Родитель
817c9e11aa
Коммит
67cc765f77
|
@ -108,6 +108,9 @@ pref("browser.cache.offline.capacity", 5120); // kilobytes
|
|||
pref("offline-apps.quota.max", 2048); // kilobytes
|
||||
pref("offline-apps.quota.warn", 1024); // kilobytes
|
||||
|
||||
/* zlib compression level used for cache compression */
|
||||
pref("browser.cache.compression_level", 1);
|
||||
|
||||
/* protocol warning prefs */
|
||||
pref("network.protocol-handler.warn-external.tel", false);
|
||||
pref("network.protocol-handler.warn-external.mailto", false);
|
||||
|
|
|
@ -92,6 +92,12 @@ pref("offline-apps.quota.max", 204800);
|
|||
// (in kilobytes)
|
||||
pref("offline-apps.quota.warn", 51200);
|
||||
|
||||
// zlib compression level used for cache compression:
|
||||
// 0 => disable compression
|
||||
// 1 => best speed
|
||||
// 9 => best compression
|
||||
pref("browser.cache.compression_level", 5);
|
||||
|
||||
// Whether or not indexedDB is enabled.
|
||||
pref("dom.indexedDB.enabled", true);
|
||||
// Space to allow indexedDB databases before prompting (in MB).
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
#include "nsIOutputStream.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#define kMinDecompressReadBufLen 1024
|
||||
#define kMinCompressWriteBufLen 1024
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsCacheEntryDescriptor,
|
||||
nsICacheEntryDescriptor,
|
||||
nsICacheEntryInfo)
|
||||
|
@ -213,7 +216,25 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result)
|
|||
nsCacheServiceAutoLock lock;
|
||||
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
const char* val = mCacheEntry->GetMetaDataElement("uncompressed-len");
|
||||
if (!val) {
|
||||
*result = mCacheEntry->DataSize();
|
||||
} else {
|
||||
*result = atol(val);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsCacheEntryDescriptor::GetStorageDataSize(PRUint32 *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
nsCacheServiceAutoLock lock;
|
||||
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
*result = mCacheEntry->DataSize();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -276,8 +297,14 @@ nsCacheEntryDescriptor::OpenInputStream(PRUint32 offset, nsIInputStream ** resul
|
|||
return NS_ERROR_CACHE_READ_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
nsInputStreamWrapper* cacheInput =
|
||||
new nsInputStreamWrapper(this, offset);
|
||||
nsInputStreamWrapper* cacheInput = nsnull;
|
||||
const char *val;
|
||||
val = mCacheEntry->GetMetaDataElement("uncompressed-len");
|
||||
if (val) {
|
||||
cacheInput = new nsDecompressInputStreamWrapper(this, offset);
|
||||
} else {
|
||||
cacheInput = new nsInputStreamWrapper(this, offset);
|
||||
}
|
||||
if (!cacheInput) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*result = cacheInput);
|
||||
|
@ -299,8 +326,15 @@ nsCacheEntryDescriptor::OpenOutputStream(PRUint32 offset, nsIOutputStream ** res
|
|||
return NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
nsOutputStreamWrapper* cacheOutput =
|
||||
new nsOutputStreamWrapper(this, offset);
|
||||
nsOutputStreamWrapper* cacheOutput = nsnull;
|
||||
PRInt32 compressionLevel = nsCacheService::CacheCompressionLevel();
|
||||
const char *val;
|
||||
val = mCacheEntry->GetMetaDataElement("uncompressed-len");
|
||||
if ((compressionLevel > 0) && val) {
|
||||
cacheOutput = new nsCompressOutputStreamWrapper(this, offset);
|
||||
} else {
|
||||
cacheOutput = new nsOutputStreamWrapper(this, offset);
|
||||
}
|
||||
if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*result = cacheOutput);
|
||||
|
@ -512,7 +546,7 @@ nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
|
|||
|
||||
|
||||
/******************************************************************************
|
||||
* nsCacheInputStream - a wrapper for nsIInputstream keeps the cache entry
|
||||
* nsCacheInputStream - a wrapper for nsIInputStream keeps the cache entry
|
||||
* open while referenced.
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -587,9 +621,136 @@ nsInputStreamWrapper::IsNonBlocking(bool *result)
|
|||
|
||||
|
||||
/******************************************************************************
|
||||
* nsCacheOutputStream - a wrapper for nsIOutputstream to track the amount of
|
||||
* data written to a cache entry.
|
||||
* - also keeps the cache entry open while referenced.
|
||||
* nsDecompressInputStreamWrapper - an input stream wrapper that decompresses
|
||||
******************************************************************************/
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsDecompressInputStreamWrapper,
|
||||
nsIInputStream)
|
||||
|
||||
NS_IMETHODIMP nsCacheEntryDescriptor::
|
||||
nsDecompressInputStreamWrapper::Read(char * buf,
|
||||
PRUint32 count,
|
||||
PRUint32 *countRead)
|
||||
{
|
||||
int zerr = Z_OK;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mStreamInitialized) {
|
||||
rv = InitZstream();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
mZstream.next_out = (Bytef*)buf;
|
||||
mZstream.avail_out = count;
|
||||
|
||||
if (mReadBufferLen < count) {
|
||||
// Allocate a buffer for reading from the input stream. This will
|
||||
// determine the max number of compressed bytes read from the
|
||||
// input stream at one time. Making the buffer size proportional
|
||||
// to the request size is not necessary, but helps minimize the
|
||||
// number of read requests to the input stream.
|
||||
PRUint32 newBufLen = NS_MAX(count, (PRUint32)kMinDecompressReadBufLen);
|
||||
unsigned char* newBuf;
|
||||
newBuf = (unsigned char*)nsMemory::Realloc(mReadBuffer,
|
||||
newBufLen);
|
||||
if (newBuf) {
|
||||
mReadBuffer = newBuf;
|
||||
mReadBufferLen = newBufLen;
|
||||
}
|
||||
if (!mReadBuffer) {
|
||||
mReadBufferLen = 0;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// read and inflate data until the output buffer is full, or
|
||||
// there is no more data to read
|
||||
while (NS_SUCCEEDED(rv) &&
|
||||
zerr == Z_OK &&
|
||||
mZstream.avail_out > 0 &&
|
||||
count > 0) {
|
||||
if (mZstream.avail_in == 0) {
|
||||
rv = nsInputStreamWrapper::Read((char*)mReadBuffer,
|
||||
mReadBufferLen,
|
||||
&mZstream.avail_in);
|
||||
if (NS_FAILED(rv) || !mZstream.avail_in) {
|
||||
break;
|
||||
}
|
||||
mZstream.next_in = mReadBuffer;
|
||||
}
|
||||
zerr = inflate(&mZstream, Z_NO_FLUSH);
|
||||
if (zerr == Z_STREAM_END) {
|
||||
// The compressed data may have been stored in multiple
|
||||
// chunks/streams. To allow for this case, re-initialize
|
||||
// the inflate stream and continue decompressing from
|
||||
// the next byte.
|
||||
Bytef * saveNextIn = mZstream.next_in;
|
||||
unsigned int saveAvailIn = mZstream.avail_in;
|
||||
Bytef * saveNextOut = mZstream.next_out;
|
||||
unsigned int saveAvailOut = mZstream.avail_out;
|
||||
inflateReset(&mZstream);
|
||||
mZstream.next_in = saveNextIn;
|
||||
mZstream.avail_in = saveAvailIn;
|
||||
mZstream.next_out = saveNextOut;
|
||||
mZstream.avail_out = saveAvailOut;
|
||||
zerr = Z_OK;
|
||||
} else if (zerr != Z_OK) {
|
||||
rv = NS_ERROR_INVALID_CONTENT_ENCODING;
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*countRead = count - mZstream.avail_out;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsCacheEntryDescriptor::
|
||||
nsDecompressInputStreamWrapper::Close()
|
||||
{
|
||||
EndZstream();
|
||||
if (mReadBuffer) {
|
||||
nsMemory::Free(mReadBuffer);
|
||||
mReadBuffer = 0;
|
||||
mReadBufferLen = 0;
|
||||
}
|
||||
return nsInputStreamWrapper::Close();
|
||||
}
|
||||
|
||||
nsresult nsCacheEntryDescriptor::
|
||||
nsDecompressInputStreamWrapper::InitZstream()
|
||||
{
|
||||
// Initialize zlib inflate stream
|
||||
mZstream.zalloc = Z_NULL;
|
||||
mZstream.zfree = Z_NULL;
|
||||
mZstream.opaque = Z_NULL;
|
||||
mZstream.next_out = Z_NULL;
|
||||
mZstream.avail_out = 0;
|
||||
mZstream.next_in = Z_NULL;
|
||||
mZstream.avail_in = 0;
|
||||
if (inflateInit(&mZstream) != Z_OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mStreamInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCacheEntryDescriptor::
|
||||
nsDecompressInputStreamWrapper::EndZstream()
|
||||
{
|
||||
if (mStreamInitialized && !mStreamEnded) {
|
||||
inflateEnd(&mZstream);
|
||||
mStreamEnded = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nsOutputStreamWrapper - a wrapper for nsIOutputstream to track the amount of
|
||||
* data written to a cache entry.
|
||||
* - also keeps the cache entry open while referenced.
|
||||
******************************************************************************/
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper,
|
||||
|
@ -704,3 +865,144 @@ nsOutputStreamWrapper::IsNonBlocking(bool *result)
|
|||
*result = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nsCompressOutputStreamWrapper - an output stream wrapper that compresses
|
||||
* data before it is written
|
||||
******************************************************************************/
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsCompressOutputStreamWrapper,
|
||||
nsIOutputStream)
|
||||
|
||||
NS_IMETHODIMP nsCacheEntryDescriptor::
|
||||
nsCompressOutputStreamWrapper::Write(const char * buf,
|
||||
PRUint32 count,
|
||||
PRUint32 * result)
|
||||
{
|
||||
int zerr = Z_OK;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mStreamInitialized) {
|
||||
rv = InitZstream();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mWriteBuffer) {
|
||||
// Once allocated, this buffer is referenced by the zlib stream and
|
||||
// cannot be grown. We use 2x(initial write request) to approximate
|
||||
// a stream buffer size proportional to request buffers.
|
||||
mWriteBufferLen = NS_MAX(count*2, (PRUint32)kMinCompressWriteBufLen);
|
||||
mWriteBuffer = (unsigned char*)nsMemory::Alloc(mWriteBufferLen);
|
||||
if (!mWriteBuffer) {
|
||||
mWriteBufferLen = 0;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mZstream.next_out = mWriteBuffer;
|
||||
mZstream.avail_out = mWriteBufferLen;
|
||||
}
|
||||
|
||||
// Compress (deflate) the requested buffer. Keep going
|
||||
// until the entire buffer has been deflated.
|
||||
mZstream.avail_in = count;
|
||||
mZstream.next_in = (Bytef*)buf;
|
||||
while (mZstream.avail_in > 0) {
|
||||
zerr = deflate(&mZstream, Z_NO_FLUSH);
|
||||
if (zerr == Z_STREAM_ERROR) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Note: Z_BUF_ERROR is non-fatal and sometimes expected here.
|
||||
|
||||
// If the compression stream output buffer is filled, write
|
||||
// it out to the underlying stream wrapper.
|
||||
if (mZstream.avail_out == 0) {
|
||||
rv = WriteBuffer();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
*result = count;
|
||||
mUncompressedCount += *result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCacheEntryDescriptor::
|
||||
nsCompressOutputStreamWrapper::Close()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
int zerr = 0;
|
||||
|
||||
if (mStreamInitialized) {
|
||||
// complete compression of any data remaining in the zlib stream
|
||||
do {
|
||||
zerr = deflate(&mZstream, Z_FINISH);
|
||||
rv = WriteBuffer();
|
||||
} while (zerr == Z_OK && rv == NS_OK);
|
||||
deflateEnd(&mZstream);
|
||||
}
|
||||
|
||||
if (mDescriptor->CacheEntry()) {
|
||||
nsCAutoString uncompressedLenStr;
|
||||
rv = mDescriptor->GetMetaDataElement("uncompressed-len",
|
||||
getter_Copies(uncompressedLenStr));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRInt32 oldCount = uncompressedLenStr.ToInteger(&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mUncompressedCount += oldCount;
|
||||
}
|
||||
}
|
||||
uncompressedLenStr.Adopt(0);
|
||||
uncompressedLenStr.AppendInt(mUncompressedCount);
|
||||
rv = mDescriptor->SetMetaDataElement("uncompressed-len",
|
||||
uncompressedLenStr.get());
|
||||
}
|
||||
|
||||
if (mWriteBuffer) {
|
||||
nsMemory::Free(mWriteBuffer);
|
||||
mWriteBuffer = 0;
|
||||
mWriteBufferLen = 0;
|
||||
}
|
||||
|
||||
return nsOutputStreamWrapper::Close();
|
||||
}
|
||||
|
||||
nsresult nsCacheEntryDescriptor::
|
||||
nsCompressOutputStreamWrapper::InitZstream()
|
||||
{
|
||||
// Determine compression level: Aggressive compression
|
||||
// may impact performance on mobile devices, while a
|
||||
// lower compression level still provides substantial
|
||||
// space savings for many text streams.
|
||||
PRInt32 compressionLevel = nsCacheService::CacheCompressionLevel();
|
||||
|
||||
// Initialize zlib deflate stream
|
||||
mZstream.zalloc = Z_NULL;
|
||||
mZstream.zfree = Z_NULL;
|
||||
mZstream.opaque = Z_NULL;
|
||||
if (deflateInit2(&mZstream, compressionLevel, Z_DEFLATED,
|
||||
MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mZstream.next_in = Z_NULL;
|
||||
mZstream.avail_in = 0;
|
||||
|
||||
mStreamInitialized = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCacheEntryDescriptor::
|
||||
nsCompressOutputStreamWrapper::WriteBuffer()
|
||||
{
|
||||
PRUint32 bytesToWrite = mWriteBufferLen - mZstream.avail_out;
|
||||
PRUint32 result = 0;
|
||||
nsresult rv = nsCacheEntryDescriptor::nsOutputStreamWrapper::Write(
|
||||
(const char *)mWriteBuffer, bytesToWrite, &result);
|
||||
mZstream.next_out = mWriteBuffer;
|
||||
mZstream.avail_out = mWriteBufferLen;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsIOutputStream.h"
|
||||
#include "nsCacheService.h"
|
||||
#include "nsIDiskCacheStreamInternal.h"
|
||||
#include "zlib.h"
|
||||
|
||||
/******************************************************************************
|
||||
* nsCacheEntryDescriptor
|
||||
|
@ -129,6 +130,37 @@ private:
|
|||
friend class nsInputStreamWrapper;
|
||||
|
||||
|
||||
class nsDecompressInputStreamWrapper : public nsInputStreamWrapper {
|
||||
private:
|
||||
unsigned char* mReadBuffer;
|
||||
PRUint32 mReadBufferLen;
|
||||
z_stream mZstream;
|
||||
PRBool mStreamInitialized;
|
||||
PRBool mStreamEnded;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsDecompressInputStreamWrapper(nsCacheEntryDescriptor * desc,
|
||||
PRUint32 off)
|
||||
: nsInputStreamWrapper(desc, off)
|
||||
, mReadBuffer(0)
|
||||
, mReadBufferLen(0)
|
||||
, mStreamInitialized(PR_FALSE)
|
||||
, mStreamEnded(PR_FALSE)
|
||||
{
|
||||
}
|
||||
virtual ~nsDecompressInputStreamWrapper()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
NS_IMETHOD Read(char* buf, PRUint32 count, PRUint32 * result);
|
||||
NS_IMETHOD Close();
|
||||
private:
|
||||
nsresult InitZstream();
|
||||
nsresult EndZstream();
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* output stream wrapper class -
|
||||
*
|
||||
|
@ -136,7 +168,7 @@ private:
|
|||
* doesn't need any references to the stream wrapper.
|
||||
*************************************************************************/
|
||||
class nsOutputStreamWrapper : public nsIOutputStream {
|
||||
private:
|
||||
protected:
|
||||
nsCacheEntryDescriptor * mDescriptor;
|
||||
nsCOMPtr<nsIOutputStream> mOutput;
|
||||
PRUint32 mStartOffset;
|
||||
|
@ -170,6 +202,36 @@ private:
|
|||
};
|
||||
friend class nsOutputStreamWrapper;
|
||||
|
||||
class nsCompressOutputStreamWrapper : public nsOutputStreamWrapper {
|
||||
private:
|
||||
unsigned char* mWriteBuffer;
|
||||
PRUint32 mWriteBufferLen;
|
||||
z_stream mZstream;
|
||||
PRBool mStreamInitialized;
|
||||
PRUint32 mUncompressedCount;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsCompressOutputStreamWrapper(nsCacheEntryDescriptor * desc,
|
||||
PRUint32 off)
|
||||
: nsOutputStreamWrapper(desc, off)
|
||||
, mWriteBuffer(0)
|
||||
, mWriteBufferLen(0)
|
||||
, mStreamInitialized(PR_FALSE)
|
||||
, mUncompressedCount(0)
|
||||
{
|
||||
}
|
||||
virtual ~nsCompressOutputStreamWrapper()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
NS_IMETHOD Write(const char* buf, PRUint32 count, PRUint32 * result);
|
||||
NS_IMETHOD Close();
|
||||
private:
|
||||
nsresult InitZstream();
|
||||
nsresult WriteBuffer();
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
* nsCacheEntryDescriptor data members
|
||||
|
|
|
@ -105,6 +105,9 @@ using namespace mozilla;
|
|||
#define MEMORY_CACHE_CAPACITY_PREF "browser.cache.memory.capacity"
|
||||
#define MEMORY_CACHE_MAX_ENTRY_SIZE_PREF "browser.cache.memory.max_entry_size"
|
||||
|
||||
#define CACHE_COMPRESSION_LEVEL_PREF "browser.cache.compression_level"
|
||||
#define CACHE_COMPRESSION_LEVEL 1
|
||||
|
||||
static const char * observerList[] = {
|
||||
"profile-before-change",
|
||||
"profile-do-change",
|
||||
|
@ -122,7 +125,8 @@ static const char * prefList[] = {
|
|||
OFFLINE_CACHE_DIR_PREF,
|
||||
MEMORY_CACHE_ENABLE_PREF,
|
||||
MEMORY_CACHE_CAPACITY_PREF,
|
||||
MEMORY_CACHE_MAX_ENTRY_SIZE_PREF
|
||||
MEMORY_CACHE_MAX_ENTRY_SIZE_PREF,
|
||||
CACHE_COMPRESSION_LEVEL_PREF
|
||||
};
|
||||
|
||||
// Cache sizes, in KB
|
||||
|
@ -149,6 +153,7 @@ public:
|
|||
, mMemoryCacheCapacity(-1)
|
||||
, mMemoryCacheMaxEntrySize(-1) // -1 means "no limit"
|
||||
, mInPrivateBrowsing(false)
|
||||
, mCacheCompressionLevel(CACHE_COMPRESSION_LEVEL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -172,6 +177,8 @@ public:
|
|||
PRInt32 MemoryCacheCapacity();
|
||||
PRInt32 MemoryCacheMaxEntrySize() { return mMemoryCacheMaxEntrySize; }
|
||||
|
||||
PRInt32 CacheCompressionLevel();
|
||||
|
||||
static PRUint32 GetSmartCacheSize(const nsAString& cachePath,
|
||||
PRUint32 currentSize);
|
||||
|
||||
|
@ -193,6 +200,8 @@ private:
|
|||
PRInt32 mMemoryCacheMaxEntrySize; // in kilobytes
|
||||
|
||||
bool mInPrivateBrowsing;
|
||||
|
||||
PRInt32 mCacheCompressionLevel;
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheProfilePrefObserver, nsIObserver)
|
||||
|
@ -508,6 +517,12 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject,
|
|||
|
||||
mMemoryCacheMaxEntrySize = NS_MAX(-1, newMaxSize);
|
||||
nsCacheService::SetMemoryCacheMaxEntrySize(mMemoryCacheMaxEntrySize);
|
||||
} else if (!strcmp(CACHE_COMPRESSION_LEVEL_PREF, data.get())) {
|
||||
mCacheCompressionLevel = CACHE_COMPRESSION_LEVEL;
|
||||
(void)branch->GetIntPref(CACHE_COMPRESSION_LEVEL_PREF,
|
||||
&mCacheCompressionLevel);
|
||||
mCacheCompressionLevel = NS_MAX(0, mCacheCompressionLevel);
|
||||
mCacheCompressionLevel = NS_MIN(9, mCacheCompressionLevel);
|
||||
}
|
||||
} else if (!strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, topic)) {
|
||||
if (!strcmp(NS_PRIVATE_BROWSING_ENTER, data.get())) {
|
||||
|
@ -797,6 +812,14 @@ nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
|
|||
(void) branch->GetIntPref(MEMORY_CACHE_MAX_ENTRY_SIZE_PREF,
|
||||
&mMemoryCacheMaxEntrySize);
|
||||
mMemoryCacheMaxEntrySize = NS_MAX(-1, mMemoryCacheMaxEntrySize);
|
||||
|
||||
// read cache compression level pref
|
||||
mCacheCompressionLevel = CACHE_COMPRESSION_LEVEL;
|
||||
(void)branch->GetIntPref(CACHE_COMPRESSION_LEVEL_PREF,
|
||||
&mCacheCompressionLevel);
|
||||
mCacheCompressionLevel = NS_MAX(0, mCacheCompressionLevel);
|
||||
mCacheCompressionLevel = NS_MIN(9, mCacheCompressionLevel);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -930,6 +953,11 @@ nsCacheProfilePrefObserver::MemoryCacheCapacity()
|
|||
return capacity;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsCacheProfilePrefObserver::CacheCompressionLevel()
|
||||
{
|
||||
return mCacheCompressionLevel;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* nsProcessRequestEvent
|
||||
|
@ -2291,6 +2319,14 @@ nsCacheService::ValidateEntry(nsCacheEntry * entry)
|
|||
}
|
||||
|
||||
|
||||
PRInt32
|
||||
nsCacheService::CacheCompressionLevel()
|
||||
{
|
||||
PRInt32 level = gService->mObserver->CacheCompressionLevel();
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsCacheService::DeactivateEntry(nsCacheEntry * entry)
|
||||
{
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
|
||||
static nsresult ValidateEntry(nsCacheEntry * entry);
|
||||
|
||||
static PRInt32 CacheCompressionLevel();
|
||||
|
||||
/**
|
||||
* Methods called by any cache classes
|
||||
|
@ -176,6 +177,8 @@ public:
|
|||
|
||||
static void SetMemoryCache();
|
||||
|
||||
static void SetCacheCompressionLevel(PRInt32 level);
|
||||
|
||||
static void OnEnterExitPrivateBrowsing();
|
||||
|
||||
// Starts smart cache size computation if disk device is available
|
||||
|
|
|
@ -136,6 +136,12 @@ interface nsICacheEntryDescriptor : nsICacheEntryInfo
|
|||
*/
|
||||
attribute nsISupports securityInfo;
|
||||
|
||||
/**
|
||||
* Get the size of the cache entry data, as stored. This may differ
|
||||
* from the entry's dataSize, if the entry is compressed.
|
||||
*/
|
||||
readonly attribute unsigned long storageDataSize;
|
||||
|
||||
/**
|
||||
* Doom the cache entry this descriptor references in order to slate it for
|
||||
* removal. Once doomed a cache entry cannot be undoomed.
|
||||
|
|
|
@ -340,7 +340,7 @@ nsAboutCacheEntry::WriteCacheEntryDescription(nsIOutputStream *outputStream,
|
|||
// Data Size
|
||||
s.Truncate();
|
||||
PRUint32 dataSize;
|
||||
descriptor->GetDataSize(&dataSize);
|
||||
descriptor->GetStorageDataSize(&dataSize);
|
||||
s.AppendInt((PRInt32)dataSize); // XXX nsICacheEntryInfo interfaces should be fixed.
|
||||
APPEND_ROW("Data size", s);
|
||||
|
||||
|
@ -404,11 +404,8 @@ nsAboutCacheEntry::WriteCacheEntryDescription(nsIOutputStream *outputStream,
|
|||
"<pre>");
|
||||
PRUint32 hexDumpState = 0;
|
||||
char chunk[4096];
|
||||
while (dataSize) {
|
||||
PRUint32 count = NS_MIN<PRUint32>(dataSize, sizeof(chunk));
|
||||
if (NS_FAILED(stream->Read(chunk, count, &n)) || n == 0)
|
||||
break;
|
||||
dataSize -= n;
|
||||
while(NS_SUCCEEDED(stream->Read(chunk, sizeof(chunk), &n)) &&
|
||||
n > 0) {
|
||||
HexDump(&hexDumpState, chunk, n, buffer);
|
||||
outputStream->Write(buffer.get(), buffer.Length(), &n);
|
||||
buffer.Truncate();
|
||||
|
|
|
@ -3203,6 +3203,32 @@ nsHttpChannel::InstallCacheListener(PRUint32 offset)
|
|||
NS_ASSERTION(mCacheEntry, "no cache entry");
|
||||
NS_ASSERTION(mListener, "no listener");
|
||||
|
||||
nsCacheStoragePolicy policy;
|
||||
rv = mCacheEntry->GetStoragePolicy(&policy);
|
||||
if (NS_FAILED(rv)) {
|
||||
policy = nsICache::STORE_ON_DISK_AS_FILE;
|
||||
}
|
||||
|
||||
// If the content is compressible and the server has not compressed it,
|
||||
// mark the cache entry for compression.
|
||||
if ((mResponseHead->PeekHeader(nsHttp::Content_Encoding) == nsnull) && (
|
||||
policy != nsICache::STORE_ON_DISK_AS_FILE) && (
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_HTML) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_PLAIN) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_CSS) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_JAVASCRIPT) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_ECMASCRIPT) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(TEXT_XML) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_JAVASCRIPT) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_ECMASCRIPT) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XHTML_XML))) {
|
||||
rv = mCacheEntry->SetMetaDataElement("uncompressed-len", "0");
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("unable to mark cache entry for compression"));
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
rv = mCacheEntry->OpenOutputStream(offset, getter_AddRefs(out));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -3225,10 +3251,7 @@ nsHttpChannel::InstallCacheListener(PRUint32 offset)
|
|||
nsCOMPtr<nsIEventTarget> cacheIOTarget;
|
||||
serv->GetCacheIOTarget(getter_AddRefs(cacheIOTarget));
|
||||
|
||||
nsCacheStoragePolicy policy;
|
||||
rv = mCacheEntry->GetStoragePolicy(&policy);
|
||||
|
||||
if (NS_FAILED(rv) || policy == nsICache::STORE_ON_DISK_AS_FILE ||
|
||||
if (policy == nsICache::STORE_ON_DISK_AS_FILE ||
|
||||
!cacheIOTarget) {
|
||||
LOG(("nsHttpChannel::InstallCacheListener sync tee %p rv=%x policy=%d "
|
||||
"cacheIOTarget=%p", tee.get(), rv, policy, cacheIOTarget.get()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче