michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsUnknownDecoder_h__ michael@0: #define nsUnknownDecoder_h__ michael@0: michael@0: #include "nsIStreamConverter.h" michael@0: #include "nsIContentSniffer.h" michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsString.h" michael@0: michael@0: #define NS_UNKNOWNDECODER_CID \ michael@0: { /* 7d7008a0-c49a-11d3-9b22-0080c7cb1080 */ \ michael@0: 0x7d7008a0, \ michael@0: 0xc49a, \ michael@0: 0x11d3, \ michael@0: {0x9b, 0x22, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x80} \ michael@0: } michael@0: michael@0: michael@0: class nsUnknownDecoder : public nsIStreamConverter, public nsIContentSniffer michael@0: { michael@0: public: michael@0: // nsISupports methods michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: // nsIStreamConverter methods michael@0: NS_DECL_NSISTREAMCONVERTER michael@0: michael@0: // nsIStreamListener methods michael@0: NS_DECL_NSISTREAMLISTENER michael@0: michael@0: // nsIRequestObserver methods michael@0: NS_DECL_NSIREQUESTOBSERVER michael@0: michael@0: // nsIContentSniffer methods michael@0: NS_DECL_NSICONTENTSNIFFER michael@0: michael@0: nsUnknownDecoder(); michael@0: michael@0: protected: michael@0: virtual ~nsUnknownDecoder(); michael@0: michael@0: virtual void DetermineContentType(nsIRequest* aRequest); michael@0: nsresult FireListenerNotifications(nsIRequest* request, nsISupports *aCtxt); michael@0: michael@0: protected: michael@0: nsCOMPtr mNextListener; michael@0: michael@0: // Function to use to check whether sniffing some potentially michael@0: // dangerous types (eg HTML) is ok for this request. We can disable michael@0: // sniffing for local files if needed using this. Just a security michael@0: // precation thingy... who knows when we suddenly need to flip this michael@0: // pref? michael@0: bool AllowSniffing(nsIRequest* aRequest); michael@0: michael@0: // Various sniffer functions. Returning true means that a type michael@0: // was determined; false means no luck. michael@0: bool SniffForHTML(nsIRequest* aRequest); michael@0: bool SniffForXML(nsIRequest* aRequest); michael@0: michael@0: // SniffURI guesses at the content type based on the URI (typically michael@0: // using the extentsion) michael@0: bool SniffURI(nsIRequest* aRequest); michael@0: michael@0: // LastDitchSniff guesses at text/plain vs. application/octet-stream michael@0: // by just looking at whether the data contains null bytes, and michael@0: // maybe at the fraction of chars with high bit set. Use this only michael@0: // as a last-ditch attempt to decide a content type! michael@0: bool LastDitchSniff(nsIRequest* aRequest); michael@0: michael@0: /** michael@0: * An entry struct for our array of sniffers. Each entry has either michael@0: * a type associated with it (set these with the SNIFFER_ENTRY macro) michael@0: * or a function to be executed (set these with the michael@0: * SNIFFER_ENTRY_WITH_FUNC macro). The function should take a single michael@0: * nsIRequest* and returns bool -- true if it sets mContentType, michael@0: * false otherwise michael@0: */ michael@0: struct nsSnifferEntry { michael@0: typedef bool (nsUnknownDecoder::*TypeSniffFunc)(nsIRequest* aRequest); michael@0: michael@0: const char* mBytes; michael@0: uint32_t mByteLen; michael@0: michael@0: // Exactly one of mMimeType and mContentTypeSniffer should be set non-null michael@0: const char* mMimeType; michael@0: TypeSniffFunc mContentTypeSniffer; michael@0: }; michael@0: michael@0: #define SNIFFER_ENTRY(_bytes, _type) \ michael@0: { _bytes, sizeof(_bytes) - 1, _type, nullptr } michael@0: michael@0: #define SNIFFER_ENTRY_WITH_FUNC(_bytes, _func) \ michael@0: { _bytes, sizeof(_bytes) - 1, nullptr, _func } michael@0: michael@0: static nsSnifferEntry sSnifferEntries[]; michael@0: static uint32_t sSnifferEntryNum; michael@0: michael@0: char *mBuffer; michael@0: uint32_t mBufferLen; michael@0: bool mRequireHTMLsuffix; michael@0: michael@0: nsCString mContentType; michael@0: michael@0: }; michael@0: michael@0: #define NS_BINARYDETECTOR_CID \ michael@0: { /* a2027ec6-ba0d-4c72-805d-148233f5f33c */ \ michael@0: 0xa2027ec6, \ michael@0: 0xba0d, \ michael@0: 0x4c72, \ michael@0: {0x80, 0x5d, 0x14, 0x82, 0x33, 0xf5, 0xf3, 0x3c} \ michael@0: } michael@0: michael@0: /** michael@0: * Class that detects whether a data stream is text or binary. This reuses michael@0: * most of nsUnknownDecoder except the actual content-type determination logic michael@0: * -- our overridden DetermineContentType simply calls LastDitchSniff and sets michael@0: * the type to APPLICATION_GUESS_FROM_EXT if the data is detected as binary. michael@0: */ michael@0: class nsBinaryDetector : public nsUnknownDecoder michael@0: { michael@0: protected: michael@0: virtual void DetermineContentType(nsIRequest* aRequest); michael@0: }; michael@0: michael@0: #define NS_BINARYDETECTOR_CATEGORYENTRY \ michael@0: { NS_CONTENT_SNIFFER_CATEGORY, "Binary Detector", NS_BINARYDETECTOR_CONTRACTID } michael@0: michael@0: #endif /* nsUnknownDecoder_h__ */ michael@0: