diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 91a2ca395369..bbbf5b5c3515 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9338,7 +9338,7 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) { } if (StaticPrefs::browser_tabs_documentchannel() && XRE_IsContentProcess() && - SchemeUsesDocChannel(aLoadState->URI()) && !isSrcdoc) { + SchemeUsesDocChannel(aLoadState->URI())) { RefPtr child = new DocumentChannelChild( aLoadState, aLoadInfo, aInitiatorType, aLoadFlags, aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc, aHasNonEmptySandboxingFlags); diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index f7782f3ac6f9..26d5b3653dab 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -114,6 +114,7 @@ #include "nsIConsoleService.h" #include "audio_thread_priority.h" #include "nsIURIMutator.h" +#include "nsIInputStreamChannel.h" #if !defined(XP_WIN) # include "mozilla/Omnijar.h" @@ -3693,11 +3694,24 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( } nsCOMPtr newChannel; - rv = NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, - nullptr, // PerformanceStorage - nullptr, // aLoadGroup - nullptr, // aCallbacks - aArgs.newLoadFlags()); + if (aArgs.loadStateLoadFlags() & + nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC) { + rv = NS_NewInputStreamChannelInternal( + getter_AddRefs(newChannel), aArgs.uri(), aArgs.srcdocData(), + NS_LITERAL_CSTRING("text/html"), loadInfo, true); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr isc = do_QueryInterface(newChannel); + MOZ_ASSERT(isc); + isc->SetBaseURI(aArgs.baseUri()); + } + } else { + rv = + NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, + nullptr, // PerformanceStorage + nullptr, // aLoadGroup + nullptr, // aCallbacks + aArgs.newLoadFlags()); + } // This is used to report any errors back to the parent by calling // CrossProcessRedirectFinished. diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index 27adad606747..5cc113381f40 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -22,6 +22,7 @@ #include "nsContentSecurityManager.h" #include "nsDocShellLoadState.h" #include "nsHttpHandler.h" +#include "nsIInputStreamChannel.h" #include "nsQueryObject.h" #include "nsSerializationHelper.h" #include "nsStreamListenerWrapper.h" @@ -320,12 +321,26 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( mRedirectResolver = std::move(aResolve); nsCOMPtr newChannel; - nsresult rv = - NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, - nullptr, // PerformanceStorage - mLoadGroup, // aLoadGroup - nullptr, // aCallbacks - aArgs.newLoadFlags()); + nsresult rv; + if (aArgs.loadStateLoadFlags() & + nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC) { + rv = NS_NewInputStreamChannelInternal( + getter_AddRefs(newChannel), aArgs.uri(), aArgs.srcdocData(), + NS_LITERAL_CSTRING("text/html"), loadInfo, true); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr isc = do_QueryInterface(newChannel); + MOZ_ASSERT(isc); + isc->SetBaseURI(aArgs.baseUri()); + newChannel->SetLoadGroup(mLoadGroup); + } + } else { + rv = + NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, + nullptr, // PerformanceStorage + mLoadGroup, // aLoadGroup + nullptr, // aCallbacks + aArgs.newLoadFlags()); + } // This is used to report any errors back to the parent by calling // CrossProcessRedirectFinished. diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 191fa581e74f..296666169c40 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -340,6 +340,8 @@ bool DocumentLoadListener::Open( mChannelCreationURI = aLoadState->URI(); mLoadStateLoadFlags = aLoadState->LoadFlags(); + mSrcdocData = aLoadState->SrcdocData(); + mBaseURI = aLoadState->BaseURI(); return true; } @@ -722,6 +724,8 @@ void DocumentLoadListener::SerializeRedirectData( nsDocShell::ExtractLastVisit(mChannel, getter_AddRefs(previousURI), &previousFlags); aArgs.lastVisitInfo() = LastVisitInfo{previousURI, previousFlags}; + aArgs.srcdocData() = mSrcdocData; + aArgs.baseUri() = mBaseURI; } void DocumentLoadListener::TriggerCrossProcessSwitch() { diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index 3a64875edcf1..6d86cb0286ac 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -322,6 +322,9 @@ class DocumentLoadListener : public nsIInterfaceRequestor, nsTArray mRedirects; + nsString mSrcdocData; + nsCOMPtr mBaseURI; + // Flags from nsDocShellLoadState::LoadFlags that we want to make available // to the new docshell if we switch processes. uint32_t mLoadStateLoadFlags = 0; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 5cda780f180b..d8e0d7481938 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -441,6 +441,8 @@ struct RedirectToRealChannelArgs { nsIPropertyBag2 properties; LastVisitInfo lastVisitInfo; uint32_t loadStateLoadFlags; + nsString srcdocData; + nsIURI baseUri; }; struct TimingStructArgs {