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.
8 #include "base/pickle.h"
9 #include "base/run_loop.h"
10 #include "base/time/time.h"
11 #include "chrome/browser/history/history_backend.h"
12 #include "chrome/browser/history/history_service.h"
13 #include "chrome/browser/history/history_service_factory.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/safe_browsing/malware_details.h"
16 #include "chrome/browser/safe_browsing/malware_details_history.h"
17 #include "chrome/browser/safe_browsing/report.pb.h"
18 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
19 #include "chrome/browser/safe_browsing/ui_manager.h"
20 #include "chrome/common/render_messages.h"
21 #include "chrome/common/safe_browsing/safebrowsing_messages.h"
22 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "content/public/browser/render_process_host.h"
25 #include "content/public/browser/web_contents.h"
26 #include "net/base/io_buffer.h"
27 #include "net/base/net_errors.h"
28 #include "net/base/test_completion_callback.h"
29 #include "net/disk_cache/disk_cache.h"
30 #include "net/http/http_cache.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/http/http_response_info.h"
33 #include "net/http/http_util.h"
34 #include "net/url_request/url_request_context.h"
35 #include "net/url_request/url_request_context_getter.h"
37 // Mixture of HTTP and HTTPS. No special treatment for HTTPS.
38 static const char* kOriginalLandingURL
=
39 "http://www.originallandingpage.com/with/path";
40 static const char* kDOMChildURL
= "https://www.domparent.com/with/path";
41 static const char* kDOMParentURL
= "https://www.domchild.com/with/path";
42 static const char* kFirstRedirectURL
= "http://redirectone.com/with/path";
43 static const char* kSecondRedirectURL
= "https://redirecttwo.com/with/path";
44 static const char* kReferrerURL
= "http://www.referrer.com/with/path";
46 static const char* kMalwareURL
= "http://www.malware.com/with/path";
47 static const char* kMalwareHeaders
=
49 "Content-Type: image/jpeg\n";
50 static const char* kMalwareData
= "exploit();";
52 static const char* kLandingURL
= "http://www.landingpage.com/with/path";
53 static const char* kLandingHeaders
=
55 "Content-Type: text/html\n"
56 "Content-Length: 1024\n"
57 "Set-Cookie: tastycookie\n"; // This header is stripped.
58 static const char* kLandingData
=
59 "<iframe src='http://www.malware.com/with/path'>";
62 using content::BrowserThread
;
63 using content::WebContents
;
64 using safe_browsing::ClientMalwareReportRequest
;
68 void WriteHeaders(disk_cache::Entry
* entry
, const std::string
& headers
) {
69 net::HttpResponseInfo responseinfo
;
70 std::string raw_headers
= net::HttpUtil::AssembleRawHeaders(
71 headers
.c_str(), headers
.size());
72 responseinfo
.socket_address
= net::HostPortPair("1.2.3.4", 80);
73 responseinfo
.headers
= new net::HttpResponseHeaders(raw_headers
);
76 responseinfo
.Persist(&pickle
, false, false);
78 scoped_refptr
<net::WrappedIOBuffer
> buf(new net::WrappedIOBuffer(
79 reinterpret_cast<const char*>(pickle
.data())));
80 int len
= static_cast<int>(pickle
.size());
82 net::TestCompletionCallback cb
;
83 int rv
= entry
->WriteData(0, 0, buf
.get(), len
, cb
.callback(), true);
84 ASSERT_EQ(len
, cb
.GetResult(rv
));
87 void WriteData(disk_cache::Entry
* entry
, const std::string
& data
) {
91 int len
= data
.length();
92 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(len
));
93 memcpy(buf
->data(), data
.data(), data
.length());
95 net::TestCompletionCallback cb
;
96 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
97 ASSERT_EQ(len
, cb
.GetResult(rv
));
100 void WriteToEntry(disk_cache::Backend
* cache
, const std::string
& key
,
101 const std::string
& headers
, const std::string
& data
) {
102 net::TestCompletionCallback cb
;
103 disk_cache::Entry
* entry
;
104 int rv
= cache
->CreateEntry(key
, &entry
, cb
.callback());
105 rv
= cb
.GetResult(rv
);
107 rv
= cache
->OpenEntry(key
, &entry
, cb
.callback());
108 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
111 WriteHeaders(entry
, headers
);
112 WriteData(entry
, data
);
116 void FillCache(net::URLRequestContextGetter
* context_getter
) {
117 net::TestCompletionCallback cb
;
118 disk_cache::Backend
* cache
;
120 context_getter
->GetURLRequestContext()->http_transaction_factory()->
121 GetCache()->GetBackend(&cache
, cb
.callback());
122 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
124 WriteToEntry(cache
, kMalwareURL
, kMalwareHeaders
, kMalwareData
);
125 WriteToEntry(cache
, kLandingURL
, kLandingHeaders
, kLandingData
);
128 // Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate.
129 // Also exposes the constructor.
130 class MalwareDetailsWrap
: public MalwareDetails
{
133 SafeBrowsingUIManager
* ui_manager
,
134 WebContents
* web_contents
,
135 const SafeBrowsingUIManager::UnsafeResource
& unsafe_resource
,
136 net::URLRequestContextGetter
* request_context_getter
)
137 : MalwareDetails(ui_manager
, web_contents
, unsafe_resource
) {
138 request_context_getter_
= request_context_getter
;
142 ~MalwareDetailsWrap() override
{}
145 class MockSafeBrowsingUIManager
: public SafeBrowsingUIManager
{
147 base::RunLoop
* run_loop_
;
148 // The safe browsing UI manager does not need a service for this test.
149 MockSafeBrowsingUIManager()
150 : SafeBrowsingUIManager(NULL
), run_loop_(NULL
) {}
152 // When the MalwareDetails is done, this is called.
153 void SendSerializedMalwareDetails(const std::string
& serialized
) override
{
154 DVLOG(1) << "SendSerializedMalwareDetails";
157 serialized_
= serialized
;
160 // Used to synchronize SendSerializedMalwareDetails() with
161 // WaitForSerializedReport(). RunLoop::RunUntilIdle() is not sufficient
162 // because the MessageLoop task queue completely drains at some point
163 // between the send and the wait.
164 void SetRunLoopToQuit(base::RunLoop
* run_loop
) {
165 DCHECK(run_loop_
== NULL
);
166 run_loop_
= run_loop
;
169 const std::string
& GetSerialized() {
174 ~MockSafeBrowsingUIManager() override
{}
176 std::string serialized_
;
177 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager
);
182 class MalwareDetailsTest
: public ChromeRenderViewHostTestHarness
{
184 typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource
;
187 : ui_manager_(new MockSafeBrowsingUIManager()) {
190 void SetUp() override
{
191 ChromeRenderViewHostTestHarness::SetUp();
192 ASSERT_TRUE(profile()->CreateHistoryService(
193 true /* delete_file */, false /* no_db */));
196 void TearDown() override
{
197 profile()->DestroyHistoryService();
198 ChromeRenderViewHostTestHarness::TearDown();
201 static bool ResourceLessThan(
202 const ClientMalwareReportRequest::Resource
* lhs
,
203 const ClientMalwareReportRequest::Resource
* rhs
) {
204 return lhs
->id() < rhs
->id();
207 std::string
WaitForSerializedReport(MalwareDetails
* report
) {
208 BrowserThread::PostTask(
211 base::Bind(&MalwareDetails::FinishCollection
, report
));
212 // Wait for the callback (SendSerializedMalwareDetails).
213 DVLOG(1) << "Waiting for SendSerializedMalwareDetails";
214 base::RunLoop run_loop
;
215 ui_manager_
->SetRunLoopToQuit(&run_loop
);
217 return ui_manager_
->GetSerialized();
220 HistoryService
* history_service() {
221 return HistoryServiceFactory::GetForProfile(
222 profile(), ServiceAccessType::EXPLICIT_ACCESS
);
226 void InitResource(UnsafeResource
* resource
,
230 resource
->is_subresource
= is_subresource
;
231 resource
->threat_type
= SB_THREAT_TYPE_URL_MALWARE
;
232 resource
->render_process_host_id
=
233 web_contents()->GetRenderProcessHost()->GetID();
234 resource
->render_view_id
=
235 web_contents()->GetRenderViewHost()->GetRoutingID();
238 void VerifyResults(const ClientMalwareReportRequest
& report_pb
,
239 const ClientMalwareReportRequest
& expected_pb
) {
240 EXPECT_EQ(expected_pb
.malware_url(), report_pb
.malware_url());
241 EXPECT_EQ(expected_pb
.page_url(), report_pb
.page_url());
242 EXPECT_EQ(expected_pb
.referrer_url(), report_pb
.referrer_url());
244 ASSERT_EQ(expected_pb
.resources_size(), report_pb
.resources_size());
245 // Sort the resources, to make the test deterministic
246 std::vector
<const ClientMalwareReportRequest::Resource
*> resources
;
247 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
248 const ClientMalwareReportRequest::Resource
& resource
=
249 report_pb
.resources(i
);
250 resources
.push_back(&resource
);
252 std::sort(resources
.begin(), resources
.end(),
253 &MalwareDetailsTest::ResourceLessThan
);
255 std::vector
<const ClientMalwareReportRequest::Resource
*> expected
;
256 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
257 const ClientMalwareReportRequest::Resource
& resource
=
258 expected_pb
.resources(i
);
259 expected
.push_back(&resource
);
261 std::sort(expected
.begin(), expected
.end(),
262 &MalwareDetailsTest::ResourceLessThan
);
264 for (uint32 i
= 0; i
< expected
.size(); ++i
) {
265 VerifyResource(resources
[i
], expected
[i
]);
268 EXPECT_EQ(expected_pb
.complete(), report_pb
.complete());
271 void VerifyResource(const ClientMalwareReportRequest::Resource
* resource
,
272 const ClientMalwareReportRequest::Resource
* expected
) {
273 EXPECT_EQ(expected
->id(), resource
->id());
274 EXPECT_EQ(expected
->url(), resource
->url());
275 EXPECT_EQ(expected
->parent_id(), resource
->parent_id());
276 ASSERT_EQ(expected
->child_ids_size(), resource
->child_ids_size());
277 for (int i
= 0; i
< expected
->child_ids_size(); i
++) {
278 EXPECT_EQ(expected
->child_ids(i
), resource
->child_ids(i
));
281 // Verify HTTP Responses
282 if (expected
->has_response()) {
283 ASSERT_TRUE(resource
->has_response());
284 EXPECT_EQ(expected
->response().firstline().code(),
285 resource
->response().firstline().code());
287 ASSERT_EQ(expected
->response().headers_size(),
288 resource
->response().headers_size());
289 for (int i
= 0; i
< expected
->response().headers_size(); ++i
) {
290 EXPECT_EQ(expected
->response().headers(i
).name(),
291 resource
->response().headers(i
).name());
292 EXPECT_EQ(expected
->response().headers(i
).value(),
293 resource
->response().headers(i
).value());
296 EXPECT_EQ(expected
->response().body(), resource
->response().body());
297 EXPECT_EQ(expected
->response().bodylength(),
298 resource
->response().bodylength());
299 EXPECT_EQ(expected
->response().bodydigest(),
300 resource
->response().bodydigest());
303 // Verify IP:port pair
304 EXPECT_EQ(expected
->response().remote_ip(),
305 resource
->response().remote_ip());
308 // Adds a page to history.
309 // The redirects is the redirect url chain leading to the url.
310 void AddPageToHistory(const GURL
& url
,
311 history::RedirectList
* redirects
) {
312 // The last item of the redirect chain has to be the final url when adding
313 // to history backend.
314 redirects
->push_back(url
);
315 history_service()->AddPage(
316 url
, base::Time::Now(), reinterpret_cast<history::ContextID
>(1), 0,
317 GURL(), *redirects
, ui::PAGE_TRANSITION_TYPED
,
318 history::SOURCE_BROWSED
, false);
321 scoped_refptr
<MockSafeBrowsingUIManager
> ui_manager_
;
324 // Tests creating a simple malware report.
325 TEST_F(MalwareDetailsTest
, MalwareSubResource
) {
327 controller().LoadURL(
329 content::Referrer(GURL(kReferrerURL
), blink::WebReferrerPolicyDefault
),
330 ui::PAGE_TRANSITION_TYPED
, std::string());
332 UnsafeResource resource
;
333 InitResource(&resource
, true, GURL(kMalwareURL
));
335 scoped_refptr
<MalwareDetailsWrap
> report
=
336 new MalwareDetailsWrap(ui_manager_
.get(), web_contents(), resource
, NULL
);
338 std::string serialized
= WaitForSerializedReport(report
.get());
340 ClientMalwareReportRequest actual
;
341 actual
.ParseFromString(serialized
);
343 ClientMalwareReportRequest expected
;
344 expected
.set_malware_url(kMalwareURL
);
345 expected
.set_page_url(kLandingURL
);
346 // Note that the referrer policy is not actually enacted here, since that's
348 expected
.set_referrer_url(kReferrerURL
);
350 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
351 pb_resource
->set_id(0);
352 pb_resource
->set_url(kLandingURL
);
353 pb_resource
= expected
.add_resources();
354 pb_resource
->set_id(1);
355 pb_resource
->set_url(kMalwareURL
);
356 pb_resource
= expected
.add_resources();
357 pb_resource
->set_id(2);
358 pb_resource
->set_url(kReferrerURL
);
360 VerifyResults(actual
, expected
);
363 // Tests creating a simple malware report where the subresource has a
364 // different original_url.
365 TEST_F(MalwareDetailsTest
, MalwareSubResourceWithOriginalUrl
) {
366 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
367 ui::PAGE_TRANSITION_TYPED
, std::string());
369 UnsafeResource resource
;
370 InitResource(&resource
, true, GURL(kMalwareURL
));
371 resource
.original_url
= GURL(kOriginalLandingURL
);
373 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
374 ui_manager_
.get(), web_contents(), resource
, NULL
);
376 std::string serialized
= WaitForSerializedReport(report
.get());
378 ClientMalwareReportRequest actual
;
379 actual
.ParseFromString(serialized
);
381 ClientMalwareReportRequest expected
;
382 expected
.set_malware_url(kMalwareURL
);
383 expected
.set_page_url(kLandingURL
);
384 expected
.set_referrer_url("");
386 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
387 pb_resource
->set_id(0);
388 pb_resource
->set_url(kLandingURL
);
390 pb_resource
= expected
.add_resources();
391 pb_resource
->set_id(1);
392 pb_resource
->set_url(kOriginalLandingURL
);
394 pb_resource
= expected
.add_resources();
395 pb_resource
->set_id(2);
396 pb_resource
->set_url(kMalwareURL
);
397 // The Resource for kMalwareUrl should have the Resource for
398 // kOriginalLandingURL (with id 1) as parent.
399 pb_resource
->set_parent_id(1);
401 VerifyResults(actual
, expected
);
404 // Tests creating a malware report with data from the renderer.
405 TEST_F(MalwareDetailsTest
, MalwareDOMDetails
) {
406 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
407 ui::PAGE_TRANSITION_TYPED
, std::string());
409 UnsafeResource resource
;
410 InitResource(&resource
, true, GURL(kMalwareURL
));
412 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
413 ui_manager_
.get(), web_contents(), resource
, NULL
);
415 // Send a message from the DOM, with 2 nodes, a parent and a child.
416 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
417 SafeBrowsingHostMsg_MalwareDOMDetails_Node child_node
;
418 child_node
.url
= GURL(kDOMChildURL
);
419 child_node
.tag_name
= "iframe";
420 child_node
.parent
= GURL(kDOMParentURL
);
421 params
.push_back(child_node
);
422 SafeBrowsingHostMsg_MalwareDOMDetails_Node parent_node
;
423 parent_node
.url
= GURL(kDOMParentURL
);
424 parent_node
.children
.push_back(GURL(kDOMChildURL
));
425 params
.push_back(parent_node
);
426 report
->OnReceivedMalwareDOMDetails(params
);
428 std::string serialized
= WaitForSerializedReport(report
.get());
429 ClientMalwareReportRequest actual
;
430 actual
.ParseFromString(serialized
);
432 ClientMalwareReportRequest expected
;
433 expected
.set_malware_url(kMalwareURL
);
434 expected
.set_page_url(kLandingURL
);
435 expected
.set_referrer_url("");
437 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
438 pb_resource
->set_id(0);
439 pb_resource
->set_url(kLandingURL
);
441 pb_resource
= expected
.add_resources();
442 pb_resource
->set_id(1);
443 pb_resource
->set_url(kMalwareURL
);
445 pb_resource
= expected
.add_resources();
446 pb_resource
->set_id(2);
447 pb_resource
->set_url(kDOMChildURL
);
448 pb_resource
->set_parent_id(3);
450 pb_resource
= expected
.add_resources();
451 pb_resource
->set_id(3);
452 pb_resource
->set_url(kDOMParentURL
);
453 pb_resource
->add_child_ids(2);
454 expected
.set_complete(false); // Since the cache was missing.
456 VerifyResults(actual
, expected
);
459 // Tests creating a malware report where there are redirect urls to an unsafe
461 TEST_F(MalwareDetailsTest
, MalwareWithRedirectUrl
) {
462 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
463 ui::PAGE_TRANSITION_TYPED
, std::string());
465 UnsafeResource resource
;
466 InitResource(&resource
, true, GURL(kMalwareURL
));
467 resource
.original_url
= GURL(kOriginalLandingURL
);
469 // add some redirect urls
470 resource
.redirect_urls
.push_back(GURL(kFirstRedirectURL
));
471 resource
.redirect_urls
.push_back(GURL(kSecondRedirectURL
));
472 resource
.redirect_urls
.push_back(GURL(kMalwareURL
));
474 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
475 ui_manager_
.get(), web_contents(), resource
, NULL
);
477 std::string serialized
= WaitForSerializedReport(report
.get());
478 ClientMalwareReportRequest actual
;
479 actual
.ParseFromString(serialized
);
481 ClientMalwareReportRequest expected
;
482 expected
.set_malware_url(kMalwareURL
);
483 expected
.set_page_url(kLandingURL
);
484 expected
.set_referrer_url("");
486 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
487 pb_resource
->set_id(0);
488 pb_resource
->set_url(kLandingURL
);
490 pb_resource
= expected
.add_resources();
491 pb_resource
->set_id(1);
492 pb_resource
->set_url(kOriginalLandingURL
);
494 pb_resource
= expected
.add_resources();
495 pb_resource
->set_id(2);
496 pb_resource
->set_url(kMalwareURL
);
497 pb_resource
->set_parent_id(4);
499 pb_resource
= expected
.add_resources();
500 pb_resource
->set_id(3);
501 pb_resource
->set_url(kFirstRedirectURL
);
502 pb_resource
->set_parent_id(1);
504 pb_resource
= expected
.add_resources();
505 pb_resource
->set_id(4);
506 pb_resource
->set_url(kSecondRedirectURL
);
507 pb_resource
->set_parent_id(3);
509 VerifyResults(actual
, expected
);
512 // Tests the interaction with the HTTP cache.
513 TEST_F(MalwareDetailsTest
, HTTPCache
) {
514 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
515 ui::PAGE_TRANSITION_TYPED
, std::string());
517 UnsafeResource resource
;
518 InitResource(&resource
, true, GURL(kMalwareURL
));
520 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
521 ui_manager_
.get(), web_contents(), resource
,
522 profile()->GetRequestContext());
524 BrowserThread::PostTask(
525 BrowserThread::IO
, FROM_HERE
,
526 base::Bind(&FillCache
,
527 make_scoped_refptr(profile()->GetRequestContext())));
529 // The cache collection starts after the IPC from the DOM is fired.
530 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
531 report
->OnReceivedMalwareDOMDetails(params
);
533 // Let the cache callbacks complete.
534 base::RunLoop().RunUntilIdle();
536 DVLOG(1) << "Getting serialized report";
537 std::string serialized
= WaitForSerializedReport(report
.get());
538 ClientMalwareReportRequest actual
;
539 actual
.ParseFromString(serialized
);
541 ClientMalwareReportRequest expected
;
542 expected
.set_malware_url(kMalwareURL
);
543 expected
.set_page_url(kLandingURL
);
544 expected
.set_referrer_url("");
546 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
547 pb_resource
->set_id(0);
548 pb_resource
->set_url(kLandingURL
);
549 safe_browsing::ClientMalwareReportRequest::HTTPResponse
* pb_response
=
550 pb_resource
->mutable_response();
551 pb_response
->mutable_firstline()->set_code(200);
552 safe_browsing::ClientMalwareReportRequest::HTTPHeader
* pb_header
=
553 pb_response
->add_headers();
554 pb_header
->set_name("Content-Type");
555 pb_header
->set_value("text/html");
556 pb_header
= pb_response
->add_headers();
557 pb_header
->set_name("Content-Length");
558 pb_header
->set_value("1024");
559 pb_header
= pb_response
->add_headers();
560 pb_header
->set_name("Set-Cookie");
561 pb_header
->set_value(""); // The cookie is dropped.
562 pb_response
->set_body(kLandingData
);
563 pb_response
->set_bodylength(47);
564 pb_response
->set_bodydigest("5abb4e63d806ec2c16a40b2699700554");
565 pb_response
->set_remote_ip("1.2.3.4:80");
567 pb_resource
= expected
.add_resources();
568 pb_resource
->set_id(1);
569 pb_resource
->set_url(kMalwareURL
);
570 pb_response
= pb_resource
->mutable_response();
571 pb_response
->mutable_firstline()->set_code(200);
572 pb_header
= pb_response
->add_headers();
573 pb_header
->set_name("Content-Type");
574 pb_header
->set_value("image/jpeg");
575 pb_response
->set_body(kMalwareData
);
576 pb_response
->set_bodylength(10);
577 pb_response
->set_bodydigest("581373551c43d4cf33bfb3b26838ff95");
578 pb_response
->set_remote_ip("1.2.3.4:80");
579 expected
.set_complete(true);
581 VerifyResults(actual
, expected
);
584 // Tests the interaction with the HTTP cache (where the cache is empty).
585 TEST_F(MalwareDetailsTest
, HTTPCacheNoEntries
) {
586 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
587 ui::PAGE_TRANSITION_TYPED
, std::string());
589 UnsafeResource resource
;
590 InitResource(&resource
, true, GURL(kMalwareURL
));
592 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
593 ui_manager_
.get(), web_contents(), resource
,
594 profile()->GetRequestContext());
596 // No call to FillCache
598 // The cache collection starts after the IPC from the DOM is fired.
599 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
600 report
->OnReceivedMalwareDOMDetails(params
);
602 // Let the cache callbacks complete.
603 base::RunLoop().RunUntilIdle();
605 DVLOG(1) << "Getting serialized report";
606 std::string serialized
= WaitForSerializedReport(report
.get());
607 ClientMalwareReportRequest actual
;
608 actual
.ParseFromString(serialized
);
610 ClientMalwareReportRequest expected
;
611 expected
.set_malware_url(kMalwareURL
);
612 expected
.set_page_url(kLandingURL
);
613 expected
.set_referrer_url("");
615 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
616 pb_resource
->set_id(0);
617 pb_resource
->set_url(kLandingURL
);
618 pb_resource
= expected
.add_resources();
619 pb_resource
->set_id(1);
620 pb_resource
->set_url(kMalwareURL
);
621 expected
.set_complete(true);
623 VerifyResults(actual
, expected
);
626 // Test getting redirects from history service.
627 TEST_F(MalwareDetailsTest
, HistoryServiceUrls
) {
628 // Add content to history service.
629 // There are two redirect urls before reacing malware url:
630 // kFirstRedirectURL -> kSecondRedirectURL -> kMalwareURL
631 GURL
baseurl(kMalwareURL
);
632 history::RedirectList redirects
;
633 redirects
.push_back(GURL(kFirstRedirectURL
));
634 redirects
.push_back(GURL(kSecondRedirectURL
));
635 AddPageToHistory(baseurl
, &redirects
);
636 // Wait for history service operation finished.
637 profile()->BlockUntilHistoryProcessesPendingRequests();
639 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
640 ui::PAGE_TRANSITION_TYPED
, std::string());
642 UnsafeResource resource
;
643 InitResource(&resource
, true, GURL(kMalwareURL
));
644 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
645 ui_manager_
.get(), web_contents(), resource
, NULL
);
647 // The redirects collection starts after the IPC from the DOM is fired.
648 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
649 report
->OnReceivedMalwareDOMDetails(params
);
651 // Let the redirects callbacks complete.
652 base::RunLoop().RunUntilIdle();
654 std::string serialized
= WaitForSerializedReport(report
.get());
655 ClientMalwareReportRequest actual
;
656 actual
.ParseFromString(serialized
);
658 ClientMalwareReportRequest expected
;
659 expected
.set_malware_url(kMalwareURL
);
660 expected
.set_page_url(kLandingURL
);
661 expected
.set_referrer_url("");
663 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
664 pb_resource
->set_id(0);
665 pb_resource
->set_url(kLandingURL
);
666 pb_resource
= expected
.add_resources();
667 pb_resource
->set_id(1);
668 pb_resource
->set_parent_id(2);
669 pb_resource
->set_url(kMalwareURL
);
670 pb_resource
= expected
.add_resources();
671 pb_resource
->set_id(2);
672 pb_resource
->set_parent_id(3);
673 pb_resource
->set_url(kSecondRedirectURL
);
674 pb_resource
= expected
.add_resources();
675 pb_resource
->set_id(3);
676 pb_resource
->set_url(kFirstRedirectURL
);
678 VerifyResults(actual
, expected
);