зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1487100 - Allow calling nsICacheInfoChannel.preferAlternativeDataType(altDataType, contentType) multiple times r=michal,luke
This patch changes the way we set and handle the preferred alternate data type. It is no longer just one choice, but a set of preferences, each conditional on the contentType of the resource. For example: var cc = chan.QueryInterface(Ci.nsICacheInfoChannel); cc.preferAlternativeDataType("js-bytecode", "text/javascript"); cc.preferAlternativeDataType("ammended-text", "text/plain"); cc.preferAlternativeDataType("something-else", ""); When loaded from the cache, the available alt-data type will be checked against "js-bytecode" if the contentType is "text/javascript", "ammended-text" if the contentType is "text/plain" or "something-else" for all contentTypes. Note that the alt-data type could be "something-else" even if the contentType is "text/javascript". The preferences are saved as an nsTArray<mozilla::Tuple<nsCString, nsCString>>. Differential Revision: https://phabricator.services.mozilla.com/D8071 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
8103abc63b
Коммит
e392dbc5dd
|
@ -734,7 +734,7 @@ FetchDriver::HttpFetch(const nsACString& aPreferredAlternativeDataType)
|
|||
if (!aPreferredAlternativeDataType.IsEmpty()) {
|
||||
nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(chan);
|
||||
if (cic) {
|
||||
cic->PreferAlternativeDataType(aPreferredAlternativeDataType);
|
||||
cic->PreferAlternativeDataType(aPreferredAlternativeDataType, EmptyCString());
|
||||
MOZ_ASSERT(!mAltDataListener);
|
||||
mAltDataListener =
|
||||
new AlternativeDataStreamListener(this, chan, aPreferredAlternativeDataType);
|
||||
|
|
|
@ -1109,7 +1109,7 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
|||
// Inform the HTTP cache that we prefer to have information coming from the
|
||||
// bytecode cache instead of the sources, if such entry is already registered.
|
||||
LOG(("ScriptLoadRequest (%p): Maybe request bytecode", aRequest));
|
||||
cic->PreferAlternativeDataType(nsContentUtils::JSBytecodeMimeType());
|
||||
cic->PreferAlternativeDataType(nsContentUtils::JSBytecodeMimeType(), EmptyCString());
|
||||
} else {
|
||||
// If we are explicitly loading from the sources, such as after a
|
||||
// restarted request, we might still want to save the bytecode after.
|
||||
|
@ -1118,7 +1118,7 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
|||
// does not exist, such that we can later save the bytecode with a
|
||||
// different alternative data type.
|
||||
LOG(("ScriptLoadRequest (%p): Request saving bytecode later", aRequest));
|
||||
cic->PreferAlternativeDataType(kNullMimeType);
|
||||
cic->PreferAlternativeDataType(kNullMimeType, EmptyCString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -343,8 +343,9 @@ public:
|
|||
// Get the preferred alternative data type of outter channel
|
||||
nsAutoCString preferredAltDataType(EmptyCString());
|
||||
nsCOMPtr<nsICacheInfoChannel> outerChannel = do_QueryInterface(underlyingChannel);
|
||||
if (outerChannel) {
|
||||
outerChannel->GetPreferredAlternativeDataType(preferredAltDataType);
|
||||
if (outerChannel && !outerChannel->PreferredAlternativeDataTypes().IsEmpty()) {
|
||||
// TODO: handle multiple types properly.
|
||||
preferredAltDataType.Assign(mozilla::Get<0>(outerChannel->PreferredAlternativeDataTypes()[0]));
|
||||
}
|
||||
|
||||
// Get the alternative data type saved in the InternalResponse
|
||||
|
|
|
@ -1587,11 +1587,11 @@ private:
|
|||
nsresult rv = mInterceptedChannel->GetChannel(getter_AddRefs(channel));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsAutoCString alternativeDataType;
|
||||
nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(channel);
|
||||
if (cic &&
|
||||
NS_SUCCEEDED(cic->GetPreferredAlternativeDataType(alternativeDataType)) &&
|
||||
!alternativeDataType.IsEmpty()) {
|
||||
if (cic && !cic->PreferredAlternativeDataTypes().IsEmpty()) {
|
||||
// TODO: the internal request probably needs all the preferred types.
|
||||
nsAutoCString alternativeDataType;
|
||||
alternativeDataType.Assign(mozilla::Get<0>(cic->PreferredAlternativeDataTypes()[0]));
|
||||
internalReq->SetPreferredAlternativeDataType(alternativeDataType);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
|
||||
interface nsIOutputStream;
|
||||
|
||||
%{C++
|
||||
namespace mozilla {
|
||||
template<typename... Elements> class Tuple;
|
||||
} // namespace mozilla
|
||||
%}
|
||||
|
||||
[ref] native ConstPreferenceArray(const nsTArray<mozilla::Tuple<nsCString, nsCString>>);
|
||||
|
||||
[scriptable, uuid(72c34415-c6eb-48af-851f-772fa9ee5972)]
|
||||
interface nsICacheInfoChannel : nsISupports
|
||||
{
|
||||
|
@ -79,16 +87,25 @@ interface nsICacheInfoChannel : nsISupports
|
|||
* Calling this method instructs the channel to serve the alternative data
|
||||
* if that was previously saved in the cache, otherwise it will serve the
|
||||
* real data.
|
||||
* @param type
|
||||
* a string identifying the alt-data format
|
||||
* @param contentType
|
||||
* the contentType for which the preference applies.
|
||||
* an empty contentType means the preference applies for ANY contentType
|
||||
*
|
||||
* The method may be called several times, with different type and contentType.
|
||||
*
|
||||
* Must be called before AsyncOpen.
|
||||
*/
|
||||
void preferAlternativeDataType(in ACString type);
|
||||
void preferAlternativeDataType(in ACString type, in ACString contentType);
|
||||
|
||||
/**
|
||||
* Get the preferred alternative data type set by preferAlternativeDataType().
|
||||
* This attribute stands for the desired data type instead of the type of the
|
||||
* The returned types stand for the desired data type instead of the type of the
|
||||
* information retrieved from the network stack.
|
||||
*/
|
||||
readonly attribute ACString preferredAlternativeDataType;
|
||||
[noscript, notxpcom, nostdcall]
|
||||
ConstPreferenceArray preferredAlternativeDataTypes();
|
||||
|
||||
/**
|
||||
* Holds the type of the alternative data representation that the channel
|
||||
|
|
|
@ -1275,6 +1275,11 @@ nsresult CacheEntry::OpenAlternativeOutputStream(const nsACString & type, int64_
|
|||
|
||||
nsresult rv;
|
||||
|
||||
if (type.IsEmpty()) {
|
||||
// The empty string is reserved to mean no alt-data available.
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
if (!mHasData || mState < READY || mOutputStream || mIsDoomed) {
|
||||
|
@ -1554,7 +1559,6 @@ nsresult CacheEntry::GetDataSize(int64_t *aDataSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult CacheEntry::GetAltDataSize(int64_t *aDataSize)
|
||||
{
|
||||
LOG(("CacheEntry::GetAltDataSize [this=%p]", this));
|
||||
|
@ -1564,6 +1568,14 @@ nsresult CacheEntry::GetAltDataSize(int64_t *aDataSize)
|
|||
return mFile->GetAltDataSize(aDataSize);
|
||||
}
|
||||
|
||||
nsresult CacheEntry::GetAltDataType(nsACString &aType)
|
||||
{
|
||||
LOG(("CacheEntry::GetAltDataType [this=%p]", this));
|
||||
if (NS_FAILED(mFileStatus)) {
|
||||
return mFileStatus;
|
||||
}
|
||||
return mFile->GetAltDataType(aType);
|
||||
}
|
||||
|
||||
nsresult CacheEntry::MarkValid()
|
||||
{
|
||||
|
|
|
@ -93,6 +93,7 @@ public:
|
|||
nsresult Recreate(bool aMemoryOnly, nsICacheEntry * *_retval);
|
||||
nsresult GetDataSize(int64_t *aDataSize);
|
||||
nsresult GetAltDataSize(int64_t *aAltDataSize);
|
||||
nsresult GetAltDataType(nsACString &aAltDataType);
|
||||
nsresult OpenAlternativeOutputStream(const nsACString & type, int64_t predictedSize, nsIOutputStream * *_retval);
|
||||
nsresult OpenAlternativeInputStream(const nsACString & type, nsIInputStream * *_retval);
|
||||
nsresult GetLoadContextInfo(nsILoadContextInfo * *aLoadContextInfo);
|
||||
|
@ -461,6 +462,7 @@ public:
|
|||
NS_IMETHOD Recreate(bool aMemoryOnly, nsICacheEntry * *_retval) override { return mEntry->Recreate(aMemoryOnly, _retval); }
|
||||
NS_IMETHOD GetDataSize(int64_t *aDataSize) override { return mEntry->GetDataSize(aDataSize); }
|
||||
NS_IMETHOD GetAltDataSize(int64_t *aAltDataSize) override { return mEntry->GetAltDataSize(aAltDataSize); }
|
||||
NS_IMETHOD GetAltDataType(nsACString &aType) override { return mEntry->GetAltDataType(aType); }
|
||||
NS_IMETHOD OpenAlternativeOutputStream(const nsACString & type, int64_t predictedSize, nsIOutputStream * *_retval) override { return mEntry->OpenAlternativeOutputStream(type, predictedSize, _retval); }
|
||||
NS_IMETHOD OpenAlternativeInputStream(const nsACString & type, nsIInputStream * *_retval) override { return mEntry->OpenAlternativeInputStream(type, _retval); }
|
||||
NS_IMETHOD GetLoadContextInfo(nsILoadContextInfo * *aLoadContextInfo) override { return mEntry->GetLoadContextInfo(aLoadContextInfo); }
|
||||
|
|
|
@ -647,12 +647,13 @@ CacheFile::OnMetadataRead(nsresult aResult)
|
|||
const char *altData = mMetadata->GetElement(CacheFileUtils::kAltDataKey);
|
||||
if (altData &&
|
||||
(NS_FAILED(CacheFileUtils::ParseAlternativeDataInfo(
|
||||
altData, &mAltDataOffset, nullptr)) ||
|
||||
altData, &mAltDataOffset, &mAltDataType)) ||
|
||||
(mAltDataOffset > mDataSize))) {
|
||||
// alt-metadata cannot be parsed or alt-data offset is invalid
|
||||
mMetadata->InitEmptyMetadata();
|
||||
isNew = true;
|
||||
mAltDataOffset = -1;
|
||||
mAltDataType.Truncate();
|
||||
mDataSize = 0;
|
||||
} else {
|
||||
CacheFileAutoLock lock(this);
|
||||
|
@ -801,8 +802,6 @@ CacheFile::OpenAlternativeInputStream(nsICacheEntry *aEntryHandle,
|
|||
|
||||
MOZ_ASSERT(mHandle || mMemoryOnly || mOpeningFile);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (NS_WARN_IF(!mReady)) {
|
||||
LOG(("CacheFile::OpenAlternativeInputStream() - CacheFile is not ready "
|
||||
"[this=%p]", this));
|
||||
|
@ -828,35 +827,13 @@ CacheFile::OpenAlternativeInputStream(nsICacheEntry *aEntryHandle,
|
|||
return mStatus;
|
||||
}
|
||||
|
||||
const char *altData = mMetadata->GetElement(CacheFileUtils::kAltDataKey);
|
||||
MOZ_ASSERT(altData, "alt-metadata should exist but was not found!");
|
||||
if (NS_WARN_IF(!altData)) {
|
||||
LOG(("CacheFile::OpenAlternativeInputStream() - alt-metadata not found but "
|
||||
"alt-data exists according to mAltDataOffset! [this=%p, ]", this));
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
int64_t offset;
|
||||
nsCString availableAltData;
|
||||
rv = CacheFileUtils::ParseAlternativeDataInfo(altData, &offset,
|
||||
&availableAltData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(false, "alt-metadata unexpectedly failed to parse");
|
||||
LOG(("CacheFile::OpenAlternativeInputStream() - Cannot parse alternative "
|
||||
"metadata! [this=%p]", this));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (availableAltData != aAltDataType) {
|
||||
if (mAltDataType != aAltDataType) {
|
||||
LOG(("CacheFile::OpenAlternativeInputStream() - Alternative data is of a "
|
||||
"different type than requested [this=%p, availableType=%s, "
|
||||
"requestedType=%s]", this, availableAltData.get(), aAltDataType));
|
||||
"requestedType=%s]", this, mAltDataType.get(), aAltDataType));
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// mAltDataOffset must be in sync with what is stored in metadata
|
||||
MOZ_ASSERT(mAltDataOffset == offset);
|
||||
|
||||
// Once we open input stream we no longer allow preloading of chunks without
|
||||
// input stream, i.e. we will no longer keep first few chunks preloaded when
|
||||
// the last input stream is closed.
|
||||
|
@ -925,6 +902,7 @@ CacheFile::OpenOutputStream(CacheOutputCloseListener *aCloseListener, nsIOutputS
|
|||
}
|
||||
SetAltMetadata(nullptr);
|
||||
mAltDataOffset = -1;
|
||||
mAltDataType.Truncate();
|
||||
}
|
||||
|
||||
// Once we open output stream we no longer allow preloading of chunks without
|
||||
|
@ -1019,6 +997,7 @@ CacheFile::OpenAlternativeOutputStream(CacheOutputCloseListener *aCloseListener,
|
|||
"%p [this=%p]", mOutput, this));
|
||||
|
||||
mDataAccessed = true;
|
||||
mAltDataType = aAltDataType;
|
||||
NS_ADDREF(*_retval = mOutput);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1328,6 +1307,7 @@ CacheFile::SetAltMetadata(const char* aAltMetadata)
|
|||
mMetadata->SetElement(CacheFileUtils::kAltDataKey, nullptr);
|
||||
|
||||
mAltDataOffset = -1;
|
||||
mAltDataType.Truncate();
|
||||
hasAltData = false;
|
||||
}
|
||||
|
||||
|
@ -2196,6 +2176,7 @@ CacheFile::RemoveOutput(CacheFileOutputStream *aOutput, nsresult aStatus)
|
|||
} else {
|
||||
SetAltMetadata(nullptr);
|
||||
mAltDataOffset = -1;
|
||||
mAltDataType.Truncate();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2381,6 +2362,19 @@ CacheFile::GetAltDataSize(int64_t *aSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheFile::GetAltDataType(nsACString& aType)
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
if (mAltDataOffset == -1) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
aType = mAltDataType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheFile::IsDoomed()
|
||||
{
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
nsresult ThrowMemoryCachedData();
|
||||
|
||||
nsresult GetAltDataSize(int64_t *aSize);
|
||||
nsresult GetAltDataType(nsACString& aType);
|
||||
|
||||
// metadata forwarders
|
||||
nsresult GetElement(const char *aKey, char **_retval);
|
||||
|
@ -215,6 +216,7 @@ private:
|
|||
// offset where alternative data starts.
|
||||
// Otherwise it is -1.
|
||||
nsCString mKey;
|
||||
nsCString mAltDataType; // The type of the saved alt-data. May be empty.
|
||||
|
||||
RefPtr<CacheFileHandle> mHandle;
|
||||
RefPtr<CacheFileMetadata> mMetadata;
|
||||
|
|
|
@ -396,6 +396,11 @@ NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataSize(int64_t *aSize)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataType(nsACString &aType)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP _OldCacheEntryWrapper::GetPersistent(bool *aPersistToDisk)
|
||||
{
|
||||
if (!mOldDesc) {
|
||||
|
|
|
@ -160,6 +160,7 @@ public:
|
|||
NS_IMETHOD Recreate(bool, nsICacheEntry**) override;
|
||||
NS_IMETHOD GetDataSize(int64_t *size) override;
|
||||
NS_IMETHOD GetAltDataSize(int64_t *size) override;
|
||||
NS_IMETHOD GetAltDataType(nsACString &aType) override;
|
||||
NS_IMETHOD OpenInputStream(int64_t offset, nsIInputStream * *_retval) override;
|
||||
NS_IMETHOD OpenOutputStream(int64_t offset, int64_t predictedSize, nsIOutputStream * *_retval) override;
|
||||
NS_IMETHOD MaybeMarkValid() override;
|
||||
|
|
|
@ -239,6 +239,13 @@ interface nsICacheEntry : nsISupports
|
|||
*/
|
||||
readonly attribute long long altDataSize;
|
||||
|
||||
/**
|
||||
* Returns the type of the saved alt data.
|
||||
* @throws
|
||||
* - NS_ERROR_NOT_AVAILABLE if alt data does not exist.
|
||||
*/
|
||||
readonly attribute ACString altDataType;
|
||||
|
||||
/**
|
||||
* Opens and returns an output stream that a consumer may use to save an
|
||||
* alternate representation of the data.
|
||||
|
|
|
@ -18,6 +18,7 @@ include PBackgroundSharedTypes;
|
|||
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
|
||||
using ArrayOfStringPairs from "mozilla/net/PHttpChannelParams.h";
|
||||
using struct nsHttpAtom from "nsHttp.h";
|
||||
using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
|
||||
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
|
||||
|
@ -245,7 +246,7 @@ struct HttpChannelOpenArgs
|
|||
uint64_t channelId;
|
||||
nsString integrityMetadata;
|
||||
uint64_t contentWindowId;
|
||||
nsCString preferredAlternativeType;
|
||||
ArrayOfStringPairs preferredAlternativeTypes;
|
||||
uint64_t topLevelOuterContentWindowId;
|
||||
TimeStamp launchServiceWorkerStart;
|
||||
TimeStamp launchServiceWorkerEnd;
|
||||
|
|
|
@ -3909,7 +3909,9 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
|||
// Pass the preferred alt-data type on to the new channel.
|
||||
nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
|
||||
if (cacheInfoChan) {
|
||||
cacheInfoChan->PreferAlternativeDataType(mPreferredCachedAltDataType);
|
||||
for (auto& pair : mPreferredCachedAltDataTypes) {
|
||||
cacheInfoChan->PreferAlternativeDataType(mozilla::Get<0>(pair), mozilla::Get<1>(pair));
|
||||
}
|
||||
}
|
||||
|
||||
if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsCOMArray.h"
|
||||
#include "mozilla/net/ChannelEventQueue.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Tuple.h"
|
||||
#include "nsIThrottledInputChannel.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -71,6 +72,8 @@ class LogCollector;
|
|||
namespace net {
|
||||
extern mozilla::LazyLogModule gHttpLog;
|
||||
|
||||
typedef nsTArray<Tuple<nsCString, nsCString>> ArrayOfStringPairs;
|
||||
|
||||
/*
|
||||
* This class is a partial implementation of nsIHttpChannel. It contains code
|
||||
* shared by nsHttpChannel and HttpChannelChild.
|
||||
|
@ -553,8 +556,8 @@ protected:
|
|||
// The initiator type (for this resource) - how was the resource referenced in
|
||||
// the HTML file.
|
||||
nsString mInitiatorType;
|
||||
// Holds the name of the preferred alt-data type.
|
||||
nsCString mPreferredCachedAltDataType;
|
||||
// Holds the name of the preferred alt-data type for each contentType.
|
||||
ArrayOfStringPairs mPreferredCachedAltDataTypes;
|
||||
// Holds the name of the alternative data type the channel returned.
|
||||
nsCString mAvailableCachedAltDataType;
|
||||
nsString mIntegrityMetadata;
|
||||
|
|
|
@ -1267,7 +1267,7 @@ HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
|
|||
// message but request the cache entry to be kept by the parent.
|
||||
// If the channel has failed, the cache entry is in a non-writtable state and
|
||||
// we want to release it to not block following consumers.
|
||||
if (NS_SUCCEEDED(channelStatus) && !mPreferredCachedAltDataType.IsEmpty()) {
|
||||
if (NS_SUCCEEDED(channelStatus) && !mPreferredCachedAltDataTypes.IsEmpty()) {
|
||||
mKeptAlive = true;
|
||||
SendDocumentChannelCleanup(false); // don't clear cache entry
|
||||
return;
|
||||
|
@ -1374,7 +1374,7 @@ HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest, nsresult aChannelStatus,
|
|||
// If a preferred alt-data type was set, the parent would hold a reference to
|
||||
// the cache entry in case the child calls openAlternativeOutputStream().
|
||||
// (see nsHttpChannel::OnStopRequest)
|
||||
if (!mPreferredCachedAltDataType.IsEmpty()) {
|
||||
if (!mPreferredCachedAltDataTypes.IsEmpty()) {
|
||||
mAltDataCacheEntryAvailable = mCacheEntryAvailable;
|
||||
}
|
||||
mCacheEntryAvailable = false;
|
||||
|
@ -2874,7 +2874,7 @@ HttpChannelChild::ContinueAsyncOpen()
|
|||
openArgs.loadFlags() = mLoadFlags;
|
||||
openArgs.requestHeaders() = mClientSetRequestHeaders;
|
||||
mRequestHead.Method(openArgs.requestMethod());
|
||||
openArgs.preferredAlternativeType() = mPreferredCachedAltDataType;
|
||||
openArgs.preferredAlternativeTypes() = mPreferredCachedAltDataTypes;
|
||||
|
||||
AutoIPCStream autoStream(openArgs.uploadStream());
|
||||
if (mUploadStream) {
|
||||
|
@ -3271,23 +3271,23 @@ HttpChannelChild::GetAllowStaleCacheContent(bool *aAllowStaleCacheContent)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::PreferAlternativeDataType(const nsACString & aType)
|
||||
HttpChannelChild::PreferAlternativeDataType(const nsACString& aType,
|
||||
const nsACString& aContentType)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||
|
||||
if (mSynthesizedCacheInfo) {
|
||||
return mSynthesizedCacheInfo->PreferAlternativeDataType(aType);
|
||||
return mSynthesizedCacheInfo->PreferAlternativeDataType(aType, aContentType);
|
||||
}
|
||||
|
||||
mPreferredCachedAltDataType = aType;
|
||||
mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetPreferredAlternativeDataType(nsACString & aType)
|
||||
const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
|
||||
HttpChannelChild::PreferredAlternativeDataTypes()
|
||||
{
|
||||
aType = mPreferredCachedAltDataType;
|
||||
return NS_OK;
|
||||
return mPreferredCachedAltDataTypes;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -153,7 +153,7 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
|
|||
a.allowStaleCacheContent(), a.contentTypeHint(),
|
||||
a.corsMode(), a.redirectMode(),
|
||||
a.channelId(), a.integrityMetadata(),
|
||||
a.contentWindowId(), a.preferredAlternativeType(),
|
||||
a.contentWindowId(), a.preferredAlternativeTypes(),
|
||||
a.topLevelOuterContentWindowId(),
|
||||
a.launchServiceWorkerStart(),
|
||||
a.launchServiceWorkerEnd(),
|
||||
|
@ -455,7 +455,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
const uint64_t& aChannelId,
|
||||
const nsString& aIntegrityMetadata,
|
||||
const uint64_t& aContentWindowId,
|
||||
const nsCString& aPreferredAlternativeType,
|
||||
const ArrayOfStringPairs& aPreferredAlternativeTypes,
|
||||
const uint64_t& aTopLevelOuterContentWindowId,
|
||||
const TimeStamp& aLaunchServiceWorkerStart,
|
||||
const TimeStamp& aLaunchServiceWorkerEnd,
|
||||
|
@ -614,7 +614,9 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
do_QueryInterface(static_cast<nsIChannel*>(httpChannel.get()));
|
||||
if (cacheChannel) {
|
||||
cacheChannel->SetCacheKey(aCacheKey);
|
||||
cacheChannel->PreferAlternativeDataType(aPreferredAlternativeType);
|
||||
for (auto& pair : aPreferredAlternativeTypes) {
|
||||
cacheChannel->PreferAlternativeDataType(mozilla::Get<0>(pair), mozilla::Get<1>(pair));
|
||||
}
|
||||
|
||||
cacheChannel->SetAllowStaleCacheContent(aAllowStaleCacheContent);
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ protected:
|
|||
const uint64_t& aChannelId,
|
||||
const nsString& aIntegrityMetadata,
|
||||
const uint64_t& aContentWindowId,
|
||||
const nsCString& aPreferredAlternativeType,
|
||||
const ArrayOfStringPairs& aPreferredAlternativeTypes,
|
||||
const uint64_t& aTopLevelOuterContentWindowId,
|
||||
const TimeStamp& aLaunchServiceWorkerStart,
|
||||
const TimeStamp& aLaunchServiceWorkerEnd,
|
||||
|
|
|
@ -1315,18 +1315,18 @@ InterceptedHttpChannel::GetAllowStaleCacheContent(bool *aAllowStaleCacheContent)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::PreferAlternativeDataType(const nsACString & aType)
|
||||
InterceptedHttpChannel::PreferAlternativeDataType(const nsACString & aType,
|
||||
const nsACString& aContentType)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||
mPreferredCachedAltDataType = aType;
|
||||
mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::GetPreferredAlternativeDataType(nsACString & aType)
|
||||
const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
|
||||
InterceptedHttpChannel::PreferredAlternativeDataTypes()
|
||||
{
|
||||
aType = mPreferredCachedAltDataType;
|
||||
return NS_OK;
|
||||
return mPreferredCachedAltDataTypes;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsHttp.h"
|
||||
#include "nsHttpHeaderArray.h"
|
||||
#include "nsHttpResponseHead.h"
|
||||
#include "mozilla/Tuple.h"
|
||||
|
||||
#include "nsIClassInfo.h"
|
||||
|
||||
|
@ -36,11 +37,37 @@ struct RequestHeaderTuple {
|
|||
|
||||
typedef nsTArray<RequestHeaderTuple> RequestHeaderTuples;
|
||||
|
||||
typedef nsTArray<Tuple<nsCString, nsCString>> ArrayOfStringPairs;
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::Tuple<nsCString, nsCString>>
|
||||
{
|
||||
typedef mozilla::Tuple<nsCString, nsCString> paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, mozilla::Get<0>(aParam));
|
||||
WriteParam(aMsg, mozilla::Get<1>(aParam));
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
nsCString first;
|
||||
nsCString second;
|
||||
if (!ReadParam(aMsg, aIter, &first) ||
|
||||
!ReadParam(aMsg, aIter, &second))
|
||||
return false;
|
||||
|
||||
*aResult = mozilla::MakeTuple(first, second);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::net::RequestHeaderTuple>
|
||||
{
|
||||
|
|
|
@ -5003,12 +5003,31 @@ nsHttpChannel::OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBufferi
|
|||
altDataFromChild = !value.IsEmpty();
|
||||
}
|
||||
|
||||
if (!mPreferredCachedAltDataType.IsEmpty() && (altDataFromChild == mAltDataForChild)) {
|
||||
rv = cacheEntry->OpenAlternativeInputStream(mPreferredCachedAltDataType,
|
||||
nsAutoCString altDataType;
|
||||
Unused << cacheEntry->GetAltDataType(altDataType);
|
||||
|
||||
nsAutoCString contentType;
|
||||
mCachedResponseHead->ContentType(contentType);
|
||||
|
||||
bool foundAltData = false;
|
||||
if (!altDataType.IsEmpty() &&
|
||||
!mPreferredCachedAltDataTypes.IsEmpty() &&
|
||||
altDataFromChild == mAltDataForChild) {
|
||||
for (auto& pref : mPreferredCachedAltDataTypes) {
|
||||
if (mozilla::Get<0>(pref) == altDataType &&
|
||||
(mozilla::Get<1>(pref).IsEmpty() || mozilla::Get<1>(pref) == contentType)) {
|
||||
foundAltData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundAltData) {
|
||||
rv = cacheEntry->OpenAlternativeInputStream(altDataType,
|
||||
getter_AddRefs(stream));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("Opened alt-data input stream type=%s", altDataType.get()));
|
||||
// We have succeeded.
|
||||
mAvailableCachedAltDataType = mPreferredCachedAltDataType;
|
||||
mAvailableCachedAltDataType = altDataType;
|
||||
// Set the correct data size on the channel.
|
||||
int64_t altDataSize;
|
||||
if (NS_SUCCEEDED(cacheEntry->GetAltDataSize(&altDataSize))) {
|
||||
|
@ -5017,6 +5036,7 @@ nsHttpChannel::OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBufferi
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!stream) {
|
||||
rv = cacheEntry->OpenInputStream(0, getter_AddRefs(stream));
|
||||
}
|
||||
|
@ -7864,7 +7884,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
|||
// interested in reading and/or writing the alt-data representation.
|
||||
// We need to hold a reference to the cache entry in case the listener calls
|
||||
// openAlternativeOutputStream() after CloseCacheEntry() clears mCacheEntry.
|
||||
if (!mPreferredCachedAltDataType.IsEmpty()) {
|
||||
if (!mPreferredCachedAltDataTypes.IsEmpty()) {
|
||||
mAltDataCacheEntry = mCacheEntry;
|
||||
}
|
||||
|
||||
|
@ -8286,18 +8306,18 @@ nsHttpChannel::GetAllowStaleCacheContent(bool *aAllowStaleCacheContent)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::PreferAlternativeDataType(const nsACString & aType)
|
||||
nsHttpChannel::PreferAlternativeDataType(const nsACString& aType,
|
||||
const nsACString& aContentType)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||
mPreferredCachedAltDataType = aType;
|
||||
mPreferredCachedAltDataTypes.AppendElement(MakePair(nsCString(aType), nsCString(aContentType)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::GetPreferredAlternativeDataType(nsACString & aType)
|
||||
const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
|
||||
nsHttpChannel::PreferredAlternativeDataTypes()
|
||||
{
|
||||
aType = mPreferredCachedAltDataType;
|
||||
return NS_OK;
|
||||
return mPreferredCachedAltDataTypes;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -1146,3 +1146,12 @@ nsViewSourceChannel::LogBlockedCORSRequest(const nsAString& aMessage,
|
|||
}
|
||||
return mHttpChannel->LogBlockedCORSRequest(aMessage, aCategory);
|
||||
}
|
||||
|
||||
const nsTArray<mozilla::Tuple<nsCString, nsCString>>&
|
||||
nsViewSourceChannel::PreferredAlternativeDataTypes()
|
||||
{
|
||||
if (mCacheInfoChannel) {
|
||||
return mCacheInfoChannel->PreferredAlternativeDataTypes();
|
||||
}
|
||||
return mEmptyArray;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
protected:
|
||||
~nsViewSourceChannel() = default;
|
||||
nsTArray<mozilla::Tuple<nsCString, nsCString>> mEmptyArray;
|
||||
|
||||
// Clones aURI and prefixes it with "view-source:" schema,
|
||||
nsresult BuildViewSourceURI(nsIURI* aURI, nsIURI** aResult);
|
||||
|
|
|
@ -85,7 +85,7 @@ function asyncOpen()
|
|||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
|
||||
chan.asyncOpen2(new ChannelListener(readServerContent, null));
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ function flushAndOpenAltChannel()
|
|||
function openAltChannel() {
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
|
||||
chan.asyncOpen2(new ChannelListener(readAltContent, null));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ function make_and_open_channel(url, altContentType, callback) {
|
|||
let chan = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
if (altContentType) {
|
||||
let cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
}
|
||||
chan.asyncOpen2(new ChannelListener(callback, null));
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ function asyncOpen()
|
|||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
|
||||
chan.asyncOpen2(new ChannelListener(readServerContent, null));
|
||||
}
|
||||
|
@ -136,7 +136,9 @@ function flushAndOpenAltChannel()
|
|||
function openAltChannel() {
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType("dummy1", "text/javascript");
|
||||
cc.preferAlternativeDataType(altContentType, "text/plain");
|
||||
cc.preferAlternativeDataType("dummy2", "");
|
||||
|
||||
chan.asyncOpen2(new ChannelListener(readAltContent, null));
|
||||
}
|
||||
|
@ -158,7 +160,7 @@ function requestAgain()
|
|||
shouldPassRevalidation = false;
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
chan.asyncOpen2(new ChannelListener(readEmptyAltContent, null));
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ function run_test()
|
|||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
|
||||
chan.asyncOpen2(new ChannelListener(readServerContent, null));
|
||||
do_test_pending();
|
||||
|
@ -89,7 +89,7 @@ function openAltChannel()
|
|||
{
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
|
||||
chan.asyncOpen2(listener);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ function fetch(preferredDataType = null)
|
|||
|
||||
if (preferredDataType) {
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType);
|
||||
cc.preferAlternativeDataType(altContentType, "");
|
||||
}
|
||||
|
||||
chan.asyncOpen2(new ChannelListener((request,
|
||||
|
|
|
@ -32,7 +32,7 @@ function load_channel(url) {
|
|||
URL = url; // save this to open the alt data channel later
|
||||
var chan = make_channel(url);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType("text/binary");
|
||||
cc.preferAlternativeDataType("text/binary", "");
|
||||
chan.asyncOpen2(new ChannelListener(readTextData, null));
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ function readTextData(request, buffer)
|
|||
function openAltChannel() {
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType("text/parent-binary");
|
||||
cc.preferAlternativeDataType("text/parent-binary", "");
|
||||
chan.asyncOpen2(new ChannelListener(readAltData, null));
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче