1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ 6 #define EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ 7 8 #include <list> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "base/compiler_specific.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/optional.h" 17 #include "extensions/browser/api/declarative/declarative_rule.h" 18 #include "extensions/browser/api/declarative_webrequest/request_stage.h" 19 #include "extensions/browser/api/web_request/web_request_api_helpers.h" 20 #include "extensions/common/api/events.h" 21 #include "url/gurl.h" 22 23 namespace base { 24 class Time; 25 class Value; 26 } 27 28 namespace extension_web_request_api_helpers { 29 struct EventResponseDelta; 30 } 31 32 namespace extensions { 33 class Extension; 34 class PermissionHelper; 35 struct WebRequestData; 36 } 37 38 namespace re2 { 39 class RE2; 40 } 41 42 namespace extensions { 43 44 // Base class for all WebRequestActions of the declarative Web Request API. 45 class WebRequestAction : public base::RefCounted<WebRequestAction> { 46 public: 47 // Type identifiers for concrete WebRequestActions. If you add a new type, 48 // also update the unittest WebRequestActionTest.GetName, and add a 49 // WebRequestActionWithThreadsTest.Permission* unittest. 50 enum Type { 51 ACTION_CANCEL_REQUEST, 52 ACTION_REDIRECT_REQUEST, 53 ACTION_REDIRECT_TO_TRANSPARENT_IMAGE, 54 ACTION_REDIRECT_TO_EMPTY_DOCUMENT, 55 ACTION_REDIRECT_BY_REGEX_DOCUMENT, 56 ACTION_SET_REQUEST_HEADER, 57 ACTION_REMOVE_REQUEST_HEADER, 58 ACTION_ADD_RESPONSE_HEADER, 59 ACTION_REMOVE_RESPONSE_HEADER, 60 ACTION_IGNORE_RULES, 61 ACTION_MODIFY_REQUEST_COOKIE, 62 ACTION_MODIFY_RESPONSE_COOKIE, 63 ACTION_SEND_MESSAGE_TO_EXTENSION, 64 }; 65 66 // Strategies for checking host permissions. 67 enum HostPermissionsStrategy { 68 STRATEGY_NONE, // Do not check host permissions. 69 STRATEGY_DEFAULT, // Check for host permissions for all URLs 70 // before creating the delta. 71 STRATEGY_HOST, // Check that host permissions match the URL 72 // of the request. 73 }; 74 75 // Information necessary to decide how to apply a WebRequestAction inside a 76 // matching rule. This is passed into HasPermission() and Apply() below as 77 // essentially a parameter pack, so the pointers refer to local structures of 78 // whatever function is calling one of those methods. 79 struct ApplyInfo { 80 PermissionHelper* permission_helper; 81 const WebRequestData& request_data; 82 bool crosses_incognito; 83 // Modified by each applied action: 84 std::list<extension_web_request_api_helpers::EventResponseDelta>* deltas; 85 std::set<std::string>* ignored_tags; 86 }; 87 stages()88 int stages() const { 89 return stages_; 90 } 91 type()92 Type type() const { 93 return type_; 94 } 95 96 // Compares the Type of two WebRequestActions, needs to be overridden for 97 // parameterized types. 98 virtual bool Equals(const WebRequestAction* other) const; 99 100 // Return the JavaScript type name corresponding to type(). If there are 101 // more names, they are returned separated by a colon. 102 virtual std::string GetName() const = 0; 103 minimum_priority()104 int minimum_priority() const { 105 return minimum_priority_; 106 } 107 host_permissions_strategy()108 HostPermissionsStrategy host_permissions_strategy() const { 109 return host_permissions_strategy_; 110 } 111 112 // Returns whether the specified extension has permission to execute this 113 // action on |request|. Checks the host permission if the host permissions 114 // strategy is STRATEGY_DEFAULT. 115 // |apply_info->permission_helper| may only be nullptr for during testing, in 116 // which case host permissions are ignored. |crosses_incognito| specifies 117 // whether the request comes from a different profile than |extension_id| 118 // but was processed because the extension is in spanning mode. 119 bool HasPermission(ApplyInfo* apply_info, 120 const std::string& extension_id) const; 121 122 // Factory method that instantiates a concrete WebRequestAction 123 // implementation according to |json_action|, the representation of the 124 // WebRequestAction as received from the extension API. 125 // Sets |error| and returns NULL in case of a semantic error that cannot 126 // be caught by schema validation. Sets |bad_message| and returns NULL 127 // in case the input is syntactically unexpected. 128 static scoped_refptr<const WebRequestAction> Create( 129 content::BrowserContext* browser_context, 130 const Extension* extension, 131 const base::Value& json_action, 132 std::string* error, 133 bool* bad_message); 134 135 // Returns a description of the modification to the request caused by 136 // this action. 137 virtual base::Optional<extension_web_request_api_helpers::EventResponseDelta> 138 CreateDelta(const WebRequestData& request_data, 139 const std::string& extension_id, 140 const base::Time& extension_install_time) const = 0; 141 142 // Applies this action to a request, recording the results into 143 // apply_info.deltas. 144 void Apply(const std::string& extension_id, 145 base::Time extension_install_time, 146 ApplyInfo* apply_info) const; 147 148 protected: 149 friend class base::RefCounted<WebRequestAction>; 150 virtual ~WebRequestAction(); 151 WebRequestAction(int stages, 152 Type type, 153 int minimum_priority, 154 HostPermissionsStrategy strategy); 155 156 private: 157 // A bit vector representing a set of extensions::RequestStage during which 158 // the condition can be tested. 159 const int stages_; 160 161 const Type type_; 162 163 // The minimum priority of rules that may be evaluated after the rule 164 // containing this action. 165 const int minimum_priority_; 166 167 // Defaults to STRATEGY_DEFAULT. 168 const HostPermissionsStrategy host_permissions_strategy_; 169 }; 170 171 typedef DeclarativeActionSet<WebRequestAction> WebRequestActionSet; 172 173 // 174 // The following are concrete actions. 175 // 176 177 // Action that instructs to cancel a network request. 178 class WebRequestCancelAction : public WebRequestAction { 179 public: 180 WebRequestCancelAction(); 181 182 // Implementation of WebRequestAction: 183 std::string GetName() const override; 184 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 185 CreateDelta(const WebRequestData& request_data, 186 const std::string& extension_id, 187 const base::Time& extension_install_time) const override; 188 189 private: 190 ~WebRequestCancelAction() override; 191 DISALLOW_COPY_AND_ASSIGN(WebRequestCancelAction); 192 }; 193 194 // Action that instructs to redirect a network request. 195 class WebRequestRedirectAction : public WebRequestAction { 196 public: 197 explicit WebRequestRedirectAction(const GURL& redirect_url); 198 199 // Implementation of WebRequestAction: 200 bool Equals(const WebRequestAction* other) const override; 201 std::string GetName() const override; 202 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 203 CreateDelta(const WebRequestData& request_data, 204 const std::string& extension_id, 205 const base::Time& extension_install_time) const override; 206 207 private: 208 ~WebRequestRedirectAction() override; 209 210 GURL redirect_url_; // Target to which the request shall be redirected. 211 212 DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectAction); 213 }; 214 215 // Action that instructs to redirect a network request to a transparent image. 216 class WebRequestRedirectToTransparentImageAction : public WebRequestAction { 217 public: 218 WebRequestRedirectToTransparentImageAction(); 219 220 // Implementation of WebRequestAction: 221 std::string GetName() const override; 222 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 223 CreateDelta(const WebRequestData& request_data, 224 const std::string& extension_id, 225 const base::Time& extension_install_time) const override; 226 227 private: 228 ~WebRequestRedirectToTransparentImageAction() override; 229 DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToTransparentImageAction); 230 }; 231 232 233 // Action that instructs to redirect a network request to an empty document. 234 class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction { 235 public: 236 WebRequestRedirectToEmptyDocumentAction(); 237 238 // Implementation of WebRequestAction: 239 std::string GetName() const override; 240 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 241 CreateDelta(const WebRequestData& request_data, 242 const std::string& extension_id, 243 const base::Time& extension_install_time) const override; 244 245 private: 246 ~WebRequestRedirectToEmptyDocumentAction() override; 247 DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToEmptyDocumentAction); 248 }; 249 250 // Action that instructs to redirect a network request. 251 class WebRequestRedirectByRegExAction : public WebRequestAction { 252 public: 253 // The |to_pattern| has to be passed in RE2 syntax with the exception that 254 // capture groups are referenced in Perl style ($1, $2, ...). 255 explicit WebRequestRedirectByRegExAction( 256 std::unique_ptr<re2::RE2> from_pattern, 257 const std::string& to_pattern); 258 259 // Conversion of capture group styles between Perl style ($1, $2, ...) and 260 // RE2 (\1, \2, ...). 261 static std::string PerlToRe2Style(const std::string& perl); 262 263 // Implementation of WebRequestAction: 264 bool Equals(const WebRequestAction* other) const override; 265 std::string GetName() const override; 266 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 267 CreateDelta(const WebRequestData& request_data, 268 const std::string& extension_id, 269 const base::Time& extension_install_time) const override; 270 271 private: 272 ~WebRequestRedirectByRegExAction() override; 273 274 std::unique_ptr<re2::RE2> from_pattern_; 275 std::string to_pattern_; 276 277 DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectByRegExAction); 278 }; 279 280 // Action that instructs to set a request header. 281 class WebRequestSetRequestHeaderAction : public WebRequestAction { 282 public: 283 WebRequestSetRequestHeaderAction(const std::string& name, 284 const std::string& value); 285 286 // Implementation of WebRequestAction: 287 bool Equals(const WebRequestAction* other) const override; 288 std::string GetName() const override; 289 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 290 CreateDelta(const WebRequestData& request_data, 291 const std::string& extension_id, 292 const base::Time& extension_install_time) const override; 293 294 private: 295 ~WebRequestSetRequestHeaderAction() override; 296 297 std::string name_; 298 std::string value_; 299 DISALLOW_COPY_AND_ASSIGN(WebRequestSetRequestHeaderAction); 300 }; 301 302 // Action that instructs to remove a request header. 303 class WebRequestRemoveRequestHeaderAction : public WebRequestAction { 304 public: 305 explicit WebRequestRemoveRequestHeaderAction(const std::string& name); 306 307 // Implementation of WebRequestAction: 308 bool Equals(const WebRequestAction* other) const override; 309 std::string GetName() const override; 310 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 311 CreateDelta(const WebRequestData& request_data, 312 const std::string& extension_id, 313 const base::Time& extension_install_time) const override; 314 315 private: 316 ~WebRequestRemoveRequestHeaderAction() override; 317 318 std::string name_; 319 DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveRequestHeaderAction); 320 }; 321 322 // Action that instructs to add a response header. 323 class WebRequestAddResponseHeaderAction : public WebRequestAction { 324 public: 325 WebRequestAddResponseHeaderAction(const std::string& name, 326 const std::string& value); 327 328 // Implementation of WebRequestAction: 329 bool Equals(const WebRequestAction* other) const override; 330 std::string GetName() const override; 331 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 332 CreateDelta(const WebRequestData& request_data, 333 const std::string& extension_id, 334 const base::Time& extension_install_time) const override; 335 336 private: 337 ~WebRequestAddResponseHeaderAction() override; 338 339 std::string name_; 340 std::string value_; 341 DISALLOW_COPY_AND_ASSIGN(WebRequestAddResponseHeaderAction); 342 }; 343 344 // Action that instructs to remove a response header. 345 class WebRequestRemoveResponseHeaderAction : public WebRequestAction { 346 public: 347 explicit WebRequestRemoveResponseHeaderAction(const std::string& name, 348 const std::string& value, 349 bool has_value); 350 351 // Implementation of WebRequestAction: 352 bool Equals(const WebRequestAction* other) const override; 353 std::string GetName() const override; 354 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 355 CreateDelta(const WebRequestData& request_data, 356 const std::string& extension_id, 357 const base::Time& extension_install_time) const override; 358 359 private: 360 ~WebRequestRemoveResponseHeaderAction() override; 361 362 std::string name_; 363 std::string value_; 364 bool has_value_; 365 DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveResponseHeaderAction); 366 }; 367 368 // Action that instructs to ignore rules below a certain priority. 369 class WebRequestIgnoreRulesAction : public WebRequestAction { 370 public: 371 explicit WebRequestIgnoreRulesAction(int minimum_priority, 372 const std::string& ignore_tag); 373 374 // Implementation of WebRequestAction: 375 bool Equals(const WebRequestAction* other) const override; 376 std::string GetName() const override; 377 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 378 CreateDelta(const WebRequestData& request_data, 379 const std::string& extension_id, 380 const base::Time& extension_install_time) const override; ignore_tag()381 const std::string& ignore_tag() const { return ignore_tag_; } 382 383 private: 384 ~WebRequestIgnoreRulesAction() override; 385 386 // Rules are ignored if they have a tag matching |ignore_tag_| and 387 // |ignore_tag_| is non-empty. 388 std::string ignore_tag_; 389 DISALLOW_COPY_AND_ASSIGN(WebRequestIgnoreRulesAction); 390 }; 391 392 // Action that instructs to modify (add, edit, remove) a request cookie. 393 class WebRequestRequestCookieAction : public WebRequestAction { 394 public: 395 typedef extension_web_request_api_helpers::RequestCookieModification 396 RequestCookieModification; 397 398 explicit WebRequestRequestCookieAction( 399 RequestCookieModification request_cookie_modification); 400 401 // Implementation of WebRequestAction: 402 bool Equals(const WebRequestAction* other) const override; 403 std::string GetName() const override; 404 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 405 CreateDelta(const WebRequestData& request_data, 406 const std::string& extension_id, 407 const base::Time& extension_install_time) const override; 408 409 private: 410 ~WebRequestRequestCookieAction() override; 411 412 const RequestCookieModification request_cookie_modification_; 413 DISALLOW_COPY_AND_ASSIGN(WebRequestRequestCookieAction); 414 }; 415 416 // Action that instructs to modify (add, edit, remove) a response cookie. 417 class WebRequestResponseCookieAction : public WebRequestAction { 418 public: 419 typedef extension_web_request_api_helpers::ResponseCookieModification 420 ResponseCookieModification; 421 422 explicit WebRequestResponseCookieAction( 423 ResponseCookieModification response_cookie_modification); 424 425 // Implementation of WebRequestAction: 426 bool Equals(const WebRequestAction* other) const override; 427 std::string GetName() const override; 428 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 429 CreateDelta(const WebRequestData& request_data, 430 const std::string& extension_id, 431 const base::Time& extension_install_time) const override; 432 433 private: 434 ~WebRequestResponseCookieAction() override; 435 436 const ResponseCookieModification response_cookie_modification_; 437 DISALLOW_COPY_AND_ASSIGN(WebRequestResponseCookieAction); 438 }; 439 440 // Action that triggers the chrome.declarativeWebRequest.onMessage event in 441 // the background/event/... pages of the extension. 442 class WebRequestSendMessageToExtensionAction : public WebRequestAction { 443 public: 444 explicit WebRequestSendMessageToExtensionAction(const std::string& message); 445 446 // Implementation of WebRequestAction: 447 bool Equals(const WebRequestAction* other) const override; 448 std::string GetName() const override; 449 base::Optional<extension_web_request_api_helpers::EventResponseDelta> 450 CreateDelta(const WebRequestData& request_data, 451 const std::string& extension_id, 452 const base::Time& extension_install_time) const override; 453 454 private: 455 ~WebRequestSendMessageToExtensionAction() override; 456 457 std::string message_; 458 DISALLOW_COPY_AND_ASSIGN(WebRequestSendMessageToExtensionAction); 459 }; 460 461 } // namespace extensions 462 463 #endif // EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_ 464