diff --git a/mozilla/content/html/style/src/nsCSSLoader.cpp b/mozilla/content/html/style/src/nsCSSLoader.cpp index 3985196bf6b..20451f63202 100644 --- a/mozilla/content/html/style/src/nsCSSLoader.cpp +++ b/mozilla/content/html/style/src/nsCSSLoader.cpp @@ -1359,6 +1359,10 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) } } + // Now tell the channel we expect text/css data back.... We do + // this before opening it, so it's only treated as a hint. + channel->SetContentType(NS_LITERAL_CSTRING("text/css")); + // We don't have to hold on to the stream loader. The ownership // model is: Necko owns the stream loader, which owns the load data, // which owns us diff --git a/mozilla/layout/style/nsCSSLoader.cpp b/mozilla/layout/style/nsCSSLoader.cpp index 3985196bf6b..20451f63202 100644 --- a/mozilla/layout/style/nsCSSLoader.cpp +++ b/mozilla/layout/style/nsCSSLoader.cpp @@ -1359,6 +1359,10 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) } } + // Now tell the channel we expect text/css data back.... We do + // this before opening it, so it's only treated as a hint. + channel->SetContentType(NS_LITERAL_CSTRING("text/css")); + // We don't have to hold on to the stream loader. The ownership // model is: Necko owns the stream loader, which owns the load data, // which owns us diff --git a/mozilla/modules/libjar/nsJARChannel.cpp b/mozilla/modules/libjar/nsJARChannel.cpp index a49cde6e7d9..73e841ce3d7 100644 --- a/mozilla/modules/libjar/nsJARChannel.cpp +++ b/mozilla/modules/libjar/nsJARChannel.cpp @@ -507,6 +507,9 @@ nsJARChannel::GetContentType(nsACString &result) NS_IMETHODIMP nsJARChannel::SetContentType(const nsACString &aContentType) { + // If someone gives us a type hint we should just use that type instead of + // doing our guessing. So we don't care when this is being called. + // mContentCharset is unchanged if not parsed NS_ParseContentType(aContentType, mContentType, mContentCharset); return NS_OK; @@ -515,6 +518,8 @@ nsJARChannel::SetContentType(const nsACString &aContentType) NS_IMETHODIMP nsJARChannel::GetContentCharset(nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. aContentCharset = mContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/base/public/nsIChannel.idl b/mozilla/netwerk/base/public/nsIChannel.idl index 0a10d3a67d9..9bf44d33884 100644 --- a/mozilla/netwerk/base/public/nsIChannel.idl +++ b/mozilla/netwerk/base/public/nsIChannel.idl @@ -107,7 +107,17 @@ interface nsIChannel : nsIRequest * * NOTE: the content type can often be wrongly specified (e.g., wrong file * extension, wrong MIME type, wrong document type stored on a server, etc.), - * and the caller most likely wants to verify with the actual data. + * and the caller most likely wants to verify with the actual data. + * + * Setting contentType before the channel has been opened provides a hint + * to the channel as to what the MIME type is. The channel may ignore this + * hint in deciding on the actual MIME type that it will report. + * + * Setting contentType after onStartRequest has been fired or after open() + * is called will override the type determined by the channel. + * + * Setting contentType between the time that asyncOpen() is called and the + * time when onStartRequest is fired has undefined behavior at this time. */ attribute ACString contentType; diff --git a/mozilla/netwerk/base/src/nsInputStreamChannel.cpp b/mozilla/netwerk/base/src/nsInputStreamChannel.cpp index 5292da4e4e5..20ae6ca1322 100644 --- a/mozilla/netwerk/base/src/nsInputStreamChannel.cpp +++ b/mozilla/netwerk/base/src/nsInputStreamChannel.cpp @@ -240,6 +240,9 @@ nsInputStreamChannel::GetContentType(nsACString &aContentType) NS_IMETHODIMP nsInputStreamChannel::SetContentType(const nsACString &aContentType) { + // If someone gives us a type hint we should just use that type. + // So we don't care when this is being called. + // mContentCharset is unchanged if not parsed NS_ParseContentType(aContentType, mContentType, mContentCharset); return NS_OK; @@ -255,6 +258,8 @@ nsInputStreamChannel::GetContentCharset(nsACString &aContentCharset) NS_IMETHODIMP nsInputStreamChannel::SetContentCharset(const nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. mContentCharset = aContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp b/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp index 7771600d54b..4a4ccaf2737 100644 --- a/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp +++ b/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp @@ -56,10 +56,12 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); // nsDataChannel methods -nsDataChannel::nsDataChannel() { - mStatus = NS_OK; - mContentLength = -1; - mLoadFlags = nsIRequest::LOAD_NORMAL; +nsDataChannel::nsDataChannel() : + mStatus(NS_OK), + mLoadFlags(nsIRequest::LOAD_NORMAL), + mContentLength(-1), + mOpened(PR_FALSE) +{ } nsDataChannel::~nsDataChannel() { @@ -362,6 +364,7 @@ nsDataChannel::Open(nsIInputStream **_retval) { NS_ENSURE_ARG_POINTER(_retval); NS_ADDREF(*_retval = mDataStream); + mOpened = PR_TRUE; return NS_OK; } @@ -386,6 +389,7 @@ nsDataChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) // Hold onto the real consumer... mListener = aListener; + mOpened = PR_TRUE; // Add the request to the loadgroup (if available) if (mLoadGroup) { @@ -437,7 +441,10 @@ nsDataChannel::GetContentType(nsACString &aContentType) NS_IMETHODIMP nsDataChannel::SetContentType(const nsACString &aContentType) { - mContentType = aContentType; + // Ignore content-type hints + if (mOpened) { + mContentType = aContentType; + } return NS_OK; } @@ -451,7 +458,10 @@ nsDataChannel::GetContentCharset(nsACString &aContentCharset) NS_IMETHODIMP nsDataChannel::SetContentCharset(const nsACString &aContentCharset) { - mContentCharset = aContentCharset; + // Ignore content-charset hints + if (mOpened) { + mContentCharset = aContentCharset; + } return NS_OK; } diff --git a/mozilla/netwerk/protocol/data/src/nsDataChannel.h b/mozilla/netwerk/protocol/data/src/nsDataChannel.h index 31cd4c95407..fc60475b5db 100644 --- a/mozilla/netwerk/protocol/data/src/nsDataChannel.h +++ b/mozilla/netwerk/protocol/data/src/nsDataChannel.h @@ -84,6 +84,7 @@ protected: PRInt32 mContentLength; nsCOMPtr mOwner; nsCOMPtr mListener; + PRBool mOpened; }; -#endif /* nsFTPChannel_h___ */ +#endif /* nsDataChannel_h___ */ diff --git a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp index 6c7b2523443..1a7b5416ceb 100644 --- a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp +++ b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp @@ -312,6 +312,9 @@ nsFileChannel::GetContentType(nsACString &aContentType) NS_IMETHODIMP nsFileChannel::SetContentType(const nsACString &aContentType) { + // If someone gives us a type hint we should just use that type instead of + // doing our guessing. So we don't care when this is being called. + // mContentCharset is unchanged if not parsed NS_ParseContentType(aContentType, mContentType, mContentCharset); return NS_OK; @@ -327,6 +330,8 @@ nsFileChannel::GetContentCharset(nsACString &aContentCharset) NS_IMETHODIMP nsFileChannel::SetContentCharset(const nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. mContentCharset = aContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp index 201c2dcf328..70a2ec84479 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp +++ b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp @@ -411,6 +411,8 @@ nsFTPChannel::GetContentType(nsACString &aContentType) NS_IMETHODIMP nsFTPChannel::SetContentType(const nsACString &aContentType) { + // If someone gives us a type hint we should just use that type instead of + // doing our guessing. So we don't care when this is being called. nsAutoLock lock(mLock); NS_ParseContentType(aContentType, mContentType, mContentCharset); return NS_OK; @@ -426,6 +428,8 @@ nsFTPChannel::GetContentCharset(nsACString &aContentCharset) NS_IMETHODIMP nsFTPChannel::SetContentCharset(const nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. mContentCharset = aContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp index 073767bf83f..c1bef910617 100644 --- a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp +++ b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp @@ -389,8 +389,13 @@ nsGopherChannel::GetContentType(nsACString &aContentType) aContentType = NS_LITERAL_CSTRING(TEXT_PLAIN); break; default: - NS_WARNING("Unknown gopher type"); - aContentType = NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE); + if (!mContentTypeHint.IsEmpty()) { + aContentType = mContentTypeHint; + } else { + NS_WARNING("Unknown gopher type"); + aContentType = NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE); + } + break; } PR_LOG(gGopherLog,PR_LOG_DEBUG, @@ -403,8 +408,17 @@ nsGopherChannel::GetContentType(nsACString &aContentType) NS_IMETHODIMP nsGopherChannel::SetContentType(const nsACString &aContentType) { - // only changes mContentCharset if a charset is parsed - NS_ParseContentType(aContentType, mContentType, mContentCharset); + if (mIsPending) { + // only changes mContentCharset if a charset is parsed + NS_ParseContentType(aContentType, mContentType, mContentCharset); + } else { + // We are being given a content-type hint. Since we have no ways of + // determining a charset on our own, just set mContentCharset from the + // charset part of this. + nsCAutoString charsetBuf; + NS_ParseContentType(aContentType, mContentTypeHint, mContentCharset); + } + return NS_OK; } @@ -418,6 +432,8 @@ nsGopherChannel::GetContentCharset(nsACString &aContentCharset) NS_IMETHODIMP nsGopherChannel::SetContentCharset(const nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. mContentCharset = aContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.h b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.h index 8659c3fd166..a2ef492d20b 100644 --- a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.h +++ b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.h @@ -76,6 +76,7 @@ protected: nsCOMPtr mLoadGroup; nsCString mContentType; nsCString mContentCharset; + nsCString mContentTypeHint; PRInt32 mContentLength; nsCOMPtr mOwner; PRUint32 mListFormat; diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp index c639e6ae4b6..b74430e3ad3 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -586,28 +586,35 @@ nsresult nsHttpChannel::CallOnStartRequest() { if (mResponseHead && mResponseHead->ContentType().IsEmpty()) { - // Uh-oh. We had better find out what type we are! + if (!mContentTypeHint.IsEmpty()) + mResponseHead->SetContentType(mContentTypeHint); + else { + // Uh-oh. We had better find out what type we are! - // XXX This does not work with content-encodings... but - // neither does applying the conversion from the URILoader + // XXX This does not work with content-encodings... but + // neither does applying the conversion from the URILoader - nsCOMPtr serv; - nsresult rv = gHttpHandler-> + nsCOMPtr serv; + nsresult rv = gHttpHandler-> GetStreamConverterService(getter_AddRefs(serv)); - // If we failed, we just fall through to the "normal" case - if (NS_SUCCEEDED(rv)) { - NS_ConvertASCIItoUCS2 from(UNKNOWN_CONTENT_TYPE); - nsCOMPtr converter; - rv = serv->AsyncConvertData(from.get(), - NS_LITERAL_STRING("*/*").get(), - mListener, - mListenerContext, - getter_AddRefs(converter)); + // If we failed, we just fall through to the "normal" case if (NS_SUCCEEDED(rv)) { - mListener = converter; + NS_ConvertASCIItoUCS2 from(UNKNOWN_CONTENT_TYPE); + nsCOMPtr converter; + rv = serv->AsyncConvertData(from.get(), + NS_LITERAL_STRING("*/*").get(), + mListener, + mListenerContext, + getter_AddRefs(converter)); + if (NS_SUCCEEDED(rv)) { + mListener = converter; + } } } } + + if (mResponseHead && mResponseHead->ContentCharset().IsEmpty()) + mResponseHead->SetContentCharset(mContentCharsetHint); LOG((" calling mListener->OnStartRequest\n")); nsresult rv = mListener->OnStartRequest(this, mListenerContext); @@ -2562,17 +2569,24 @@ nsHttpChannel::GetContentType(nsACString &value) NS_IMETHODIMP nsHttpChannel::SetContentType(const nsACString &value) { - if (!mResponseHead) - return NS_ERROR_NOT_AVAILABLE; + if (mIsPending) { + if (!mResponseHead) + return NS_ERROR_NOT_AVAILABLE; - nsCAutoString contentTypeBuf, charsetBuf; - NS_ParseContentType(value, contentTypeBuf, charsetBuf); + nsCAutoString contentTypeBuf, charsetBuf; + NS_ParseContentType(value, contentTypeBuf, charsetBuf); - mResponseHead->SetContentType(contentTypeBuf); + mResponseHead->SetContentType(contentTypeBuf); - // take care not to stomp on an existing charset - if (!charsetBuf.IsEmpty()) - mResponseHead->SetContentCharset(charsetBuf); + // take care not to stomp on an existing charset + if (!charsetBuf.IsEmpty()) + mResponseHead->SetContentCharset(charsetBuf); + } else { + // We are being given a content-type hint. + nsCAutoString charsetBuf; + NS_ParseContentType(value, mContentTypeHint, mContentCharsetHint); + } + return NS_OK; } @@ -2589,10 +2603,15 @@ nsHttpChannel::GetContentCharset(nsACString &value) NS_IMETHODIMP nsHttpChannel::SetContentCharset(const nsACString &value) { - if (!mResponseHead) - return NS_ERROR_NOT_AVAILABLE; + if (mIsPending) { + if (!mResponseHead) + return NS_ERROR_NOT_AVAILABLE; - mResponseHead->SetContentCharset(value); + mResponseHead->SetContentCharset(value); + } else { + // Charset hint + mContentCharsetHint = value; + } return NS_OK; } diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.h b/mozilla/netwerk/protocol/http/src/nsHttpChannel.h index eb45aa2ad1f..7aef31d68ae 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.h @@ -190,6 +190,9 @@ private: PRUint32 mLogicalOffset; PRUint8 mCaps; + nsCString mContentTypeHint; + nsCString mContentCharsetHint; + // cache specific data nsCOMPtr mCacheEntry; nsCOMPtr mCachePump; diff --git a/mozilla/netwerk/protocol/jar/src/nsJARChannel.cpp b/mozilla/netwerk/protocol/jar/src/nsJARChannel.cpp index a49cde6e7d9..73e841ce3d7 100644 --- a/mozilla/netwerk/protocol/jar/src/nsJARChannel.cpp +++ b/mozilla/netwerk/protocol/jar/src/nsJARChannel.cpp @@ -507,6 +507,9 @@ nsJARChannel::GetContentType(nsACString &result) NS_IMETHODIMP nsJARChannel::SetContentType(const nsACString &aContentType) { + // If someone gives us a type hint we should just use that type instead of + // doing our guessing. So we don't care when this is being called. + // mContentCharset is unchanged if not parsed NS_ParseContentType(aContentType, mContentType, mContentCharset); return NS_OK; @@ -515,6 +518,8 @@ nsJARChannel::SetContentType(const nsACString &aContentType) NS_IMETHODIMP nsJARChannel::GetContentCharset(nsACString &aContentCharset) { + // If someone gives us a charset hint we should just use that charset. + // So we don't care when this is being called. aContentCharset = mContentCharset; return NS_OK; } diff --git a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp index 340e0c3b0d9..a16ab4037ed 100644 --- a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp +++ b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp @@ -1,4 +1,4 @@ - /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -32,7 +32,9 @@ #include "nsNetUtil.h" // nsViewSourceChannel methods -nsViewSourceChannel::nsViewSourceChannel() : mIsDocument(PR_FALSE) +nsViewSourceChannel::nsViewSourceChannel() : + mIsDocument(PR_FALSE), + mOpened(PR_FALSE) { } @@ -50,15 +52,15 @@ NS_IMPL_THREADSAFE_RELEASE(nsViewSourceChannel) This seems like a better approach than writing out the whole QI by hand. */ NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel) - NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel) + NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel) NS_INTERFACE_MAP_END_THREADSAFE nsresult @@ -194,7 +196,12 @@ nsViewSourceChannel::Open(nsIInputStream **_retval) { NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); - return mChannel->Open(_retval); + nsresult rv = mChannel->Open(_retval); + if (NS_SUCCEEDED(rv)) { + mOpened = PR_TRUE; + } + + return rv; } NS_IMETHODIMP @@ -223,6 +230,10 @@ nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) this), nsnull, rv); + if (NS_SUCCEEDED(rv)) { + mOpened = PR_TRUE; + } + return rv; } @@ -330,6 +341,11 @@ nsViewSourceChannel::SetContentType(const nsACString &aContentType) // content type, such as, text/html and everything is kosher from // then on. + if (!mOpened) { + // We do not take hints + return NS_ERROR_NOT_AVAILABLE; + } + mContentType = aContentType; return NS_OK; } @@ -434,12 +450,12 @@ nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType) NS_IMETHODIMP nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType) { - NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); - // clear our cached content-type value - mContentType.Truncate(); + // clear our cached content-type value + mContentType.Truncate(); - return mChannel->SetContentType(aContentType); + return mChannel->SetContentType(aContentType); } // nsIRequestObserver methods diff --git a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.h b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.h index 5546a818696..ce5ad210cf3 100644 --- a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.h +++ b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceChannel.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -88,6 +88,7 @@ protected: nsCOMPtr mOriginalURI; nsCString mContentType; PRBool mIsDocument; // keeps track of the LOAD_DOCUMENT_URI flag + PRBool mOpened; }; #endif /* nsViewSourceChannel_h___ */ diff --git a/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.cpp b/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.cpp index 22de664372c..9c62a56a935 100644 --- a/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.cpp +++ b/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.cpp @@ -501,65 +501,42 @@ nsBinHexDecoder::OnStartRequest(nsIRequest* request, nsISupports *aCtxt) return rv; } -// Given the current request and the fileName we discovered inside the bin hex decoding, -// figure out the content type and set it on the channel associated with the request. -nsresult nsBinHexDecoder::SetContentType(nsIRequest * aRequest, const char * fileName) +// Given the fileName we discovered inside the bin hex decoding, figure out the +// content type and set it on the channel associated with the request. If the +// filename tells us nothing useful, just report an unknown type and let the +// unknown decoder handle things. +nsresult nsBinHexDecoder::SetContentType(nsIRequest* aRequest, + const char * fileName) { - nsresult rv = NS_OK; - - nsCOMPtr channel = do_QueryInterface(aRequest); - if (!channel) - { - NS_WARNING("QI failed"); - return NS_ERROR_FAILURE; + if (!fileName || !*fileName) { + // Nothing to do here. + return NS_OK; } - nsCOMPtr mimeService (do_GetService("@mozilla.org/mime;1", &rv)); + nsresult rv; + nsCOMPtr channel(do_QueryInterface(aRequest, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr mimeService(do_GetService("@mozilla.org/mime;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); nsXPIDLCString contentType; - if (fileName) - { - // extract the extension from fileName and look it up. - const char * fileExt = PL_strrchr(fileName, '.'); - if (fileExt) - mimeService->GetTypeFromExtension(fileExt, getter_Copies(contentType)); - mContentType = contentType; + + // extract the extension from fileName and look it up. + const char * fileExt = strrchr(fileName, '.'); + if (!fileExt) { + return NS_OK; } - if (mContentType.IsEmpty()) - { - // get the url for the channel..... - nsCOMPtr uri; - channel->GetURI(getter_AddRefs(uri)); - if (uri) - { - nsCOMPtr url = do_QueryInterface(uri); - if (url) - { - nsCAutoString fileExt; - rv = url->GetFileExtension(fileExt); - if (NS_SUCCEEDED(rv) && !fileExt.IsEmpty()) - { - rv = mimeService->GetTypeFromExtension(fileExt.get(), getter_Copies(contentType)); - if (NS_SUCCEEDED(rv) && *(contentType.get())) - mContentType = contentType; - } - } - } - } // if the content type is empty + mimeService->GetTypeFromExtension(fileExt, getter_Copies(contentType)); - // if we STILL don't have a content type....say the content type is unknown... - // AND to avoid a recursive loop, if after extracting the data fork, we didn't get a valid - // content type and still think it's mac binhex, then reset to unknown. - if (mContentType.IsEmpty() || mContentType.Equals("application/mac-binhex40")) - { - mContentType = NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE); + // Only set the type if it's not empty and, to prevent recursive loops, not the binhex type + if (!contentType.IsEmpty() && !contentType.Equals(APPLICATION_BINHEX)) { + channel->SetContentType(contentType); + } else { + channel->SetContentType(NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE)); } - // now set the content type on the channel. - channel->SetContentType(mContentType); - return NS_OK; } diff --git a/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.h b/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.h index 14bd9915937..0d9d944a9bd 100644 --- a/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.h +++ b/mozilla/netwerk/streamconv/converters/nsBinHexDecoder.h @@ -117,7 +117,6 @@ protected: nsresult SetContentType(nsIRequest * aRequest, const char * fileName); protected: - nsCString mContentType; nsCOMPtr mNextListener; // the input and output streams form a pipe...they need to be passed around together..