Bug 1638422 - Add an option for nsITraceableChannel new listeners to request that content decoding be applied before they are called. r=kmag,necko-reviewers,dragana

Differential Revision: https://phabricator.services.mozilla.com/D83595
This commit is contained in:
Matt Woodrow 2020-08-25 23:17:35 +00:00
parent bf01cd84ee
commit 228b3b0a58
6 changed files with 49 additions and 22 deletions

View File

@ -23,6 +23,9 @@ interface nsITraceableChannel : nsISupports
* The caller of setNewListener has no way to control at which place
* in the chain its listener is placed.
*
* @param aMustApplyContentConversion Pass true if the new listener requires
* content conversion to already be applied by the channel.
*
* Note: The caller of setNewListener must not delay passing
* OnStartRequest to the original listener.
*
@ -30,5 +33,5 @@ interface nsITraceableChannel : nsISupports
* It is not recommended to allow listener replacement after OnStartRequest
* has been called.
*/
nsIStreamListener setNewListener(in nsIStreamListener aListener);
nsIStreamListener setNewListener(in nsIStreamListener aListener, [optional] in boolean aMustApplyContentConversion);
};

View File

@ -239,6 +239,7 @@ HttpBaseChannel::HttpBaseChannel()
mDisableAltDataCache(false),
mForceMainDocumentChannel(false),
mPendingInputStreamLengthOperation(false),
mListenerRequiresContentConversion(false),
mHasCrossOriginOpenerPolicyMismatch(0) {
this->mSelfAddr.inet = {};
this->mPeerAddr.inet = {};
@ -1191,6 +1192,11 @@ HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
return NS_OK;
}
if (mHasAppliedConversion) {
LOG(("not applying conversion because mHasAppliedConversion is true\n"));
return NS_OK;
}
if (mDeliveringAltData) {
MOZ_ASSERT(!mAvailableCachedAltDataType.IsEmpty());
LOG(("not applying conversion because delivering alt-data\n"));
@ -3228,6 +3234,7 @@ already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
NS_IMETHODIMP
HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
bool aMustApplyContentConversion,
nsIStreamListener** _retval) {
LOG((
"HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]",
@ -3242,6 +3249,9 @@ HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
wrapper.forget(_retval);
mListener = aListener;
if (aMustApplyContentConversion) {
mListenerRequiresContentConversion = true;
}
return NS_OK;
}

View File

@ -855,38 +855,46 @@ class HttpBaseChannel : public nsHashPropertyBag,
// Number of internal redirects that has occurred.
int8_t mInternalRedirectCount;
bool mAsyncOpenTimeOverriden;
bool mForcePending;
bool mAsyncOpenTimeOverriden : 1;
bool mForcePending : 1;
// true if the channel is deliving alt-data.
bool mDeliveringAltData;
bool mDeliveringAltData : 1;
bool mCorsIncludeCredentials;
bool mCorsIncludeCredentials : 1;
// These parameters are used to ensure that we do not call OnStartRequest and
// OnStopRequest more than once.
bool mOnStartRequestCalled;
bool mOnStopRequestCalled;
bool mOnStartRequestCalled : 1;
bool mOnStopRequestCalled : 1;
// Defaults to false. Is set to true at the begining of OnStartRequest.
// Used to ensure methods can't be called before OnStartRequest.
bool mAfterOnStartRequestBegun;
bool mAfterOnStartRequestBegun : 1;
bool mRequireCORSPreflight;
bool mRequireCORSPreflight : 1;
// This flag will be true if the consumer is requesting alt-data AND the
// consumer is in the child process.
bool mAltDataForChild;
bool mAltDataForChild : 1;
// This flag will be true if the consumer cannot process alt-data. This
// is used in the webextension StreamFilter handler. If true, we bypass
// using alt-data for the request.
bool mDisableAltDataCache;
bool mDisableAltDataCache : 1;
bool mForceMainDocumentChannel;
bool mForceMainDocumentChannel : 1;
// This is set true if the channel is waiting for the
// InputStreamLengthHelper::GetAsyncLength callback.
bool mPendingInputStreamLengthOperation;
bool mPendingInputStreamLengthOperation : 1;
// Set to true if our listener has indicated that it requires
// content conversion to be done by us.
bool mListenerRequiresContentConversion : 1;
// True if this is a navigation to a page with a different cross origin
// opener policy ( see ComputeCrossOriginOpenerPolicyMismatch )
uint32_t mHasCrossOriginOpenerPolicyMismatch : 1;
bool EnsureRequestContextID();
bool EnsureRequestContext();
@ -898,10 +906,6 @@ class HttpBaseChannel : public nsHashPropertyBag,
void RemoveAsNonTailRequest();
void EnsureTopLevelOuterContentWindowId();
// True if this is a navigation to a page with a different cross origin
// opener policy ( see ComputeCrossOriginOpenerPolicyMismatch )
uint32_t mHasCrossOriginOpenerPolicyMismatch : 1;
};
NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)

View File

@ -2081,9 +2081,16 @@ nsresult nsHttpChannel::CallOnStartRequest() {
}
// Install stream converter if required.
// If we use unknownDecoder, stream converters will be installed later (in
// nsUnknownDecoder) after OnStartRequest is called for the real listener.
if (!unknownDecoderStarted) {
// Normally, we expect the listener to disable content conversion during
// OnStartRequest if it wants to handle it itself (which is common case with
// HttpChannelParent, disabling so that it can be done in the content
// process). If we've installed an nsUnknownDecoder, then we won't yet have
// called OnStartRequest on the final listener (that happens after we send
// OnDataAvailable to the nsUnknownDecoder), so it can't yet have disabled
// content conversion.
// In that case, assume that the listener will disable content conversion,
// unless it's specifically told us that it won't.
if (!unknownDecoderStarted || mListenerRequiresContentConversion) {
nsCOMPtr<nsIStreamListener> listener;
rv =
DoApplyContentConversions(mListener, getter_AddRefs(listener), nullptr);

View File

@ -1054,7 +1054,8 @@ ChannelWrapper::RequestListener::~RequestListener() {
nsresult ChannelWrapper::RequestListener::Init() {
if (nsCOMPtr<nsITraceableChannel> chan = mChannelWrapper->QueryChannel()) {
return chan->SetNewListener(this, getter_AddRefs(mOrigStreamListener));
return chan->SetNewListener(this, false,
getter_AddRefs(mOrigStreamListener));
}
return NS_ERROR_UNEXPECTED;
}

View File

@ -159,7 +159,9 @@ void StreamFilterParent::Init(nsIChannel* aChannel) {
nsCOMPtr<nsITraceableChannel> traceable = do_QueryInterface(aChannel);
MOZ_RELEASE_ASSERT(traceable);
nsresult rv = traceable->SetNewListener(this, getter_AddRefs(mOrigListener));
nsresult rv =
traceable->SetNewListener(this, /* aMustApplyContentConversion = */ true,
getter_AddRefs(mOrigListener));
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
}