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/. */
6 #ifndef nsURILoader_h__
7 #define nsURILoader_h__
9 #include "nsCURILoader.h"
10 #include "nsISupportsUtils.h"
11 #include "nsCOMArray.h"
13 #include "nsIInterfaceRequestor.h"
14 #include "nsIInterfaceRequestorUtils.h"
16 #include "nsIWeakReference.h"
17 #include "mozilla/Attributes.h"
18 #include "nsIStreamListener.h"
19 #include "nsIThreadRetargetableStreamListener.h"
20 #include "nsIExternalHelperAppService.h"
22 #include "mozilla/Logging.h"
24 class nsDocumentOpenInfo
;
26 class nsURILoader final
: public nsIURILoader
{
37 * Equivalent to nsIURILoader::openChannel, but allows specifying whether the
38 * channel is opened already.
40 [[nodiscard
]] nsresult
OpenChannel(nsIChannel
* channel
, uint32_t aFlags
,
41 nsIInterfaceRequestor
* aWindowContext
,
43 nsIStreamListener
** aListener
);
46 * we shouldn't need to have an owning ref count on registered
47 * content listeners because they are supposed to unregister themselves
48 * when they go away. This array stores weak references
50 nsCOMArray
<nsIWeakReference
> m_listeners
;
53 * Logging. The module is called "URILoader"
55 static mozilla::LazyLogModule mLog
;
57 friend class nsDocumentOpenInfo
;
61 * The nsDocumentOpenInfo contains the state required when a single
62 * document is being opened in order to discover the content type...
63 * Each instance remains alive until its target URL has been loaded
66 class nsDocumentOpenInfo
: public nsIStreamListener
,
67 public nsIThreadRetargetableStreamListener
{
70 // aFlags is a combination of the flags on nsIURILoader
71 nsDocumentOpenInfo(nsIInterfaceRequestor
* aWindowContext
, uint32_t aFlags
,
72 nsURILoader
* aURILoader
);
73 nsDocumentOpenInfo(uint32_t aFlags
, bool aAllowListenerConversions
);
75 NS_DECL_THREADSAFE_ISUPPORTS
78 * Prepares this object for receiving data. The stream
79 * listener methods of this class must not be called before calling this
84 // Call this (from OnStartRequest) to attempt to find an nsIStreamListener to
85 // take the data off our hands.
86 nsresult
DispatchContent(nsIRequest
* request
);
88 // Call this if we need to insert a stream converter from aSrcContentType to
89 // aOutContentType into the StreamListener chain. DO NOT call it if the two
90 // types are the same, since no conversion is needed in that case.
91 nsresult
ConvertData(nsIRequest
* request
, nsIURIContentListener
* aListener
,
92 const nsACString
& aSrcContentType
,
93 const nsACString
& aOutContentType
);
96 * Function to attempt to use aListener to handle the load. If
97 * true is returned, nothing else needs to be done; if false
98 * is returned, then a different way of handling the load should be
101 bool TryContentListener(nsIURIContentListener
* aListener
,
102 nsIChannel
* aChannel
);
105 * Virtual helper functions for content that we expect to be
106 * overriden when running in the parent process on behalf of
107 * a content process docshell.
108 * We also expect nsIStreamListener functions to be overriden
109 * to add functionality.
113 * Attempt to create a steam converter converting from the
114 * current mContentType into something else.
115 * Sets m_targetStreamListener if it succeeds.
117 virtual nsresult
TryStreamConversion(nsIChannel
* aChannel
);
120 * Attempt to use the default content listener as our stream
122 * Sets m_targetStreamListener if it succeeds.
124 virtual bool TryDefaultContentListener(nsIChannel
* aChannel
);
127 * Attempt to pass aChannel onto the external helper app service.
128 * Sets m_targetStreamListener if it succeeds.
130 virtual nsresult
TryExternalHelperApp(
131 nsIExternalHelperAppService
* aHelperAppService
, nsIChannel
* aChannel
);
134 * Create another nsDocumentOpenInfo like this one, so that we can chain
135 * them together when we use a stream converter and don't know what the
136 * converted content type is until the converter outputs OnStartRequest.
138 virtual nsDocumentOpenInfo
* Clone() {
139 return new nsDocumentOpenInfo(m_originalContext
, mFlags
, mURILoader
);
142 // nsIRequestObserver methods:
143 NS_DECL_NSIREQUESTOBSERVER
145 // nsIStreamListener methods:
146 NS_DECL_NSISTREAMLISTENER
148 // nsIThreadRetargetableStreamListener
149 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
152 virtual ~nsDocumentOpenInfo();
156 * The first content listener to try dispatching data to. Typically
157 * the listener associated with the entity that originated the load.
158 * This can be nullptr when running in the parent process for a content
161 nsCOMPtr
<nsIURIContentListener
> m_contentListener
;
164 * The stream listener to forward nsIStreamListener notifications
165 * to. This is set once the load is dispatched.
167 nsCOMPtr
<nsIStreamListener
> m_targetStreamListener
;
170 * A pointer to the entity that originated the load. We depend on getting
171 * things like nsIURIContentListeners, nsIDOMWindows, etc off of it.
172 * This can be nullptr when running in the parent process for a content
175 nsCOMPtr
<nsIInterfaceRequestor
> m_originalContext
;
178 * IS_CONTENT_PREFERRED is used for the boolean to pass to CanHandleContent
179 * (also determines whether we use CanHandleContent or IsPreferred).
180 * DONT_RETARGET means that we will only try m_originalContext, no other
186 * The type of the data we will be trying to dispatch.
188 nsCString mContentType
;
191 * Reference to the URILoader service so we can access its list of
192 * nsIURIContentListeners.
193 * This can be nullptr when running in the parent process for a content
196 RefPtr
<nsURILoader
> mURILoader
;
199 * Limit of data conversion depth to prevent infinite conversion loops
201 uint32_t mDataConversionDepthLimit
;
204 * Set to true if OnStartRequest handles the content using an
205 * nsIContentHandler, and the content is consumed despite
206 * m_targetStreamListener being nullptr.
208 bool mUsedContentHandler
= false;
211 * True if we allow nsIURIContentListeners to return a requested
212 * input typeToUse, and attempt to create a matching stream converter.
213 * This is false when running in the parent process for a content process
216 bool mAllowListenerConversions
= true;
219 #endif /* nsURILoader_h__ */