blob: 9f70a06fa08e77ae36b2f3cc8ec3db5356984624 [file] [log] [blame]
[email protected]5e212ed2012-03-21 23:29:151// 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#include <string>
6
7#include "base/file_util.h"
8#include "base/message_loop.h"
[email protected]06492ed2013-03-24 22:13:149#include "base/values.h"
[email protected]5e212ed2012-03-21 23:29:1510#include "chrome/browser/extensions/extension_info_map.h"
11#include "chrome/browser/extensions/extension_protocols.h"
[email protected]93ac047a2012-12-13 02:53:4912#include "chrome/common/chrome_paths.h"
[email protected]06492ed2013-03-24 22:13:1413#include "chrome/common/extensions/extension.h"
14#include "chrome/common/extensions/extension_manifest_constants.h"
[email protected]5e212ed2012-03-21 23:29:1515#include "chrome/common/url_constants.h"
16#include "content/public/browser/resource_request_info.h"
[email protected]08a932d52012-06-03 21:42:1217#include "content/public/test/mock_resource_context.h"
[email protected]e97882f2012-06-04 02:23:1718#include "content/public/test/test_browser_thread.h"
[email protected]885c0e92012-11-13 20:27:4219#include "extensions/common/constants.h"
[email protected]5e212ed2012-03-21 23:29:1520#include "net/url_request/url_request.h"
[email protected]9d5730b2012-08-24 17:42:4921#include "net/url_request/url_request_job_factory_impl.h"
[email protected]5e212ed2012-03-21 23:29:1522#include "net/url_request/url_request_status.h"
23#include "net/url_request/url_request_test_util.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
26using content::BrowserThread;
[email protected]5e212ed2012-03-21 23:29:1527
[email protected]702d8b42013-02-27 20:55:5028namespace extensions {
[email protected]5e212ed2012-03-21 23:29:1529
30scoped_refptr<Extension> CreateTestExtension(const std::string& name,
31 bool incognito_split_mode) {
32 DictionaryValue manifest;
33 manifest.SetString("name", name);
34 manifest.SetString("version", "1");
35 manifest.SetString("incognito", incognito_split_mode ? "split" : "spanning");
36
[email protected]650b2d52013-02-10 03:41:4537 base::FilePath path;
[email protected]5e212ed2012-03-21 23:29:1538 EXPECT_TRUE(file_util::GetCurrentDirectory(&path));
39
40 std::string error;
41 scoped_refptr<Extension> extension(
[email protected]1d5e58b2013-01-31 08:41:4042 Extension::Create(path, Manifest::INTERNAL, manifest,
[email protected]ed3b9b12012-05-31 18:37:5143 Extension::NO_FLAGS, &error));
[email protected]5e212ed2012-03-21 23:29:1544 EXPECT_TRUE(extension.get()) << error;
45 return extension;
46}
47
[email protected]93ac047a2012-12-13 02:53:4948scoped_refptr<Extension> CreateWebStoreExtension() {
49 DictionaryValue manifest;
50 manifest.SetString("name", "WebStore");
51 manifest.SetString("version", "1");
52 manifest.SetString("icons.16", "webstore_icon_16.png");
53
[email protected]650b2d52013-02-10 03:41:4554 base::FilePath path;
[email protected]93ac047a2012-12-13 02:53:4955 EXPECT_TRUE(PathService::Get(chrome::DIR_RESOURCES, &path));
56 path = path.AppendASCII("web_store");
57
58 std::string error;
59 scoped_refptr<Extension> extension(
[email protected]1d5e58b2013-01-31 08:41:4060 Extension::Create(path, Manifest::COMPONENT, manifest,
[email protected]93ac047a2012-12-13 02:53:4961 Extension::NO_FLAGS, &error));
62 EXPECT_TRUE(extension.get()) << error;
63 return extension;
64}
65
[email protected]5e212ed2012-03-21 23:29:1566class ExtensionProtocolTest : public testing::Test {
67 public:
68 ExtensionProtocolTest()
69 : ui_thread_(BrowserThread::UI, &message_loop_),
70 file_thread_(BrowserThread::FILE, &message_loop_),
71 io_thread_(BrowserThread::IO, &message_loop_) {}
72
[email protected]06492ed2013-03-24 22:13:1473 virtual void SetUp() OVERRIDE {
74 testing::Test::SetUp();
[email protected]5e212ed2012-03-21 23:29:1575 extension_info_map_ = new ExtensionInfoMap();
76 net::URLRequestContext* request_context =
77 resource_context_.GetRequestContext();
78 old_factory_ = request_context->job_factory();
[email protected]5e212ed2012-03-21 23:29:1579 }
80
81 virtual void TearDown() {
82 net::URLRequestContext* request_context =
83 resource_context_.GetRequestContext();
84 request_context->set_job_factory(old_factory_);
[email protected]5e212ed2012-03-21 23:29:1585 }
86
[email protected]93ac047a2012-12-13 02:53:4987 void SetProtocolHandler(bool incognito) {
88 net::URLRequestContext* request_context =
89 resource_context_.GetRequestContext();
90 job_factory_.SetProtocolHandler(
[email protected]702d8b42013-02-27 20:55:5091 kExtensionScheme,
[email protected]dc24976f2013-06-02 21:15:0992 CreateExtensionProtocolHandler(incognito, extension_info_map_.get()));
[email protected]93ac047a2012-12-13 02:53:4993 request_context->set_job_factory(&job_factory_);
94 }
95
[email protected]5e212ed2012-03-21 23:29:1596 void StartRequest(net::URLRequest* request,
97 ResourceType::Type resource_type) {
98 content::ResourceRequestInfo::AllocateForTesting(request,
99 resource_type,
[email protected]ef108e72012-06-20 14:03:54100 &resource_context_,
101 -1,
102 -1);
[email protected]5e212ed2012-03-21 23:29:15103 request->Start();
[email protected]b3a25092013-05-28 22:08:16104 base::MessageLoop::current()->Run();
[email protected]5e212ed2012-03-21 23:29:15105 }
106
107 protected:
[email protected]b3a25092013-05-28 22:08:16108 base::MessageLoopForIO message_loop_;
[email protected]5e212ed2012-03-21 23:29:15109 content::TestBrowserThread ui_thread_;
110 content::TestBrowserThread file_thread_;
111 content::TestBrowserThread io_thread_;
112 scoped_refptr<ExtensionInfoMap> extension_info_map_;
[email protected]9d5730b2012-08-24 17:42:49113 net::URLRequestJobFactoryImpl job_factory_;
[email protected]5e212ed2012-03-21 23:29:15114 const net::URLRequestJobFactory* old_factory_;
[email protected]2086a3d2012-11-13 17:49:20115 net::TestDelegate test_delegate_;
[email protected]5e212ed2012-03-21 23:29:15116 content::MockResourceContext resource_context_;
117};
118
119// Tests that making a chrome-extension request in an incognito context is
120// only allowed under the right circumstances (if the extension is allowed
121// in incognito, and it's either a non-main-frame request or a split-mode
122// extension).
123TEST_F(ExtensionProtocolTest, IncognitoRequest) {
[email protected]93ac047a2012-12-13 02:53:49124 // Register an incognito extension protocol handler.
125 SetProtocolHandler(true);
126
[email protected]5e212ed2012-03-21 23:29:15127 struct TestCase {
128 // Inputs.
129 std::string name;
130 bool incognito_split_mode;
131 bool incognito_enabled;
132
133 // Expected results.
134 bool should_allow_main_frame_load;
135 bool should_allow_sub_frame_load;
136 } cases[] = {
137 {"spanning disabled", false, false, false, false},
138 {"split disabled", true, false, false, false},
139 {"spanning enabled", false, true, false, true},
140 {"split enabled", true, true, true, true},
141 };
142
143 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
144 scoped_refptr<Extension> extension =
145 CreateTestExtension(cases[i].name, cases[i].incognito_split_mode);
146 extension_info_map_->AddExtension(
[email protected]dc24976f2013-06-02 21:15:09147 extension.get(), base::Time::Now(), cases[i].incognito_enabled);
[email protected]5e212ed2012-03-21 23:29:15148
149 // First test a main frame request.
150 {
151 // It doesn't matter that the resource doesn't exist. If the resource
152 // is blocked, we should see ADDRESS_UNREACHABLE. Otherwise, the request
153 // should just fail because the file doesn't exist.
154 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13155 &test_delegate_,
156 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15157 StartRequest(&request, ResourceType::MAIN_FRAME);
158 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
159
160 if (cases[i].should_allow_main_frame_load) {
161 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
162 cases[i].name;
163 } else {
164 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
165 cases[i].name;
166 }
167 }
168
169 // Now do a subframe request.
170 {
171 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13172 &test_delegate_,
173 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15174 StartRequest(&request, ResourceType::SUB_FRAME);
175 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
176
177 if (cases[i].should_allow_sub_frame_load) {
178 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
179 cases[i].name;
180 } else {
181 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
182 cases[i].name;
183 }
184 }
185 }
186}
187
[email protected]93ac047a2012-12-13 02:53:49188// Tests getting a resource for a component extension works correctly, both when
189// the extension is enabled and when it is disabled.
190TEST_F(ExtensionProtocolTest, ComponentResourceRequest) {
191 // Register a non-incognito extension protocol handler.
192 SetProtocolHandler(false);
193
194 scoped_refptr<Extension> extension = CreateWebStoreExtension();
[email protected]dc24976f2013-06-02 21:15:09195 extension_info_map_->AddExtension(extension.get(), base::Time::Now(), false);
[email protected]93ac047a2012-12-13 02:53:49196
197 // First test it with the extension enabled.
198 {
199 net::URLRequest request(extension->GetResourceURL("webstore_icon_16.png"),
200 &test_delegate_,
201 resource_context_.GetRequestContext());
202 StartRequest(&request, ResourceType::MEDIA);
203 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request.status().status());
204 }
205
206 // And then test it with the extension disabled.
207 extension_info_map_->RemoveExtension(extension->id(),
208 extension_misc::UNLOAD_REASON_DISABLE);
209 {
210 net::URLRequest request(extension->GetResourceURL("webstore_icon_16.png"),
211 &test_delegate_,
212 resource_context_.GetRequestContext());
213 StartRequest(&request, ResourceType::MEDIA);
214 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request.status().status());
215 }
216}
217
[email protected]702d8b42013-02-27 20:55:50218} // namespace extensions