Bug 813438 - Part 1: Implement NS_SniffContent; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2012-11-20 19:19:53 -05:00
parent 564f778357
commit 8cca5e4ac6
4 changed files with 64 additions and 1 deletions

View File

@ -79,6 +79,8 @@
#include "nsIPrivateBrowsingChannel.h"
#include "mozIApplicationClearPrivateDataParams.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIContentSniffer.h"
#include "nsCategoryCache.h"
#include <limits>
@ -2154,4 +2156,48 @@ NS_GenerateHostPort(const nsCString& host, int32_t port,
return NS_OK;
}
/**
* Sniff the content type for a given request or a given buffer.
*
* aSnifferType can be either NS_CONTENT_SNIFFER_CATEGORY or
* NS_DATA_SNIFFER_CATEGORY. The function returns the sniffed content type
* in the aSniffedType argument. This argument will not be modified if the
* content type could not be sniffed.
*/
inline void
NS_SniffContent(const char* aSnifferType, nsIRequest* aRequest,
const uint8_t* aData, uint32_t aLength,
nsACString& aSniffedType)
{
typedef nsCategoryCache<nsIContentSniffer> ContentSnifferCache;
extern NS_HIDDEN_(ContentSnifferCache*) gNetSniffers;
extern NS_HIDDEN_(ContentSnifferCache*) gDataSniffers;
ContentSnifferCache* cache = nullptr;
if (!strcmp(aSnifferType, NS_CONTENT_SNIFFER_CATEGORY)) {
if (!gNetSniffers) {
gNetSniffers = new ContentSnifferCache(NS_CONTENT_SNIFFER_CATEGORY);
}
cache = gNetSniffers;
} else if (!strcmp(aSnifferType, NS_DATA_SNIFFER_CATEGORY)) {
if (!gDataSniffers) {
gDataSniffers = new ContentSnifferCache(NS_DATA_SNIFFER_CATEGORY);
}
cache = gDataSniffers;
} else {
// Invalid content sniffer type was requested
MOZ_ASSERT(false);
return;
}
const nsCOMArray<nsIContentSniffer>& sniffers = cache->GetEntries();
for (int32_t i = 0; i < sniffers.Count(); ++i) {
nsresult rv = sniffers[i]->GetMIMETypeFromContent(aRequest, aData, aLength, aSniffedType);
if (NS_SUCCEEDED(rv) && !aSniffedType.IsEmpty()) {
return;
}
}
aSniffedType.Truncate();
}
#endif // !nsNetUtil_h__

View File

@ -1027,6 +1027,12 @@
*/
#define NS_CONTENT_SNIFFER_CATEGORY "net-content-sniffers"
/**
* Services in this category can sniff content that is not necessarily loaded
* from the network, and they won't be told about each load.
*/
#define NS_DATA_SNIFFER_CATEGORY "content-sniffing-services"
/**
* Must implement nsINSSErrorsService.
*/

View File

@ -34,6 +34,8 @@
#include "nsDNSPrefetch.h"
#include "nsAboutProtocolHandler.h"
#include "nsXULAppAPI.h"
#include "nsCategoryCache.h"
#include "nsIContentSniffer.h"
#include "nsNetCID.h"
@ -45,6 +47,10 @@
#define BUILD_BINHEX_DECODER 1
#endif
typedef nsCategoryCache<nsIContentSniffer> ContentSnifferCache;
NS_HIDDEN_(ContentSnifferCache*) gNetSniffers = nullptr;
NS_HIDDEN_(ContentSnifferCache*) gDataSniffers = nullptr;
///////////////////////////////////////////////////////////////////////////////
#include "nsIOService.h"
@ -643,6 +649,11 @@ static void nsNetShutdown()
// Release the Websocket Admission Manager
mozilla::net::WebSocketChannel::Shutdown();
#endif // NECKO_PROTOCOL_websocket
delete gNetSniffers;
gNetSniffers = nullptr;
delete gDataSniffers;
gDataSniffers = nullptr;
}
NS_DEFINE_NAMED_CID(NS_IOSERVICE_CID);

View File

@ -59,7 +59,7 @@ class NS_COM_GLUE nsCategoryObserver MOZ_FINAL : public nsIObserver {
* then get the name of the category.
*/
template<class T>
class nsCategoryCache : protected nsCategoryListener {
class nsCategoryCache MOZ_FINAL : protected nsCategoryListener {
public:
explicit nsCategoryCache(const char* aCategory);
~nsCategoryCache() { if (mObserver) mObserver->ListenerDied(); }