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_service_factory.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/safe_browsing/malware_details.h"
14 #include "chrome/browser/safe_browsing/malware_details_history.h"
15 #include "chrome/browser/safe_browsing/report.pb.h"
16 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
17 #include "chrome/browser/safe_browsing/ui_manager.h"
18 #include "chrome/common/safe_browsing/safebrowsing_messages.h"
19 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/history/core/browser/history_backend.h"
22 #include "components/history/core/browser/history_service.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/web_contents.h"
25 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h"
27 #include "net/base/test_completion_callback.h"
28 #include "net/disk_cache/disk_cache.h"
29 #include "net/http/http_cache.h"
30 #include "net/http/http_response_headers.h"
31 #include "net/http/http_response_info.h"
32 #include "net/http/http_util.h"
33 #include "net/url_request/url_request_context.h"
34 #include "net/url_request/url_request_context_getter.h"
36 // Mixture of HTTP and HTTPS. No special treatment for HTTPS.
37 static const char* kOriginalLandingURL
=
38 "http://www.originallandingpage.com/with/path";
39 static const char* kDOMChildURL
= "https://www.domparent.com/with/path";
40 static const char* kDOMParentURL
= "https://www.domchild.com/with/path";
41 static const char* kFirstRedirectURL
= "http://redirectone.com/with/path";
42 static const char* kSecondRedirectURL
= "https://redirecttwo.com/with/path";
43 static const char* kReferrerURL
= "http://www.referrer.com/with/path";
45 static const char* kMalwareURL
= "http://www.malware.com/with/path";
46 static const char* kMalwareHeaders
=
48 "Content-Type: image/jpeg\n";
49 static const char* kMalwareData
= "exploit();";
51 static const char* kLandingURL
= "http://www.landingpage.com/with/path";
52 static const char* kLandingHeaders
=
54 "Content-Type: text/html\n"
55 "Content-Length: 1024\n"
56 "Set-Cookie: tastycookie\n"; // This header is stripped.
57 static const char* kLandingData
=
58 "<iframe src='http://www.malware.com/with/path'>";
61 using content::BrowserThread
;
62 using content::WebContents
;
63 using safe_browsing::ClientMalwareReportRequest
;
67 void WriteHeaders(disk_cache::Entry
* entry
, const std::string
& headers
) {
68 net::HttpResponseInfo responseinfo
;
69 std::string raw_headers
= net::HttpUtil::AssembleRawHeaders(
70 headers
.c_str(), headers
.size());
71 responseinfo
.socket_address
= net::HostPortPair("1.2.3.4", 80);
72 responseinfo
.headers
= new net::HttpResponseHeaders(raw_headers
);
75 responseinfo
.Persist(&pickle
, false, false);
77 scoped_refptr
<net::WrappedIOBuffer
> buf(new net::WrappedIOBuffer(
78 reinterpret_cast<const char*>(pickle
.data())));
79 int len
= static_cast<int>(pickle
.size());
81 net::TestCompletionCallback cb
;
82 int rv
= entry
->WriteData(0, 0, buf
.get(), len
, cb
.callback(), true);
83 ASSERT_EQ(len
, cb
.GetResult(rv
));
86 void WriteData(disk_cache::Entry
* entry
, const std::string
& data
) {
90 int len
= data
.length();
91 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(len
));
92 memcpy(buf
->data(), data
.data(), data
.length());
94 net::TestCompletionCallback cb
;
95 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
96 ASSERT_EQ(len
, cb
.GetResult(rv
));
99 void WriteToEntry(disk_cache::Backend
* cache
, const std::string
& key
,
100 const std::string
& headers
, const std::string
& data
) {
101 net::TestCompletionCallback cb
;
102 disk_cache::Entry
* entry
;
103 int rv
= cache
->CreateEntry(key
, &entry
, cb
.callback());
104 rv
= cb
.GetResult(rv
);
106 rv
= cache
->OpenEntry(key
, &entry
, cb
.callback());
107 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
110 WriteHeaders(entry
, headers
);
111 WriteData(entry
, data
);
115 void FillCache(net::URLRequestContextGetter
* context_getter
) {
116 net::TestCompletionCallback cb
;
117 disk_cache::Backend
* cache
;
119 context_getter
->GetURLRequestContext()->http_transaction_factory()->
120 GetCache()->GetBackend(&cache
, cb
.callback());
121 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
123 WriteToEntry(cache
, kMalwareURL
, kMalwareHeaders
, kMalwareData
);
124 WriteToEntry(cache
, kLandingURL
, kLandingHeaders
, kLandingData
);
127 // Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate.
128 // Also exposes the constructor.
129 class MalwareDetailsWrap
: public MalwareDetails
{
132 SafeBrowsingUIManager
* ui_manager
,
133 WebContents
* web_contents
,
134 const SafeBrowsingUIManager::UnsafeResource
& unsafe_resource
,
135 net::URLRequestContextGetter
* request_context_getter
)
136 : MalwareDetails(ui_manager
, web_contents
, unsafe_resource
) {
137 request_context_getter_
= request_context_getter
;
141 ~MalwareDetailsWrap() override
{}
144 class MockSafeBrowsingUIManager
: public SafeBrowsingUIManager
{
146 base::RunLoop
* run_loop_
;
147 // The safe browsing UI manager does not need a service for this test.
148 MockSafeBrowsingUIManager()
149 : SafeBrowsingUIManager(NULL
), run_loop_(NULL
) {}
151 // When the MalwareDetails is done, this is called.
152 void SendSerializedMalwareDetails(const std::string
& serialized
) override
{
153 DVLOG(1) << "SendSerializedMalwareDetails";
156 serialized_
= serialized
;
159 // Used to synchronize SendSerializedMalwareDetails() with
160 // WaitForSerializedReport(). RunLoop::RunUntilIdle() is not sufficient
161 // because the MessageLoop task queue completely drains at some point
162 // between the send and the wait.
163 void SetRunLoopToQuit(base::RunLoop
* run_loop
) {
164 DCHECK(run_loop_
== NULL
);
165 run_loop_
= run_loop
;
168 const std::string
& GetSerialized() {
173 ~MockSafeBrowsingUIManager() override
{}
175 std::string serialized_
;
176 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager
);
181 class MalwareDetailsTest
: public ChromeRenderViewHostTestHarness
{
183 typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource
;
186 : ui_manager_(new MockSafeBrowsingUIManager()) {
189 void SetUp() override
{
190 ChromeRenderViewHostTestHarness::SetUp();
191 ASSERT_TRUE(profile()->CreateHistoryService(
192 true /* delete_file */, false /* no_db */));
195 void TearDown() override
{
196 profile()->DestroyHistoryService();
197 ChromeRenderViewHostTestHarness::TearDown();
200 static bool ResourceLessThan(
201 const ClientMalwareReportRequest::Resource
* lhs
,
202 const ClientMalwareReportRequest::Resource
* rhs
) {
203 return lhs
->id() < rhs
->id();
206 std::string
WaitForSerializedReport(MalwareDetails
* report
,
209 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
210 base::Bind(&MalwareDetails::FinishCollection
,
211 report
, did_proceed
, num_visit
));
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 history::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());
243 EXPECT_EQ(expected_pb
.did_proceed(), report_pb
.did_proceed());
244 EXPECT_EQ(expected_pb
.has_repeat_visit(), report_pb
.has_repeat_visit());
245 if (expected_pb
.has_repeat_visit() && report_pb
.has_repeat_visit()) {
246 EXPECT_EQ(expected_pb
.repeat_visit(), report_pb
.repeat_visit());
249 ASSERT_EQ(expected_pb
.resources_size(), report_pb
.resources_size());
250 // Sort the resources, to make the test deterministic
251 std::vector
<const ClientMalwareReportRequest::Resource
*> resources
;
252 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
253 const ClientMalwareReportRequest::Resource
& resource
=
254 report_pb
.resources(i
);
255 resources
.push_back(&resource
);
257 std::sort(resources
.begin(), resources
.end(),
258 &MalwareDetailsTest::ResourceLessThan
);
260 std::vector
<const ClientMalwareReportRequest::Resource
*> expected
;
261 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
262 const ClientMalwareReportRequest::Resource
& resource
=
263 expected_pb
.resources(i
);
264 expected
.push_back(&resource
);
266 std::sort(expected
.begin(), expected
.end(),
267 &MalwareDetailsTest::ResourceLessThan
);
269 for (uint32 i
= 0; i
< expected
.size(); ++i
) {
270 VerifyResource(resources
[i
], expected
[i
]);
273 EXPECT_EQ(expected_pb
.complete(), report_pb
.complete());
276 void VerifyResource(const ClientMalwareReportRequest::Resource
* resource
,
277 const ClientMalwareReportRequest::Resource
* expected
) {
278 EXPECT_EQ(expected
->id(), resource
->id());
279 EXPECT_EQ(expected
->url(), resource
->url());
280 EXPECT_EQ(expected
->parent_id(), resource
->parent_id());
281 ASSERT_EQ(expected
->child_ids_size(), resource
->child_ids_size());
282 for (int i
= 0; i
< expected
->child_ids_size(); i
++) {
283 EXPECT_EQ(expected
->child_ids(i
), resource
->child_ids(i
));
286 // Verify HTTP Responses
287 if (expected
->has_response()) {
288 ASSERT_TRUE(resource
->has_response());
289 EXPECT_EQ(expected
->response().firstline().code(),
290 resource
->response().firstline().code());
292 ASSERT_EQ(expected
->response().headers_size(),
293 resource
->response().headers_size());
294 for (int i
= 0; i
< expected
->response().headers_size(); ++i
) {
295 EXPECT_EQ(expected
->response().headers(i
).name(),
296 resource
->response().headers(i
).name());
297 EXPECT_EQ(expected
->response().headers(i
).value(),
298 resource
->response().headers(i
).value());
301 EXPECT_EQ(expected
->response().body(), resource
->response().body());
302 EXPECT_EQ(expected
->response().bodylength(),
303 resource
->response().bodylength());
304 EXPECT_EQ(expected
->response().bodydigest(),
305 resource
->response().bodydigest());
308 // Verify IP:port pair
309 EXPECT_EQ(expected
->response().remote_ip(),
310 resource
->response().remote_ip());
313 // Adds a page to history.
314 // The redirects is the redirect url chain leading to the url.
315 void AddPageToHistory(const GURL
& url
,
316 history::RedirectList
* redirects
) {
317 // The last item of the redirect chain has to be the final url when adding
318 // to history backend.
319 redirects
->push_back(url
);
320 history_service()->AddPage(
321 url
, base::Time::Now(), reinterpret_cast<history::ContextID
>(1), 0,
322 GURL(), *redirects
, ui::PAGE_TRANSITION_TYPED
,
323 history::SOURCE_BROWSED
, false);
326 scoped_refptr
<MockSafeBrowsingUIManager
> ui_manager_
;
329 // Tests creating a simple malware report.
330 TEST_F(MalwareDetailsTest
, MalwareSubResource
) {
332 controller().LoadURL(
334 content::Referrer(GURL(kReferrerURL
), blink::WebReferrerPolicyDefault
),
335 ui::PAGE_TRANSITION_TYPED
, std::string());
337 UnsafeResource resource
;
338 InitResource(&resource
, true, GURL(kMalwareURL
));
340 scoped_refptr
<MalwareDetailsWrap
> report
=
341 new MalwareDetailsWrap(ui_manager_
.get(), web_contents(), resource
, NULL
);
343 std::string serialized
= WaitForSerializedReport(
344 report
.get(), true /* did_proceed*/, 1 /* num_visit */);
346 ClientMalwareReportRequest actual
;
347 actual
.ParseFromString(serialized
);
349 ClientMalwareReportRequest expected
;
350 expected
.set_malware_url(kMalwareURL
);
351 expected
.set_page_url(kLandingURL
);
352 // Note that the referrer policy is not actually enacted here, since that's
354 expected
.set_referrer_url(kReferrerURL
);
355 expected
.set_did_proceed(true);
356 expected
.set_repeat_visit(true);
358 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
359 pb_resource
->set_id(0);
360 pb_resource
->set_url(kLandingURL
);
361 pb_resource
= expected
.add_resources();
362 pb_resource
->set_id(1);
363 pb_resource
->set_url(kMalwareURL
);
364 pb_resource
= expected
.add_resources();
365 pb_resource
->set_id(2);
366 pb_resource
->set_url(kReferrerURL
);
368 VerifyResults(actual
, expected
);
371 // Tests creating a simple malware report where the subresource has a
372 // different original_url.
373 TEST_F(MalwareDetailsTest
, MalwareSubResourceWithOriginalUrl
) {
374 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
375 ui::PAGE_TRANSITION_TYPED
, std::string());
377 UnsafeResource resource
;
378 InitResource(&resource
, true, GURL(kMalwareURL
));
379 resource
.original_url
= GURL(kOriginalLandingURL
);
381 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
382 ui_manager_
.get(), web_contents(), resource
, NULL
);
384 std::string serialized
= WaitForSerializedReport(
385 report
.get(), false /* did_proceed*/, 1 /* num_visit */);
387 ClientMalwareReportRequest actual
;
388 actual
.ParseFromString(serialized
);
390 ClientMalwareReportRequest expected
;
391 expected
.set_malware_url(kMalwareURL
);
392 expected
.set_page_url(kLandingURL
);
393 expected
.set_referrer_url("");
394 expected
.set_did_proceed(false);
395 expected
.set_repeat_visit(true);
397 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
398 pb_resource
->set_id(0);
399 pb_resource
->set_url(kLandingURL
);
401 pb_resource
= expected
.add_resources();
402 pb_resource
->set_id(1);
403 pb_resource
->set_url(kOriginalLandingURL
);
405 pb_resource
= expected
.add_resources();
406 pb_resource
->set_id(2);
407 pb_resource
->set_url(kMalwareURL
);
408 // The Resource for kMalwareUrl should have the Resource for
409 // kOriginalLandingURL (with id 1) as parent.
410 pb_resource
->set_parent_id(1);
412 VerifyResults(actual
, expected
);
415 // Tests creating a malware report with data from the renderer.
416 TEST_F(MalwareDetailsTest
, MalwareDOMDetails
) {
417 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
418 ui::PAGE_TRANSITION_TYPED
, std::string());
420 UnsafeResource resource
;
421 InitResource(&resource
, true, GURL(kMalwareURL
));
423 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
424 ui_manager_
.get(), web_contents(), resource
, NULL
);
426 // Send a message from the DOM, with 2 nodes, a parent and a child.
427 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
428 SafeBrowsingHostMsg_MalwareDOMDetails_Node child_node
;
429 child_node
.url
= GURL(kDOMChildURL
);
430 child_node
.tag_name
= "iframe";
431 child_node
.parent
= GURL(kDOMParentURL
);
432 params
.push_back(child_node
);
433 SafeBrowsingHostMsg_MalwareDOMDetails_Node parent_node
;
434 parent_node
.url
= GURL(kDOMParentURL
);
435 parent_node
.children
.push_back(GURL(kDOMChildURL
));
436 params
.push_back(parent_node
);
437 report
->OnReceivedMalwareDOMDetails(params
);
439 std::string serialized
= WaitForSerializedReport(
440 report
.get(), false /* did_proceed*/, 0 /* num_visit */);
441 ClientMalwareReportRequest actual
;
442 actual
.ParseFromString(serialized
);
444 ClientMalwareReportRequest expected
;
445 expected
.set_malware_url(kMalwareURL
);
446 expected
.set_page_url(kLandingURL
);
447 expected
.set_referrer_url("");
448 expected
.set_did_proceed(false);
449 expected
.set_repeat_visit(false);
451 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
452 pb_resource
->set_id(0);
453 pb_resource
->set_url(kLandingURL
);
455 pb_resource
= expected
.add_resources();
456 pb_resource
->set_id(1);
457 pb_resource
->set_url(kMalwareURL
);
459 pb_resource
= expected
.add_resources();
460 pb_resource
->set_id(2);
461 pb_resource
->set_url(kDOMChildURL
);
462 pb_resource
->set_parent_id(3);
464 pb_resource
= expected
.add_resources();
465 pb_resource
->set_id(3);
466 pb_resource
->set_url(kDOMParentURL
);
467 pb_resource
->add_child_ids(2);
468 expected
.set_complete(false); // Since the cache was missing.
470 VerifyResults(actual
, expected
);
473 // Tests creating a malware report where there are redirect urls to an unsafe
475 TEST_F(MalwareDetailsTest
, MalwareWithRedirectUrl
) {
476 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
477 ui::PAGE_TRANSITION_TYPED
, std::string());
479 UnsafeResource resource
;
480 InitResource(&resource
, true, GURL(kMalwareURL
));
481 resource
.original_url
= GURL(kOriginalLandingURL
);
483 // add some redirect urls
484 resource
.redirect_urls
.push_back(GURL(kFirstRedirectURL
));
485 resource
.redirect_urls
.push_back(GURL(kSecondRedirectURL
));
486 resource
.redirect_urls
.push_back(GURL(kMalwareURL
));
488 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
489 ui_manager_
.get(), web_contents(), resource
, NULL
);
491 std::string serialized
= WaitForSerializedReport(
492 report
.get(), true /* did_proceed*/, 0 /* num_visit */);
493 ClientMalwareReportRequest actual
;
494 actual
.ParseFromString(serialized
);
496 ClientMalwareReportRequest expected
;
497 expected
.set_malware_url(kMalwareURL
);
498 expected
.set_page_url(kLandingURL
);
499 expected
.set_referrer_url("");
500 expected
.set_did_proceed(true);
501 expected
.set_repeat_visit(false);
503 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
504 pb_resource
->set_id(0);
505 pb_resource
->set_url(kLandingURL
);
507 pb_resource
= expected
.add_resources();
508 pb_resource
->set_id(1);
509 pb_resource
->set_url(kOriginalLandingURL
);
511 pb_resource
= expected
.add_resources();
512 pb_resource
->set_id(2);
513 pb_resource
->set_url(kMalwareURL
);
514 pb_resource
->set_parent_id(4);
516 pb_resource
= expected
.add_resources();
517 pb_resource
->set_id(3);
518 pb_resource
->set_url(kFirstRedirectURL
);
519 pb_resource
->set_parent_id(1);
521 pb_resource
= expected
.add_resources();
522 pb_resource
->set_id(4);
523 pb_resource
->set_url(kSecondRedirectURL
);
524 pb_resource
->set_parent_id(3);
526 VerifyResults(actual
, expected
);
529 // Tests the interaction with the HTTP cache.
530 TEST_F(MalwareDetailsTest
, HTTPCache
) {
531 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
532 ui::PAGE_TRANSITION_TYPED
, std::string());
534 UnsafeResource resource
;
535 InitResource(&resource
, true, GURL(kMalwareURL
));
537 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
538 ui_manager_
.get(), web_contents(), resource
,
539 profile()->GetRequestContext());
541 BrowserThread::PostTask(
542 BrowserThread::IO
, FROM_HERE
,
543 base::Bind(&FillCache
,
544 make_scoped_refptr(profile()->GetRequestContext())));
546 // The cache collection starts after the IPC from the DOM is fired.
547 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
548 report
->OnReceivedMalwareDOMDetails(params
);
550 // Let the cache callbacks complete.
551 base::RunLoop().RunUntilIdle();
553 DVLOG(1) << "Getting serialized report";
554 std::string serialized
= WaitForSerializedReport(
555 report
.get(), true /* did_proceed*/, -1 /* num_visit */);
556 ClientMalwareReportRequest actual
;
557 actual
.ParseFromString(serialized
);
559 ClientMalwareReportRequest expected
;
560 expected
.set_malware_url(kMalwareURL
);
561 expected
.set_page_url(kLandingURL
);
562 expected
.set_referrer_url("");
563 expected
.set_did_proceed(true);
565 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
566 pb_resource
->set_id(0);
567 pb_resource
->set_url(kLandingURL
);
568 safe_browsing::ClientMalwareReportRequest::HTTPResponse
* pb_response
=
569 pb_resource
->mutable_response();
570 pb_response
->mutable_firstline()->set_code(200);
571 safe_browsing::ClientMalwareReportRequest::HTTPHeader
* pb_header
=
572 pb_response
->add_headers();
573 pb_header
->set_name("Content-Type");
574 pb_header
->set_value("text/html");
575 pb_header
= pb_response
->add_headers();
576 pb_header
->set_name("Content-Length");
577 pb_header
->set_value("1024");
578 pb_header
= pb_response
->add_headers();
579 pb_header
->set_name("Set-Cookie");
580 pb_header
->set_value(""); // The cookie is dropped.
581 pb_response
->set_body(kLandingData
);
582 pb_response
->set_bodylength(47);
583 pb_response
->set_bodydigest("5abb4e63d806ec2c16a40b2699700554");
584 pb_response
->set_remote_ip("1.2.3.4:80");
586 pb_resource
= expected
.add_resources();
587 pb_resource
->set_id(1);
588 pb_resource
->set_url(kMalwareURL
);
589 pb_response
= pb_resource
->mutable_response();
590 pb_response
->mutable_firstline()->set_code(200);
591 pb_header
= pb_response
->add_headers();
592 pb_header
->set_name("Content-Type");
593 pb_header
->set_value("image/jpeg");
594 pb_response
->set_body(kMalwareData
);
595 pb_response
->set_bodylength(10);
596 pb_response
->set_bodydigest("581373551c43d4cf33bfb3b26838ff95");
597 pb_response
->set_remote_ip("1.2.3.4:80");
598 expected
.set_complete(true);
600 VerifyResults(actual
, expected
);
603 // Tests the interaction with the HTTP cache (where the cache is empty).
604 TEST_F(MalwareDetailsTest
, HTTPCacheNoEntries
) {
605 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
606 ui::PAGE_TRANSITION_TYPED
, std::string());
608 UnsafeResource resource
;
609 InitResource(&resource
, true, GURL(kMalwareURL
));
611 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
612 ui_manager_
.get(), web_contents(), resource
,
613 profile()->GetRequestContext());
615 // No call to FillCache
617 // The cache collection starts after the IPC from the DOM is fired.
618 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
619 report
->OnReceivedMalwareDOMDetails(params
);
621 // Let the cache callbacks complete.
622 base::RunLoop().RunUntilIdle();
624 DVLOG(1) << "Getting serialized report";
625 std::string serialized
= WaitForSerializedReport(
626 report
.get(), false /* did_proceed*/, -1 /* num_visit */);
627 ClientMalwareReportRequest actual
;
628 actual
.ParseFromString(serialized
);
630 ClientMalwareReportRequest expected
;
631 expected
.set_malware_url(kMalwareURL
);
632 expected
.set_page_url(kLandingURL
);
633 expected
.set_referrer_url("");
634 expected
.set_did_proceed(false);
636 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
637 pb_resource
->set_id(0);
638 pb_resource
->set_url(kLandingURL
);
639 pb_resource
= expected
.add_resources();
640 pb_resource
->set_id(1);
641 pb_resource
->set_url(kMalwareURL
);
642 expected
.set_complete(true);
644 VerifyResults(actual
, expected
);
647 // Test getting redirects from history service.
648 TEST_F(MalwareDetailsTest
, HistoryServiceUrls
) {
649 // Add content to history service.
650 // There are two redirect urls before reacing malware url:
651 // kFirstRedirectURL -> kSecondRedirectURL -> kMalwareURL
652 GURL
baseurl(kMalwareURL
);
653 history::RedirectList redirects
;
654 redirects
.push_back(GURL(kFirstRedirectURL
));
655 redirects
.push_back(GURL(kSecondRedirectURL
));
656 AddPageToHistory(baseurl
, &redirects
);
657 // Wait for history service operation finished.
658 profile()->BlockUntilHistoryProcessesPendingRequests();
660 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
661 ui::PAGE_TRANSITION_TYPED
, std::string());
663 UnsafeResource resource
;
664 InitResource(&resource
, true, GURL(kMalwareURL
));
665 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
666 ui_manager_
.get(), web_contents(), resource
, NULL
);
668 // The redirects collection starts after the IPC from the DOM is fired.
669 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
670 report
->OnReceivedMalwareDOMDetails(params
);
672 // Let the redirects callbacks complete.
673 base::RunLoop().RunUntilIdle();
675 std::string serialized
= WaitForSerializedReport(
676 report
.get(), true /* did_proceed*/, 1 /* num_visit */);
677 ClientMalwareReportRequest actual
;
678 actual
.ParseFromString(serialized
);
680 ClientMalwareReportRequest expected
;
681 expected
.set_malware_url(kMalwareURL
);
682 expected
.set_page_url(kLandingURL
);
683 expected
.set_referrer_url("");
684 expected
.set_did_proceed(true);
685 expected
.set_repeat_visit(true);
687 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
688 pb_resource
->set_id(0);
689 pb_resource
->set_url(kLandingURL
);
690 pb_resource
= expected
.add_resources();
691 pb_resource
->set_id(1);
692 pb_resource
->set_parent_id(2);
693 pb_resource
->set_url(kMalwareURL
);
694 pb_resource
= expected
.add_resources();
695 pb_resource
->set_id(2);
696 pb_resource
->set_parent_id(3);
697 pb_resource
->set_url(kSecondRedirectURL
);
698 pb_resource
= expected
.add_resources();
699 pb_resource
->set_id(3);
700 pb_resource
->set_url(kFirstRedirectURL
);
702 VerifyResults(actual
, expected
);