Bug 567267 - disable decoding in HttpChannelParent, make smart decisions in child process, r=dwitte, blocking-fennec2.0b1=mfinkle

This commit is contained in:
Brian Crowder 2010-09-15 15:55:08 -07:00
Родитель 66ac3cc86e
Коммит a34e533a0c
7 изменённых файлов: 80 добавлений и 64 удалений

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

@ -506,6 +506,47 @@ HttpBaseChannel::SetApplyConversion(PRBool value)
return NS_OK; return NS_OK;
} }
nsresult
HttpBaseChannel::ApplyContentConversions()
{
if (!mResponseHead)
return NS_OK;
LOG(("nsHttpChannel::ApplyContentConversions [this=%p]\n", this));
if (!mApplyConversion) {
LOG(("not applying conversion per mApplyConversion\n"));
return NS_OK;
}
const char *val = mResponseHead->PeekHeader(nsHttp::Content_Encoding);
if (gHttpHandler->IsAcceptableEncoding(val)) {
nsCOMPtr<nsIStreamConverterService> serv;
nsresult rv = gHttpHandler->
GetStreamConverterService(getter_AddRefs(serv));
// we won't fail to load the page just because we couldn't load the
// stream converter service.. carry on..
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIStreamListener> converter;
nsCAutoString from(val);
ToLowerCase(from);
rv = serv->AsyncConvertData(from.get(),
"uncompressed",
mListener,
mListenerContext,
getter_AddRefs(converter));
if (NS_SUCCEEDED(rv)) {
LOG(("converter installed from \'%s\' to \'uncompressed\'\n", val));
mListener = converter;
}
}
} else if (val != nsnull) {
LOG(("Unknown content encoding '%s', ignoring\n", val));
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings)
{ {

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

@ -208,6 +208,8 @@ public:
}; };
protected: protected:
nsresult ApplyContentConversions();
void AddCookiesToRequest(); void AddCookiesToRequest();
virtual nsresult SetupReplacementChannel(nsIURI *, virtual nsresult SetupReplacementChannel(nsIURI *,
nsIChannel *, nsIChannel *,

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

@ -293,12 +293,17 @@ HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
AutoEventEnqueuer ensureSerialDispatch(this); AutoEventEnqueuer ensureSerialDispatch(this);
nsresult rv = mListener->OnStartRequest(this, mListenerContext); nsresult rv = mListener->OnStartRequest(this, mListenerContext);
if (NS_SUCCEEDED(rv)) { if (NS_FAILED(rv)) {
if (mResponseHead)
SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));
} else {
Cancel(rv); Cancel(rv);
return;
} }
if (mResponseHead)
SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));
rv = ApplyContentConversions();
if (NS_FAILED(rv))
Cancel(rv);
} }
class DataAvailableEvent : public ChildChannelEvent class DataAvailableEvent : public ChildChannelEvent

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

@ -292,6 +292,10 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
nsCString cachedCharset; nsCString cachedCharset;
chan->GetCacheTokenCachedCharset(cachedCharset); chan->GetCacheTokenCachedCharset(cachedCharset);
nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
if (encodedChannel)
encodedChannel->SetApplyConversion(PR_FALSE);
// Keep the cache entry for future use in RecvSetCacheTokenCachedCharset(). // Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
// It could be already released by nsHttpChannel at that time. // It could be already released by nsHttpChannel at that time.
chan->GetCacheToken(getter_AddRefs(mCacheDescriptor)); chan->GetCacheToken(getter_AddRefs(mCacheDescriptor));

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

