diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp index 535e595cbd8..03563b9da69 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -31,9 +31,9 @@ #include "nsIHttpAuthenticator.h" #include "nsIAuthPrompt.h" #include "nsIStringBundle.h" -#include "nsIStreamConverterService.h" #include "nsISupportsPrimitives.h" #include "nsIFileStream.h" +#include "nsMimeTypes.h" #include "nsNetUtil.h" #include "nsString2.h" #include "nsReadableUtils.h" @@ -1655,15 +1655,60 @@ nsHttpChannel::GetSecurityInfo(nsISupports **securityInfo) NS_IMETHODIMP nsHttpChannel::GetContentType(char **value) { - if (!mResponseHead) - return NS_ERROR_NOT_AVAILABLE; + nsresult rv; - return DupString(mResponseHead->ContentType(), value); + NS_ENSURE_ARG_POINTER(value); + + if (mResponseHead && mResponseHead->ContentType()) + return DupString(mResponseHead->ContentType(), value); + + // else if the there isn't a response yet or if the response does not + // contain a content-type header, try to determine the content type + // from the file extension of the URI... + + // We had to do this same hack in 4.x. Sometimes, we run an http url that + // ends in special extensions like .dll, .exe, etc and the server doesn't + // provide a specific content type for the document. In actuality the + // document is really text/html (sometimes). For these cases, we don't want + // to ask the mime service for the content type because it will make + // incorrect conclusions based on the file extension. Instead, set the + // content type to unknown and allow our unknown content type decoder a + // chance to sniff the data stream and conclude a content type. + + PRBool doMimeLookup = PR_TRUE; + nsCOMPtr url = do_QueryInterface(mURI); + if (url) { + nsXPIDLCString ext; + url->GetFileExtension(getter_Copies(ext)); + if (ext && (!PL_strcasecmp(ext, "dll") || !PL_strcasecmp(ext, "exe"))) + doMimeLookup = PR_FALSE; + } + if (doMimeLookup) { + nsCOMPtr mime; + nsHttpHandler::get()->GetMimeService(getter_AddRefs(mime)); + if (mime) { + rv = mime->GetTypeFromURI(mURI, value); + if (NS_SUCCEEDED(rv)) { + // cache this result if possible + if (mResponseHead) + mResponseHead->SetContentType(*value); + return rv; + } + } + } + + if (!*value) + *value = PL_strdup(UNKNOWN_CONTENT_TYPE); + + return *value ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } NS_IMETHODIMP nsHttpChannel::SetContentType(const char *value) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!mResponseHead) + return NS_ERROR_NOT_AVAILABLE; + + return mResponseHead->SetContentType(value); } NS_IMETHODIMP diff --git a/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp b/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp index b19d667c8ec..3dc3deafea9 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp @@ -65,6 +65,7 @@ static NS_DEFINE_CID(kNetModuleMgrCID, NS_NETMODULEMGR_CID); static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID); static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +static NS_DEFINE_CID(kMimeServiceCID, NS_MIMESERVICE_CID); #define UA_PREF_PREFIX "general.useragent." #define UA_APPNAME "Mozilla" @@ -498,6 +499,19 @@ nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result) return NS_OK; } +nsresult +nsHttpHandler::GetMimeService(nsIMIMEService **result) +{ + if (!mMimeService) { + nsresult rv; + mMimeService = do_GetService(kMimeServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + } + *result = mMimeService; + NS_ADDREF(*result); + return NS_OK; +} + nsresult nsHttpHandler::OnModifyRequest(nsIHttpChannel *chan) { diff --git a/mozilla/netwerk/protocol/http/src/nsHttpHandler.h b/mozilla/netwerk/protocol/http/src/nsHttpHandler.h index 01214649737..4d11ddafdf8 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpHandler.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpHandler.h @@ -35,6 +35,7 @@ #include "nsIStreamConverterService.h" #include "nsICacheSession.h" #include "nsIEventQueueService.h" +#include "nsIMIMEService.h" #include "nsXPIDLString.h" #include "nsString.h" #include "nsCOMPtr.h" @@ -123,6 +124,7 @@ public: nsresult GetProxyObjectManager(nsIProxyObjectManager **); nsresult GetEventQueueService(nsIEventQueueService **); nsresult GetStreamConverterService(nsIStreamConverterService **); + nsresult GetMimeService(nsIMIMEService **); // Called by the channel before writing a request nsresult OnModifyRequest(nsIHttpChannel *); @@ -185,6 +187,7 @@ private: nsCOMPtr mEventQueueService; nsCOMPtr mNetModuleMgr; nsCOMPtr mStreamConvSvc; + nsCOMPtr mMimeService; // the authentication credentials cache nsHttpAuthCache *mAuthCache; diff --git a/mozilla/netwerk/protocol/http/src/nsHttpResponseHead.h b/mozilla/netwerk/protocol/http/src/nsHttpResponseHead.h index 92cc0b5fb42..09038761d9d 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpResponseHead.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpResponseHead.h @@ -54,6 +54,8 @@ public: nsresult GetHeader(nsHttpAtom h, char **v) { return mHeaders.GetHeader(h, v); } void ClearHeaders() { mHeaders.Clear(); } + nsresult SetContentType(const char *s) { mContentType = s; } + // write out the response status line and headers as a single text block, // optionally pruning out transient headers (ie. headers that only make // sense the first time the response is handled).