• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "base/command_line.h"
6 #include "base/strings/string_util.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/policy/cloud/policy_header_service_factory.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/test/base/in_process_browser_test.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
15 #include "components/policy/core/common/cloud/policy_header_io_helper.h"
16 #include "components/policy/core/common/cloud/policy_header_service.h"
17 #include "components/policy/core/common/policy_switches.h"
18 #include "content/public/browser/resource_dispatcher_host.h"
19 #include "net/http/http_request_headers.h"
20 #include "net/test/embedded_test_server/embedded_test_server.h"
21 #include "net/test/embedded_test_server/http_request.h"
22 #include "net/test/embedded_test_server/http_response.h"
23 #include "net/url_request/url_request.h"
24 
25 namespace {
26 static const char kTestPolicyHeader[] = "test_header";
27 static const char kServerRedirectUrl[] = "/server-redirect";
28 
HandleTestRequest(const net::test_server::HttpRequest & request)29 scoped_ptr<net::test_server::HttpResponse> HandleTestRequest(
30     const net::test_server::HttpRequest& request) {
31   if (StartsWithASCII(request.relative_url, kServerRedirectUrl, true)) {
32     // Extract the target URL and redirect there.
33     size_t query_string_pos = request.relative_url.find('?');
34     std::string redirect_target =
35         request.relative_url.substr(query_string_pos + 1);
36 
37     scoped_ptr<net::test_server::BasicHttpResponse> http_response(
38         new net::test_server::BasicHttpResponse);
39     http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
40     http_response->AddCustomHeader("Location", redirect_target);
41     return http_response.PassAs<net::test_server::HttpResponse>();
42   } else {
43     scoped_ptr<net::test_server::BasicHttpResponse> http_response(
44         new net::test_server::BasicHttpResponse);
45     http_response->set_code(net::HTTP_OK);
46     http_response->set_content("Success");
47     return http_response.PassAs<net::test_server::HttpResponse>();
48   }
49 }
50 
51 class TestDispatcherHostDelegate : public ChromeResourceDispatcherHostDelegate {
52  public:
TestDispatcherHostDelegate(prerender::PrerenderTracker * prerender_tracker)53   explicit TestDispatcherHostDelegate(
54       prerender::PrerenderTracker* prerender_tracker)
55       : ChromeResourceDispatcherHostDelegate(prerender_tracker) {
56   }
57 
~TestDispatcherHostDelegate()58   virtual ~TestDispatcherHostDelegate() {}
59 
RequestBeginning(net::URLRequest * request,content::ResourceContext * resource_context,appcache::AppCacheService * appcache_service,ResourceType::Type resource_type,int child_id,int route_id,ScopedVector<content::ResourceThrottle> * throttles)60   virtual void RequestBeginning(
61       net::URLRequest* request,
62       content::ResourceContext* resource_context,
63       appcache::AppCacheService* appcache_service,
64       ResourceType::Type resource_type,
65       int child_id,
66       int route_id,
67       ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE {
68     ChromeResourceDispatcherHostDelegate::RequestBeginning(
69         request,
70         resource_context,
71         appcache_service,
72         resource_type,
73         child_id,
74         route_id,
75         throttles);
76     request_headers_.MergeFrom(request->extra_request_headers());
77   }
78 
OnRequestRedirected(const GURL & redirect_url,net::URLRequest * request,content::ResourceContext * resource_context,content::ResourceResponse * response)79   virtual void OnRequestRedirected(
80       const GURL& redirect_url,
81       net::URLRequest* request,
82       content::ResourceContext* resource_context,
83       content::ResourceResponse* response) OVERRIDE {
84     ChromeResourceDispatcherHostDelegate::OnRequestRedirected(
85         redirect_url,
86         request,
87         resource_context,
88         response);
89     request_headers_.MergeFrom(request->extra_request_headers());
90   }
91 
92   net::HttpRequestHeaders request_headers_;
93 
94  private:
95   DISALLOW_COPY_AND_ASSIGN(TestDispatcherHostDelegate);
96 };
97 
98 }  // namespace
99 
100 class ChromeResourceDispatcherHostDelegateBrowserTest :
101     public InProcessBrowserTest {
102  public:
ChromeResourceDispatcherHostDelegateBrowserTest()103   ChromeResourceDispatcherHostDelegateBrowserTest() {}
104 
SetUpOnMainThread()105   virtual void SetUpOnMainThread() OVERRIDE {
106     InProcessBrowserTest::SetUpOnMainThread();
107     // Hook navigations with our delegate.
108     dispatcher_host_delegate_.reset(new TestDispatcherHostDelegate(
109         g_browser_process->prerender_tracker()));
110     content::ResourceDispatcherHost::Get()->SetDelegate(
111         dispatcher_host_delegate_.get());
112 
113     embedded_test_server()->RegisterRequestHandler(
114         base::Bind(&HandleTestRequest));
115     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
116     // Tell chrome that this is our DM server.
117     dm_url_ = embedded_test_server()->GetURL("/DeviceManagement");
118 
119     // At this point, the Profile is already initialized and it's too
120     // late to set the DMServer URL via command line flags, so directly
121     // inject it to the PolicyHeaderIOHelper.
122     policy::PolicyHeaderService* policy_header_service =
123         policy::PolicyHeaderServiceFactory::GetForBrowserContext(
124             browser()->profile());
125     std::vector<policy::PolicyHeaderIOHelper*> helpers =
126         policy_header_service->GetHelpersForTest();
127     for (std::vector<policy::PolicyHeaderIOHelper*>::const_iterator it =
128              helpers.begin();
129          it != helpers.end(); ++it) {
130       (*it)->SetServerURLForTest(dm_url_.spec());
131       (*it)->UpdateHeader(kTestPolicyHeader);
132     }
133   }
134 
CleanUpOnMainThread()135   virtual void CleanUpOnMainThread() OVERRIDE {
136     content::ResourceDispatcherHost::Get()->SetDelegate(NULL);
137     dispatcher_host_delegate_.reset();
138     InProcessBrowserTest::CleanUpOnMainThread();
139   }
140 
141  protected:
142   // The fake URL for DMServer we are using.
143   GURL dm_url_;
144   scoped_ptr<TestDispatcherHostDelegate> dispatcher_host_delegate_;
145 
146  private:
147   DISALLOW_COPY_AND_ASSIGN(ChromeResourceDispatcherHostDelegateBrowserTest);
148 };
149 
150 
IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,NoPolicyHeader)151 IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
152                        NoPolicyHeader) {
153   // When fetching non-DMServer URLs, we should not add a policy header to the
154   // request.
155   DCHECK(!embedded_test_server()->base_url().spec().empty());
156   ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url());
157   ASSERT_FALSE(dispatcher_host_delegate_->request_headers_.HasHeader(
158       policy::kChromePolicyHeader));
159 }
160 
IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,PolicyHeader)161 IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
162                        PolicyHeader) {
163   // When fetching a DMServer URL, we should add a policy header to the
164   // request.
165   ui_test_utils::NavigateToURL(browser(), dm_url_);
166   std::string value;
167   ASSERT_TRUE(dispatcher_host_delegate_->request_headers_.GetHeader(
168       policy::kChromePolicyHeader, &value));
169   ASSERT_EQ(kTestPolicyHeader, value);
170 }
171 
IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,PolicyHeaderForRedirect)172 IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
173                        PolicyHeaderForRedirect) {
174 
175   // Build up a URL that results in a redirect to the DMServer URL to make
176   // sure the policy header is still added.
177   std::string redirect_url;
178   redirect_url += kServerRedirectUrl;
179   redirect_url += "?";
180   redirect_url += dm_url_.spec();
181   ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
182       redirect_url));
183   std::string value;
184   ASSERT_TRUE(dispatcher_host_delegate_->request_headers_.GetHeader(
185       policy::kChromePolicyHeader, &value));
186   ASSERT_EQ(kTestPolicyHeader, value);
187 }
188