Bug 648429: HTTP cache: compress all compressible files; r=michal.novotny

This commit is contained in:
Geoff Brown 2011-12-17 11:30:29 +01:00
Родитель 817c9e11aa
Коммит 67cc765f77
9 изменённых файлов: 458 добавлений и 20 удалений

Просмотреть файл

@ -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).

318
netwerk/cache/nsCacheEntryDescriptor.cpp поставляемый
Просмотреть файл

@ -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;
}

64
netwerk/cache/nsCacheEntryDescriptor.h поставляемый
Просмотреть файл

@ -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

38
netwerk/cache/nsCacheService.cpp поставляемый
Просмотреть файл

@ -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)
{

3
netwerk/cache/nsCacheService.h поставляемый
Просмотреть файл

@ -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

6
netwerk/cache/nsICacheEntryDescriptor.idl поставляемый
Просмотреть файл

@ -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()));