Bug 1690340 - Part 5: Remove the menu separators from the developer tools menu. r...
[gecko.git] / netwerk / ipc / DocumentChannel.cpp
blob4dfa0eddf8ca76c2a544dc14c3d96165964b02f9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "mozilla/net/DocumentChannel.h"
10 #include <inttypes.h>
11 #include <utility>
12 #include "mozIDOMWindow.h"
13 #include "mozilla/AlreadyAddRefed.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/LoadInfo.h"
16 #include "mozilla/Logging.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/TimeStamp.h"
19 #include "mozilla/Unused.h"
20 #include "mozilla/dom/Document.h"
21 #include "mozilla/net/DocumentChannelChild.h"
22 #include "mozilla/net/ParentProcessDocumentChannel.h"
23 #include "nsCOMPtr.h"
24 #include "nsDebug.h"
25 #include "nsDocShell.h"
26 #include "nsDocShellLoadState.h"
27 #include "nsHttpHandler.h"
28 #include "nsIContentPolicy.h"
29 #include "nsIInterfaceRequestor.h"
30 #include "nsILoadContext.h"
31 #include "nsILoadGroup.h"
32 #include "nsILoadInfo.h"
33 #include "nsIStreamListener.h"
34 #include "nsIURI.h"
35 #include "nsMimeTypes.h"
36 #include "nsNetUtil.h"
37 #include "nsPIDOMWindow.h"
38 #include "nsPIDOMWindowInlines.h"
39 #include "nsStringFwd.h"
40 #include "nsThreadUtils.h"
41 #include "nsXULAppAPI.h"
42 #include "nscore.h"
44 using namespace mozilla::dom;
45 using namespace mozilla::ipc;
47 extern mozilla::LazyLogModule gDocumentChannelLog;
48 #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
50 namespace mozilla {
51 namespace net {
53 //-----------------------------------------------------------------------------
54 // DocumentChannel::nsISupports
56 NS_IMPL_ADDREF(DocumentChannel)
57 NS_IMPL_RELEASE(DocumentChannel)
59 NS_INTERFACE_MAP_BEGIN(DocumentChannel)
60 NS_INTERFACE_MAP_ENTRY(nsIRequest)
61 NS_INTERFACE_MAP_ENTRY(nsIChannel)
62 NS_INTERFACE_MAP_ENTRY(nsIIdentChannel)
63 NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannel)
64 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequest)
65 NS_INTERFACE_MAP_END
67 DocumentChannel::DocumentChannel(nsDocShellLoadState* aLoadState,
68 net::LoadInfo* aLoadInfo,
69 nsLoadFlags aLoadFlags, uint32_t aCacheKey,
70 bool aUriModified, bool aIsXFOError)
71 : mAsyncOpenTime(TimeStamp::Now()),
72 mLoadState(aLoadState),
73 mCacheKey(aCacheKey),
74 mLoadFlags(aLoadFlags),
75 mURI(aLoadState->URI()),
76 mLoadInfo(aLoadInfo),
77 mUriModified(aUriModified),
78 mIsXFOError(aIsXFOError) {
79 LOG(("DocumentChannel ctor [this=%p, uri=%s]", this,
80 aLoadState->URI()->GetSpecOrDefault().get()));
81 RefPtr<nsHttpHandler> handler = nsHttpHandler::GetInstance();
82 uint64_t channelId;
83 Unused << handler->NewChannelId(channelId);
84 mChannelId = channelId;
87 NS_IMETHODIMP
88 DocumentChannel::AsyncOpen(nsIStreamListener* aListener) {
89 MOZ_CRASH("If we get here, something is broken");
90 return NS_ERROR_NOT_IMPLEMENTED;
93 void DocumentChannel::ShutdownListeners(nsresult aStatusCode) {
94 LOG(("DocumentChannel ShutdownListeners [this=%p, status=%" PRIx32 "]", this,
95 static_cast<uint32_t>(aStatusCode)));
96 mStatus = aStatusCode;
98 nsCOMPtr<nsIStreamListener> listener = mListener;
99 if (listener) {
100 listener->OnStartRequest(this);
103 mIsPending = false;
105 listener = mListener; // it might have changed!
106 nsCOMPtr<nsILoadGroup> loadGroup = mLoadGroup;
108 mListener = nullptr;
109 mLoadGroup = nullptr;
110 mCallbacks = nullptr;
112 NS_DispatchToMainThread(NS_NewRunnableFunction(
113 "DocumentChannel::ShutdownListeners", [=, self = RefPtr{this}] {
114 if (listener) {
115 listener->OnStopRequest(self, aStatusCode);
118 if (loadGroup) {
119 loadGroup->RemoveRequest(self, nullptr, aStatusCode);
121 }));
123 DeleteIPDL();
126 void DocumentChannel::DisconnectChildListeners(
127 const nsresult& aStatus, const nsresult& aLoadGroupStatus) {
128 MOZ_ASSERT(NS_FAILED(aStatus));
129 mStatus = aLoadGroupStatus;
130 // Make sure we remove from the load group before
131 // setting mStatus, as existing tests expect the
132 // status to be successful when we disconnect.
133 if (mLoadGroup) {
134 mLoadGroup->RemoveRequest(this, nullptr, aStatus);
135 mLoadGroup = nullptr;
138 ShutdownListeners(aStatus);
141 nsDocShell* DocumentChannel::GetDocShell() {
142 nsCOMPtr<nsILoadContext> loadContext;
143 NS_QueryNotificationCallbacks(this, loadContext);
144 if (!loadContext) {
145 return nullptr;
147 nsCOMPtr<mozIDOMWindowProxy> domWindow;
148 loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
149 if (!domWindow) {
150 return nullptr;
152 auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
153 nsIDocShell* docshell = pDomWindow->GetDocShell();
154 return nsDocShell::Cast(docshell);
157 // Changes here should also be made in
158 // E10SUtils.documentChannelPermittedForURI().
159 static bool URIUsesDocChannel(nsIURI* aURI) {
160 if (SchemeIsJavascript(aURI)) {
161 return false;
164 nsCString spec = aURI->GetSpecOrDefault();
165 return !spec.EqualsLiteral("about:printpreview") &&
166 !spec.EqualsLiteral("about:crashcontent");
169 bool DocumentChannel::CanUseDocumentChannel(nsIURI* aURI) {
170 // We want to use DocumentChannel if we're using a supported scheme.
171 return URIUsesDocChannel(aURI);
174 /* static */
175 already_AddRefed<DocumentChannel> DocumentChannel::CreateForDocument(
176 nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
177 nsLoadFlags aLoadFlags, nsIInterfaceRequestor* aNotificationCallbacks,
178 uint32_t aCacheKey, bool aUriModified, bool aIsXFOError) {
179 RefPtr<DocumentChannel> channel;
180 if (XRE_IsContentProcess()) {
181 channel = new DocumentChannelChild(aLoadState, aLoadInfo, aLoadFlags,
182 aCacheKey, aUriModified, aIsXFOError);
183 } else {
184 channel =
185 new ParentProcessDocumentChannel(aLoadState, aLoadInfo, aLoadFlags,
186 aCacheKey, aUriModified, aIsXFOError);
188 channel->SetNotificationCallbacks(aNotificationCallbacks);
189 return channel.forget();
192 /* static */
193 already_AddRefed<DocumentChannel> DocumentChannel::CreateForObject(
194 nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
195 nsLoadFlags aLoadFlags, nsIInterfaceRequestor* aNotificationCallbacks) {
196 return CreateForDocument(aLoadState, aLoadInfo, aLoadFlags,
197 aNotificationCallbacks, 0, false, false);
200 NS_IMETHODIMP
201 DocumentChannel::Cancel(nsresult aStatusCode) {
202 MOZ_CRASH("If we get here, something is broken");
203 return NS_ERROR_NOT_IMPLEMENTED;
206 NS_IMETHODIMP
207 DocumentChannel::Suspend() {
208 MOZ_CRASH("If we get here, something is broken");
209 return NS_ERROR_NOT_IMPLEMENTED;
212 NS_IMETHODIMP
213 DocumentChannel::Resume() {
214 MOZ_CRASH("If we get here, something is broken");
215 return NS_ERROR_NOT_IMPLEMENTED;
218 //-----------------------------------------------------------------------------
219 // Remainder of nsIRequest/nsIChannel.
220 //-----------------------------------------------------------------------------
222 NS_IMETHODIMP DocumentChannel::GetNotificationCallbacks(
223 nsIInterfaceRequestor** aCallbacks) {
224 nsCOMPtr<nsIInterfaceRequestor> callbacks(mCallbacks);
225 callbacks.forget(aCallbacks);
226 return NS_OK;
229 NS_IMETHODIMP DocumentChannel::SetNotificationCallbacks(
230 nsIInterfaceRequestor* aNotificationCallbacks) {
231 mCallbacks = aNotificationCallbacks;
232 return NS_OK;
235 NS_IMETHODIMP DocumentChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
236 nsCOMPtr<nsILoadGroup> loadGroup(mLoadGroup);
237 loadGroup.forget(aLoadGroup);
238 return NS_OK;
241 NS_IMETHODIMP DocumentChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
242 mLoadGroup = aLoadGroup;
243 return NS_OK;
246 NS_IMETHODIMP DocumentChannel::GetStatus(nsresult* aStatus) {
247 *aStatus = mStatus;
248 return NS_OK;
251 NS_IMETHODIMP DocumentChannel::GetName(nsACString& aResult) {
252 if (!mURI) {
253 aResult.Truncate();
254 return NS_OK;
256 nsCString spec;
257 nsresult rv = mURI->GetSpec(spec);
258 NS_ENSURE_SUCCESS(rv, rv);
260 aResult.AssignLiteral("documentchannel:");
261 aResult.Append(spec);
262 return NS_OK;
265 NS_IMETHODIMP DocumentChannel::IsPending(bool* aResult) {
266 *aResult = mIsPending;
267 return NS_OK;
270 NS_IMETHODIMP DocumentChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
271 *aLoadFlags = mLoadFlags;
272 return NS_OK;
275 NS_IMETHODIMP
276 DocumentChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
277 return GetTRRModeImpl(aTRRMode);
280 NS_IMETHODIMP
281 DocumentChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
282 return SetTRRModeImpl(aTRRMode);
285 NS_IMETHODIMP DocumentChannel::SetLoadFlags(nsLoadFlags aLoadFlags) {
286 // Setting load flags for TYPE_OBJECT is OK, so long as the channel to parent
287 // isn't opened yet, or we're only setting the `LOAD_DOCUMENT_URI` flag.
288 auto contentPolicy = mLoadInfo->GetExternalContentPolicyType();
289 if (contentPolicy == ExtContentPolicy::TYPE_OBJECT) {
290 if (mWasOpened) {
291 MOZ_DIAGNOSTIC_ASSERT(
292 aLoadFlags == (mLoadFlags | nsIChannel::LOAD_DOCUMENT_URI),
293 "After the channel has been opened, can only set the "
294 "`LOAD_DOCUMENT_URI` flag.");
296 mLoadFlags = aLoadFlags;
297 return NS_OK;
300 MOZ_CRASH("DocumentChannel::SetLoadFlags: Don't set flags after creation");
303 NS_IMETHODIMP DocumentChannel::GetOriginalURI(nsIURI** aOriginalURI) {
304 nsCOMPtr<nsIURI> originalURI =
305 mLoadState->OriginalURI() ? mLoadState->OriginalURI() : mLoadState->URI();
306 originalURI.forget(aOriginalURI);
307 return NS_OK;
310 NS_IMETHODIMP DocumentChannel::SetOriginalURI(nsIURI* aOriginalURI) {
311 MOZ_CRASH("If we get here, something is broken");
312 return NS_ERROR_NOT_IMPLEMENTED;
315 NS_IMETHODIMP DocumentChannel::GetURI(nsIURI** aURI) {
316 nsCOMPtr<nsIURI> uri(mURI);
317 uri.forget(aURI);
318 return NS_OK;
321 NS_IMETHODIMP DocumentChannel::GetOwner(nsISupports** aOwner) {
322 nsCOMPtr<nsISupports> owner(mOwner);
323 owner.forget(aOwner);
324 return NS_OK;
327 NS_IMETHODIMP DocumentChannel::SetOwner(nsISupports* aOwner) {
328 mOwner = aOwner;
329 return NS_OK;
332 NS_IMETHODIMP DocumentChannel::GetSecurityInfo(nsISupports** aSecurityInfo) {
333 *aSecurityInfo = nullptr;
334 return NS_OK;
337 NS_IMETHODIMP DocumentChannel::GetContentType(nsACString& aContentType) {
338 // We may be trying to load HTML object data, and have determined that we're
339 // going to be performing a document load. In that case, fake the "text/html"
340 // content type for nsObjectLoadingContent.
341 if ((mLoadFlags & nsIRequest::LOAD_HTML_OBJECT_DATA) &&
342 (mLoadFlags & nsIChannel::LOAD_DOCUMENT_URI)) {
343 aContentType = TEXT_HTML;
344 return NS_OK;
347 NS_ERROR("If we get here, something is broken");
348 return NS_ERROR_NOT_IMPLEMENTED;
351 NS_IMETHODIMP DocumentChannel::SetContentType(const nsACString& aContentType) {
352 MOZ_CRASH("If we get here, something is broken");
353 return NS_ERROR_NOT_IMPLEMENTED;
356 NS_IMETHODIMP DocumentChannel::GetContentCharset(nsACString& aContentCharset) {
357 MOZ_CRASH("If we get here, something is broken");
358 return NS_ERROR_NOT_IMPLEMENTED;
361 NS_IMETHODIMP DocumentChannel::SetContentCharset(
362 const nsACString& aContentCharset) {
363 MOZ_CRASH("If we get here, something is broken");
364 return NS_ERROR_NOT_IMPLEMENTED;
367 NS_IMETHODIMP DocumentChannel::GetContentLength(int64_t* aContentLength) {
368 MOZ_CRASH("If we get here, something is broken");
369 return NS_ERROR_NOT_IMPLEMENTED;
372 NS_IMETHODIMP DocumentChannel::SetContentLength(int64_t aContentLength) {
373 MOZ_CRASH("If we get here, something is broken");
374 return NS_ERROR_NOT_IMPLEMENTED;
377 NS_IMETHODIMP DocumentChannel::Open(nsIInputStream** aStream) {
378 MOZ_CRASH("If we get here, something is broken");
379 return NS_ERROR_NOT_IMPLEMENTED;
382 NS_IMETHODIMP DocumentChannel::GetContentDisposition(
383 uint32_t* aContentDisposition) {
384 MOZ_CRASH("If we get here, something is broken");
385 return NS_ERROR_NOT_IMPLEMENTED;
388 NS_IMETHODIMP DocumentChannel::SetContentDisposition(
389 uint32_t aContentDisposition) {
390 MOZ_CRASH("If we get here, something is broken");
391 return NS_ERROR_NOT_IMPLEMENTED;
394 NS_IMETHODIMP DocumentChannel::GetContentDispositionFilename(
395 nsAString& aContentDispositionFilename) {
396 MOZ_CRASH("If we get here, something will be broken");
397 return NS_ERROR_NOT_IMPLEMENTED;
400 NS_IMETHODIMP DocumentChannel::SetContentDispositionFilename(
401 const nsAString& aContentDispositionFilename) {
402 MOZ_CRASH("If we get here, something will be broken");
403 return NS_ERROR_NOT_IMPLEMENTED;
406 NS_IMETHODIMP DocumentChannel::GetContentDispositionHeader(
407 nsACString& aContentDispositionHeader) {
408 MOZ_CRASH("If we get here, something is broken");
409 return NS_ERROR_NOT_IMPLEMENTED;
412 NS_IMETHODIMP DocumentChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
413 nsCOMPtr<nsILoadInfo> loadInfo(mLoadInfo);
414 loadInfo.forget(aLoadInfo);
415 return NS_OK;
418 NS_IMETHODIMP DocumentChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
419 MOZ_CRASH("If we get here, something is broken");
420 return NS_ERROR_NOT_IMPLEMENTED;
423 NS_IMETHODIMP DocumentChannel::GetIsDocument(bool* aIsDocument) {
424 return NS_GetIsDocumentChannel(this, aIsDocument);
427 NS_IMETHODIMP DocumentChannel::GetCanceled(bool* aCanceled) {
428 *aCanceled = mCanceled;
429 return NS_OK;
432 //-----------------------------------------------------------------------------
433 // nsIIdentChannel
434 //-----------------------------------------------------------------------------
436 NS_IMETHODIMP
437 DocumentChannel::GetChannelId(uint64_t* aChannelId) {
438 *aChannelId = mChannelId;
439 return NS_OK;
442 NS_IMETHODIMP
443 DocumentChannel::SetChannelId(uint64_t aChannelId) {
444 mChannelId = aChannelId;
445 return NS_OK;
448 //-----------------------------------------------------------------------------
449 // Helpers
450 //-----------------------------------------------------------------------------
452 uint64_t InnerWindowIDForExtantDoc(nsDocShell* docShell) {
453 if (!docShell) {
454 return 0;
457 Document* doc = docShell->GetExtantDocument();
458 if (!doc) {
459 return 0;
462 return doc->InnerWindowID();
465 } // namespace net
466 } // namespace mozilla
468 #undef LOG