blob: e9090311461c80e0b56b3439fd2f114260f153da [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]702d8b42013-02-27 20:55:5012#include "chrome/common/extensions/api/icons/icons_handler.h"
13#include "chrome/common/extensions/extension_manifest_constants.h"
14#include "chrome/common/extensions/manifest_handler.h"
[email protected]93ac047a2012-12-13 02:53:4915#include "chrome/common/chrome_paths.h"
[email protected]06492ed2013-03-24 22:13:1416#include "chrome/common/extensions/extension.h"
17#include "chrome/common/extensions/extension_manifest_constants.h"
18#include "chrome/common/extensions/incognito_handler.h"
19#include "chrome/common/extensions/manifest_handler.h"
[email protected]5e212ed2012-03-21 23:29:1520#include "chrome/common/url_constants.h"
21#include "content/public/browser/resource_request_info.h"
[email protected]08a932d52012-06-03 21:42:1222#include "content/public/test/mock_resource_context.h"
[email protected]e97882f2012-06-04 02:23:1723#include "content/public/test/test_browser_thread.h"
[email protected]885c0e92012-11-13 20:27:4224#include "extensions/common/constants.h"
[email protected]5e212ed2012-03-21 23:29:1525#include "net/url_request/url_request.h"
[email protected]9d5730b2012-08-24 17:42:4926#include "net/url_request/url_request_job_factory_impl.h"
[email protected]5e212ed2012-03-21 23:29:1527#include "net/url_request/url_request_status.h"
28#include "net/url_request/url_request_test_util.h"
29#include "testing/gtest/include/gtest/gtest.h"
30
31using content::BrowserThread;
[email protected]5e212ed2012-03-21 23:29:1532
[email protected]702d8b42013-02-27 20:55:5033namespace extensions {
[email protected]5e212ed2012-03-21 23:29:1534
35scoped_refptr<Extension> CreateTestExtension(const std::string& name,
36 bool incognito_split_mode) {
37 DictionaryValue manifest;
38 manifest.SetString("name", name);
39 manifest.SetString("version", "1");
40 manifest.SetString("incognito", incognito_split_mode ? "split" : "spanning");
41
[email protected]650b2d52013-02-10 03:41:4542 base::FilePath path;
[email protected]5e212ed2012-03-21 23:29:1543 EXPECT_TRUE(file_util::GetCurrentDirectory(&path));
44
45 std::string error;
46 scoped_refptr<Extension> extension(
[email protected]1d5e58b2013-01-31 08:41:4047 Extension::Create(path, Manifest::INTERNAL, manifest,
[email protected]ed3b9b12012-05-31 18:37:5148 Extension::NO_FLAGS, &error));
[email protected]5e212ed2012-03-21 23:29:1549 EXPECT_TRUE(extension.get()) << error;
50 return extension;
51}
52
[email protected]93ac047a2012-12-13 02:53:4953scoped_refptr<Extension> CreateWebStoreExtension() {
54 DictionaryValue manifest;
55 manifest.SetString("name", "WebStore");
56 manifest.SetString("version", "1");
57 manifest.SetString("icons.16", "webstore_icon_16.png");
58
[email protected]650b2d52013-02-10 03:41:4559 base::FilePath path;
[email protected]93ac047a2012-12-13 02:53:4960 EXPECT_TRUE(PathService::Get(chrome::DIR_RESOURCES, &path));
61 path = path.AppendASCII("web_store");
62
63 std::string error;
64 scoped_refptr<Extension> extension(
[email protected]1d5e58b2013-01-31 08:41:4065 Extension::Create(path, Manifest::COMPONENT, manifest,
[email protected]93ac047a2012-12-13 02:53:4966 Extension::NO_FLAGS, &error));
67 EXPECT_TRUE(extension.get()) << error;
68 return extension;
69}
70
[email protected]5e212ed2012-03-21 23:29:1571class ExtensionProtocolTest : public testing::Test {
72 public:
73 ExtensionProtocolTest()
74 : ui_thread_(BrowserThread::UI, &message_loop_),
75 file_thread_(BrowserThread::FILE, &message_loop_),
76 io_thread_(BrowserThread::IO, &message_loop_) {}
77
[email protected]06492ed2013-03-24 22:13:1478 virtual void SetUp() OVERRIDE {
79 testing::Test::SetUp();
[email protected]5e212ed2012-03-21 23:29:1580 extension_info_map_ = new ExtensionInfoMap();
81 net::URLRequestContext* request_context =
82 resource_context_.GetRequestContext();
83 old_factory_ = request_context->job_factory();
[email protected]06492ed2013-03-24 22:13:1484 (new IncognitoHandler)->Register();
[email protected]9367eabc2013-03-01 01:29:2985 (new IconsHandler)->Register();
[email protected]5e212ed2012-03-21 23:29:1586 }
87
88 virtual void TearDown() {
89 net::URLRequestContext* request_context =
90 resource_context_.GetRequestContext();
91 request_context->set_job_factory(old_factory_);
[email protected]9367eabc2013-03-01 01:29:2992 ManifestHandler::ClearRegistryForTesting();
[email protected]5e212ed2012-03-21 23:29:1593 }
94
[email protected]93ac047a2012-12-13 02:53:4995 void SetProtocolHandler(bool incognito) {
96 net::URLRequestContext* request_context =
97 resource_context_.GetRequestContext();
98 job_factory_.SetProtocolHandler(
[email protected]702d8b42013-02-27 20:55:5099 kExtensionScheme,
[email protected]93ac047a2012-12-13 02:53:49100 CreateExtensionProtocolHandler(incognito, extension_info_map_));
101 request_context->set_job_factory(&job_factory_);
102 }
103
[email protected]5e212ed2012-03-21 23:29:15104 void StartRequest(net::URLRequest* request,
105 ResourceType::Type resource_type) {
106 content::ResourceRequestInfo::AllocateForTesting(request,
107 resource_type,
[email protected]ef108e72012-06-20 14:03:54108 &resource_context_,
109 -1,
110 -1);
[email protected]5e212ed2012-03-21 23:29:15111 request->Start();
112 MessageLoop::current()->Run();
113 }
114
115 protected:
116 MessageLoopForIO message_loop_;
117 content::TestBrowserThread ui_thread_;
118 content::TestBrowserThread file_thread_;
119 content::TestBrowserThread io_thread_;
120 scoped_refptr<ExtensionInfoMap> extension_info_map_;
[email protected]9d5730b2012-08-24 17:42:49121 net::URLRequestJobFactoryImpl job_factory_;
[email protected]5e212ed2012-03-21 23:29:15122 const net::URLRequestJobFactory* old_factory_;
[email protected]2086a3d2012-11-13 17:49:20123 net::TestDelegate test_delegate_;
[email protected]5e212ed2012-03-21 23:29:15124 content::MockResourceContext resource_context_;
125};
126
127// Tests that making a chrome-extension request in an incognito context is
128// only allowed under the right circumstances (if the extension is allowed
129// in incognito, and it's either a non-main-frame request or a split-mode
130// extension).
131TEST_F(ExtensionProtocolTest, IncognitoRequest) {
[email protected]93ac047a2012-12-13 02:53:49132 // Register an incognito extension protocol handler.
133 SetProtocolHandler(true);
134
[email protected]5e212ed2012-03-21 23:29:15135 struct TestCase {
136 // Inputs.
137 std::string name;
138 bool incognito_split_mode;
139 bool incognito_enabled;
140
141 // Expected results.
142 bool should_allow_main_frame_load;
143 bool should_allow_sub_frame_load;
144 } cases[] = {
145 {"spanning disabled", false, false, false, false},
146 {"split disabled", true, false, false, false},
147 {"spanning enabled", false, true, false, true},
148 {"split enabled", true, true, true, true},
149 };
150
151 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
152 scoped_refptr<Extension> extension =
153 CreateTestExtension(cases[i].name, cases[i].incognito_split_mode);
154 extension_info_map_->AddExtension(
155 extension, base::Time::Now(), cases[i].incognito_enabled);
156
157 // First test a main frame request.
158 {
159 // It doesn't matter that the resource doesn't exist. If the resource
160 // is blocked, we should see ADDRESS_UNREACHABLE. Otherwise, the request
161 // should just fail because the file doesn't exist.
162 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13163 &test_delegate_,
164 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15165 StartRequest(&request, ResourceType::MAIN_FRAME);
166 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
167
168 if (cases[i].should_allow_main_frame_load) {
169 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
170 cases[i].name;
171 } else {
172 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
173 cases[i].name;
174 }
175 }
176
177 // Now do a subframe request.
178 {
179 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13180 &test_delegate_,
181 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15182 StartRequest(&request, ResourceType::SUB_FRAME);
183 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
184
185 if (cases[i].should_allow_sub_frame_load) {
186 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
187 cases[i].name;
188 } else {
189 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
190 cases[i].name;
191 }
192 }
193 }
194}
195
[email protected]93ac047a2012-12-13 02:53:49196// Tests getting a resource for a component extension works correctly, both when
197// the extension is enabled and when it is disabled.
198TEST_F(ExtensionProtocolTest, ComponentResourceRequest) {
199 // Register a non-incognito extension protocol handler.
200 SetProtocolHandler(false);
201
202 scoped_refptr<Extension> extension = CreateWebStoreExtension();
203 extension_info_map_->AddExtension(
204 extension, base::Time::Now(), false);
205
206 // First test it with the extension enabled.
207 {
208 net::URLRequest request(extension->GetResourceURL("webstore_icon_16.png"),
209 &test_delegate_,
210 resource_context_.GetRequestContext());
211 StartRequest(&request, ResourceType::MEDIA);
212 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request.status().status());
213 }
214
215 // And then test it with the extension disabled.
216 extension_info_map_->RemoveExtension(extension->id(),
217 extension_misc::UNLOAD_REASON_DISABLE);
218 {
219 net::URLRequest request(extension->GetResourceURL("webstore_icon_16.png"),
220 &test_delegate_,
221 resource_context_.GetRequestContext());
222 StartRequest(&request, ResourceType::MEDIA);
223 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request.status().status());
224 }
225}
226
[email protected]702d8b42013-02-27 20:55:50227} // namespace extensions