| // Copyright (c) 2012 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_WEBREQUEST_WEBREQUEST_ACTION_H_ |
| #define EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ |
| |
| #include <list> |
| #include <string> |
| #include <vector> |
| |
| #include "base/compiler_specific.h" |
| #include "base/macros.h" |
| #include "base/memory/linked_ptr.h" |
| #include "base/memory/ref_counted.h" |
| #include "extensions/browser/api/declarative/declarative_rule.h" |
| #include "extensions/browser/api/declarative_webrequest/request_stage.h" |
| #include "extensions/browser/api/web_request/web_request_api_helpers.h" |
| #include "extensions/common/api/events.h" |
| #include "url/gurl.h" |
| |
| namespace base { |
| class Time; |
| class Value; |
| } |
| |
| namespace extension_web_request_api_helpers { |
| struct EventResponseDelta; |
| } |
| |
| namespace extensions { |
| class Extension; |
| class InfoMap; |
| struct WebRequestData; |
| } |
| |
| namespace re2 { |
| class RE2; |
| } |
| |
| namespace extensions { |
| |
| typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta> |
| LinkedPtrEventResponseDelta; |
| |
| // Base class for all WebRequestActions of the declarative Web Request API. |
| class WebRequestAction : public base::RefCounted<WebRequestAction> { |
| public: |
| // Type identifiers for concrete WebRequestActions. If you add a new type, |
| // also update the unittest WebRequestActionTest.GetName, and add a |
| // WebRequestActionWithThreadsTest.Permission* unittest. |
| enum Type { |
| ACTION_CANCEL_REQUEST, |
| ACTION_REDIRECT_REQUEST, |
| ACTION_REDIRECT_TO_TRANSPARENT_IMAGE, |
| ACTION_REDIRECT_TO_EMPTY_DOCUMENT, |
| ACTION_REDIRECT_BY_REGEX_DOCUMENT, |
| ACTION_SET_REQUEST_HEADER, |
| ACTION_REMOVE_REQUEST_HEADER, |
| ACTION_ADD_RESPONSE_HEADER, |
| ACTION_REMOVE_RESPONSE_HEADER, |
| ACTION_IGNORE_RULES, |
| ACTION_MODIFY_REQUEST_COOKIE, |
| ACTION_MODIFY_RESPONSE_COOKIE, |
| ACTION_SEND_MESSAGE_TO_EXTENSION, |
| }; |
| |
| // Strategies for checking host permissions. |
| enum HostPermissionsStrategy { |
| STRATEGY_NONE, // Do not check host permissions. |
| STRATEGY_DEFAULT, // Check for host permissions for all URLs |
| // before creating the delta. |
| STRATEGY_HOST, // Check that host permissions match the URL |
| // of the request. |
| }; |
| |
| // Information necessary to decide how to apply a WebRequestAction |
| // inside a matching rule. |
| struct ApplyInfo { |
| const InfoMap* extension_info_map; |
| const WebRequestData& request_data; |
| bool crosses_incognito; |
| // Modified by each applied action: |
| std::list<LinkedPtrEventResponseDelta>* deltas; |
| std::set<std::string>* ignored_tags; |
| }; |
| |
| int stages() const { |
| return stages_; |
| } |
| |
| Type type() const { |
| return type_; |
| } |
| |
| // Compares the Type of two WebRequestActions, needs to be overridden for |
| // parameterized types. |
| virtual bool Equals(const WebRequestAction* other) const; |
| |
| // Return the JavaScript type name corresponding to type(). If there are |
| // more names, they are returned separated by a colon. |
| virtual std::string GetName() const = 0; |
| |
| int minimum_priority() const { |
| return minimum_priority_; |
| } |
| |
| HostPermissionsStrategy host_permissions_strategy() const { |
| return host_permissions_strategy_; |
| } |
| |
| // Returns whether the specified extension has permission to execute this |
| // action on |request|. Checks the host permission if the host permissions |
| // strategy is STRATEGY_DEFAULT. |
| // |apply_info->extension_info_map| may only be NULL for during testing, in |
| // which case host permissions are ignored. |crosses_incognito| specifies |
| // whether the request comes from a different profile than |extension_id| |
| // but was processed because the extension is in spanning mode. |
| bool HasPermission(ApplyInfo* apply_info, |
| const std::string& extension_id) const; |
| |
| // Factory method that instantiates a concrete WebRequestAction |
| // implementation according to |json_action|, the representation of the |
| // WebRequestAction as received from the extension API. |
| // Sets |error| and returns NULL in case of a semantic error that cannot |
| // be caught by schema validation. Sets |bad_message| and returns NULL |
| // in case the input is syntactically unexpected. |
| static scoped_refptr<const WebRequestAction> Create( |
| content::BrowserContext* browser_context, |
| const Extension* extension, |
| const base::Value& json_action, |
| std::string* error, |
| bool* bad_message); |
| |
| // Returns a description of the modification to the request caused by |
| // this action. |
| virtual LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const = 0; |
| |
| // Applies this action to a request, recording the results into |
| // apply_info.deltas. |
| void Apply(const std::string& extension_id, |
| base::Time extension_install_time, |
| ApplyInfo* apply_info) const; |
| |
| protected: |
| friend class base::RefCounted<WebRequestAction>; |
| virtual ~WebRequestAction(); |
| WebRequestAction(int stages, |
| Type type, |
| int minimum_priority, |
| HostPermissionsStrategy strategy); |
| |
| private: |
| // A bit vector representing a set of extensions::RequestStage during which |
| // the condition can be tested. |
| const int stages_; |
| |
| const Type type_; |
| |
| // The minimum priority of rules that may be evaluated after the rule |
| // containing this action. |
| const int minimum_priority_; |
| |
| // Defaults to STRATEGY_DEFAULT. |
| const HostPermissionsStrategy host_permissions_strategy_; |
| }; |
| |
| typedef DeclarativeActionSet<WebRequestAction> WebRequestActionSet; |
| |
| // |
| // The following are concrete actions. |
| // |
| |
| // Action that instructs to cancel a network request. |
| class WebRequestCancelAction : public WebRequestAction { |
| public: |
| WebRequestCancelAction(); |
| |
| // Implementation of WebRequestAction: |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestCancelAction() override; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestCancelAction); |
| }; |
| |
| // Action that instructs to redirect a network request. |
| class WebRequestRedirectAction : public WebRequestAction { |
| public: |
| explicit WebRequestRedirectAction(const GURL& redirect_url); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRedirectAction() override; |
| |
| GURL redirect_url_; // Target to which the request shall be redirected. |
| |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectAction); |
| }; |
| |
| // Action that instructs to redirect a network request to a transparent image. |
| class WebRequestRedirectToTransparentImageAction : public WebRequestAction { |
| public: |
| WebRequestRedirectToTransparentImageAction(); |
| |
| // Implementation of WebRequestAction: |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRedirectToTransparentImageAction() override; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToTransparentImageAction); |
| }; |
| |
| |
| // Action that instructs to redirect a network request to an empty document. |
| class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction { |
| public: |
| WebRequestRedirectToEmptyDocumentAction(); |
| |
| // Implementation of WebRequestAction: |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRedirectToEmptyDocumentAction() override; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToEmptyDocumentAction); |
| }; |
| |
| // Action that instructs to redirect a network request. |
| class WebRequestRedirectByRegExAction : public WebRequestAction { |
| public: |
| // The |to_pattern| has to be passed in RE2 syntax with the exception that |
| // capture groups are referenced in Perl style ($1, $2, ...). |
| explicit WebRequestRedirectByRegExAction( |
| std::unique_ptr<re2::RE2> from_pattern, |
| const std::string& to_pattern); |
| |
| // Conversion of capture group styles between Perl style ($1, $2, ...) and |
| // RE2 (\1, \2, ...). |
| static std::string PerlToRe2Style(const std::string& perl); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRedirectByRegExAction() override; |
| |
| std::unique_ptr<re2::RE2> from_pattern_; |
| std::string to_pattern_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectByRegExAction); |
| }; |
| |
| // Action that instructs to set a request header. |
| class WebRequestSetRequestHeaderAction : public WebRequestAction { |
| public: |
| WebRequestSetRequestHeaderAction(const std::string& name, |
| const std::string& value); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestSetRequestHeaderAction() override; |
| |
| std::string name_; |
| std::string value_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestSetRequestHeaderAction); |
| }; |
| |
| // Action that instructs to remove a request header. |
| class WebRequestRemoveRequestHeaderAction : public WebRequestAction { |
| public: |
| explicit WebRequestRemoveRequestHeaderAction(const std::string& name); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRemoveRequestHeaderAction() override; |
| |
| std::string name_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveRequestHeaderAction); |
| }; |
| |
| // Action that instructs to add a response header. |
| class WebRequestAddResponseHeaderAction : public WebRequestAction { |
| public: |
| WebRequestAddResponseHeaderAction(const std::string& name, |
| const std::string& value); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestAddResponseHeaderAction() override; |
| |
| std::string name_; |
| std::string value_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestAddResponseHeaderAction); |
| }; |
| |
| // Action that instructs to remove a response header. |
| class WebRequestRemoveResponseHeaderAction : public WebRequestAction { |
| public: |
| explicit WebRequestRemoveResponseHeaderAction(const std::string& name, |
| const std::string& value, |
| bool has_value); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRemoveResponseHeaderAction() override; |
| |
| std::string name_; |
| std::string value_; |
| bool has_value_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveResponseHeaderAction); |
| }; |
| |
| // Action that instructs to ignore rules below a certain priority. |
| class WebRequestIgnoreRulesAction : public WebRequestAction { |
| public: |
| explicit WebRequestIgnoreRulesAction(int minimum_priority, |
| const std::string& ignore_tag); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| const std::string& ignore_tag() const { return ignore_tag_; } |
| |
| private: |
| ~WebRequestIgnoreRulesAction() override; |
| |
| // Rules are ignored if they have a tag matching |ignore_tag_| and |
| // |ignore_tag_| is non-empty. |
| std::string ignore_tag_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestIgnoreRulesAction); |
| }; |
| |
| // Action that instructs to modify (add, edit, remove) a request cookie. |
| class WebRequestRequestCookieAction : public WebRequestAction { |
| public: |
| typedef extension_web_request_api_helpers::RequestCookieModification |
| RequestCookieModification; |
| |
| explicit WebRequestRequestCookieAction( |
| RequestCookieModification request_cookie_modification); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestRequestCookieAction() override; |
| |
| const RequestCookieModification request_cookie_modification_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestRequestCookieAction); |
| }; |
| |
| // Action that instructs to modify (add, edit, remove) a response cookie. |
| class WebRequestResponseCookieAction : public WebRequestAction { |
| public: |
| typedef extension_web_request_api_helpers::ResponseCookieModification |
| ResponseCookieModification; |
| |
| explicit WebRequestResponseCookieAction( |
| ResponseCookieModification response_cookie_modification); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestResponseCookieAction() override; |
| |
| const ResponseCookieModification response_cookie_modification_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestResponseCookieAction); |
| }; |
| |
| // Action that triggers the chrome.declarativeWebRequest.onMessage event in |
| // the background/event/... pages of the extension. |
| class WebRequestSendMessageToExtensionAction : public WebRequestAction { |
| public: |
| explicit WebRequestSendMessageToExtensionAction(const std::string& message); |
| |
| // Implementation of WebRequestAction: |
| bool Equals(const WebRequestAction* other) const override; |
| std::string GetName() const override; |
| LinkedPtrEventResponseDelta CreateDelta( |
| const WebRequestData& request_data, |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const override; |
| |
| private: |
| ~WebRequestSendMessageToExtensionAction() override; |
| |
| std::string message_; |
| DISALLOW_COPY_AND_ASSIGN(WebRequestSendMessageToExtensionAction); |
| }; |
| |
| } // namespace extensions |
| |
| #endif // EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ |