Refactor WebsiteSettings to operate on a SecurityInfo
[chromium-blink-merge.git] / content / renderer / resource_fetcher_browsertest.cc
blob3b0f70443f2052bab718194191f13568dbdea965
1 // 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.
5 #include "content/public/renderer/resource_fetcher.h"
7 #include <stdint.h>
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/command_line.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/time/time.h"
13 #include "base/timer/timer.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/public/common/url_constants.h"
18 #include "content/public/renderer/render_view.h"
19 #include "content/public/test/content_browser_test.h"
20 #include "content/public/test/content_browser_test_utils.h"
21 #include "content/public/test/test_utils.h"
22 #include "content/shell/browser/shell.h"
23 #include "third_party/WebKit/public/platform/WebURLResponse.h"
24 #include "third_party/WebKit/public/web/WebFrame.h"
25 #include "third_party/WebKit/public/web/WebView.h"
27 using blink::WebFrame;
28 using blink::WebURLRequest;
29 using blink::WebURLResponse;
31 namespace content {
33 static const int kMaxWaitTimeMs = 5000;
35 class FetcherDelegate {
36 public:
37 FetcherDelegate()
38 : completed_(false),
39 timed_out_(false) {
40 // Start a repeating timer waiting for the download to complete. The
41 // callback has to be a static function, so we hold on to our instance.
42 FetcherDelegate::instance_ = this;
43 StartTimer();
46 virtual ~FetcherDelegate() {}
48 ResourceFetcher::Callback NewCallback() {
49 return base::Bind(&FetcherDelegate::OnURLFetchComplete,
50 base::Unretained(this));
53 virtual void OnURLFetchComplete(const WebURLResponse& response,
54 const std::string& data) {
55 response_ = response;
56 data_ = data;
57 completed_ = true;
58 timer_.Stop();
59 if (!timed_out_)
60 quit_task_.Run();
63 bool completed() const { return completed_; }
64 bool timed_out() const { return timed_out_; }
66 std::string data() const { return data_; }
67 const WebURLResponse& response() const { return response_; }
69 // Wait for the request to complete or timeout.
70 void WaitForResponse() {
71 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
72 quit_task_ = runner->QuitClosure();
73 runner->Run();
76 void StartTimer() {
77 timer_.Start(FROM_HERE,
78 base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
79 this,
80 &FetcherDelegate::TimerFired);
83 void TimerFired() {
84 ASSERT_FALSE(completed_);
86 timed_out_ = true;
87 if (!completed_)
88 quit_task_.Run();
89 FAIL() << "fetch timed out";
92 static FetcherDelegate* instance_;
94 private:
95 base::OneShotTimer<FetcherDelegate> timer_;
96 bool completed_;
97 bool timed_out_;
98 WebURLResponse response_;
99 std::string data_;
100 base::Closure quit_task_;
103 FetcherDelegate* FetcherDelegate::instance_ = NULL;
105 class EvilFetcherDelegate : public FetcherDelegate {
106 public:
107 ~EvilFetcherDelegate() override {}
109 void SetFetcher(ResourceFetcher* fetcher) {
110 fetcher_.reset(fetcher);
113 void OnURLFetchComplete(const WebURLResponse& response,
114 const std::string& data) override {
115 FetcherDelegate::OnURLFetchComplete(response, data);
117 // Destroy the ResourceFetcher here. We are testing that upon returning
118 // to the ResourceFetcher that it does not crash. This must be done after
119 // calling FetcherDelegate::OnURLFetchComplete, since deleting the fetcher
120 // invalidates |response| and |data|.
121 fetcher_.reset();
124 private:
125 scoped_ptr<ResourceFetcher> fetcher_;
128 class ResourceFetcherTests : public ContentBrowserTest {
129 public:
130 ResourceFetcherTests() : render_view_routing_id_(MSG_ROUTING_NONE) {}
132 void SetUpCommandLine(base::CommandLine* command_line) override {
133 command_line->AppendSwitch(switches::kSingleProcess);
134 #if defined(OS_WIN)
135 // Don't want to try to create a GPU process.
136 command_line->AppendSwitch(switches::kDisableGpu);
137 #endif
140 void SetUpOnMainThread() override {
141 render_view_routing_id_ =
142 shell()->web_contents()->GetRenderViewHost()->GetRoutingID();
145 RenderView* GetRenderView() {
146 return RenderView::FromRoutingID(render_view_routing_id_);
149 void ResourceFetcherDownloadOnRenderer(const GURL& url) {
150 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
152 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
153 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
154 fetcher->Start(frame,
155 WebURLRequest::RequestContextInternal,
156 WebURLRequest::FrameTypeNone,
157 ResourceFetcher::PLATFORM_LOADER,
158 delegate->NewCallback());
160 delegate->WaitForResponse();
162 ASSERT_TRUE(delegate->completed());
163 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
164 std::string text = delegate->data();
165 EXPECT_TRUE(text.find("Basic html test.") != std::string::npos);
168 void ResourceFetcher404OnRenderer(const GURL& url) {
169 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
171 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
172 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
173 fetcher->Start(frame,
174 WebURLRequest::RequestContextInternal,
175 WebURLRequest::FrameTypeNone,
176 ResourceFetcher::PLATFORM_LOADER,
177 delegate->NewCallback());
179 delegate->WaitForResponse();
181 ASSERT_TRUE(delegate->completed());
182 EXPECT_EQ(delegate->response().httpStatusCode(), 404);
183 EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
186 void ResourceFetcherDidFailOnRenderer() {
187 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
189 // Try to fetch a page on a site that doesn't exist.
190 GURL url("http://localhost:1339/doesnotexist");
191 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
192 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
193 fetcher->Start(frame,
194 WebURLRequest::RequestContextInternal,
195 WebURLRequest::FrameTypeNone,
196 ResourceFetcher::PLATFORM_LOADER,
197 delegate->NewCallback());
199 delegate->WaitForResponse();
201 // When we fail, we still call the Delegate callback but we pass in empty
202 // values.
203 EXPECT_TRUE(delegate->completed());
204 EXPECT_TRUE(delegate->response().isNull());
205 EXPECT_EQ(delegate->data(), std::string());
206 EXPECT_FALSE(delegate->timed_out());
209 void ResourceFetcherTimeoutOnRenderer(const GURL& url) {
210 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
212 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
213 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
214 fetcher->Start(frame,
215 WebURLRequest::RequestContextInternal,
216 WebURLRequest::FrameTypeNone,
217 ResourceFetcher::PLATFORM_LOADER,
218 delegate->NewCallback());
219 fetcher->SetTimeout(base::TimeDelta());
221 delegate->WaitForResponse();
223 // When we timeout, we still call the Delegate callback but we pass in empty
224 // values.
225 EXPECT_TRUE(delegate->completed());
226 EXPECT_TRUE(delegate->response().isNull());
227 EXPECT_EQ(delegate->data(), std::string());
228 EXPECT_FALSE(delegate->timed_out());
231 void ResourceFetcherDeletedInCallbackOnRenderer(const GURL& url) {
232 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
234 scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
235 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
236 fetcher->Start(frame,
237 WebURLRequest::RequestContextInternal,
238 WebURLRequest::FrameTypeNone,
239 ResourceFetcher::PLATFORM_LOADER,
240 delegate->NewCallback());
241 fetcher->SetTimeout(base::TimeDelta());
242 delegate->SetFetcher(fetcher.release());
244 delegate->WaitForResponse();
245 EXPECT_FALSE(delegate->timed_out());
248 void ResourceFetcherPost(const GURL& url) {
249 const char* kBody = "Really nifty POST body!";
251 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
253 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
254 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
255 fetcher->SetMethod("POST");
256 fetcher->SetBody(kBody);
257 fetcher->Start(frame,
258 WebURLRequest::RequestContextInternal,
259 WebURLRequest::FrameTypeNone,
260 ResourceFetcher::PLATFORM_LOADER,
261 delegate->NewCallback());
263 delegate->WaitForResponse();
264 ASSERT_TRUE(delegate->completed());
265 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
266 EXPECT_EQ(kBody, delegate->data());
269 void ResourceFetcherSetHeader(const GURL& url) {
270 const char* kHeader = "Rather boring header.";
272 WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
274 scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
275 scoped_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
276 fetcher->SetHeader("header", kHeader);
277 fetcher->Start(frame,
278 WebURLRequest::RequestContextInternal,
279 WebURLRequest::FrameTypeNone,
280 ResourceFetcher::PLATFORM_LOADER,
281 delegate->NewCallback());
283 delegate->WaitForResponse();
284 ASSERT_TRUE(delegate->completed());
285 EXPECT_EQ(delegate->response().httpStatusCode(), 200);
286 EXPECT_EQ(kHeader, delegate->data());
289 int32 render_view_routing_id_;
292 // Test a fetch from the test server.
293 // If this flakes, use http://crbug.com/51622.
294 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDownload) {
295 // Need to spin up the renderer.
296 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
298 ASSERT_TRUE(test_server()->Start());
299 GURL url(test_server()->GetURL("files/simple_page.html"));
301 PostTaskToInProcessRendererAndWait(
302 base::Bind(&ResourceFetcherTests::ResourceFetcherDownloadOnRenderer,
303 base::Unretained(this), url));
306 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcher404) {
307 // Need to spin up the renderer.
308 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
310 // Test 404 response.
311 ASSERT_TRUE(test_server()->Start());
312 GURL url = test_server()->GetURL("files/thisfiledoesntexist.html");
314 PostTaskToInProcessRendererAndWait(
315 base::Bind(&ResourceFetcherTests::ResourceFetcher404OnRenderer,
316 base::Unretained(this), url));
319 // If this flakes, use http://crbug.com/51622.
320 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) {
321 // Need to spin up the renderer.
322 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
324 PostTaskToInProcessRendererAndWait(
325 base::Bind(&ResourceFetcherTests::ResourceFetcherDidFailOnRenderer,
326 base::Unretained(this)));
329 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
330 // Need to spin up the renderer.
331 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
333 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
334 // timeout in 0 sec.
335 ASSERT_TRUE(test_server()->Start());
336 GURL url(test_server()->GetURL("slow?1"));
338 PostTaskToInProcessRendererAndWait(
339 base::Bind(&ResourceFetcherTests::ResourceFetcherTimeoutOnRenderer,
340 base::Unretained(this), url));
343 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDeletedInCallback) {
344 // Need to spin up the renderer.
345 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
347 // Grab a page that takes at least 1 sec to respond, but set the fetcher to
348 // timeout in 0 sec.
349 ASSERT_TRUE(test_server()->Start());
350 GURL url(test_server()->GetURL("slow?1"));
352 PostTaskToInProcessRendererAndWait(
353 base::Bind(
354 &ResourceFetcherTests::ResourceFetcherDeletedInCallbackOnRenderer,
355 base::Unretained(this), url));
360 // Test that ResourceFetchers can handle POSTs.
361 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherPost) {
362 // Need to spin up the renderer.
363 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
365 // Grab a page that echos the POST body.
366 ASSERT_TRUE(test_server()->Start());
367 GURL url(test_server()->GetURL("echo"));
369 PostTaskToInProcessRendererAndWait(
370 base::Bind(
371 &ResourceFetcherTests::ResourceFetcherPost,
372 base::Unretained(this), url));
375 // Test that ResourceFetchers can set headers.
376 IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherSetHeader) {
377 // Need to spin up the renderer.
378 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
380 // Grab a page that echos the POST body.
381 ASSERT_TRUE(test_server()->Start());
382 GURL url(test_server()->GetURL("echoheader?header"));
384 PostTaskToInProcessRendererAndWait(
385 base::Bind(
386 &ResourceFetcherTests::ResourceFetcherSetHeader,
387 base::Unretained(this), url));
390 } // namespace content