1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_EXTENSION_NAVIGATION_REGISTRY_H_
#define EXTENSIONS_BROWSER_EXTENSION_NAVIGATION_REGISTRY_H_
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "url/gurl.h"
namespace extensions {
// Associate navigation_handle id's with metadata for the purpose of determining
// whether an extension triggered a redirect.
class ExtensionNavigationRegistry : public BrowserContextKeyedAPI {
public:
explicit ExtensionNavigationRegistry(
content::BrowserContext* browser_context);
ExtensionNavigationRegistry(const ExtensionNavigationRegistry&) = delete;
ExtensionNavigationRegistry& operator=(const ExtensionNavigationRegistry&) =
delete;
~ExtensionNavigationRegistry() override;
struct Metadata {
explicit Metadata(GURL gurl, ExtensionId extension_id)
: gurl(gurl), extension_id(extension_id) {}
GURL gurl;
ExtensionId extension_id;
};
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<ExtensionNavigationRegistry>*
GetFactoryInstance();
// Returns the instance for the given `browser_context`.
static ExtensionNavigationRegistry* Get(
content::BrowserContext* browser_context);
// Remove navigation handle id, if it exists.
void Erase(int64_t navigation_handle_id);
// Record specific metadata about a navigation.
void RecordExtensionRedirect(int64_t navigation_handle_id,
const GURL& target_url,
const ExtensionId& extension_id);
// Return metadata if it exists and remove it from memory.
std::optional<Metadata> GetAndErase(int64_t navigation_handle_id);
// Determine if the server redirect is allowed to succeed. This is not
// idempotent because it erases the corresponding record on the first call, so
// this should only be called once for a given stage in the navigation.
bool CanRedirect(int64_t navigation_id,
const GURL& gurl,
const Extension& extension);
private:
// Determine whether the feature is enabled.
bool IsEnabled();
// BrowserContextKeyedAPIFactory or BrowserContextKeyedAPI related.
friend class BrowserContextKeyedAPIFactory<ExtensionNavigationRegistry>;
static const char* service_name() { return "ExtensionNavigationRegistry"; }
static const bool kServiceHasOwnInstanceInIncognito = true;
const raw_ptr<content::BrowserContext> browser_context_;
// An ID in existence means that the navigation was intercepted by WebRequest.
using NavigationId = int64_t;
base::flat_map<NavigationId, Metadata> redirect_metadata_;
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_EXTENSION_NAVIGATION_REGISTRY_H_
|