1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_resource_context.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/browser/extension_protocols.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/info_map.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/base/request_priority.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing content::ResourceType;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateTestExtension(const std::string& name,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             bool incognito_split_mode) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue manifest;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.SetString("name", name);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.SetString("version", "1");
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manifest.SetInteger("manifest_version", 2);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.SetString("incognito", incognito_split_mode ? "split" : "spanning");
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  path = path.AppendASCII("extensions").AppendASCII("response_headers");
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension(
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Extension::Create(path, Manifest::INTERNAL, manifest,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        Extension::NO_FLAGS, &error));
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(extension.get()) << error;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extension;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<Extension> CreateWebStoreExtension() {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue manifest;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest.SetString("name", "WebStore");
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest.SetString("version", "1");
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest.SetString("icons.16", "webstore_icon_16.png");
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(PathService::Get(chrome::DIR_RESOURCES, &path));
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path = path.AppendASCII("web_store");
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Extension> extension(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Extension::Create(path, Manifest::COMPONENT, manifest,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Extension::NO_FLAGS, &error));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(extension.get()) << error;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<Extension> CreateTestResponseHeaderExtension() {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue manifest;
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manifest.SetString("name", "An extension with web-accessible resources");
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manifest.SetString("version", "2");
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ListValue* web_accessible_list = new base::ListValue();
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  web_accessible_list->AppendString("test.dat");
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manifest.Set("web_accessible_resources", web_accessible_list);
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FilePath path;
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  path = path.AppendASCII("extensions").AppendASCII("response_headers");
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error;
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> extension(
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Extension::Create(path, Manifest::UNPACKED, manifest,
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        Extension::NO_FLAGS, &error));
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(extension.get()) << error;
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return extension;
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This test lives in src/chrome instead of src/extensions because it tests
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// functionality delegated back to Chrome via ChromeExtensionsBrowserClient.
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// See chrome/browser/extensions/chrome_url_request_util.cc.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionProtocolTest : public testing::Test {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionProtocolTest()
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        old_factory_(NULL),
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        resource_context_(&test_url_request_context_) {}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::Test::SetUp();
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extension_info_map_ = new InfoMap();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContext* request_context =
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resource_context_.GetRequestContext();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_factory_ = request_context->job_factory();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContext* request_context =
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resource_context_.GetRequestContext();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context->set_job_factory(old_factory_);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void SetProtocolHandler(bool is_incognito) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContext* request_context =
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_context_.GetRequestContext();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_factory_.SetProtocolHandler(
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kExtensionScheme,
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        CreateExtensionProtocolHandler(is_incognito,
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       extension_info_map_.get()));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request_context->set_job_factory(&job_factory_);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartRequest(net::URLRequest* request,
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    ResourceType resource_type) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::ResourceRequestInfo::AllocateForTesting(request,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     resource_type,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     &resource_context_,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     -1,
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                     -1,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     -1,
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                     false);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->Start();
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<InfoMap> extension_info_map_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestJobFactoryImpl job_factory_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const net::URLRequestJobFactory* old_factory_;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate test_delegate_;
147a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  net::TestURLRequestContext test_url_request_context_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::MockResourceContext resource_context_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that making a chrome-extension request in an incognito context is
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only allowed under the right circumstances (if the extension is allowed
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in incognito, and it's either a non-main-frame request or a split-mode
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extension).
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionProtocolTest, IncognitoRequest) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Register an incognito extension protocol handler.
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetProtocolHandler(true);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestCase {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Inputs.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool incognito_split_mode;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool incognito_enabled;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expected results.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_allow_main_frame_load;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_allow_sub_frame_load;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"spanning disabled", false, false, false, false},
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"split disabled", true, false, false, false},
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"spanning enabled", false, true, false, true},
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"split enabled", true, true, true, true},
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<Extension> extension =
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CreateTestExtension(cases[i].name, cases[i].incognito_split_mode);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_info_map_->AddExtension(
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        extension.get(), base::Time::Now(), cases[i].incognito_enabled, false);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First test a main frame request.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // It doesn't matter that the resource doesn't exist. If the resource
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is blocked, we should see ADDRESS_UNREACHABLE. Otherwise, the request
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // should just fail because the file doesn't exist.
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      scoped_ptr<net::URLRequest> request(
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          resource_context_.GetRequestContext()->CreateRequest(
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              extension->GetResourceURL("404.html"),
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              net::DEFAULT_PRIORITY,
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              &test_delegate_,
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              NULL));
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      StartRequest(request.get(), content::RESOURCE_TYPE_MAIN_FRAME);
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (cases[i].should_allow_main_frame_load) {
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request->status().error()) <<
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cases[i].name;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request->status().error()) <<
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cases[i].name;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now do a subframe request.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      scoped_ptr<net::URLRequest> request(
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          resource_context_.GetRequestContext()->CreateRequest(
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              extension->GetResourceURL("404.html"),
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              net::DEFAULT_PRIORITY,
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              &test_delegate_,
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              NULL));
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      StartRequest(request.get(), content::RESOURCE_TYPE_SUB_FRAME);
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (cases[i].should_allow_sub_frame_load) {
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request->status().error()) <<
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cases[i].name;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE, request->status().error()) <<
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cases[i].name;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CheckForContentLengthHeader(net::URLRequest* request) {
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string content_length;
22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->GetResponseHeaderByName(net::HttpRequestHeaders::kContentLength,
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  &content_length);
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(content_length.empty());
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int length_value = 0;
23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(base::StringToInt(content_length, &length_value));
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_GT(length_value, 0);
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests getting a resource for a component extension works correctly, both when
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the extension is enabled and when it is disabled.
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExtensionProtocolTest, ComponentResourceRequest) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Register a non-incognito extension protocol handler.
240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetProtocolHandler(false);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Extension> extension = CreateWebStoreExtension();
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extension_info_map_->AddExtension(extension.get(),
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Time::Now(),
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false,
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First test it with the extension enabled.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("webstore_icon_16.png"),
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_MEDIA);
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckForContentLengthHeader(request.get());
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // And then test it with the extension disabled.
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extension_info_map_->RemoveExtension(extension->id(),
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                       UnloadedExtensionInfo::REASON_DISABLE);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("webstore_icon_16.png"),
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_MEDIA);
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckForContentLengthHeader(request.get());
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests that a URL request for resource from an extension returns a few
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// expected response headers.
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ExtensionProtocolTest, ResourceRequestResponseHeaders) {
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Register a non-incognito extension protocol handler.
281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetProtocolHandler(false);
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> extension = CreateTestResponseHeaderExtension();
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extension_info_map_->AddExtension(extension.get(),
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Time::Now(),
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false,
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false);
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  {
29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("test.dat"),
29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_MEDIA);
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Check that cache-related headers are set.
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string etag;
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request->GetResponseHeaderByName("ETag", &etag);
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(StartsWithASCII(etag, "\"", false));
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(EndsWith(etag, "\"", false));
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string revalidation_header;
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request->GetResponseHeaderByName("cache-control", &revalidation_header);
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ("no-cache", revalidation_header);
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // We set test.dat as web-accessible, so it should have a CORS header.
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string access_control;
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request->GetResponseHeaderByName("Access-Control-Allow-Origin",
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    &access_control);
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ("*", access_control);
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Tests that a URL request for main frame or subframe from an extension
3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// succeeds, but subresources fail. See http://crbug.com/312269.
3190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(ExtensionProtocolTest, AllowFrameRequests) {
3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Register a non-incognito extension protocol handler.
321a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetProtocolHandler(false);
3220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_refptr<Extension> extension = CreateTestExtension("foo", false);
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extension_info_map_->AddExtension(extension.get(),
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Time::Now(),
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false,
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    false);
3280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // All MAIN_FRAME and SUB_FRAME requests should succeed.
3300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("test.dat"),
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
33603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_MAIN_FRAME);
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
3390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("test.dat"),
34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_SUB_FRAME);
34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
3490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // And subresource types, such as media, should fail.
3520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<net::URLRequest> request(
35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        resource_context_.GetRequestContext()->CreateRequest(
35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension->GetResourceURL("test.dat"),
35603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            net::DEFAULT_PRIORITY,
35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &test_delegate_,
35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            NULL));
35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    StartRequest(request.get(), content::RESOURCE_TYPE_MEDIA);
36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
3610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
365