Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: chrome/browser/safe_browsing/protocol_manager.cc

Issue 2868030: Add switches and apis in safebrowsing code to allow tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/protocol_manager.h" 5 #include "chrome/browser/safe_browsing/protocol_manager.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/env_var.h" 8 #include "base/env_var.h"
9 #include "base/file_version_info.h" 9 #include "base/file_version_info.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
(...skipping 16 matching lines...) Expand all
27 27
28 using base::Time; 28 using base::Time;
29 using base::TimeDelta; 29 using base::TimeDelta;
30 30
31 // Maximum time, in seconds, from start up before we must issue an update query. 31 // Maximum time, in seconds, from start up before we must issue an update query.
32 static const int kSbTimerStartIntervalSec = 5 * 60; 32 static const int kSbTimerStartIntervalSec = 5 * 60;
33 33
34 // The maximum time, in seconds, to wait for a response to an update request. 34 // The maximum time, in seconds, to wait for a response to an update request.
35 static const int kSbMaxUpdateWaitSec = 10; 35 static const int kSbMaxUpdateWaitSec = 10;
36 36
37 // Update URL for querying about the latest set of chunk updates.
38 static const char* const kSbUpdateUrl =
39 "http://safebrowsing.clients.google.com/safebrowsing/downloads?client=%s"
40 "&appver=%s&pver=2.2";
41
42 // GetHash request URL for retrieving full hashes.
43 static const char* const kSbGetHashUrl =
44 "http://safebrowsing.clients.google.com/safebrowsing/gethash?client=%s"
45 "&appver=%s&pver=2.2";
46
47 // New MAC client key requests URL.
48 static const char* const kSbNewKeyUrl =
49 "https://sb-ssl.google.com/safebrowsing/newkey?client=%s&appver=%s"
50 "&pver=2.2";
51
52 // URL for reporting malware pages.
53 static const char* const kSbMalwareReportUrl =
54 "http://safebrowsing.clients.google.com/safebrowsing/report?evts=malblhit"
55 "&evtd=%s&evtr=%s&evhr=%s&client=%s&appver=%s";
56
57 // Maximum back off multiplier. 37 // Maximum back off multiplier.
58 static const int kSbMaxBackOff = 8; 38 static const int kSbMaxBackOff = 8;
59 39
60 40
61 // SafeBrowsingProtocolManager implementation ---------------------------------- 41 // SafeBrowsingProtocolManager implementation ----------------------------------
62 42
63 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager( 43 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager(
64 SafeBrowsingService* sb_service, 44 SafeBrowsingService* sb_service,
65 const std::string& client_name, 45 const std::string& client_name,
66 const std::string& client_key, 46 const std::string& client_key,
67 const std::string& wrapped_key, 47 const std::string& wrapped_key,
68 URLRequestContextGetter* request_context_getter) 48 URLRequestContextGetter* request_context_getter,
49 const std::string& info_url_prefix,
50 const std::string& mackey_url_prefix,
51 bool disable_auto_update)
69 : sb_service_(sb_service), 52 : sb_service_(sb_service),
70 request_type_(NO_REQUEST), 53 request_type_(NO_REQUEST),
71 update_error_count_(0), 54 update_error_count_(0),
72 gethash_error_count_(0), 55 gethash_error_count_(0),
73 update_back_off_mult_(1), 56 update_back_off_mult_(1),
74 gethash_back_off_mult_(1), 57 gethash_back_off_mult_(1),
75 next_update_sec_(-1), 58 next_update_sec_(-1),
76 update_state_(FIRST_REQUEST), 59 update_state_(FIRST_REQUEST),
77 initial_request_(true), 60 initial_request_(true),
78 chunk_pending_to_write_(false), 61 chunk_pending_to_write_(false),
79 client_key_(client_key), 62 client_key_(client_key),
80 wrapped_key_(wrapped_key), 63 wrapped_key_(wrapped_key),
81 update_size_(0), 64 update_size_(0),
82 client_name_(client_name), 65 client_name_(client_name),
83 request_context_getter_(request_context_getter) { 66 request_context_getter_(request_context_getter),
67 info_url_prefix_(info_url_prefix),
68 mackey_url_prefix_(mackey_url_prefix),
69 disable_auto_update_(disable_auto_update) {
70 DCHECK(!info_url_prefix_.empty() && !mackey_url_prefix_.empty());
71
84 // Set the backoff multiplier fuzz to a random value between 0 and 1. 72 // Set the backoff multiplier fuzz to a random value between 0 and 1.
85 back_off_fuzz_ = static_cast<float>(base::RandDouble()); 73 back_off_fuzz_ = static_cast<float>(base::RandDouble());
86
87 // The first update must happen between 1-5 minutes of start up. 74 // The first update must happen between 1-5 minutes of start up.
88 next_update_sec_ = base::RandInt(60, kSbTimerStartIntervalSec); 75 next_update_sec_ = base::RandInt(60, kSbTimerStartIntervalSec);
89 76
90 scoped_ptr<FileVersionInfo> version_info( 77 scoped_ptr<FileVersionInfo> version_info(chrome_app::GetChromeVersionInfo());
91 chrome_app::GetChromeVersionInfo());
92 if (!version_info.get()) 78 if (!version_info.get())
93 version_ = "0.1"; 79 version_ = "0.1";
94 else 80 else
95 version_ = WideToASCII(version_info->product_version()); 81 version_ = WideToASCII(version_info->product_version());
96 } 82 }
97 83
98 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { 84 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() {
99 // Delete in-progress SafeBrowsing requests. 85 // Delete in-progress SafeBrowsing requests.
100 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), 86 STLDeleteContainerPairFirstPointers(hash_requests_.begin(),
101 hash_requests_.end()); 87 hash_requests_.end());
(...skipping 13 matching lines...) Expand all
115 SafeBrowsingService::SafeBrowsingCheck* check, 101 SafeBrowsingService::SafeBrowsingCheck* check,
116 const std::vector<SBPrefix>& prefixes) { 102 const std::vector<SBPrefix>& prefixes) {
117 // If we are in GetHash backoff, we need to check if we're past the next 103 // If we are in GetHash backoff, we need to check if we're past the next
118 // allowed time. If we are, we can proceed with the request. If not, we are 104 // allowed time. If we are, we can proceed with the request. If not, we are
119 // required to return empty results (i.e. treat the page as safe). 105 // required to return empty results (i.e. treat the page as safe).
120 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) { 106 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) {
121 std::vector<SBFullHashResult> full_hashes; 107 std::vector<SBFullHashResult> full_hashes;
122 sb_service_->HandleGetHashResults(check, full_hashes, false); 108 sb_service_->HandleGetHashResults(check, full_hashes, false);
123 return; 109 return;
124 } 110 }
125 111 bool use_mac = !client_key_.empty();
126 std::string url = StringPrintf(kSbGetHashUrl, 112 GURL gethash_url = GetHashUrl(use_mac);
127 client_name_.c_str(),
128 version_.c_str());
129 if (!client_key_.empty()) {
130 url.append("&wrkey=");
131 url.append(wrapped_key_);
132 }
133
134 GURL gethash_url(url);
135 URLFetcher* fetcher = new URLFetcher(gethash_url, URLFetcher::POST, this); 113 URLFetcher* fetcher = new URLFetcher(gethash_url, URLFetcher::POST, this);
136 hash_requests_[fetcher] = check; 114 hash_requests_[fetcher] = check;
137 115
138 std::string get_hash; 116 std::string get_hash;
139 SafeBrowsingProtocolParser parser; 117 SafeBrowsingProtocolParser parser;
140 parser.FormatGetHash(prefixes, &get_hash); 118 parser.FormatGetHash(prefixes, &get_hash);
141 119
142 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE); 120 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE);
143 fetcher->set_request_context(request_context_getter_); 121 fetcher->set_request_context(request_context_getter_);
144 fetcher->set_upload_data("text/plain", get_hash); 122 fetcher->set_upload_data("text/plain", get_hash);
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 void SafeBrowsingProtocolManager::Initialize() { 419 void SafeBrowsingProtocolManager::Initialize() {
442 // Don't want to hit the safe browsing servers on build/chrome bots. 420 // Don't want to hit the safe browsing servers on build/chrome bots.
443 scoped_ptr<base::EnvVarGetter> env(base::EnvVarGetter::Create()); 421 scoped_ptr<base::EnvVarGetter> env(base::EnvVarGetter::Create());
444 if (env->HasEnv(env_vars::kHeadless)) 422 if (env->HasEnv(env_vars::kHeadless))
445 return; 423 return;
446 424
447 ScheduleNextUpdate(false /* no back off */); 425 ScheduleNextUpdate(false /* no back off */);
448 } 426 }
449 427
450 void SafeBrowsingProtocolManager::ScheduleNextUpdate(bool back_off) { 428 void SafeBrowsingProtocolManager::ScheduleNextUpdate(bool back_off) {
451 DCHECK(next_update_sec_ > 0); 429 DCHECK_GT(next_update_sec_, 0);
452 430
431 if (disable_auto_update_) {
432 // Unschedule any current timer.
433 update_timer_.Stop();
434 return;
435 }
436 // Reschedule with the new update.
437 const int next_update = GetNextUpdateTime(back_off);
438 ForceScheduleNextUpdate(next_update);
439 }
440
441 void SafeBrowsingProtocolManager::ForceScheduleNextUpdate(
442 const int next_update_msec) {
443 DCHECK_GE(next_update_msec, 0);
453 // Unschedule any current timer. 444 // Unschedule any current timer.
454 update_timer_.Stop(); 445 update_timer_.Stop();
455 446 update_timer_.Start(TimeDelta::FromMilliseconds(next_update_msec), this,
456 // Reschedule with the new update.
457 const int next_update = GetNextUpdateTime(back_off);
458 update_timer_.Start(TimeDelta::FromMilliseconds(next_update), this,
459 &SafeBrowsingProtocolManager::GetNextUpdate); 447 &SafeBrowsingProtocolManager::GetNextUpdate);
460 } 448 }
461 449
462 // According to section 5 of the SafeBrowsing protocol specification, we must 450 // According to section 5 of the SafeBrowsing protocol specification, we must
463 // back off after a certain number of errors. We only change 'next_update_sec_' 451 // back off after a certain number of errors. We only change 'next_update_sec_'
464 // when we receive a response from the SafeBrowsing service. 452 // when we receive a response from the SafeBrowsing service.
465 int SafeBrowsingProtocolManager::GetNextUpdateTime(bool back_off) { 453 int SafeBrowsingProtocolManager::GetNextUpdateTime(bool back_off) {
466 int next = next_update_sec_; 454 int next = next_update_sec_;
467 if (back_off) { 455 if (back_off) {
468 next = GetNextBackOffTime(&update_error_count_, &update_back_off_mult_); 456 next = GetNextBackOffTime(&update_error_count_, &update_back_off_mult_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 494
507 void SafeBrowsingProtocolManager::IssueChunkRequest() { 495 void SafeBrowsingProtocolManager::IssueChunkRequest() {
508 // We are only allowed to have one request outstanding at any time. Also, 496 // We are only allowed to have one request outstanding at any time. Also,
509 // don't get the next url until the previous one has been written to disk so 497 // don't get the next url until the previous one has been written to disk so
510 // that we don't use too much memory. 498 // that we don't use too much memory.
511 if (request_.get() || chunk_request_urls_.empty() || chunk_pending_to_write_) 499 if (request_.get() || chunk_request_urls_.empty() || chunk_pending_to_write_)
512 return; 500 return;
513 501
514 ChunkUrl next_chunk = chunk_request_urls_.front(); 502 ChunkUrl next_chunk = chunk_request_urls_.front();
515 DCHECK(!next_chunk.url.empty()); 503 DCHECK(!next_chunk.url.empty());
516 if (!StartsWithASCII(next_chunk.url, "http://", false) && 504 GURL chunk_url = NextChunkUrl(next_chunk.url);
517 !StartsWithASCII(next_chunk.url, "https://", false))
518 next_chunk.url = "http://" + next_chunk.url;
519 GURL chunk_url(next_chunk.url);
520 request_type_ = CHUNK_REQUEST; 505 request_type_ = CHUNK_REQUEST;
521 request_.reset(new URLFetcher(chunk_url, URLFetcher::GET, this)); 506 request_.reset(new URLFetcher(chunk_url, URLFetcher::GET, this));
522 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 507 request_->set_load_flags(net::LOAD_DISABLE_CACHE);
523 request_->set_request_context(request_context_getter_); 508 request_->set_request_context(request_context_getter_);
524 chunk_request_start_ = base::Time::Now(); 509 chunk_request_start_ = base::Time::Now();
525 request_->Start(); 510 request_->Start();
526 } 511 }
527 512
528 void SafeBrowsingProtocolManager::IssueKeyRequest() { 513 void SafeBrowsingProtocolManager::IssueKeyRequest() {
529 GURL key_url(StringPrintf(kSbNewKeyUrl, 514 GURL key_url = MacKeyUrl();
530 client_name_.c_str(),
531 version_.c_str()));
532 request_type_ = GETKEY_REQUEST; 515 request_type_ = GETKEY_REQUEST;
533 request_.reset(new URLFetcher(key_url, URLFetcher::GET, this)); 516 request_.reset(new URLFetcher(key_url, URLFetcher::GET, this));
534 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 517 request_->set_load_flags(net::LOAD_DISABLE_CACHE);
535 request_->set_request_context(request_context_getter_); 518 request_->set_request_context(request_context_getter_);
536 request_->Start(); 519 request_->Start();
537 } 520 }
538 521
539 void SafeBrowsingProtocolManager::OnGetChunksComplete( 522 void SafeBrowsingProtocolManager::OnGetChunksComplete(
540 const std::vector<SBListChunkRanges>& lists, bool database_error) { 523 const std::vector<SBListChunkRanges>& lists, bool database_error) {
541 DCHECK(request_type_ == UPDATE_REQUEST); 524 DCHECK_EQ(request_type_, UPDATE_REQUEST);
542 if (database_error) { 525 if (database_error) {
543 UpdateFinished(false); 526 UpdateFinished(false);
544 ScheduleNextUpdate(false); 527 ScheduleNextUpdate(false);
545 return; 528 return;
546 } 529 }
547 530
548 const bool use_mac = !client_key_.empty(); 531 const bool use_mac = !client_key_.empty();
549 532
550 // Format our stored chunks: 533 // Format our stored chunks:
551 std::string list_data; 534 std::string list_data;
(...skipping 11 matching lines...) Expand all
563 // If we have an empty database, let the server know we want data for these 546 // If we have an empty database, let the server know we want data for these
564 // lists. 547 // lists.
565 if (!found_phishing) 548 if (!found_phishing)
566 list_data.append(FormatList( 549 list_data.append(FormatList(
567 SBListChunkRanges(safe_browsing_util::kPhishingList), use_mac)); 550 SBListChunkRanges(safe_browsing_util::kPhishingList), use_mac));
568 551
569 if (!found_malware) 552 if (!found_malware)
570 list_data.append(FormatList( 553 list_data.append(FormatList(
571 SBListChunkRanges(safe_browsing_util::kMalwareList), use_mac)); 554 SBListChunkRanges(safe_browsing_util::kMalwareList), use_mac));
572 555
573 std::string url = StringPrintf(kSbUpdateUrl, 556 GURL update_url = UpdateUrl(use_mac);
574 client_name_.c_str(),
575 version_.c_str());
576 if (use_mac) {
577 url.append("&wrkey=");
578 url.append(wrapped_key_);
579 }
580
581 GURL update_url(url);
582 request_.reset(new URLFetcher(update_url, URLFetcher::POST, this)); 557 request_.reset(new URLFetcher(update_url, URLFetcher::POST, this));
583 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 558 request_->set_load_flags(net::LOAD_DISABLE_CACHE);
584 request_->set_request_context(request_context_getter_); 559 request_->set_request_context(request_context_getter_);
585 request_->set_upload_data("text/plain", list_data); 560 request_->set_upload_data("text/plain", list_data);
586 request_->Start(); 561 request_->Start();
587 562
588 // Begin the update request timeout. 563 // Begin the update request timeout.
589 update_timer_.Start(TimeDelta::FromSeconds(kSbMaxUpdateWaitSec), this, 564 update_timer_.Start(TimeDelta::FromSeconds(kSbMaxUpdateWaitSec), this,
590 &SafeBrowsingProtocolManager::UpdateResponseTimeout); 565 &SafeBrowsingProtocolManager::UpdateResponseTimeout);
591 } 566 }
592 567
593 // If we haven't heard back from the server with an update response, this method 568 // If we haven't heard back from the server with an update response, this method
594 // will run. Close the current update session and schedule another update. 569 // will run. Close the current update session and schedule another update.
595 void SafeBrowsingProtocolManager::UpdateResponseTimeout() { 570 void SafeBrowsingProtocolManager::UpdateResponseTimeout() {
596 DCHECK(request_type_ == UPDATE_REQUEST); 571 DCHECK_EQ(request_type_, UPDATE_REQUEST);
597 request_.reset(); 572 request_.reset();
598 UpdateFinished(false); 573 UpdateFinished(false);
599 ScheduleNextUpdate(false); 574 ScheduleNextUpdate(false);
600 } 575 }
601 576
602 void SafeBrowsingProtocolManager::OnChunkInserted() { 577 void SafeBrowsingProtocolManager::OnChunkInserted() {
603 chunk_pending_to_write_ = false; 578 chunk_pending_to_write_ = false;
604 579
605 if (chunk_request_urls_.empty()) { 580 if (chunk_request_urls_.empty()) {
606 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_); 581 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_);
607 UpdateFinished(true); 582 UpdateFinished(true);
608 } else { 583 } else {
609 IssueChunkRequest(); 584 IssueChunkRequest();
610 } 585 }
611 } 586 }
612 587
613 void SafeBrowsingProtocolManager::ReportMalware(const GURL& malware_url, 588 void SafeBrowsingProtocolManager::ReportMalware(const GURL& malware_url,
614 const GURL& page_url, 589 const GURL& page_url,
615 const GURL& referrer_url) { 590 const GURL& referrer_url) {
616 std::string report_str = StringPrintf( 591 GURL report_url = MalwareReportUrl(malware_url, page_url, referrer_url);
617 kSbMalwareReportUrl,
618 EscapeQueryParamValue(malware_url.spec(), true).c_str(),
619 EscapeQueryParamValue(page_url.spec(), true).c_str(),
620 EscapeQueryParamValue(referrer_url.spec(), true).c_str(),
621 client_name_.c_str(),
622 version_.c_str());
623 GURL report_url(report_str);
624 URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this); 592 URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this);
625 report->set_load_flags(net::LOAD_DISABLE_CACHE); 593 report->set_load_flags(net::LOAD_DISABLE_CACHE);
626 report->set_request_context(request_context_getter_); 594 report->set_request_context(request_context_getter_);
627 report->Start(); 595 report->Start();
628 malware_reports_.insert(report); 596 malware_reports_.insert(report);
629 } 597 }
630 598
631 // static 599 // static
632 std::string SafeBrowsingProtocolManager::FormatList( 600 std::string SafeBrowsingProtocolManager::FormatList(
633 const SBListChunkRanges& list, bool use_mac) { 601 const SBListChunkRanges& list, bool use_mac) {
(...skipping 26 matching lines...) Expand all
660 void SafeBrowsingProtocolManager::HandleGetHashError(const Time& now) { 628 void SafeBrowsingProtocolManager::HandleGetHashError(const Time& now) {
661 int next = GetNextBackOffTime(&gethash_error_count_, &gethash_back_off_mult_); 629 int next = GetNextBackOffTime(&gethash_error_count_, &gethash_back_off_mult_);
662 next_gethash_time_ = now + TimeDelta::FromSeconds(next); 630 next_gethash_time_ = now + TimeDelta::FromSeconds(next);
663 } 631 }
664 632
665 void SafeBrowsingProtocolManager::UpdateFinished(bool success) { 633 void SafeBrowsingProtocolManager::UpdateFinished(bool success) {
666 UMA_HISTOGRAM_COUNTS("SB2.UpdateSize", update_size_); 634 UMA_HISTOGRAM_COUNTS("SB2.UpdateSize", update_size_);
667 update_size_ = 0; 635 update_size_ = 0;
668 sb_service_->UpdateFinished(success); 636 sb_service_->UpdateFinished(success);
669 } 637 }
638
639 std::string SafeBrowsingProtocolManager::ComposeUrl(
640 const std::string& prefix, const std::string& method,
641 const std::string& client_name, const std::string& version,
642 const std::string& additional_query) {
643 DCHECK(!prefix.empty() && !method.empty() &&
644 !client_name.empty() && !version.empty());
645 std::string url = StringPrintf("%s/%s?client=%s&appver=%s&pver=2.2",
646 prefix.c_str(), method.c_str(),
647 client_name.c_str(), version.c_str());
648 if (!additional_query.empty()) {
649 url.append(additional_query);
650 }
651 return url;
652 }
653
654 GURL SafeBrowsingProtocolManager::UpdateUrl(bool use_mac) const {
655 std::string url = ComposeUrl(info_url_prefix_, "downloads", client_name_,
656 version_, additional_query_);
657 if (use_mac) {
658 url.append("&wrkey=");
659 url.append(wrapped_key_);
660 }
661 return GURL(url);
662 }
663
664 GURL SafeBrowsingProtocolManager::GetHashUrl(bool use_mac) const {
665 std::string url= ComposeUrl(info_url_prefix_, "gethash", client_name_,
666 version_, additional_query_);
667 if (use_mac) {
668 url.append("&wrkey=");
669 url.append(wrapped_key_);
670 }
671 return GURL(url);
672 }
673
674 GURL SafeBrowsingProtocolManager::MacKeyUrl() const {
675 return GURL(ComposeUrl(mackey_url_prefix_, "newkey", client_name_, version_,
676 additional_query_));
677 }
678
679 GURL SafeBrowsingProtocolManager::MalwareReportUrl(
680 const GURL& malware_url, const GURL& page_url,
681 const GURL& referrer_url) const {
682 std::string url = ComposeUrl(info_url_prefix_, "report", client_name_,
683 version_, additional_query_);
684 return GURL(StringPrintf("%s&evts=malblhit&evtd=%s&evtr=%s&evhr=%s",
685 url.c_str(), EscapeQueryParamValue(malware_url.spec(), true).c_str(),
686 EscapeQueryParamValue(page_url.spec(), true).c_str(),
687 EscapeQueryParamValue(referrer_url.spec(), true).c_str()));
688 }
689
690 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const {
691 std::string next_url;
692 if (!StartsWithASCII(url, "http://", false) &&
693 !StartsWithASCII(url, "https://", false)) {
694 next_url = "http://" + url;
695 } else {
696 next_url = url;
697 }
698 if (!additional_query_.empty())
699 next_url += additional_query_;
700 return GURL(next_url);
701 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/protocol_manager.h ('k') | chrome/browser/safe_browsing/protocol_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698