1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #define ALLOW_LATE_HTTPLOG_H_INCLUDE 1
8 #include "base/basictypes.h"
9 
10 #include "nsCOMPtr.h"
11 #include "nsIClassInfoImpl.h"
12 #include "mozilla/Components.h"
13 #include "mozilla/ModuleUtils.h"
14 #include "nscore.h"
15 #include "nsSimpleURI.h"
16 #include "nsLoadGroup.h"
17 #include "nsMimeTypes.h"
18 #include "nsDNSPrefetch.h"
19 #include "nsXULAppAPI.h"
20 #include "nsCategoryCache.h"
21 #include "nsIContentSniffer.h"
22 #include "nsStandardURL.h"
23 #include "mozilla/net/BackgroundChannelRegistrar.h"
24 #include "mozilla/net/NeckoChild.h"
25 #include "RedirectChannelRegistrar.h"
26 #ifdef MOZ_AUTH_EXTENSION
27 #  include "nsAuthGSSAPI.h"
28 #endif
29 
30 #include "nsNetCID.h"
31 
32 #if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX)
33 #  define BUILD_NETWORK_INFO_SERVICE 1
34 #endif
35 
36 using namespace mozilla;
37 
38 using ContentSnifferCache = nsCategoryCache<nsIContentSniffer>;
39 ContentSnifferCache* gNetSniffers = nullptr;
40 ContentSnifferCache* gDataSniffers = nullptr;
41 ContentSnifferCache* gORBSniffers = nullptr;
42 ContentSnifferCache* gNetAndORBSniffers = nullptr;
43 
44 #define static
45 using nsLoadGroup = mozilla::net::nsLoadGroup;
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLoadGroup,Init)46 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLoadGroup, Init)
47 #undef static
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 // protocols
51 ///////////////////////////////////////////////////////////////////////////////
52 
53 // http/https
54 #include "nsHttpHandler.h"
55 #include "Http2Compression.h"
56 #undef LOG
57 #undef LOG_ENABLED
58 #include "nsHttpAuthManager.h"
59 #include "nsHttpActivityDistributor.h"
60 #include "ThrottleQueue.h"
61 #undef LOG
62 #undef LOG_ENABLED
63 
64 NS_IMPL_COMPONENT_FACTORY(net::nsHttpHandler) {
65   return net::nsHttpHandler::GetInstance().downcast<nsIHttpProtocolHandler>();
66 }
67 
NS_IMPL_COMPONENT_FACTORY(net::nsHttpsHandler)68 NS_IMPL_COMPONENT_FACTORY(net::nsHttpsHandler) {
69   auto handler = MakeRefPtr<net::nsHttpsHandler>();
70 
71   if (NS_FAILED(handler->Init())) {
72     return nullptr;
73   }
74   return handler.forget().downcast<nsIHttpProtocolHandler>();
75 }
76 
77 #include "WebSocketChannel.h"
78 #include "WebSocketChannelChild.h"
79 namespace mozilla::net {
WebSocketChannelConstructor(bool aSecure)80 static BaseWebSocketChannel* WebSocketChannelConstructor(bool aSecure) {
81   if (IsNeckoChild()) {
82     return new WebSocketChannelChild(aSecure);
83   }
84 
85   if (aSecure) {
86     return new WebSocketSSLChannel;
87   }
88   return new WebSocketChannel;
89 }
90 
91 #define WEB_SOCKET_HANDLER_CONSTRUCTOR(type, secure)             \
92   nsresult type##Constructor(nsISupports* aOuter, REFNSIID aIID, \
93                              void** aResult) {                   \
94     nsresult rv;                                                 \
95                                                                  \
96     RefPtr<BaseWebSocketChannel> inst;                           \
97                                                                  \
98     *aResult = nullptr;                                          \
99     if (nullptr != aOuter) {                                     \
100       rv = NS_ERROR_NO_AGGREGATION;                              \
101       return rv;                                                 \
102     }                                                            \
103     inst = WebSocketChannelConstructor(secure);                  \
104     return inst->QueryInterface(aIID, aResult);                  \
105   }
106 
107 WEB_SOCKET_HANDLER_CONSTRUCTOR(WebSocketChannel, false)
108 WEB_SOCKET_HANDLER_CONSTRUCTOR(WebSocketSSLChannel, true)
109 #undef WEB_SOCKET_HANDLER_CONSTRUCTOR
110 }  // namespace mozilla::net
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 
114 #include "nsStreamConverterService.h"
115 #include "nsMultiMixedConv.h"
116 #include "nsHTTPCompressConv.h"
117 #include "mozTXTToHTMLConv.h"
118 #include "nsUnknownDecoder.h"
119 
120 ///////////////////////////////////////////////////////////////////////////////
121 
122 #include "nsIndexedToHTML.h"
123 
124 nsresult NS_NewMultiMixedConv(nsMultiMixedConv** result);
125 nsresult MOZ_NewTXTToHTMLConv(mozTXTToHTMLConv** result);
126 nsresult NS_NewHTTPCompressConv(mozilla::net::nsHTTPCompressConv** result);
127 nsresult NS_NewStreamConv(nsStreamConverterService** aStreamConv);
128 
129 #define INDEX_TO_HTML "?from=application/http-index-format&to=text/html"
130 #define MULTI_MIXED_X "?from=multipart/x-mixed-replace&to=*/*"
131 #define MULTI_MIXED "?from=multipart/mixed&to=*/*"
132 #define MULTI_BYTERANGES "?from=multipart/byteranges&to=*/*"
133 #define UNKNOWN_CONTENT "?from=" UNKNOWN_CONTENT_TYPE "&to=*/*"
134 #define GZIP_TO_UNCOMPRESSED "?from=gzip&to=uncompressed"
135 #define XGZIP_TO_UNCOMPRESSED "?from=x-gzip&to=uncompressed"
136 #define BROTLI_TO_UNCOMPRESSED "?from=br&to=uncompressed"
137 #define COMPRESS_TO_UNCOMPRESSED "?from=compress&to=uncompressed"
138 #define XCOMPRESS_TO_UNCOMPRESSED "?from=x-compress&to=uncompressed"
139 #define DEFLATE_TO_UNCOMPRESSED "?from=deflate&to=uncompressed"
140 
141 static const mozilla::Module::CategoryEntry kNeckoCategories[] = {
142     {NS_ISTREAMCONVERTER_KEY, INDEX_TO_HTML, ""},
143     {NS_ISTREAMCONVERTER_KEY, MULTI_MIXED_X, ""},
144     {NS_ISTREAMCONVERTER_KEY, MULTI_MIXED, ""},
145     {NS_ISTREAMCONVERTER_KEY, MULTI_BYTERANGES, ""},
146     {NS_ISTREAMCONVERTER_KEY, UNKNOWN_CONTENT, ""},
147     {NS_ISTREAMCONVERTER_KEY, GZIP_TO_UNCOMPRESSED, ""},
148     {NS_ISTREAMCONVERTER_KEY, XGZIP_TO_UNCOMPRESSED, ""},
149     {NS_ISTREAMCONVERTER_KEY, BROTLI_TO_UNCOMPRESSED, ""},
150     {NS_ISTREAMCONVERTER_KEY, COMPRESS_TO_UNCOMPRESSED, ""},
151     {NS_ISTREAMCONVERTER_KEY, XCOMPRESS_TO_UNCOMPRESSED, ""},
152     {NS_ISTREAMCONVERTER_KEY, DEFLATE_TO_UNCOMPRESSED, ""},
153     NS_BINARYDETECTOR_CATEGORYENTRY,
154     {nullptr}};
155 
CreateNewStreamConvServiceFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)156 nsresult CreateNewStreamConvServiceFactory(nsISupports* aOuter, REFNSIID aIID,
157                                            void** aResult) {
158   if (!aResult) {
159     return NS_ERROR_INVALID_POINTER;
160   }
161   if (aOuter) {
162     *aResult = nullptr;
163     return NS_ERROR_NO_AGGREGATION;
164   }
165   RefPtr<nsStreamConverterService> inst;
166   nsresult rv = NS_NewStreamConv(getter_AddRefs(inst));
167   if (NS_FAILED(rv)) {
168     *aResult = nullptr;
169     return rv;
170   }
171   rv = inst->QueryInterface(aIID, aResult);
172   if (NS_FAILED(rv)) {
173     *aResult = nullptr;
174   }
175   return rv;
176 }
177 
CreateNewMultiMixedConvFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)178 nsresult CreateNewMultiMixedConvFactory(nsISupports* aOuter, REFNSIID aIID,
179                                         void** aResult) {
180   if (!aResult) {
181     return NS_ERROR_INVALID_POINTER;
182   }
183   if (aOuter) {
184     *aResult = nullptr;
185     return NS_ERROR_NO_AGGREGATION;
186   }
187   RefPtr<nsMultiMixedConv> inst;
188   nsresult rv = NS_NewMultiMixedConv(getter_AddRefs(inst));
189   if (NS_FAILED(rv)) {
190     *aResult = nullptr;
191     return rv;
192   }
193   rv = inst->QueryInterface(aIID, aResult);
194   if (NS_FAILED(rv)) {
195     *aResult = nullptr;
196   }
197   return rv;
198 }
199 
CreateNewTXTToHTMLConvFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)200 nsresult CreateNewTXTToHTMLConvFactory(nsISupports* aOuter, REFNSIID aIID,
201                                        void** aResult) {
202   if (!aResult) {
203     return NS_ERROR_INVALID_POINTER;
204   }
205   if (aOuter) {
206     *aResult = nullptr;
207     return NS_ERROR_NO_AGGREGATION;
208   }
209   RefPtr<mozTXTToHTMLConv> inst;
210   nsresult rv = MOZ_NewTXTToHTMLConv(getter_AddRefs(inst));
211   if (NS_FAILED(rv)) {
212     *aResult = nullptr;
213     return rv;
214   }
215   rv = inst->QueryInterface(aIID, aResult);
216   if (NS_FAILED(rv)) {
217     *aResult = nullptr;
218   }
219   return rv;
220 }
221 
CreateNewHTTPCompressConvFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)222 nsresult CreateNewHTTPCompressConvFactory(nsISupports* aOuter, REFNSIID aIID,
223                                           void** aResult) {
224   if (!aResult) {
225     return NS_ERROR_INVALID_POINTER;
226   }
227   if (aOuter) {
228     *aResult = nullptr;
229     return NS_ERROR_NO_AGGREGATION;
230   }
231   RefPtr<mozilla::net::nsHTTPCompressConv> inst;
232   nsresult rv = NS_NewHTTPCompressConv(getter_AddRefs(inst));
233   if (NS_FAILED(rv)) {
234     *aResult = nullptr;
235     return rv;
236   }
237   rv = inst->QueryInterface(aIID, aResult);
238   if (NS_FAILED(rv)) {
239     *aResult = nullptr;
240   }
241   return rv;
242 }
243 
CreateNewUnknownDecoderFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)244 nsresult CreateNewUnknownDecoderFactory(nsISupports* aOuter, REFNSIID aIID,
245                                         void** aResult) {
246   if (!aResult) {
247     return NS_ERROR_NULL_POINTER;
248   }
249   *aResult = nullptr;
250 
251   if (aOuter) {
252     return NS_ERROR_NO_AGGREGATION;
253   }
254 
255   RefPtr<nsUnknownDecoder> inst = new nsUnknownDecoder();
256   return inst->QueryInterface(aIID, aResult);
257 }
258 
CreateNewBinaryDetectorFactory(nsISupports * aOuter,REFNSIID aIID,void ** aResult)259 nsresult CreateNewBinaryDetectorFactory(nsISupports* aOuter, REFNSIID aIID,
260                                         void** aResult) {
261   if (!aResult) {
262     return NS_ERROR_NULL_POINTER;
263   }
264   *aResult = nullptr;
265 
266   if (aOuter) {
267     return NS_ERROR_NO_AGGREGATION;
268   }
269 
270   RefPtr<nsBinaryDetector> inst = new nsBinaryDetector();
271   return inst->QueryInterface(aIID, aResult);
272 }
273 
274 ///////////////////////////////////////////////////////////////////////////////
275 // Module implementation for the net library
276 
277 // Net module startup hook
nsNetStartup()278 nsresult nsNetStartup() {
279   mozilla::net::nsStandardURL::InitGlobalObjects();
280   return NS_OK;
281 }
282 
283 // Net module shutdown hook
nsNetShutdown()284 void nsNetShutdown() {
285   // Release the url parser that the stdurl is holding.
286   mozilla::net::nsStandardURL::ShutdownGlobalObjects();
287 
288   // Release global state used by the URL helper module.
289   net_ShutdownURLHelper();
290 #ifdef XP_MACOSX
291   net_ShutdownURLHelperOSX();
292 #endif
293 
294   // Release DNS service reference.
295   nsDNSPrefetch::Shutdown();
296 
297   // Release the Websocket Admission Manager
298   mozilla::net::WebSocketChannel::Shutdown();
299 
300   mozilla::net::Http2CompressionCleanup();
301 
302   mozilla::net::RedirectChannelRegistrar::Shutdown();
303 
304   mozilla::net::BackgroundChannelRegistrar::Shutdown();
305 
306 #ifdef MOZ_AUTH_EXTENSION
307   nsAuthGSSAPI::Shutdown();
308 #endif
309 
310   delete gNetSniffers;
311   gNetSniffers = nullptr;
312   delete gDataSniffers;
313   gDataSniffers = nullptr;
314   delete gORBSniffers;
315   gORBSniffers = nullptr;
316   delete gNetAndORBSniffers;
317   gNetAndORBSniffers = nullptr;
318 }
319 
320 extern const mozilla::Module kNeckoModule = {
321     mozilla::Module::kVersion,
322     nullptr,
323     nullptr,
324     kNeckoCategories,
325     nullptr,
326     nullptr,
327     nullptr,
328     mozilla::Module::ALLOW_IN_SOCKET_PROCESS};
329