commit de1557487939cf263648d94bca1a30dd66759edd
parent 105c0ee1489b02f857cb2fbb39533cd86a24d462
Author: Sandor Molnar <smolnar@mozilla.com>
Date: Wed, 7 Jan 2026 18:48:01 +0200
Revert "Bug 2002144 - Replace New Tab Wallpaper blob URLs with MozNewTabWallpaper protocol handler. r=mconley,home-newtab-reviewers" for causing build bustages @ NeckoParent.cpp
This reverts commit f063a98a3dbb6ade3fc46694c7ac9f9946874612.
Revert "Bug 2002129 - Add unit tests for MozNewTabWallpaperProtocolHandler. r=necko-reviewers,valentin"
This reverts commit cd18695e48ac25a4d6e14b794aac886e52386a2a.
Revert "Bug 1989609 - Create protocol handler to allow New Tabs in containers to use custom wallpapers. r=home-newtab-reviewers,necko-reviewers,mconley,kershaw,ckerschb"
This reverts commit d2fb41d9d1fc48af33430b6965d6c5fc04ad7d72.
Diffstat:
14 files changed, 129 insertions(+), 627 deletions(-)
diff --git a/browser/extensions/newtab/lib/Wallpapers/WallpaperFeed.sys.mjs b/browser/extensions/newtab/lib/Wallpapers/WallpaperFeed.sys.mjs
@@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
-
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
BasePromiseWorker: "resource://gre/modules/PromiseWorker.sys.mjs",
@@ -39,22 +37,12 @@ const RS_FALLBACK_BASE_URL =
export class WallpaperFeed {
#customBackgroundObjectURL = null;
- // @backward-compat { version 148 } This newtab train-hop compatibility
- // shim can be removed once Firefox 148 makes it to the release channel.
- #usesProtocolHandler =
- Services.vc.compare(AppConstants.MOZ_APP_VERSION, "148.0a1") >= 0;
-
constructor() {
this.loaded = false;
this.wallpaperClient = null;
this._onSync = this.onSync.bind(this);
}
- // Constructs a moz-newtab-wallpaper:// URI for the given wallpaper UUID.
- getWallpaperURL(uuid) {
- return `moz-newtab-wallpaper://${uuid}`;
- }
-
/**
* This thin wrapper around global.fetch makes it easier for us to write
* automated tests that simulate responses from this fetch.
@@ -111,15 +99,6 @@ export class WallpaperFeed {
}
async updateWallpapers(isStartup = false) {
- // @backward-compat { version 148 } This newtab train-hop compatibility
- // shim can be removed once Firefox 148 makes it to the release channel.
- if (!this.#usesProtocolHandler) {
- if (this.#customBackgroundObjectURL) {
- URL.revokeObjectURL(this.#customBackgroundObjectURL);
- this.#customBackgroundObjectURL = null;
- }
- }
-
let uuid = Services.prefs.getStringPref(
PREF_WALLPAPERS_CUSTOM_WALLPAPER_UUID,
""
@@ -130,43 +109,35 @@ export class WallpaperFeed {
""
);
+ if (this.#customBackgroundObjectURL) {
+ URL.revokeObjectURL(this.#customBackgroundObjectURL);
+ this.#customBackgroundObjectURL = null;
+ }
+
if (uuid && selectedWallpaper === "custom") {
- // @backward-compat { version 148 } This newtab train-hop compatibility
- // shim can be removed once Firefox 148 makes it to the release channel.
- if (this.#usesProtocolHandler) {
- const wallpaperURI = this.getWallpaperURL(uuid);
+ const wallpaperDir = PathUtils.join(PathUtils.profileDir, "wallpaper");
+ const filePath = PathUtils.join(wallpaperDir, uuid);
+
+ try {
+ let testFile = await IOUtils.getFile(filePath);
+
+ if (!testFile) {
+ throw new Error("File does not exist");
+ }
+
+ let imageFile = await File.createFromNsIFile(testFile);
+ this.#customBackgroundObjectURL = URL.createObjectURL(imageFile);
this.store.dispatch(
ac.BroadcastToContent({
type: at.WALLPAPERS_CUSTOM_SET,
- data: wallpaperURI,
+ data: this.#customBackgroundObjectURL,
})
);
- } else {
- const wallpaperDir = PathUtils.join(PathUtils.profileDir, "wallpaper");
- const filePath = PathUtils.join(wallpaperDir, uuid);
-
- try {
- let testFile = await IOUtils.getFile(filePath);
-
- if (!testFile) {
- throw new Error("File does not exist");
- }
-
- let imageFile = await File.createFromNsIFile(testFile);
- this.#customBackgroundObjectURL = URL.createObjectURL(imageFile);
-
- this.store.dispatch(
- ac.BroadcastToContent({
- type: at.WALLPAPERS_CUSTOM_SET,
- data: this.#customBackgroundObjectURL,
- })
- );
- } catch (error) {
- console.warn(`Wallpaper file not found: ${error.message}`);
- Services.prefs.clearUserPref(PREF_WALLPAPERS_CUSTOM_WALLPAPER_UUID);
- return;
- }
+ } catch (error) {
+ console.warn(`Wallpaper file not found: ${error.message}`);
+ Services.prefs.clearUserPref(PREF_WALLPAPERS_CUSTOM_WALLPAPER_UUID);
+ return;
}
} else {
this.store.dispatch(
@@ -310,32 +281,19 @@ export class WallpaperFeed {
await IOUtils.write(filePath, uint8Array, { tmpPath: `${filePath}.tmp` });
- // @backward-compat { version 148 } This newtab train-hop compatibility
- // shim can be removed once Firefox 148 makes it to the release channel.
- if (this.#usesProtocolHandler) {
- const wallpaperURI = this.getWallpaperURL(uuid);
-
- this.store.dispatch(
- ac.BroadcastToContent({
- type: at.WALLPAPERS_CUSTOM_SET,
- data: wallpaperURI,
- })
- );
- } else {
- if (this.#customBackgroundObjectURL) {
- URL.revokeObjectURL(this.#customBackgroundObjectURL);
- this.#customBackgroundObjectURL = null;
- }
+ if (this.#customBackgroundObjectURL) {
+ URL.revokeObjectURL(this.#customBackgroundObjectURL);
+ this.#customBackgroundObjectURL = null;
+ }
- this.#customBackgroundObjectURL = URL.createObjectURL(file);
+ this.#customBackgroundObjectURL = URL.createObjectURL(file);
- this.store.dispatch(
- ac.BroadcastToContent({
- type: at.WALLPAPERS_CUSTOM_SET,
- data: this.#customBackgroundObjectURL,
- })
- );
- }
+ this.store.dispatch(
+ ac.BroadcastToContent({
+ type: at.WALLPAPERS_CUSTOM_SET,
+ data: this.#customBackgroundObjectURL,
+ })
+ );
this.store.dispatch(
ac.SetPref("newtabWallpapers.customWallpaper.theme", wallpaperTheme)
diff --git a/browser/extensions/newtab/test/xpcshell/test_WallpaperFeed.js b/browser/extensions/newtab/test/xpcshell/test_WallpaperFeed.js
@@ -202,10 +202,10 @@ add_task(async function test_Wallpaper_Upload() {
});
/**
- * Tests that the parent process sends down a moz-newtab-wallpaper:// protocol URI
- * to newtab to render as the background.
+ * Tests that the parent process sends down a consistent object URL to newtab to
+ * render as the background.
*/
-add_task(async function test_Wallpaper_protocolURI() {
+add_task(async function test_Wallpaper_objectURI() {
let sandbox = sinon.createSandbox();
let feed = getWallpaperFeedForTest(sandbox);
@@ -243,26 +243,22 @@ add_task(async function test_Wallpaper_protocolURI() {
feed.store.dispatch.calledWith(
actionCreators.BroadcastToContent({
type: actionTypes.WALLPAPERS_CUSTOM_SET,
- data: sandbox.match("moz-newtab-wallpaper://"),
+ data: sandbox.match("blob:null/"),
})
- ),
- "Should dispatch WALLPAPERS_CUSTOM_SET with moz-newtab-wallpaper:// URI"
+ )
);
- // Verify the protocol URI uses the correct scheme and gets stored in state
+ // Now ensure that a consistent object URL gets returned for each subsequent
+ // request for a wallpaper by checking to see that it exists in the state
+ // object. This URL is non-deterministic, but we can pull it out from what was
+ // just passed to the store dispatch method.
const [action] = feed.store.dispatch.getCall(0).args;
- const wallpaperURI = action.data;
-
- Assert.ok(
- wallpaperURI.startsWith("moz-newtab-wallpaper://"),
- "Wallpaper URI should use moz-newtab-wallpaper:// protocol"
- );
-
+ const wallpaperURL = action.data;
const state = reducers.Wallpapers(null, action);
Assert.equal(
state.uploadedWallpaper,
- wallpaperURI,
- "Should have updated the state to include the protocol URI"
+ wallpaperURL,
+ "Should have updated the state to include the object URL"
);
// Cleanup files
diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp
@@ -1073,8 +1073,7 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags(
}
}
} else if (targetScheme.EqualsLiteral("moz-page-thumb") ||
- targetScheme.EqualsLiteral("page-icon") ||
- targetScheme.EqualsLiteral("moz-newtab-wallpaper")) {
+ targetScheme.EqualsLiteral("page-icon")) {
if (XRE_IsParentProcess()) {
return NS_OK;
}
diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
@@ -107,7 +107,6 @@
#include "mozilla/net/CookieJarSettings.h"
#include "mozilla/net/MozSrcProtocolHandler.h"
#include "mozilla/net/ExtensionProtocolHandler.h"
-#include "mozilla/net/MozNewTabWallpaperProtocolHandler.h"
#include "mozilla/net/PageThumbProtocolHandler.h"
#include "mozilla/net/SFVService.h"
#include "nsICookieService.h"
@@ -1994,15 +1993,6 @@ nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec,
return handler->NewURI(aSpec, aCharset, aBaseURI, aURI);
}
- if (scheme.EqualsLiteral("moz-newtab-wallpaper")) {
- RefPtr<mozilla::net::MozNewTabWallpaperProtocolHandler> handler =
- mozilla::net::MozNewTabWallpaperProtocolHandler::GetSingleton();
- if (!handler) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- return handler->NewURI(aSpec, aCharset, aBaseURI, aURI);
- }
-
if (scheme.EqualsLiteral("about")) {
return nsAboutProtocolHandler::CreateNewURI(aSpec, aCharset, aBaseURI,
aURI);
diff --git a/netwerk/build/components.conf b/netwerk/build/components.conf
@@ -435,25 +435,6 @@ Classes = [
},
},
{
- 'cid': '{64095195-aa8a-4d17-8ec8-c470d85b609b}',
- 'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-newtab-wallpaper'],
- 'singleton': True,
- 'type': 'mozilla::net::MozNewTabWallpaperProtocolHandler',
- 'headers': ['mozilla/net/MozNewTabWallpaperProtocolHandler.h'],
- 'constructor': 'mozilla::net::MozNewTabWallpaperProtocolHandler::GetSingleton',
- 'protocol_config': {
- 'scheme': 'moz-newtab-wallpaper',
- 'flags': [
- 'URI_STD',
- 'URI_IS_UI_RESOURCE',
- 'URI_IS_LOCAL_RESOURCE',
- 'URI_NORELATIVE',
- 'URI_NOAUTH',
- ],
- 'default_port': -1,
- },
- },
- {
'cid': '{1423e739-782c-4081-b5d8-fe6fba68c0ef}',
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-safe-about'],
'singleton': True,
diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp
@@ -13,7 +13,6 @@
#include "mozilla/ipc/IPCStreamUtils.h"
#include "mozilla/net/ExtensionProtocolHandler.h"
#include "mozilla/net/PageThumbProtocolHandler.h"
-#include "mozilla/net/MozNewTabWallpaperProtocolHandler.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/HttpChannelParent.h"
#include "mozilla/net/CookieServiceParent.h"
@@ -802,52 +801,6 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream(
return IPC_OK();
}
-mozilla::ipc::IPCResult NeckoParent::RecvGetMozNewTabWallpaperStream(
- nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
- GetMozNewTabWallpaperStreamResolver&& aResolver) {
- // Only the privileged about content process is allowed to access
- // things over the moz-newtab-wallpaper protocol. Any other content process
- // that tries to send this should have been blocked via the
- // ScriptSecurityManager, but if somehow the process has been tricked into
- // sending this message, we send IPC_FAIL in order to crash that
- // likely-compromised content process.
- if (static_cast<ContentParent*>(Manager())->GetRemoteType() !=
- PRIVILEGEDABOUT_REMOTE_TYPE) {
- return IPC_FAIL(this, "Wrong process type");
- }
-
- RefPtr<net::MozNewTabWallpaperProtocolHandler> ph(
- net::MozNewTabWallpaperProtocolHandler::GetSingleton());
- MOZ_ASSERT(ph);
-
- // Ask the MozNewTabWallpaperProtocolHandler to give us a new input stream for
- // this URI. The request comes from a MozNewTabWallpaperProtocolHandler in the
- // child process, but is not guaranteed to be a valid moz-newtab-wallpaper
- // URI, and not guaranteed to represent a resource that the child should be
- // allowed to access. The MozNewTabWallpaperProtocolHandler is responsible for
- // validating the request.
- nsCOMPtr<nsIInputStream> inputStream;
- bool terminateSender = true;
- auto inputStreamPromise = ph->NewStream(aURI, &terminateSender);
-
- if (terminateSender) {
- return IPC_FAIL(this, "Malformed moz-newtab-wallpaper request");
- }
-
- inputStreamPromise->Then(
- GetMainThreadSerialEventTarget(), __func__,
- [aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
- [aResolver](nsresult aRv) {
- // If NewStream failed, we send back an invalid stream to the child so
- // it can handle the error. MozPromise rejection is reserved for channel
- // errors/disconnects.
- (void)NS_WARN_IF(NS_FAILED(aRv));
- aResolver(Nothing());
- });
-
- return IPC_OK();
-}
-
mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
GetPageIconStreamResolver&& aResolver) {
@@ -900,109 +853,5 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
#endif
}
-/* static */
-RefPtr<RemoteStreamPromise> NeckoParent::CreateRemoteStreamForResolvedURI(
- nsIURI* aChildURI, const nsACString& aResolvedSpec,
- const nsACString& aDefaultMimeType) {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(XRE_IsParentProcess());
-
- nsresult rv;
-
- nsAutoCString resolvedScheme;
- rv = net_ExtractURLScheme(aResolvedSpec, resolvedScheme);
- if (NS_FAILED(rv) || !resolvedScheme.EqualsLiteral("file")) {
- return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED, __func__);
- }
-
- MOZ_ASSERT(resolvedScheme.EqualsLiteral("file"),
- "CreateRemoteStreamForResolvedURI requires file:// URI");
-
- nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- nsCOMPtr<nsIURI> resolvedURI;
- rv = ioService->NewURI(aResolvedSpec, nullptr, nullptr,
- getter_AddRefs(resolvedURI));
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- // Load local file resources for internal protocol handlers (moz-page-thumb,
- // moz-newtab-wallpaper). resolvedURI must be file:// scheme pointing to the
- // profile directory. Callers validate the original URI scheme/host and use
- // internal path resolution (PageThumbsStorageService, profile/wallpaper/)
- // before calling this method.
- nsCOMPtr<nsIChannel> channel;
- nsCOMPtr<nsIPrincipal> nullPrincipal =
- NullPrincipal::CreateWithoutOriginAttributes();
- rv = NS_NewChannel(getter_AddRefs(channel), resolvedURI, nullPrincipal,
- nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
- nsIContentPolicy::TYPE_IMAGE);
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- auto promiseHolder = MakeUnique<MozPromiseHolder<RemoteStreamPromise>>();
- RefPtr<RemoteStreamPromise> promise = promiseHolder->Ensure(__func__);
-
- nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- nsAutoCString contentType;
- rv = mime->GetTypeFromURI(aChildURI, contentType);
- if (NS_FAILED(rv)) {
- if (!aDefaultMimeType.IsEmpty()) {
- contentType = aDefaultMimeType;
- } else {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
- }
-
- rv = NS_DispatchBackgroundTask(
- NS_NewRunnableFunction(
- "NeckoParent::CreateRemoteStreamForResolvedURI",
- [contentType, channel, holder = std::move(promiseHolder)]() {
- nsresult rv;
-
- nsCOMPtr<nsIFileChannel> fileChannel =
- do_QueryInterface(channel, &rv);
- if (NS_FAILED(rv)) {
- holder->Reject(rv, __func__);
- return;
- }
-
- nsCOMPtr<nsIFile> requestedFile;
- rv = fileChannel->GetFile(getter_AddRefs(requestedFile));
- if (NS_FAILED(rv)) {
- holder->Reject(rv, __func__);
- return;
- }
-
- nsCOMPtr<nsIInputStream> inputStream;
- rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream),
- requestedFile, PR_RDONLY, -1);
- if (NS_FAILED(rv)) {
- holder->Reject(rv, __func__);
- return;
- }
-
- RemoteStreamInfo info(inputStream, contentType, -1);
-
- holder->Resolve(std::move(info), __func__);
- }),
- NS_DISPATCH_EVENT_MAY_BLOCK);
-
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- return promise;
-}
-
} // namespace net
} // namespace mozilla
diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h
@@ -8,7 +8,6 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/net/PNeckoParent.h"
#include "mozilla/net/NeckoCommon.h"
-#include "mozilla/MozPromise.h"
#include "nsIAuthPrompt2.h"
#include "nsNetUtil.h"
@@ -18,10 +17,6 @@
namespace mozilla {
namespace net {
-class RemoteStreamInfo;
-using RemoteStreamPromise =
- mozilla::MozPromise<RemoteStreamInfo, nsresult, false>;
-
// Used to override channel Private Browsing status if needed.
enum PBOverrideStatus {
kPBOverride_Unset = 0,
@@ -60,14 +55,6 @@ class NeckoParent : public PNeckoParent {
return PNeckoParent::RecvPCookieServiceConstructor(aActor);
}
- /*
- * Helper method to create a remote stream from a resolved file URI.
- * Shared by PageThumbProtocolHandler and MozNewTabWallpaperProtocolHandler.
- */
- static RefPtr<RemoteStreamPromise> CreateRemoteStreamForResolvedURI(
- nsIURI* aChildURI, const nsACString& aResolvedSpec,
- const nsACString& aDefaultMimeType);
-
protected:
virtual ~NeckoParent() = default;
@@ -209,11 +196,6 @@ class NeckoParent : public PNeckoParent {
nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
GetPageIconStreamResolver&& aResolve);
- /* New Tab wallpaper remote resource loading */
- mozilla::ipc::IPCResult RecvGetMozNewTabWallpaperStream(
- nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
- GetMozNewTabWallpaperStreamResolver&& aResolve);
-
mozilla::ipc::IPCResult RecvInitSocketProcessBridge(
InitSocketProcessBridgeResolver&& aResolver);
mozilla::ipc::IPCResult RecvResetSocketProcessBridge();
diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl
@@ -158,11 +158,6 @@ parent:
async GetPageThumbStream(nullable nsIURI uri, LoadInfoArgs loadInfo) returns (RemoteStreamInfo? info);
async GetPageIconStream(nullable nsIURI uri, LoadInfoArgs loadInfo) returns (RemoteStreamInfo? info);
- /**
- * New Tab wallpaper remote resource loading
- */
- async GetMozNewTabWallpaperStream(nullable nsIURI uri, LoadInfoArgs loadInfo) returns (RemoteStreamInfo? info);
-
child:
async SpeculativeConnectRequest();
diff --git a/netwerk/protocol/res/MozNewTabWallpaperProtocolHandler.cpp b/netwerk/protocol/res/MozNewTabWallpaperProtocolHandler.cpp
@@ -1,195 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MozNewTabWallpaperProtocolHandler.h"
-
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/net/NeckoParent.h"
-#include "nsContentUtils.h"
-#include "nsIFile.h"
-#include "nsIFileChannel.h"
-#include "nsIFileURL.h"
-#include "nsIMIMEService.h"
-#include "nsDirectoryServiceUtils.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsNetUtil.h"
-#include "nsURLHelper.h"
-#include "prio.h"
-#include "SimpleChannel.h"
-
-#define NEWTAB_WALLPAPER_SCHEME "moz-newtab-wallpaper"
-
-namespace mozilla {
-namespace net {
-
-StaticRefPtr<MozNewTabWallpaperProtocolHandler>
- MozNewTabWallpaperProtocolHandler::sSingleton;
-
-NS_IMPL_QUERY_INTERFACE(MozNewTabWallpaperProtocolHandler,
- nsISubstitutingProtocolHandler, nsIProtocolHandler,
- nsISupportsWeakReference)
-NS_IMPL_ADDREF_INHERITED(MozNewTabWallpaperProtocolHandler,
- SubstitutingProtocolHandler)
-NS_IMPL_RELEASE_INHERITED(MozNewTabWallpaperProtocolHandler,
- SubstitutingProtocolHandler)
-
-already_AddRefed<MozNewTabWallpaperProtocolHandler>
-MozNewTabWallpaperProtocolHandler::GetSingleton() {
- if (!sSingleton) {
- sSingleton = new MozNewTabWallpaperProtocolHandler();
- ClearOnShutdown(&sSingleton);
- }
-
- return do_AddRef(sSingleton);
-}
-
-// A moz-newtab-wallpaper URI is only loadable by chrome pages in the parent
-// process, or privileged content running in the privileged about content
-// process.
-MozNewTabWallpaperProtocolHandler::MozNewTabWallpaperProtocolHandler()
- : SubstitutingProtocolHandler(NEWTAB_WALLPAPER_SCHEME) {}
-
-RefPtr<RemoteStreamPromise> MozNewTabWallpaperProtocolHandler::NewStream(
- nsIURI* aChildURI, bool* aTerminateSender) {
- MOZ_ASSERT(!IsNeckoChild());
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!aChildURI || !aTerminateSender) {
- return RemoteStreamPromise::CreateAndReject(NS_ERROR_INVALID_ARG, __func__);
- }
-
- *aTerminateSender = true;
- nsresult rv;
-
- bool isWallpaperScheme = false;
- if (NS_FAILED(
- aChildURI->SchemeIs(NEWTAB_WALLPAPER_SCHEME, &isWallpaperScheme)) ||
- !isWallpaperScheme) {
- return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNKNOWN_PROTOCOL,
- __func__);
- }
-
- nsAutoCString host;
- if (NS_FAILED(aChildURI->GetAsciiHost(host)) || host.IsEmpty()) {
- return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED, __func__);
- }
-
- *aTerminateSender = false;
-
- nsAutoCString resolvedSpec;
- rv = ResolveURI(aChildURI, resolvedSpec);
- if (NS_FAILED(rv)) {
- return RemoteStreamPromise::CreateAndReject(rv, __func__);
- }
-
- return mozilla::net::NeckoParent::CreateRemoteStreamForResolvedURI(
- aChildURI, resolvedSpec, "image/jpeg"_ns);
-}
-
-bool MozNewTabWallpaperProtocolHandler::ResolveSpecialCases(
- const nsACString& aHost, const nsACString& aPath,
- const nsACString& aPathname, nsACString& aResult) {
- if (aHost.IsEmpty()) {
- return false;
- }
-
- if (IsNeckoChild()) {
- // Child process: return placeholder file:// URI for
- // SubstitutingProtocolHandler. SubstituteChannel will replace with a remote
- // channel that proxies the load to the parent process.
- aResult.Assign("file://");
- aResult.Append(aHost);
- return true;
- } else {
- // Parent process: resolve to profile/wallpaper/{host} directory.
- nsCOMPtr<nsIFile> file;
- nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
- getter_AddRefs(file));
- if (NS_FAILED(rv)) {
- return false;
- }
-
- rv = file->AppendNative("wallpaper"_ns);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- rv = file->AppendNative(nsCString(aHost));
- if (NS_FAILED(rv)) {
- return false;
- }
-
- nsCOMPtr<nsIURI> uri;
- rv = NS_NewFileURI(getter_AddRefs(uri), file);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- return NS_SUCCEEDED(uri->GetSpec(aResult));
- }
-}
-
-nsresult MozNewTabWallpaperProtocolHandler::SubstituteChannel(
- nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel** aRetVal) {
- // Check if URI resolves to a file URI.
- nsAutoCString resolvedSpec;
- MOZ_TRY(ResolveURI(aURI, resolvedSpec));
-
- nsAutoCString scheme;
- MOZ_TRY(net_ExtractURLScheme(resolvedSpec, scheme));
-
- if (!scheme.EqualsLiteral("file")) {
- NS_WARNING("moz-newtab-wallpaper URIs should only resolve to file URIs.");
- return NS_ERROR_NO_INTERFACE;
- }
-
- if (IsNeckoChild()) {
- MOZ_TRY(SubstituteRemoteChannel(aURI, aLoadInfo, aRetVal));
- }
-
- return NS_OK;
-}
-
-Result<Ok, nsresult> MozNewTabWallpaperProtocolHandler::SubstituteRemoteChannel(
- nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel** aRetVal) {
- MOZ_ASSERT(IsNeckoChild());
- MOZ_TRY(aURI ? NS_OK : NS_ERROR_INVALID_ARG);
- MOZ_TRY(aLoadInfo ? NS_OK : NS_ERROR_INVALID_ARG);
-
-#ifdef DEBUG
- nsAutoCString resolvedSpec;
- MOZ_TRY(ResolveURI(aURI, resolvedSpec));
-
- nsAutoCString scheme;
- MOZ_TRY(net_ExtractURLScheme(resolvedSpec, scheme));
-
- MOZ_ASSERT(scheme.EqualsLiteral("file"));
-#endif /* DEBUG */
-
- RefPtr<RemoteStreamGetter> streamGetter =
- new RemoteStreamGetter(aURI, aLoadInfo);
-
- NewSimpleChannel(aURI, aLoadInfo, streamGetter, aRetVal);
- return Ok();
-}
-
-// static
-void MozNewTabWallpaperProtocolHandler::NewSimpleChannel(
- nsIURI* aURI, nsILoadInfo* aLoadinfo, RemoteStreamGetter* aStreamGetter,
- nsIChannel** aRetVal) {
- nsCOMPtr<nsIChannel> channel = NS_NewSimpleChannel(
- aURI, aLoadinfo, aStreamGetter,
- [](nsIStreamListener* listener, nsIChannel* simpleChannel,
- RemoteStreamGetter* getter) -> RequestOrReason {
- return getter->GetAsync(listener, simpleChannel,
- &NeckoChild::SendGetMozNewTabWallpaperStream);
- });
-
- channel.swap(*aRetVal);
-}
-
-} // namespace net
-} // namespace mozilla
diff --git a/netwerk/protocol/res/MozNewTabWallpaperProtocolHandler.h b/netwerk/protocol/res/MozNewTabWallpaperProtocolHandler.h
@@ -1,91 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MozNewTabWallpaperProtocolHandler_h___
-#define MozNewTabWallpaperProtocolHandler_h___
-
-#include "mozilla/Result.h"
-#include "mozilla/MozPromise.h"
-#include "mozilla/net/RemoteStreamGetter.h"
-#include "SubstitutingProtocolHandler.h"
-#include "nsIInputStream.h"
-#include "nsWeakReference.h"
-
-namespace mozilla {
-namespace net {
-
-class RemoteStreamGetter;
-
-class MozNewTabWallpaperProtocolHandler final
- : public nsISubstitutingProtocolHandler,
- public SubstitutingProtocolHandler,
- public nsSupportsWeakReference {
- public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_FORWARD_NSIPROTOCOLHANDLER(SubstitutingProtocolHandler::)
- NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(SubstitutingProtocolHandler::)
-
- static already_AddRefed<MozNewTabWallpaperProtocolHandler> GetSingleton();
-
- /**
- * Obtains an input stream for a user-uploaded New Tab wallpaper.
- *
- * @param aChildURI moz-newtab-wallpaper URI from child process
- * @param aTerminateSender set to true if URI is invalid (terminates child)
- * @return RemoteStreamPromise resolving to RemoteStreamInfo on success or
- * nsresult on failure
- */
- RefPtr<RemoteStreamPromise> NewStream(nsIURI* aChildURI,
- bool* aTerminateSender);
-
- protected:
- ~MozNewTabWallpaperProtocolHandler() = default;
-
- private:
- explicit MozNewTabWallpaperProtocolHandler();
-
- [[nodiscard]] bool ResolveSpecialCases(const nsACString& aHost,
- const nsACString& aPath,
- const nsACString& aPathname,
- nsACString& aResult) override;
-
- /**
- * Substitutes the channel with a remote channel in child process.
- *
- * @param aURI the moz-newtab-wallpaper URI
- * @param aLoadInfo the loadinfo for the request
- * @param aRetVal in/out channel param for the substituted channel
- * @return NS_OK on success or NS_ERROR_NO_INTERFACE if URI doesn't
- * resolve to file://
- */
- [[nodiscard]] virtual nsresult SubstituteChannel(
- nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel** aRetVal) override;
-
- /**
- * Replaces the channel with one that proxies the load to parent process.
- *
- * @param aURI the moz-newtab-wallpaper URI
- * @param aLoadInfo the loadinfo for the request
- * @param aRetVal in/out channel param for the substituted remote channel
- * @return NS_OK if successful, otherwise an error
- */
- Result<Ok, nsresult> SubstituteRemoteChannel(nsIURI* aURI,
- nsILoadInfo* aLoadInfo,
- nsIChannel** aRetVal);
-
- // To allow parent IPDL actors to invoke methods on this handler when
- // handling moz-newtab-wallpaper requests from the child.
- static StaticRefPtr<MozNewTabWallpaperProtocolHandler> sSingleton;
-
- // Gets a SimpleChannel that wraps the provided channel.
- static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
- RemoteStreamGetter* aStreamGetter,
- nsIChannel** aRetVal);
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif /* MozNewTabWallpaperProtocolHandler_h___ */
diff --git a/netwerk/protocol/res/PageThumbProtocolHandler.cpp b/netwerk/protocol/res/PageThumbProtocolHandler.cpp
@@ -11,7 +11,6 @@
#include "mozilla/ipc/URIParams.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/NeckoChild.h"
-#include "mozilla/net/NeckoParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Try.h"
@@ -120,8 +119,89 @@ RefPtr<RemoteStreamPromise> PageThumbProtocolHandler::NewStream(
return RemoteStreamPromise::CreateAndReject(rv, __func__);
}
- return mozilla::net::NeckoParent::CreateRemoteStreamForResolvedURI(
- aChildURI, resolvedSpec, ""_ns);
+ nsAutoCString resolvedScheme;
+ rv = net_ExtractURLScheme(resolvedSpec, resolvedScheme);
+ if (NS_FAILED(rv) || !resolvedScheme.EqualsLiteral("file")) {
+ return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED, __func__);
+ }
+
+ nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ nsCOMPtr<nsIURI> resolvedURI;
+ rv = ioService->NewURI(resolvedSpec, nullptr, nullptr,
+ getter_AddRefs(resolvedURI));
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ // We use the system principal to get a file channel for the request,
+ // but only after we've checked (above) that the child URI is of
+ // moz-page-thumb scheme and that the URI host matches PAGE_THUMB_HOST.
+ nsCOMPtr<nsIChannel> channel;
+ rv = NS_NewChannel(getter_AddRefs(channel), resolvedURI,
+ nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ nsIContentPolicy::TYPE_OTHER);
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ auto promiseHolder = MakeUnique<MozPromiseHolder<RemoteStreamPromise>>();
+ RefPtr<RemoteStreamPromise> promise = promiseHolder->Ensure(__func__);
+
+ nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ nsAutoCString contentType;
+ rv = mime->GetTypeFromURI(aChildURI, contentType);
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ rv = NS_DispatchBackgroundTask(
+ NS_NewRunnableFunction(
+ "PageThumbProtocolHandler::NewStream",
+ [contentType, channel, holder = std::move(promiseHolder)]() {
+ nsresult rv;
+
+ nsCOMPtr<nsIFileChannel> fileChannel =
+ do_QueryInterface(channel, &rv);
+ if (NS_FAILED(rv)) {
+ holder->Reject(rv, __func__);
+ return;
+ }
+
+ nsCOMPtr<nsIFile> requestedFile;
+ rv = fileChannel->GetFile(getter_AddRefs(requestedFile));
+ if (NS_FAILED(rv)) {
+ holder->Reject(rv, __func__);
+ return;
+ }
+
+ nsCOMPtr<nsIInputStream> inputStream;
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream),
+ requestedFile, PR_RDONLY, -1);
+ if (NS_FAILED(rv)) {
+ holder->Reject(rv, __func__);
+ return;
+ }
+
+ RemoteStreamInfo info(inputStream, contentType, -1);
+
+ holder->Resolve(std::move(info), __func__);
+ }),
+ NS_DISPATCH_EVENT_MAY_BLOCK);
+
+ if (NS_FAILED(rv)) {
+ return RemoteStreamPromise::CreateAndReject(rv, __func__);
+ }
+
+ return promise;
}
bool PageThumbProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
diff --git a/netwerk/protocol/res/moz.build b/netwerk/protocol/res/moz.build
@@ -13,7 +13,6 @@ XPIDL_MODULE = "necko_res"
EXPORTS.mozilla.net += [
"ExtensionProtocolHandler.h",
- "MozNewTabWallpaperProtocolHandler.h",
"MozSrcProtocolHandler.h",
"PageThumbProtocolHandler.h",
"RemoteStreamGetter.h",
@@ -28,7 +27,6 @@ EXPORTS += [
UNIFIED_SOURCES += [
"ExtensionProtocolHandler.cpp",
- "MozNewTabWallpaperProtocolHandler.cpp",
"MozSrcProtocolHandler.cpp",
"nsResProtocolHandler.cpp",
"PageThumbProtocolHandler.cpp",
diff --git a/netwerk/test/unit/test_wallpaper_protocol.js b/netwerk/test/unit/test_wallpaper_protocol.js
@@ -1,38 +0,0 @@
-"use strict";
-
-// Need profile so that the protocol handler can resolve the path to the underlying file
-do_get_profile();
-
-function run_test() {
- // Check the protocol handler implements the correct interfaces
- let handler = Services.io.getProtocolHandler("moz-newtab-wallpaper");
- ok(
- handler instanceof Ci.nsIProtocolHandler,
- "moz-newtab-wallpaper handler provides nsIProtocolHandler interface"
- );
- ok(
- handler instanceof Ci.nsISubstitutingProtocolHandler,
- "moz-newtab-wallpaper handler provides nsISubstitutingProtocolHandler interface"
- );
-
- // Create a dummy loadinfo which we can hand to newChannel
- let dummyURI = Services.io.newURI("https://www.example.com/");
- let dummyChannel = NetUtil.newChannel({
- uri: dummyURI,
- loadUsingSystemPrincipal: true,
- });
- let dummyLoadInfo = dummyChannel.loadInfo;
-
- // Test that empty host fails
- let emptyHost = Services.io.newURI("moz-newtab-wallpaper://");
- Assert.throws(
- () => handler.newChannel(emptyHost, dummyLoadInfo),
- /NS_ERROR/i,
- "moz-newtab-wallpaper URI with empty host must not resolve"
- );
-
- // Test that valid host creates a channel (even if file doesn't exist yet)
- let validURI = Services.io.newURI("moz-newtab-wallpaper://wallpaper.jpg");
- let channel = handler.newChannel(validURI, dummyLoadInfo);
- ok(channel, "moz-newtab-wallpaper URI with valid host creates a channel");
-}
diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml
@@ -1586,8 +1586,6 @@ run-sequentially = ["true"] # node server exceptions dont replay well
["test_verify_traffic.js"]
-["test_wallpaper_protocol.js"]
-
["test_websocket_500k.js"]
skip-if = [
"verify",