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 nsIThreadRetargetableStreamListener
{
69 // aFlags is a combination of the flags on nsIURILoader
70 nsDocumentOpenInfo(nsIInterfaceRequestor
* aWindowContext
, uint32_t aFlags
,
71 nsURILoader
* aURILoader
);
72 nsDocumentOpenInfo(uint32_t aFlags
, bool aAllowListenerConversions
);
74 NS_DECL_THREADSAFE_ISUPPORTS
77 * Prepares this object for receiving data. The stream
78 * listener methods of this class must not be called before calling this
83 // Call this (from OnStartRequest) to attempt to find an nsIStreamListener to
84 // take the data off our hands.
85 nsresult
DispatchContent(nsIRequest
* request
);
87 // Call this if we need to insert a stream converter from aSrcContentType to
88 // aOutContentType into the StreamListener chain. DO NOT call it if the two
89 // types are the same, since no conversion is needed in that case.
90 nsresult
ConvertData(nsIRequest
* request
, nsIURIContentListener
* aListener
,
91 const nsACString
& aSrcContentType
,
92 const nsACString
& aOutContentType
);
95 * Function to attempt to use aListener to handle the load. If
96 * true is returned, nothing else needs to be done; if false
97 * is returned, then a different way of handling the load should be
100 bool TryContentListener(nsIURIContentListener
* aListener
,
101 nsIChannel
* aChannel
);
104 * Virtual helper functions for content that we expect to be
105 * overriden when running in the parent process on behalf of
106 * a content process docshell.
107 * We also expect nsIStreamListener functions to be overriden
108 * to add functionality.
112 * Attempt to create a steam converter converting from the
113 * current mContentType into something else.
114 * Sets m_targetStreamListener if it succeeds.
116 virtual nsresult
TryStreamConversion(nsIChannel
* aChannel
);
119 * Attempt to use the default content listener as our stream
121 * Sets m_targetStreamListener if it succeeds.
123 virtual bool TryDefaultContentListener(nsIChannel
* aChannel
);
126 * Attempt to pass aChannel onto the external helper app service.
127 * Sets m_targetStreamListener if it succeeds.
129 virtual nsresult
TryExternalHelperApp(
130 nsIExternalHelperAppService
* aHelperAppService
, nsIChannel
* aChannel
);
133 * Create another nsDocumentOpenInfo like this one, so that we can chain
134 * them together when we use a stream converter and don't know what the
135 * converted content type is until the converter outputs OnStartRequest.
137 virtual nsDocumentOpenInfo
* Clone() {
138 return new nsDocumentOpenInfo(m_originalContext
, mFlags
, mURILoader
);
141 // nsIRequestObserver methods:
142 NS_DECL_NSIREQUESTOBSERVER
144 // nsIStreamListener methods:
145 NS_DECL_NSISTREAMLISTENER
147 // nsIThreadRetargetableStreamListener
148 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
151 virtual ~nsDocumentOpenInfo();
155 * The first content listener to try dispatching data to. Typically
156 * the listener associated with the entity that originated the load.
157 * This can be nullptr when running in the parent process for a content
160 nsCOMPtr
<nsIURIContentListener
> m_contentListener
;
163 * The stream listener to forward nsIStreamListener notifications
164 * to. This is set once the load is dispatched.
166 nsCOMPtr
<nsIStreamListener
> m_targetStreamListener
;
169 * A pointer to the entity that originated the load. We depend on getting
170 * things like nsIURIContentListeners, nsIDOMWindows, etc off of it.
171 * This can be nullptr when running in the parent process for a content
174 nsCOMPtr
<nsIInterfaceRequestor
> m_originalContext
;
177 * IS_CONTENT_PREFERRED is used for the boolean to pass to CanHandleContent
178 * (also determines whether we use CanHandleContent or IsPreferred).
179 * DONT_RETARGET means that we will only try m_originalContext, no other
185 * The type of the data we will be trying to dispatch.
187 nsCString mContentType
;
190 * Reference to the URILoader service so we can access its list of
191 * nsIURIContentListeners.
192 * This can be nullptr when running in the parent process for a content
195 RefPtr
<nsURILoader
> mURILoader
;
198 * Limit of data conversion depth to prevent infinite conversion loops
200 uint32_t mDataConversionDepthLimit
;
203 * Set to true if OnStartRequest handles the content using an
204 * nsIContentHandler, and the content is consumed despite
205 * m_targetStreamListener being nullptr.
207 bool mUsedContentHandler
= false;
210 * True if we allow nsIURIContentListeners to return a requested
211 * input typeToUse, and attempt to create a matching stream converter.
212 * This is false when running in the parent process for a content process
215 bool mAllowListenerConversions
= true;
218 #endif /* nsURILoader_h__ */