blob: c0e78373a2e8c7ecb715ac59cc5396ec357a5050 [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"
9#include "chrome/browser/extensions/extension_info_map.h"
10#include "chrome/browser/extensions/extension_protocols.h"
11#include "chrome/common/url_constants.h"
12#include "content/public/browser/resource_request_info.h"
[email protected]08a932d52012-06-03 21:42:1213#include "content/public/test/mock_resource_context.h"
[email protected]e97882f2012-06-04 02:23:1714#include "content/public/test/test_browser_thread.h"
[email protected]5e212ed2012-03-21 23:29:1515#include "net/url_request/url_request.h"
[email protected]9d5730b2012-08-24 17:42:4916#include "net/url_request/url_request_job_factory_impl.h"
[email protected]5e212ed2012-03-21 23:29:1517#include "net/url_request/url_request_status.h"
18#include "net/url_request/url_request_test_util.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21using content::BrowserThread;
[email protected]1c321ee52012-05-21 03:02:3422using extensions::Extension;
[email protected]5e212ed2012-03-21 23:29:1523
24namespace {
25
26scoped_refptr<Extension> CreateTestExtension(const std::string& name,
27 bool incognito_split_mode) {
28 DictionaryValue manifest;
29 manifest.SetString("name", name);
30 manifest.SetString("version", "1");
31 manifest.SetString("incognito", incognito_split_mode ? "split" : "spanning");
32
33 FilePath path;
34 EXPECT_TRUE(file_util::GetCurrentDirectory(&path));
35
36 std::string error;
37 scoped_refptr<Extension> extension(
38 Extension::Create(path, Extension::INTERNAL, manifest,
[email protected]ed3b9b12012-05-31 18:37:5139 Extension::NO_FLAGS, &error));
[email protected]5e212ed2012-03-21 23:29:1540 EXPECT_TRUE(extension.get()) << error;
41 return extension;
42}
43
44class ExtensionProtocolTest : public testing::Test {
45 public:
46 ExtensionProtocolTest()
47 : ui_thread_(BrowserThread::UI, &message_loop_),
48 file_thread_(BrowserThread::FILE, &message_loop_),
49 io_thread_(BrowserThread::IO, &message_loop_) {}
50
51 virtual void SetUp() {
52 extension_info_map_ = new ExtensionInfoMap();
53 net::URLRequestContext* request_context =
54 resource_context_.GetRequestContext();
55 old_factory_ = request_context->job_factory();
56 // Register an incognito extension protocol handler.
57 job_factory_.SetProtocolHandler(
58 chrome::kExtensionScheme,
59 CreateExtensionProtocolHandler(true, extension_info_map_));
60 request_context->set_job_factory(&job_factory_);
61 }
62
63 virtual void TearDown() {
64 net::URLRequestContext* request_context =
65 resource_context_.GetRequestContext();
66 request_context->set_job_factory(old_factory_);
67 }
68
69 void StartRequest(net::URLRequest* request,
70 ResourceType::Type resource_type) {
71 content::ResourceRequestInfo::AllocateForTesting(request,
72 resource_type,
[email protected]ef108e72012-06-20 14:03:5473 &resource_context_,
74 -1,
75 -1);
[email protected]5e212ed2012-03-21 23:29:1576 request->Start();
77 MessageLoop::current()->Run();
78 }
79
80 protected:
81 MessageLoopForIO message_loop_;
82 content::TestBrowserThread ui_thread_;
83 content::TestBrowserThread file_thread_;
84 content::TestBrowserThread io_thread_;
85 scoped_refptr<ExtensionInfoMap> extension_info_map_;
[email protected]9d5730b2012-08-24 17:42:4986 net::URLRequestJobFactoryImpl job_factory_;
[email protected]5e212ed2012-03-21 23:29:1587 const net::URLRequestJobFactory* old_factory_;
[email protected]2086a3d2012-11-13 17:49:2088 net::TestDelegate test_delegate_;
[email protected]5e212ed2012-03-21 23:29:1589 content::MockResourceContext resource_context_;
90};
91
92// Tests that making a chrome-extension request in an incognito context is
93// only allowed under the right circumstances (if the extension is allowed
94// in incognito, and it's either a non-main-frame request or a split-mode
95// extension).
96TEST_F(ExtensionProtocolTest, IncognitoRequest) {
97 struct TestCase {
98 // Inputs.
99 std::string name;
100 bool incognito_split_mode;
101 bool incognito_enabled;
102
103 // Expected results.
104 bool should_allow_main_frame_load;
105 bool should_allow_sub_frame_load;
106 } cases[] = {
107 {"spanning disabled", false, false, false, false},
108 {"split disabled", true, false, false, false},
109 {"spanning enabled", false, true, false, true},
110 {"split enabled", true, true, true, true},
111 };
112
113 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
114 scoped_refptr<Extension> extension =
115 CreateTestExtension(cases[i].name, cases[i].incognito_split_mode);
116 extension_info_map_->AddExtension(
117 extension, base::Time::Now(), cases[i].incognito_enabled);
118
119 // First test a main frame request.
120 {
121 // It doesn't matter that the resource doesn't exist. If the resource
122 // is blocked, we should see ADDRESS_UNREACHABLE. Otherwise, the request
123 // should just fail because the file doesn't exist.
124 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13125 &test_delegate_,
126 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15127 StartRequest(&request, ResourceType::MAIN_FRAME);
128 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
129
130 if (cases[i].should_allow_main_frame_load) {
131 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
132 cases[i].name;
133 } else {
134 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
135 cases[i].name;
136 }
137 }
138
139 // Now do a subframe request.
140 {
141 net::URLRequest request(extension->GetResourceURL("404.html"),
[email protected]94e2bbe2012-06-22 15:26:13142 &test_delegate_,
143 resource_context_.GetRequestContext());
[email protected]5e212ed2012-03-21 23:29:15144 StartRequest(&request, ResourceType::SUB_FRAME);
145 EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
146
147 if (cases[i].should_allow_sub_frame_load) {
148 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request.status().error()) <<
149 cases[i].name;
150 } else {
151 EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request.status().error()) <<
152 cases[i].name;
153 }
154 }
155 }
156}
157
158} // namespace