/src/mozilla-central/netwerk/streamconv/converters/nsUnknownDecoder.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef nsUnknownDecoder_h__ |
7 | | #define nsUnknownDecoder_h__ |
8 | | |
9 | | #include "nsIStreamConverter.h" |
10 | | #include "nsIThreadRetargetableStreamListener.h" |
11 | | #include "nsIContentSniffer.h" |
12 | | #include "mozilla/Mutex.h" |
13 | | #include "mozilla/Atomics.h" |
14 | | |
15 | | #include "nsCOMPtr.h" |
16 | | #include "nsString.h" |
17 | | |
18 | | #define NS_UNKNOWNDECODER_CID \ |
19 | | { /* 7d7008a0-c49a-11d3-9b22-0080c7cb1080 */ \ |
20 | | 0x7d7008a0, \ |
21 | | 0xc49a, \ |
22 | | 0x11d3, \ |
23 | | {0x9b, 0x22, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x80} \ |
24 | | } |
25 | | |
26 | | |
27 | | class nsUnknownDecoder : public nsIStreamConverter |
28 | | , public nsIContentSniffer |
29 | | , public nsIThreadRetargetableStreamListener |
30 | | { |
31 | | public: |
32 | | // nsISupports methods |
33 | | NS_DECL_ISUPPORTS |
34 | | |
35 | | // nsIStreamConverter methods |
36 | | NS_DECL_NSISTREAMCONVERTER |
37 | | |
38 | | // nsIStreamListener methods |
39 | | NS_DECL_NSISTREAMLISTENER |
40 | | |
41 | | // nsIRequestObserver methods |
42 | | NS_DECL_NSIREQUESTOBSERVER |
43 | | |
44 | | // nsIContentSniffer methods |
45 | | NS_DECL_NSICONTENTSNIFFER |
46 | | |
47 | | // nsIThreadRetargetableStreamListener methods |
48 | | NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER |
49 | | |
50 | | nsUnknownDecoder(); |
51 | | |
52 | | protected: |
53 | | virtual ~nsUnknownDecoder(); |
54 | | |
55 | | virtual void DetermineContentType(nsIRequest* aRequest); |
56 | | nsresult FireListenerNotifications(nsIRequest* request, nsISupports *aCtxt); |
57 | | |
58 | | class ConvertedStreamListener: public nsIStreamListener |
59 | | { |
60 | | public: |
61 | | explicit ConvertedStreamListener(nsUnknownDecoder *aDecoder); |
62 | | |
63 | | NS_DECL_ISUPPORTS |
64 | | NS_DECL_NSIREQUESTOBSERVER |
65 | | NS_DECL_NSISTREAMLISTENER |
66 | | |
67 | | private: |
68 | 0 | virtual ~ConvertedStreamListener() = default; |
69 | | static nsresult AppendDataToString(nsIInputStream* inputStream, |
70 | | void* closure, |
71 | | const char* rawSegment, |
72 | | uint32_t toOffset, |
73 | | uint32_t count, |
74 | | uint32_t* writeCount); |
75 | | nsUnknownDecoder *mDecoder; |
76 | | }; |
77 | | |
78 | | protected: |
79 | | nsCOMPtr<nsIStreamListener> mNextListener; |
80 | | |
81 | | // Function to use to check whether sniffing some potentially |
82 | | // dangerous types (eg HTML) is ok for this request. We can disable |
83 | | // sniffing for local files if needed using this. Just a security |
84 | | // precation thingy... who knows when we suddenly need to flip this |
85 | | // pref? |
86 | | bool AllowSniffing(nsIRequest* aRequest); |
87 | | |
88 | | // Various sniffer functions. Returning true means that a type |
89 | | // was determined; false means no luck. |
90 | | bool SniffForHTML(nsIRequest* aRequest); |
91 | | bool SniffForXML(nsIRequest* aRequest); |
92 | | |
93 | | // SniffURI guesses at the content type based on the URI (typically |
94 | | // using the extentsion) |
95 | | bool SniffURI(nsIRequest* aRequest); |
96 | | |
97 | | // LastDitchSniff guesses at text/plain vs. application/octet-stream |
98 | | // by just looking at whether the data contains null bytes, and |
99 | | // maybe at the fraction of chars with high bit set. Use this only |
100 | | // as a last-ditch attempt to decide a content type! |
101 | | bool LastDitchSniff(nsIRequest* aRequest); |
102 | | |
103 | | /** |
104 | | * An entry struct for our array of sniffers. Each entry has either |
105 | | * a type associated with it (set these with the SNIFFER_ENTRY macro) |
106 | | * or a function to be executed (set these with the |
107 | | * SNIFFER_ENTRY_WITH_FUNC macro). The function should take a single |
108 | | * nsIRequest* and returns bool -- true if it sets mContentType, |
109 | | * false otherwise |
110 | | */ |
111 | | struct nsSnifferEntry { |
112 | | typedef bool (nsUnknownDecoder::*TypeSniffFunc)(nsIRequest* aRequest); |
113 | | |
114 | | const char* mBytes; |
115 | | uint32_t mByteLen; |
116 | | |
117 | | // Exactly one of mMimeType and mContentTypeSniffer should be set non-null |
118 | | const char* mMimeType; |
119 | | TypeSniffFunc mContentTypeSniffer; |
120 | | }; |
121 | | |
122 | | #define SNIFFER_ENTRY(_bytes, _type) \ |
123 | | { _bytes, sizeof(_bytes) - 1, _type, nullptr } |
124 | | |
125 | | #define SNIFFER_ENTRY_WITH_FUNC(_bytes, _func) \ |
126 | | { _bytes, sizeof(_bytes) - 1, nullptr, _func } |
127 | | |
128 | | static nsSnifferEntry sSnifferEntries[]; |
129 | | static uint32_t sSnifferEntryNum; |
130 | | |
131 | | // We guarantee in order delivery of OnStart, OnStop and OnData, therefore |
132 | | // we do not need proper locking for mBuffer. |
133 | | mozilla::Atomic<char *>mBuffer; |
134 | | mozilla::Atomic<uint32_t> mBufferLen; |
135 | | mozilla::Atomic<bool> mRequireHTMLsuffix; |
136 | | |
137 | | nsCString mContentType; |
138 | | |
139 | | // This mutex syncs: mContentType, mDecodedData and mNextListener. |
140 | | mutable mozilla::Mutex mMutex; |
141 | | |
142 | | protected: |
143 | | nsresult ConvertEncodedData(nsIRequest* request, const char* data, |
144 | | uint32_t length); |
145 | | nsCString mDecodedData; // If data are encoded this will be uncompress data. |
146 | | }; |
147 | | |
148 | | #define NS_BINARYDETECTOR_CID \ |
149 | | { /* a2027ec6-ba0d-4c72-805d-148233f5f33c */ \ |
150 | | 0xa2027ec6, \ |
151 | | 0xba0d, \ |
152 | | 0x4c72, \ |
153 | | {0x80, 0x5d, 0x14, 0x82, 0x33, 0xf5, 0xf3, 0x3c} \ |
154 | | } |
155 | | |
156 | | /** |
157 | | * Class that detects whether a data stream is text or binary. This reuses |
158 | | * most of nsUnknownDecoder except the actual content-type determination logic |
159 | | * -- our overridden DetermineContentType simply calls LastDitchSniff and sets |
160 | | * the type to APPLICATION_GUESS_FROM_EXT if the data is detected as binary. |
161 | | */ |
162 | | class nsBinaryDetector : public nsUnknownDecoder |
163 | | { |
164 | | protected: |
165 | | virtual void DetermineContentType(nsIRequest* aRequest) override; |
166 | | }; |
167 | | |
168 | | #define NS_BINARYDETECTOR_CATEGORYENTRY \ |
169 | | { NS_CONTENT_SNIFFER_CATEGORY, "Binary Detector", NS_BINARYDETECTOR_CONTRACTID } |
170 | | |
171 | | #endif /* nsUnknownDecoder_h__ */ |