| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/api/declarative_webrequest/webrequest_action.h" | 5 #include "extensions/browser/api/declarative_webrequest/webrequest_action.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> |
| 10 |
| 9 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 10 #include "base/json/json_file_value_serializer.h" | 12 #include "base/json/json_file_value_serializer.h" |
| 11 #include "base/macros.h" | 13 #include "base/macros.h" |
| 12 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" | |
| 14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 15 #include "base/test/values_test_util.h" | 16 #include "base/test/values_test_util.h" |
| 16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 17 #include "base/values.h" | 18 #include "base/values.h" |
| 18 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
| 19 #include "chrome/common/extensions/extension_constants.h" | 20 #include "chrome/common/extensions/extension_constants.h" |
| 20 #include "chrome/common/extensions/extension_test_util.h" | 21 #include "chrome/common/extensions/extension_test_util.h" |
| 21 #include "content/public/test/test_browser_thread_bundle.h" | 22 #include "content/public/test/test_browser_thread_bundle.h" |
| 22 #include "extensions/browser/api/declarative_webrequest/request_stage.h" | 23 #include "extensions/browser/api/declarative_webrequest/request_stage.h" |
| 23 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h" | 24 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 36 using base::ListValue; | 37 using base::ListValue; |
| 37 using extension_test_util::LoadManifestUnchecked; | 38 using extension_test_util::LoadManifestUnchecked; |
| 38 using testing::HasSubstr; | 39 using testing::HasSubstr; |
| 39 | 40 |
| 40 namespace extensions { | 41 namespace extensions { |
| 41 | 42 |
| 42 namespace { | 43 namespace { |
| 43 | 44 |
| 44 const char kUnknownActionType[] = "unknownType"; | 45 const char kUnknownActionType[] = "unknownType"; |
| 45 | 46 |
| 46 scoped_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) { | 47 std::unique_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) { |
| 47 scoped_ptr<base::Value> parsed_value(base::test::ParseJson(json)); | 48 std::unique_ptr<base::Value> parsed_value(base::test::ParseJson(json)); |
| 48 const base::ListValue* parsed_list; | 49 const base::ListValue* parsed_list; |
| 49 CHECK(parsed_value->GetAsList(&parsed_list)); | 50 CHECK(parsed_value->GetAsList(&parsed_list)); |
| 50 | 51 |
| 51 WebRequestActionSet::Values actions; | 52 WebRequestActionSet::Values actions; |
| 52 for (base::ListValue::const_iterator it = parsed_list->begin(); | 53 for (base::ListValue::const_iterator it = parsed_list->begin(); |
| 53 it != parsed_list->end(); | 54 it != parsed_list->end(); |
| 54 ++it) { | 55 ++it) { |
| 55 const base::DictionaryValue* dict; | 56 const base::DictionaryValue* dict; |
| 56 CHECK((*it)->GetAsDictionary(&dict)); | 57 CHECK((*it)->GetAsDictionary(&dict)); |
| 57 actions.push_back(dict->CreateDeepCopy()); | 58 actions.push_back(dict->CreateDeepCopy()); |
| 58 } | 59 } |
| 59 | 60 |
| 60 std::string error; | 61 std::string error; |
| 61 bool bad_message = false; | 62 bool bad_message = false; |
| 62 | 63 |
| 63 scoped_ptr<WebRequestActionSet> action_set( | 64 std::unique_ptr<WebRequestActionSet> action_set( |
| 64 WebRequestActionSet::Create(NULL, NULL, actions, &error, &bad_message)); | 65 WebRequestActionSet::Create(NULL, NULL, actions, &error, &bad_message)); |
| 65 EXPECT_EQ("", error); | 66 EXPECT_EQ("", error); |
| 66 EXPECT_FALSE(bad_message); | 67 EXPECT_FALSE(bad_message); |
| 67 CHECK(action_set); | 68 CHECK(action_set); |
| 68 return action_set; | 69 return action_set; |
| 69 } | 70 } |
| 70 | 71 |
| 71 } // namespace | 72 } // namespace |
| 72 | 73 |
| 73 namespace keys = declarative_webrequest_constants; | 74 namespace keys = declarative_webrequest_constants; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 base::Time::Now(), | 138 base::Time::Now(), |
| 138 false /*incognito_enabled*/, | 139 false /*incognito_enabled*/, |
| 139 false /*notifications_disabled*/); | 140 false /*notifications_disabled*/); |
| 140 } | 141 } |
| 141 | 142 |
| 142 bool WebRequestActionWithThreadsTest::ActionWorksOnRequest( | 143 bool WebRequestActionWithThreadsTest::ActionWorksOnRequest( |
| 143 const char* url_string, | 144 const char* url_string, |
| 144 const std::string& extension_id, | 145 const std::string& extension_id, |
| 145 const WebRequestActionSet* action_set, | 146 const WebRequestActionSet* action_set, |
| 146 RequestStage stage) { | 147 RequestStage stage) { |
| 147 scoped_ptr<net::URLRequest> regular_request(context_.CreateRequest( | 148 std::unique_ptr<net::URLRequest> regular_request( |
| 148 GURL(url_string), net::DEFAULT_PRIORITY, NULL)); | 149 context_.CreateRequest(GURL(url_string), net::DEFAULT_PRIORITY, NULL)); |
| 149 std::list<LinkedPtrEventResponseDelta> deltas; | 150 std::list<LinkedPtrEventResponseDelta> deltas; |
| 150 scoped_refptr<net::HttpResponseHeaders> headers( | 151 scoped_refptr<net::HttpResponseHeaders> headers( |
| 151 new net::HttpResponseHeaders("")); | 152 new net::HttpResponseHeaders("")); |
| 152 WebRequestData request_data(regular_request.get(), stage, headers.get()); | 153 WebRequestData request_data(regular_request.get(), stage, headers.get()); |
| 153 std::set<std::string> ignored_tags; | 154 std::set<std::string> ignored_tags; |
| 154 WebRequestAction::ApplyInfo apply_info = { extension_info_map_.get(), | 155 WebRequestAction::ApplyInfo apply_info = { extension_info_map_.get(), |
| 155 request_data, | 156 request_data, |
| 156 false /*crosses_incognito*/, | 157 false /*crosses_incognito*/, |
| 157 &deltas, &ignored_tags }; | 158 &deltas, &ignored_tags }; |
| 158 action_set->Apply(extension_id, base::Time(), &apply_info); | 159 action_set->Apply(extension_id, base::Time(), &apply_info); |
| 159 return (1u == deltas.size() || 0u < ignored_tags.size()); | 160 return (1u == deltas.size() || 0u < ignored_tags.size()); |
| 160 } | 161 } |
| 161 | 162 |
| 162 void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls( | 163 void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls( |
| 163 const char* action, | 164 const char* action, |
| 164 RequestStage stage) { | 165 RequestStage stage) { |
| 165 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action)); | 166 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action)); |
| 166 | 167 |
| 167 // Although |extension_| has matching *.com host permission, |action| | 168 // Although |extension_| has matching *.com host permission, |action| |
| 168 // is intentionally forbidden -- in Declarative WR, host permission | 169 // is intentionally forbidden -- in Declarative WR, host permission |
| 169 // for less than all URLs are ignored (except in SendMessageToExtension). | 170 // for less than all URLs are ignored (except in SendMessageToExtension). |
| 170 EXPECT_FALSE(ActionWorksOnRequest( | 171 EXPECT_FALSE(ActionWorksOnRequest( |
| 171 "http://test.com", extension_->id(), action_set.get(), stage)); | 172 "http://test.com", extension_->id(), action_set.get(), stage)); |
| 172 // With the "<all_urls>" host permission they are allowed. | 173 // With the "<all_urls>" host permission they are allowed. |
| 173 EXPECT_TRUE(ActionWorksOnRequest( | 174 EXPECT_TRUE(ActionWorksOnRequest( |
| 174 "http://test.com", extension_all_urls_->id(), action_set.get(), stage)); | 175 "http://test.com", extension_all_urls_->id(), action_set.get(), stage)); |
| 175 | 176 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 result = WebRequestAction::Create(NULL, NULL, input, &error, &bad_message); | 216 result = WebRequestAction::Create(NULL, NULL, input, &error, &bad_message); |
| 216 EXPECT_EQ("", error); | 217 EXPECT_EQ("", error); |
| 217 EXPECT_FALSE(bad_message); | 218 EXPECT_FALSE(bad_message); |
| 218 ASSERT_TRUE(result.get()); | 219 ASSERT_TRUE(result.get()); |
| 219 EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, result->type()); | 220 EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, result->type()); |
| 220 } | 221 } |
| 221 | 222 |
| 222 TEST(WebRequestActionTest, CreateActionSet) { | 223 TEST(WebRequestActionTest, CreateActionSet) { |
| 223 std::string error; | 224 std::string error; |
| 224 bool bad_message = false; | 225 bool bad_message = false; |
| 225 scoped_ptr<WebRequestActionSet> result; | 226 std::unique_ptr<WebRequestActionSet> result; |
| 226 | 227 |
| 227 WebRequestActionSet::Values input; | 228 WebRequestActionSet::Values input; |
| 228 | 229 |
| 229 // Test empty input. | 230 // Test empty input. |
| 230 error.clear(); | 231 error.clear(); |
| 231 result = WebRequestActionSet::Create(NULL, NULL, input, &error, &bad_message); | 232 result = WebRequestActionSet::Create(NULL, NULL, input, &error, &bad_message); |
| 232 EXPECT_TRUE(error.empty()) << error; | 233 EXPECT_TRUE(error.empty()) << error; |
| 233 EXPECT_FALSE(bad_message); | 234 EXPECT_FALSE(bad_message); |
| 234 ASSERT_TRUE(result.get()); | 235 ASSERT_TRUE(result.get()); |
| 235 EXPECT_TRUE(result->actions().empty()); | 236 EXPECT_TRUE(result->actions().empty()); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 "}]"; | 335 "}]"; |
| 335 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED); | 336 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED); |
| 336 } | 337 } |
| 337 | 338 |
| 338 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) { | 339 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) { |
| 339 const char kAction[] = | 340 const char kAction[] = |
| 340 "[{" | 341 "[{" |
| 341 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\"," | 342 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\"," |
| 342 " \"message\": \"testtext\"" | 343 " \"message\": \"testtext\"" |
| 343 "}]"; | 344 "}]"; |
| 344 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); | 345 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); |
| 345 | 346 |
| 346 // For sending messages, specific host permissions actually matter. | 347 // For sending messages, specific host permissions actually matter. |
| 347 EXPECT_TRUE(ActionWorksOnRequest("http://test.com", | 348 EXPECT_TRUE(ActionWorksOnRequest("http://test.com", |
| 348 extension_->id(), | 349 extension_->id(), |
| 349 action_set.get(), | 350 action_set.get(), |
| 350 ON_BEFORE_REQUEST)); | 351 ON_BEFORE_REQUEST)); |
| 351 // With the "<all_urls>" host permission they are allowed. | 352 // With the "<all_urls>" host permission they are allowed. |
| 352 EXPECT_TRUE(ActionWorksOnRequest("http://test.com", | 353 EXPECT_TRUE(ActionWorksOnRequest("http://test.com", |
| 353 extension_all_urls_->id(), | 354 extension_all_urls_->id(), |
| 354 action_set.get(), | 355 action_set.get(), |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }" | 420 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }" |
| 420 "}]"; | 421 "}]"; |
| 421 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED); | 422 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED); |
| 422 } | 423 } |
| 423 | 424 |
| 424 TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) { | 425 TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) { |
| 425 const char kAction[] = | 426 const char kAction[] = |
| 426 "[{" | 427 "[{" |
| 427 " \"instanceType\": \"declarativeWebRequest.CancelRequest\"" | 428 " \"instanceType\": \"declarativeWebRequest.CancelRequest\"" |
| 428 "}]"; | 429 "}]"; |
| 429 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); | 430 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); |
| 430 | 431 |
| 431 // Cancelling requests works without full host permissions. | 432 // Cancelling requests works without full host permissions. |
| 432 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 433 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 433 extension_->id(), | 434 extension_->id(), |
| 434 action_set.get(), | 435 action_set.get(), |
| 435 ON_BEFORE_REQUEST)); | 436 ON_BEFORE_REQUEST)); |
| 436 } | 437 } |
| 437 | 438 |
| 438 TEST_F(WebRequestActionWithThreadsTest, | 439 TEST_F(WebRequestActionWithThreadsTest, |
| 439 PermissionsToRedirectToTransparentImage) { | 440 PermissionsToRedirectToTransparentImage) { |
| 440 const char kAction[] = | 441 const char kAction[] = |
| 441 "[{" | 442 "[{" |
| 442 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\"" | 443 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\"" |
| 443 "}]"; | 444 "}]"; |
| 444 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); | 445 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); |
| 445 | 446 |
| 446 // Redirecting to transparent images works without full host permissions. | 447 // Redirecting to transparent images works without full host permissions. |
| 447 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 448 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 448 extension_->id(), | 449 extension_->id(), |
| 449 action_set.get(), | 450 action_set.get(), |
| 450 ON_BEFORE_REQUEST)); | 451 ON_BEFORE_REQUEST)); |
| 451 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 452 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 452 extension_->id(), | 453 extension_->id(), |
| 453 action_set.get(), | 454 action_set.get(), |
| 454 ON_HEADERS_RECEIVED)); | 455 ON_HEADERS_RECEIVED)); |
| 455 } | 456 } |
| 456 | 457 |
| 457 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) { | 458 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) { |
| 458 const char kAction[] = | 459 const char kAction[] = |
| 459 "[{" | 460 "[{" |
| 460 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\"" | 461 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\"" |
| 461 "}]"; | 462 "}]"; |
| 462 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); | 463 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); |
| 463 | 464 |
| 464 // Redirecting to the empty document works without full host permissions. | 465 // Redirecting to the empty document works without full host permissions. |
| 465 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 466 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 466 extension_->id(), | 467 extension_->id(), |
| 467 action_set.get(), | 468 action_set.get(), |
| 468 ON_BEFORE_REQUEST)); | 469 ON_BEFORE_REQUEST)); |
| 469 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 470 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 470 extension_->id(), | 471 extension_->id(), |
| 471 action_set.get(), | 472 action_set.get(), |
| 472 ON_HEADERS_RECEIVED)); | 473 ON_HEADERS_RECEIVED)); |
| 473 } | 474 } |
| 474 | 475 |
| 475 TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) { | 476 TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) { |
| 476 const char kAction[] = | 477 const char kAction[] = |
| 477 "[{" | 478 "[{" |
| 478 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\"," | 479 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\"," |
| 479 " \"lowerPriorityThan\": 123," | 480 " \"lowerPriorityThan\": 123," |
| 480 " \"hasTag\": \"some_tag\"" | 481 " \"hasTag\": \"some_tag\"" |
| 481 "}]"; | 482 "}]"; |
| 482 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); | 483 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction)); |
| 483 | 484 |
| 484 // Ignoring rules works without full host permissions. | 485 // Ignoring rules works without full host permissions. |
| 485 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", | 486 EXPECT_TRUE(ActionWorksOnRequest("http://test.org", |
| 486 extension_->id(), | 487 extension_->id(), |
| 487 action_set.get(), | 488 action_set.get(), |
| 488 ON_BEFORE_REQUEST)); | 489 ON_BEFORE_REQUEST)); |
| 489 } | 490 } |
| 490 | 491 |
| 491 TEST(WebRequestActionTest, GetName) { | 492 TEST(WebRequestActionTest, GetName) { |
| 492 const char kActions[] = | 493 const char kActions[] = |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 "declarativeWebRequest.AddResponseCookie", | 574 "declarativeWebRequest.AddResponseCookie", |
| 574 "declarativeWebRequest.EditRequestCookie", | 575 "declarativeWebRequest.EditRequestCookie", |
| 575 "declarativeWebRequest.EditResponseCookie", | 576 "declarativeWebRequest.EditResponseCookie", |
| 576 "declarativeWebRequest.RemoveRequestCookie", | 577 "declarativeWebRequest.RemoveRequestCookie", |
| 577 "declarativeWebRequest.RemoveResponseCookie", | 578 "declarativeWebRequest.RemoveResponseCookie", |
| 578 "declarativeWebRequest.CancelRequest", | 579 "declarativeWebRequest.CancelRequest", |
| 579 "declarativeWebRequest.RedirectToTransparentImage", | 580 "declarativeWebRequest.RedirectToTransparentImage", |
| 580 "declarativeWebRequest.RedirectToEmptyDocument", | 581 "declarativeWebRequest.RedirectToEmptyDocument", |
| 581 "declarativeWebRequest.IgnoreRules", | 582 "declarativeWebRequest.IgnoreRules", |
| 582 }; | 583 }; |
| 583 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions)); | 584 std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions)); |
| 584 ASSERT_EQ(arraysize(kExpectedNames), action_set->actions().size()); | 585 ASSERT_EQ(arraysize(kExpectedNames), action_set->actions().size()); |
| 585 size_t index = 0; | 586 size_t index = 0; |
| 586 for (WebRequestActionSet::Actions::const_iterator it = | 587 for (WebRequestActionSet::Actions::const_iterator it = |
| 587 action_set->actions().begin(); | 588 action_set->actions().begin(); |
| 588 it != action_set->actions().end(); | 589 it != action_set->actions().end(); |
| 589 ++it) { | 590 ++it) { |
| 590 EXPECT_EQ(kExpectedNames[index], (*it)->GetName()); | 591 EXPECT_EQ(kExpectedNames[index], (*it)->GetName()); |
| 591 ++index; | 592 ++index; |
| 592 } | 593 } |
| 593 } | 594 } |
| 594 | 595 |
| 595 } // namespace extensions | 596 } // namespace extensions |
| OLD | NEW |