@ -676,47 +676,6 @@ nsHttpChannel::SetupTransaction()
return rv; return rv;
} }
nsresult
nsHttpChannel::ApplyContentConversions()
{
if (!mResponseHead)
return NS_OK;
LOG(("nsHttpChannel::ApplyContentConversions [this=%p]\n", this));
if (!mApplyConversion) {
LOG(("not applying conversion per mApplyConversion\n"));
return NS_OK;
}
const char *val = mResponseHead->PeekHeader(nsHttp::Content_Encoding);
if (gHttpHandler->IsAcceptableEncoding(val)) {
nsCOMPtr<nsIStreamConverterService> serv;
nsresult rv = gHttpHandler->
GetStreamConverterService(getter_AddRefs(serv));
// we won't fail to load the page just because we couldn't load the
// stream converter service.. carry on..
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIStreamListener> converter;
nsCAutoString from(val);
ToLowerCase(from);
rv = serv->AsyncConvertData(from.get(),
"uncompressed",
mListener,
mListenerContext,
getter_AddRefs(converter));
if (NS_SUCCEEDED(rv)) {
LOG(("converter installed from \'%s\' to \'uncompressed\'\n", val));
mListener = converter;
}
}
} else if (val != nsnull) {
LOG(("Unknown content encoding '%s', ignoring\n", val));
}
return NS_OK;
}
// NOTE: This function duplicates code from nsBaseChannel. This will go away // NOTE: This function duplicates code from nsBaseChannel. This will go away
// once HTTP uses nsBaseChannel (part of bug 312760) // once HTTP uses nsBaseChannel (part of bug 312760)
static void static void

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

@ -176,7 +176,6 @@ private:
void HandleAsyncNotifyListener(); void HandleAsyncNotifyListener();
void DoNotifyListener(); void DoNotifyListener();
nsresult SetupTransaction(); nsresult SetupTransaction();
nsresult ApplyContentConversions();
nsresult CallOnStartRequest(); nsresult CallOnStartRequest();
nsresult ProcessResponse(); nsresult ProcessResponse();
nsresult ContinueProcessResponse(nsresult); nsresult ContinueProcessResponse(nsresult);

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

@ -1593,24 +1593,12 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest *request, nsISuppo
// and it was opened specifically for the download // and it was opened specifically for the download
MaybeCloseWindow(); MaybeCloseWindow();
#ifdef MOZ_IPC // In an IPC setting, we're allowing the child process, here, to make
// At this point, the child process has done everything it can usefully do // decisions about decoding the channel (e.g. decompression). It will
// for OnStartRequest. // still forward the decoded (uncompressed) data back to the parent.
if (XRE_GetProcessType() == GeckoProcessType_Content) // Con: Uncompressed data means more IPC overhead.
return NS_OK; // Pros: ExternalHelperAppParent doesn't need to implement nsIEncodedChannel.
#endif // Parent process doesn't need to expect CPU time on decompression.
rv = SetUpTempFile(aChannel);
if (NS_FAILED(rv)) {
mCanceled = PR_TRUE;
request->Cancel(rv);
nsAutoString path;
if (mTempFile)
mTempFile->GetPath(path);
SendStatusChange(kWriteError, rv, request, path);
return NS_OK;
}
nsCOMPtr<nsIEncodedChannel> encChannel = do_QueryInterface( aChannel ); nsCOMPtr<nsIEncodedChannel> encChannel = do_QueryInterface( aChannel );
if (encChannel) if (encChannel)
{ {
@ -1648,6 +1636,24 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest *request, nsISuppo
encChannel->SetApplyConversion( applyConversion ); encChannel->SetApplyConversion( applyConversion );
} }
#ifdef MOZ_IPC
// At this point, the child process has done everything it can usefully do
// for OnStartRequest.
if (XRE_GetProcessType() == GeckoProcessType_Content)
return NS_OK;
#endif
rv = SetUpTempFile(aChannel);
if (NS_FAILED(rv)) {
mCanceled = PR_TRUE;
request->Cancel(rv);
nsAutoString path;
if (mTempFile)
mTempFile->GetPath(path);
SendStatusChange(kWriteError, rv, request, path);
return NS_OK;
}
// Inform channel it is open on behalf of a download to prevent caching. // Inform channel it is open on behalf of a download to prevent caching.
nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(aChannel); nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(aChannel);
if (httpInternal) { if (httpInternal) {