Bug 1012917 - Send HttpBaseChannel::mApplyConversion with ChannelDiverter constructor in IPDL r=mayhemer

This commit is contained in:
Steve Workman 2014-10-21 16:40:08 -07:00
parent 7d7b130d9c
commit 49393025ca
8 changed files with 94 additions and 23 deletions

View File

@ -24,19 +24,23 @@ ChannelDiverterParent::~ChannelDiverterParent()
}
bool
ChannelDiverterParent::Init(const ChannelDiverterArgs& aChannel)
ChannelDiverterParent::Init(const ChannelDiverterArgs& aArgs)
{
switch (aChannel.type()) {
case ChannelDiverterArgs::TPHttpChannelParent:
switch (aArgs.type()) {
case ChannelDiverterArgs::THttpChannelDiverterArgs:
{
mDivertableChannelParent = static_cast<ADivertableParentChannel*>(
static_cast<HttpChannelParent*>(aChannel.get_PHttpChannelParent()));
auto httpParent = static_cast<HttpChannelParent*>(
aArgs.get_HttpChannelDiverterArgs().mChannelParent());
httpParent->SetApplyConversion(aArgs.get_HttpChannelDiverterArgs().mApplyConversion());
mDivertableChannelParent =
static_cast<ADivertableParentChannel*>(httpParent);
break;
}
case ChannelDiverterArgs::TPFTPChannelParent:
{
mDivertableChannelParent = static_cast<ADivertableParentChannel*>(
static_cast<FTPChannelParent*>(aChannel.get_PFTPChannelParent()));
static_cast<FTPChannelParent*>(aArgs.get_PFTPChannelParent()));
break;
}
default:

View File

@ -24,7 +24,7 @@ public:
ChannelDiverterParent();
virtual ~ChannelDiverterParent();
bool Init(const ChannelDiverterArgs& aChannel);
bool Init(const ChannelDiverterArgs& aArgs);
void DivertTo(nsIStreamListener* newListener);

View File

@ -92,9 +92,15 @@ union FTPChannelCreationArgs
FTPChannelConnectArgs; // Used for redirected-to channels
};
struct HttpChannelDiverterArgs
{
PHttpChannel mChannel;
bool mApplyConversion;
};
union ChannelDiverterArgs
{
PHttpChannel;
HttpChannelDiverterArgs;
PFTPChannel;
};

View File

@ -619,6 +619,15 @@ HttpBaseChannel::SetApplyConversion(bool value)
return NS_OK;
}
nsresult
HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
nsIStreamListener** aNewNextListener)
{
return DoApplyContentConversions(aNextListener,
aNewNextListener,
mListenerContext);
}
NS_IMETHODIMP
HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
nsIStreamListener** aNewNextListener,
@ -639,10 +648,7 @@ HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
}
nsAutoCString contentEncoding;
char *cePtr, *val;
nsresult rv;
rv = mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
nsresult rv = mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
if (NS_FAILED(rv) || contentEncoding.IsEmpty())
return NS_OK;
@ -652,9 +658,9 @@ HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
// being a stack with the last converter created being the first one
// to accept the raw network data.
cePtr = contentEncoding.BeginWriting();
char* cePtr = contentEncoding.BeginWriting();
uint32_t count = 0;
while ((val = nsCRT::strtok(cePtr, HTTP_LWS ",", &cePtr))) {
while (char* val = nsCRT::strtok(cePtr, HTTP_LWS ",", &cePtr)) {
if (++count > 16) {
// That's ridiculous. We only understand 2 different ones :)
// but for compatibility with old code, we will just carry on without

View File

@ -124,6 +124,9 @@ public:
NS_IMETHOD GetApplyConversion(bool *value);
NS_IMETHOD SetApplyConversion(bool value);
NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator** aEncodings);
NS_IMETHOD DoApplyContentConversions(nsIStreamListener *aNextListener,
nsIStreamListener **aNewNextListener,
nsISupports *aCtxt);
// HttpBaseChannel::nsIHttpChannel
NS_IMETHOD GetRequestMethod(nsACString& aMethod);
@ -236,6 +239,11 @@ public: /* Necko internal use only... */
static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
nsHttpRequestHead::ParsedMethodType method);
// Like nsIEncodedChannel::DoApplyConversions except context is set to
// mListenerContext.
nsresult DoApplyContentConversions(nsIStreamListener *aNextListener,
nsIStreamListener **aNewNextListener);
protected:
nsCOMArray<nsISecurityConsoleMessage> mSecurityConsoleMessages;
@ -248,10 +256,6 @@ protected:
nsPerformance* GetPerformance();
NS_IMETHOD DoApplyContentConversions(nsIStreamListener *aNextListener,
nsIStreamListener **aNewNextListener,
nsISupports *aCtxt);
void AddCookiesToRequest();
virtual nsresult SetupReplacementChannel(nsIURI *,
nsIChannel *,

View File

@ -1888,8 +1888,12 @@ HttpChannelChild::DivertToParent(ChannelDiverterChild **aChild)
// Once this is set, it should not be unset before the child is taken down.
mDivertingToParent = true;
HttpChannelDiverterArgs args;
args.mChannelChild() = this;
args.mApplyConversion() = mApplyConversion;
PChannelDiverterChild* diverter =
gNeckoChild->SendPChannelDiverterConstructor(this);
gNeckoChild->SendPChannelDiverterConstructor(args);
MOZ_RELEASE_ASSERT(diverter);
*aChild = static_cast<ChannelDiverterChild*>(diverter);

View File

@ -557,7 +557,14 @@ HttpChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
return true;
}
rv = mParentListener->OnDataAvailable(mChannel, nullptr, stringStream,
nsCOMPtr<nsIStreamListener> listener;
if (mConverterListener) {
listener = mConverterListener;
} else {
listener = mParentListener;
MOZ_ASSERT(listener);
}
rv = listener->OnDataAvailable(mChannel, nullptr, stringStream,
offset, count);
stringStream->Close();
if (NS_FAILED(rv)) {
@ -589,7 +596,14 @@ HttpChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
mChannel->ForcePending(false);
}
mParentListener->OnStopRequest(mChannel, nullptr, status);
nsCOMPtr<nsIStreamListener> listener;
if (mConverterListener) {
listener = mConverterListener;
} else {
listener = mParentListener;
MOZ_ASSERT(listener);
}
listener->OnStopRequest(mChannel, nullptr, status);
return true;
}
@ -598,6 +612,7 @@ HttpChannelParent::RecvDivertComplete()
{
MOZ_ASSERT(mParentListener);
mParentListener = nullptr;
mConverterListener = nullptr;
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertComplete if diverting is not set!");
@ -985,8 +1000,30 @@ HttpChannelParent::StartDiversion()
}
mDivertedOnStartRequest = true;
// After OnStartRequest has been called, tell HttpChannelChild to divert the
// OnDataAvailables and OnStopRequest to this HttpChannelParent.
// After OnStartRequest has been called, setup content decoders if needed.
//
// We want to use the same decoders that the nsHttpChannel might use. There
// are two possible scenarios depending on whether OnStopRequest has been
// called or not.
//
// 1. nsHttpChannel has not called OnStopRequest yet.
// Create content conversion chain based on nsHttpChannel::mListener
// Get ptr to final listener and set that in mContentConverter, as well as
// nsHttpChannel::mListener.
//
// 2. nsHttpChannel has called OnStopRequest.
// Create a content conversion chain based on mParentListener.
// Get ptr to final listener and set that in mContentConverter.
nsCOMPtr<nsIStreamListener> converterListener;
mChannel->DoApplyContentConversions(mParentListener,
getter_AddRefs(converterListener));
if (converterListener) {
mConverterListener = converterListener.forget();
}
// The listener chain should now be setup; tell HttpChannelChild to divert
// the OnDataAvailables and OnStopRequest to this HttpChannelParent.
if (NS_WARN_IF(mIPCClosed || !SendDivertMessages())) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
@ -1064,6 +1101,7 @@ HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
mParentListener->OnStopRequest(mChannel, nullptr, aErrorCode);
}
mParentListener = nullptr;
mConverterListener = nullptr;
mChannel = nullptr;
if (!mIPCClosed) {

View File

@ -73,6 +73,13 @@ public:
// Called asynchronously from FailDiversion.
void NotifyDiversionFailed(nsresult aErrorCode, bool aSkipResume = true);
// Forwarded to nsHttpChannel::SetApplyConversion.
void SetApplyConversion(bool aApplyConversion) {
if (mChannel) {
mChannel->SetApplyConversion(aApplyConversion);
}
}
protected:
// used to connect redirected-to channel in parent with just created
// ChildChannel. Used during redirects.
@ -164,6 +171,8 @@ private:
nsRefPtr<nsHttpHandler> mHttpHandler;
nsRefPtr<HttpChannelParentListener> mParentListener;
// The first listener in the decode chain if channel decoding is applied.
nsCOMPtr<nsIStreamListener> mConverterListener;
// Set to the canceled status value if the main channel was canceled.
nsresult mStatus;
// Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it