blob: c1f2cacc636ab1a6ef589fff678ec720a5e1fea1 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_MANAGER_H_
#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_MANAGER_H_
#include <stddef.h>
#include <memory>
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/url_pattern_set.h"
class GURL;
namespace extensions {
class InfoMap;
struct WebRequestInfo;
namespace declarative_net_request {
class RulesetMatcher;
// Manages the set of active rulesets for the Declarative Net Request API. Can
// be constructed on any sequence but must be accessed and destroyed from the
// same sequence.
class RulesetManager {
public:
enum class Action {
NONE,
// Block the network request.
BLOCK,
// Block the network request and collapse the corresponding DOM element.
COLLAPSE,
// Redirect the network request.
REDIRECT,
};
explicit RulesetManager(const InfoMap* info_map);
~RulesetManager();
// An observer used for testing purposes.
class TestObserver {
public:
virtual void OnEvaluateRequest(const WebRequestInfo& request,
bool is_incognito_context) {}
// Called whenever a ruleset is added or removed.
virtual void OnRulesetCountChanged(size_t new_count) {}
protected:
virtual ~TestObserver() {}
};
// Adds the ruleset for the given |extension_id|. Should not be called twice
// in succession for an extension.
void AddRuleset(const ExtensionId& extension_id,
std::unique_ptr<RulesetMatcher> ruleset_matcher,
URLPatternSet allowed_pages);
// Removes the ruleset for |extension_id|. Should be called only after a
// corresponding AddRuleset.
void RemoveRuleset(const ExtensionId& extension_id);
void UpdateAllowedPages(const ExtensionId& extension_id,
URLPatternSet allowed_pages);
// Returns the action to take for the given request. |redirect_url| will be
// populated if the returned action is |REDIRECT|. Blocking rules have higher
// priority than redirect rules. For determining the |redirect_url|, most
// recently installed extensions are given preference. |redirect_url| must not
// be null.
Action EvaluateRequest(const WebRequestInfo& request,
bool is_incognito_context,
GURL* redirect_url) const;
// Returns the number of RulesetMatcher currently being managed.
size_t GetMatcherCountForTest() const { return rulesets_.size(); }
// Sets the TestObserver. Client maintains ownership of |observer|.
void SetObserverForTest(TestObserver* observer);
private:
struct ExtensionRulesetData {
ExtensionRulesetData(const ExtensionId& extension_id,
const base::Time& extension_install_time,
std::unique_ptr<RulesetMatcher> matcher,
URLPatternSet allowed_pages);
~ExtensionRulesetData();
ExtensionRulesetData(ExtensionRulesetData&& other);
ExtensionRulesetData& operator=(ExtensionRulesetData&& other);
ExtensionId extension_id;
base::Time extension_install_time;
std::unique_ptr<RulesetMatcher> matcher;
URLPatternSet allowed_pages;
bool operator<(const ExtensionRulesetData& other) const;
DISALLOW_COPY_AND_ASSIGN(ExtensionRulesetData);
};
// Returns true if the given |request| should be evaluated for
// blocking/redirection.
bool ShouldEvaluateRequest(const WebRequestInfo& request) const;
// Returns whether |ruleset| should be evaluated for the given |request|.
bool ShouldEvaluateRulesetForRequest(const ExtensionRulesetData& ruleset,
const WebRequestInfo& request,
bool is_incognito_context) const;
// Sorted in decreasing order of |extension_install_time|.
// Use a flat_set instead of std::set/map. This makes [Add/Remove]Ruleset
// O(n), but it's fine since the no. of rulesets are expected to be quite
// small.
base::flat_set<ExtensionRulesetData> rulesets_;
// Non-owning pointer to InfoMap. Owns us.
const InfoMap* const info_map_;
// Non-owning pointer to TestObserver.
TestObserver* test_observer_ = nullptr;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(RulesetManager);
};
} // namespace declarative_net_request
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_MANAGER_H_