summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 19:12:47 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 19:12:47 +0000
commitc4ff495718e7b190229e863e3387c4e5f99475a9 (patch)
tree3d2aef85fe5590905f80e71687154c664b9c42c0 /chrome/browser
parent8348cb325bebf4d3516bd94949f5a4eb7c4056a9 (diff)
downloadchromium_src-c4ff495718e7b190229e863e3387c4e5f99475a9.zip
chromium_src-c4ff495718e7b190229e863e3387c4e5f99475a9.tar.gz
chromium_src-c4ff495718e7b190229e863e3387c4e5f99475a9.tar.bz2
Add autodetection of "intranet" redirection, for ISPs etc. that send typos and nonexistent addresses to custom pages, and plumb it to the code that puts up infobars when users type in a search that appears to be an intranet address, so we don't show these for erroneous cases.
BUG=31556 TEST=none Review URL: http://codereview.chromium.org/525079 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35807 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/alternate_nav_url_fetcher.cc76
-rw-r--r--chrome/browser/alternate_nav_url_fetcher.h8
-rw-r--r--chrome/browser/browser_main.cc20
-rw-r--r--chrome/browser/browser_prefs.cc4
-rw-r--r--chrome/browser/browser_process.h4
-rw-r--r--chrome/browser/browser_process_impl.cc20
-rw-r--r--chrome/browser/browser_process_impl.h11
-rw-r--r--chrome/browser/extensions/cross_origin_xhr_apitest.cc3
-rw-r--r--chrome/browser/extensions/execute_script_apitest.cc3
-rw-r--r--chrome/browser/extensions/extension_history_apitest.cc3
-rw-r--r--chrome/browser/extensions/extension_javascript_url_apitest.cc3
-rwxr-xr-xchrome/browser/extensions/incognito_noscript_apitest.cc7
-rw-r--r--chrome/browser/first_run.h10
-rw-r--r--chrome/browser/intranet_redirect_detector.cc171
-rw-r--r--chrome/browser/intranet_redirect_detector.h106
-rw-r--r--chrome/browser/net/cookie_policy_browsertest.cc3
-rw-r--r--chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc3
17 files changed, 392 insertions, 63 deletions
diff --git a/chrome/browser/alternate_nav_url_fetcher.cc b/chrome/browser/alternate_nav_url_fetcher.cc
index 7523f66..ee8c7b6 100644
--- a/chrome/browser/alternate_nav_url_fetcher.cc
+++ b/chrome/browser/alternate_nav_url_fetcher.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "chrome/browser/intranet_redirect_detector.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
@@ -82,37 +83,7 @@ void AlternateNavURLFetcher::OnURLFetchComplete(const URLFetcher* source,
const ResponseCookies& cookies,
const std::string& data) {
DCHECK(fetcher_.get() == source);
- if (status.is_success() &&
- // HTTP 2xx, 401, and 407 all indicate that the target address exists.
- (((response_code / 100) == 2) ||
- (response_code == 401) || (response_code == 407))) {
- state_ = SUCCEEDED;
-
- // The following TLD+1s are used as destinations by ISPs/DNS providers/etc.
- // who return provider-controlled pages to arbitrary user navigation
- // attempts. Because this can result in infobars on large fractions of user
- // searches, we don't show automatic infobars for these. Note that users
- // can still choose to explicitly navigate to or search for pages in these
- // domains, and can still get infobars for cases that wind up on other
- // domains (e.g. legit intranet sites), we're just trying to avoid
- // erroneously harassing the user with our own UI prompts.
- const char* kBlacklistedSites[] = {
- // NOTE: Use complete URLs, because GURL() doesn't do fixup!
- "http://comcast.com/",
- "http://opendns.com/",
- "http://verizon.net/",
- };
- for (size_t i = 0; i < arraysize(kBlacklistedSites); ++i) {
- if (net::RegistryControlledDomainService::SameDomainOrHost(
- url, GURL(kBlacklistedSites[i]))) {
- state_ = FAILED;
- break;
- }
- }
- } else {
- state_ = FAILED;
- }
-
+ SetStatusFromURLFetch(url, status, response_code);
ShowInfobarIfPossible();
}
@@ -150,6 +121,47 @@ void AlternateNavURLFetcher::InfoBarClosed() {
delete this;
}
+void AlternateNavURLFetcher::SetStatusFromURLFetch(
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code) {
+ if (!status.is_success() ||
+ // HTTP 2xx, 401, and 407 all indicate that the target address exists.
+ (((response_code / 100) != 2) &&
+ (response_code != 401) && (response_code != 407)) ||
+ // Fail if we're redirected to a common location. This is the "automatic
+ // heuristic" version of the explicit blacklist below; see comments there.
+ net::RegistryControlledDomainService::SameDomainOrHost(url,
+ IntranetRedirectDetector::RedirectOrigin())) {
+ state_ = FAILED;
+ return;
+ }
+
+ // The following TLD+1s are used as destinations by ISPs/DNS providers/etc.
+ // who return provider-controlled pages to arbitrary user navigation attempts.
+ // Because this can result in infobars on large fractions of user searches, we
+ // don't show automatic infobars for these. Note that users can still choose
+ // to explicitly navigate to or search for pages in these domains, and can
+ // still get infobars for cases that wind up on other domains (e.g. legit
+ // intranet sites), we're just trying to avoid erroneously harassing the user
+ // with our own UI prompts.
+ const char* kBlacklistedSites[] = {
+ // NOTE: Use complete URLs, because GURL() doesn't do fixup!
+ "http://comcast.com/",
+ "http://opendns.com/",
+ "http://verizon.net/",
+ };
+ for (size_t i = 0; i < arraysize(kBlacklistedSites); ++i) {
+ if (net::RegistryControlledDomainService::SameDomainOrHost(url,
+ GURL(kBlacklistedSites[i]))) {
+ state_ = FAILED;
+ return;
+ }
+ }
+
+ state_ = SUCCEEDED;
+}
+
void AlternateNavURLFetcher::ShowInfobarIfPossible() {
if (!navigated_to_entry_ || state_ != SUCCEEDED) {
if (state_ == FAILED)
diff --git a/chrome/browser/alternate_nav_url_fetcher.h b/chrome/browser/alternate_nav_url_fetcher.h
index 40a92f2..943f23e 100644
--- a/chrome/browser/alternate_nav_url_fetcher.h
+++ b/chrome/browser/alternate_nav_url_fetcher.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -62,6 +62,12 @@ class AlternateNavURLFetcher : public NotificationObserver,
virtual void InfoBarClosed();
private:
+ // Sets |state_| to either SUCCEEDED or FAILED depending on the result of the
+ // fetch.
+ void SetStatusFromURLFetch(const GURL& url,
+ const URLRequestStatus& status,
+ int response_code);
+
// Displays the infobar if all conditions are met (the page has loaded and
// the fetch of the alternate URL succeeded).
void ShowInfobarIfPossible();
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index c5e4484..995f625 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -797,19 +797,19 @@ int BrowserMain(const MainFunctionParams& parameters) {
RegisterMetadataURLRequestHandler();
// In unittest mode, this will do nothing. In normal mode, this will create
- // the global GoogleURLTracker instance, which will promptly go to sleep for
- // five seconds (to avoid slowing startup), and wake up afterwards to see if
- // it should do anything else. If we don't cause this creation now, it won't
- // happen until someone else asks for the tracker, at which point we may no
- // longer want to sleep for five seconds.
+ // the global GoogleURLTracker and IntranetRedirectDetector instances, which
+ // will promptly go to sleep for five and seven seconds, respectively (to
+ // avoid slowing startup), and wake up afterwards to see if they should do
+ // anything else.
//
// A simpler way of doing all this would be to have some function which could
- // give the time elapsed since startup, and simply have the tracker check that
- // when asked to initialize itself, but this doesn't seem to exist.
+ // give the time elapsed since startup, and simply have these objects check
+ // that when asked to initialize themselves, but this doesn't seem to exist.
//
- // This can't be created in the BrowserProcessImpl constructor because it
- // needs to read prefs that get set after that runs.
+ // These can't be created in the BrowserProcessImpl constructor because they
+ // need to read prefs that get set after that runs.
browser_process->google_url_tracker();
+ browser_process->intranet_redirect_detector();
// Have Chrome plugins write their data to the profile directory.
PluginService::GetInstance()->SetChromePluginDataDir(profile->GetPath());
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc
index ae3abf9..300f762 100644
--- a/chrome/browser/browser_prefs.cc
+++ b/chrome/browser/browser_prefs.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,6 +17,7 @@
#include "chrome/browser/form_field_history_manager.h"
#include "chrome/browser/google_url_tracker.h"
#include "chrome/browser/host_zoom_map.h"
+#include "chrome/browser/intranet_redirect_detector.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/page_info_model.h"
@@ -63,6 +64,7 @@ void RegisterLocalState(PrefService* local_state) {
WebCacheManager::RegisterPrefs(local_state);
ExternalProtocolHandler::RegisterPrefs(local_state);
GoogleURLTracker::RegisterPrefs(local_state);
+ IntranetRedirectDetector::RegisterPrefs(local_state);
KeywordEditorController::RegisterPrefs(local_state);
MetricsLog::RegisterPrefs(local_state);
MetricsService::RegisterPrefs(local_state);
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index d826321..d1ba1a3 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -21,6 +21,7 @@ class Clipboard;
class DevToolsManager;
class DownloadRequestManager;
class GoogleURLTracker;
+class IntranetRedirectDetector;
class IconManager;
class MetricsService;
class NotificationUIManager;
@@ -122,6 +123,7 @@ class BrowserProcess {
virtual printing::PrintJobManager* print_job_manager() = 0;
virtual GoogleURLTracker* google_url_tracker() = 0;
+ virtual IntranetRedirectDetector* intranet_redirect_detector() = 0;
// Returns the locale used by the application.
virtual const std::string& GetApplicationLocale() = 0;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index f19e6a6..481d210 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,6 +20,7 @@
#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/google_url_tracker.h"
#include "chrome/browser/icon_manager.h"
+#include "chrome/browser/intranet_redirect_detector.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
@@ -182,12 +183,14 @@ BrowserProcessImpl::~BrowserProcessImpl() {
// any pending URLFetchers, and avoid creating any more.
SdchDictionaryFetcher::Shutdown();
- // We need to destroy the MetricsService and GoogleURLTracker before the
- // io_thread_ gets destroyed, since both destructors can call the URLFetcher
- // destructor, which does an PostDelayedTask operation on the IO thread. (The
- // IO thread will handle that URLFetcher operation before going away.)
+ // We need to destroy the MetricsService, GoogleURLTracker, and
+ // IntranetRedirectDetector before the io_thread_ gets destroyed, since their
+ // destructors can call the URLFetcher destructor, which does a
+ // PostDelayedTask operation on the IO thread. (The IO thread will handle
+ // that URLFetcher operation before going away.)
metrics_service_.reset();
google_url_tracker_.reset();
+ intranet_redirect_detector_.reset();
// Need to clear profiles (download managers) before the io_thread_.
profile_manager_.reset();
@@ -461,6 +464,13 @@ void BrowserProcessImpl::CreateGoogleURLTracker() {
google_url_tracker_.swap(google_url_tracker);
}
+void BrowserProcessImpl::CreateIntranetRedirectDetector() {
+ DCHECK(intranet_redirect_detector_.get() == NULL);
+ scoped_ptr<IntranetRedirectDetector> intranet_redirect_detector(
+ new IntranetRedirectDetector);
+ intranet_redirect_detector_.swap(intranet_redirect_detector);
+}
+
void BrowserProcessImpl::CreateNotificationUIManager() {
DCHECK(notification_ui_manager_.get() == NULL);
notification_ui_manager_.reset(NotificationUIManager::Create());
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 51d0cf5..2c815ee 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -182,6 +182,13 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
return google_url_tracker_.get();
}
+ virtual IntranetRedirectDetector* intranet_redirect_detector() {
+ DCHECK(CalledOnValidThread());
+ if (!intranet_redirect_detector_.get())
+ CreateIntranetRedirectDetector();
+ return intranet_redirect_detector_.get();
+ }
+
virtual const std::string& GetApplicationLocale() {
DCHECK(!locale_.empty());
return locale_;
@@ -225,6 +232,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
void CreateDebuggerWrapper(int port);
void CreateDevToolsManager();
void CreateGoogleURLTracker();
+ void CreateIntranetRedirectDetector();
void CreateNotificationUIManager();
#if defined(IPC_MESSAGE_LOG_ENABLED)
@@ -282,6 +290,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
scoped_ptr<AutomationProviderList> automation_provider_list_;
scoped_ptr<GoogleURLTracker> google_url_tracker_;
+ scoped_ptr<IntranetRedirectDetector> intranet_redirect_detector_;
scoped_ptr<NotificationService> main_notification_service_;
diff --git a/chrome/browser/extensions/cross_origin_xhr_apitest.cc b/chrome/browser/extensions/cross_origin_xhr_apitest.cc
index 5a98322..c43c612 100644
--- a/chrome/browser/extensions/cross_origin_xhr_apitest.cc
+++ b/chrome/browser/extensions/cross_origin_xhr_apitest.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
+#include "net/base/mock_host_resolver.h"
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CrossOriginXHR) {
host_resolver()->AddRule("*.com", "127.0.0.1");
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc
index 07662b6c..4c7aa87 100644
--- a/chrome/browser/extensions/execute_script_apitest.cc
+++ b/chrome/browser/extensions/execute_script_apitest.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 20109 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
+#include "net/base/mock_host_resolver.h"
// This test failed at times on the Vista dbg builder and has been marked as
// flaky for now. Bug http://code.google.com/p/chromium/issues/detail?id=28630
diff --git a/chrome/browser/extensions/extension_history_apitest.cc b/chrome/browser/extensions/extension_history_apitest.cc
index 910012f..94873b3 100644
--- a/chrome/browser/extensions/extension_history_apitest.cc
+++ b/chrome/browser/extensions/extension_history_apitest.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
+#include "net/base/mock_host_resolver.h"
// Flaky, http://crbug.com/26296.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_History) {
diff --git a/chrome/browser/extensions/extension_javascript_url_apitest.cc b/chrome/browser/extensions/extension_javascript_url_apitest.cc
index aaa7b30..657f82d 100644
--- a/chrome/browser/extensions/extension_javascript_url_apitest.cc
+++ b/chrome/browser/extensions/extension_javascript_url_apitest.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
+#include "net/base/mock_host_resolver.h"
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, JavaScriptURLPermissions) {
host_resolver()->AddRule("a.com", "127.0.0.1");
diff --git a/chrome/browser/extensions/incognito_noscript_apitest.cc b/chrome/browser/extensions/incognito_noscript_apitest.cc
index 69f3876..fa78e67 100755
--- a/chrome/browser/extensions/incognito_noscript_apitest.cc
+++ b/chrome/browser/extensions/incognito_noscript_apitest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,6 +10,7 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
+#include "net/base/mock_host_resolver.h"
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, IncognitoNoScript) {
host_resolver()->AddRule("*", "127.0.0.1");
@@ -37,8 +38,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, IncognitoNoScript) {
NULL);
otr_browser->window()->Show();
ui_test_utils::WaitForNavigationInCurrentTab(otr_browser);
-
- string16 title;
+
+ string16 title;
ui_test_utils::GetCurrentTabTitle(otr_browser, &title);
ASSERT_EQ("Unmodified", UTF16ToASCII(title));
}
diff --git a/chrome/browser/first_run.h b/chrome/browser/first_run.h
index 6b8a9d39..3b2d996 100644
--- a/chrome/browser/first_run.h
+++ b/chrome/browser/first_run.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -136,8 +136,9 @@ class Upgrade {
};
#endif
-// A subclass of BrowserProcessImpl that does not have a GoogleURLTracker
-// so we don't fetch as we have no IO thread (see bug #1292702).
+// A subclass of BrowserProcessImpl that does not have a GoogleURLTracker or
+// IntranetRedirectDetector so we don't do any URL fetches (as we have no IO
+// thread to fetch on).
class FirstRunBrowserProcess : public BrowserProcessImpl {
public:
explicit FirstRunBrowserProcess(const CommandLine& command_line)
@@ -146,6 +147,9 @@ class FirstRunBrowserProcess : public BrowserProcessImpl {
virtual ~FirstRunBrowserProcess() { }
virtual GoogleURLTracker* google_url_tracker() { return NULL; }
+ virtual IntranetRedirectDetector* intranet_redirect_detector() {
+ return NULL;
+ }
private:
DISALLOW_COPY_AND_ASSIGN(FirstRunBrowserProcess);
diff --git a/chrome/browser/intranet_redirect_detector.cc b/chrome/browser/intranet_redirect_detector.cc
new file mode 100644
index 0000000..04b0a5a
--- /dev/null
+++ b/chrome/browser/intranet_redirect_detector.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/intranet_redirect_detector.h"
+
+#include "base/rand_util.h"
+#include "base/stl_util-inl.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/base/registry_controlled_domain.h"
+#include "net/url_request/url_request_status.h"
+
+const size_t IntranetRedirectDetector::kNumCharsInHostnames = 10;
+
+IntranetRedirectDetector::IntranetRedirectDetector()
+ : redirect_origin_(WideToUTF8(g_browser_process->local_state()->GetString(
+ prefs::kLastKnownIntranetRedirectOrigin))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)),
+ in_startup_sleep_(true),
+ request_context_available_(!!Profile::GetDefaultRequestContext()) {
+ registrar_.Add(this, NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE,
+ NotificationService::AllSources());
+
+ // Because this function can be called during startup, when kicking off a URL
+ // fetch can eat up 20 ms of time, we delay seven seconds, which is hopefully
+ // long enough to be after startup, but still get results back quickly.
+ // Ideally, instead of this timer, we'd do something like "check if the
+ // browser is starting up, and if so, come back later", but there is currently
+ // no function to do this.
+ static const int kStartFetchDelayMS = 7000;
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ fetcher_factory_.NewRunnableMethod(
+ &IntranetRedirectDetector::FinishSleep),
+ kStartFetchDelayMS);
+}
+
+IntranetRedirectDetector::~IntranetRedirectDetector() {
+ STLDeleteElements(&fetchers_);
+}
+
+// static
+GURL IntranetRedirectDetector::RedirectOrigin() {
+ const IntranetRedirectDetector* const detector =
+ g_browser_process->intranet_redirect_detector();
+ return detector ? detector->redirect_origin_ : GURL();
+}
+
+// static
+void IntranetRedirectDetector::RegisterPrefs(PrefService* prefs) {
+ prefs->RegisterStringPref(prefs::kLastKnownIntranetRedirectOrigin,
+ std::wstring());
+}
+
+void IntranetRedirectDetector::FinishSleep() {
+ in_startup_sleep_ = false;
+ StartFetchesIfPossible();
+}
+
+void IntranetRedirectDetector::StartFetchesIfPossible() {
+ // Bail if a fetch isn't appropriate right now. This function will be called
+ // again each time one of the preconditions changes, so we'll fetch
+ // immediately once all of them are met.
+ if (in_startup_sleep_ || !request_context_available_)
+ return;
+
+ // We shouldn't somehow run twice.
+ DCHECK(fetchers_.empty() && resulting_origins_.empty());
+
+ // Start three fetchers on random hostnames.
+ for (size_t i = 0; i < 3; ++i) {
+ std::string url_string("http://");
+ for (size_t j = 0; j < kNumCharsInHostnames; ++j)
+ url_string += ('a' + base::RandInt(0, 'z' - 'a'));
+ GURL random_url(url_string + '/');
+ URLFetcher* fetcher = new URLFetcher(random_url, URLFetcher::HEAD, this);
+ // We don't want these fetches to affect existing state in the profile.
+ fetcher->set_load_flags(net::LOAD_DISABLE_CACHE |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ fetcher->set_request_context(Profile::GetDefaultRequestContext());
+ fetcher->Start();
+ fetchers_.insert(fetcher);
+ }
+}
+
+void IntranetRedirectDetector::OnURLFetchComplete(
+ const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
+ // Delete the fetcher on this function's exit.
+ Fetchers::iterator fetcher = fetchers_.find(const_cast<URLFetcher*>(source));
+ DCHECK(fetcher != fetchers_.end());
+ scoped_ptr<URLFetcher> clean_up_fetcher(*fetcher);
+ fetchers_.erase(fetcher);
+
+ // If any two fetches result in the same domain/host, we set the redirect
+ // origin to that; otherwise we set it to nothing.
+ if (!status.is_success() || (response_code != 200)) {
+ if ((resulting_origins_.empty()) ||
+ ((resulting_origins_.size() == 1) &&
+ resulting_origins_.front().is_valid())) {
+ resulting_origins_.push_back(GURL());
+ return;
+ }
+ redirect_origin_ = GURL();
+ } else {
+ DCHECK(url.is_valid());
+ GURL origin(url.GetOrigin());
+ if (resulting_origins_.empty()) {
+ resulting_origins_.push_back(origin);
+ return;
+ }
+ if (net::RegistryControlledDomainService::SameDomainOrHost(
+ resulting_origins_.front(), origin)) {
+ redirect_origin_ = origin;
+ if (!fetchers_.empty()) {
+ // Cancel remaining fetch, we don't need it.
+ DCHECK(fetchers_.size() == 1);
+ delete (*fetchers_.begin());
+ fetchers_.clear();
+ }
+ }
+ if (resulting_origins_.size() == 1) {
+ resulting_origins_.push_back(origin);
+ return;
+ }
+ DCHECK(resulting_origins_.size() == 2);
+ redirect_origin_ = net::RegistryControlledDomainService::SameDomainOrHost(
+ resulting_origins_.back(), origin) ? origin : GURL();
+ }
+
+ g_browser_process->local_state()->SetString(
+ prefs::kLastKnownIntranetRedirectOrigin, redirect_origin_.is_valid() ?
+ UTF8ToWide(redirect_origin_.spec()) : std::wstring());
+}
+
+void IntranetRedirectDetector::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK_EQ(NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE, type.value);
+ request_context_available_ = true;
+ StartFetchesIfPossible();
+}
+
+IntranetRedirectHostResolverProc::IntranetRedirectHostResolverProc(
+ net::HostResolverProc* previous)
+ : net::HostResolverProc(previous) {
+}
+
+int IntranetRedirectHostResolverProc::Resolve(const std::string& host,
+ net::AddressFamily address_family,
+ net::AddressList* addrlist) {
+ // We'd love to just ask the IntranetRedirectDetector, but we may not be on
+ // the same thread. So just use the heuristic that any all-lowercase a-z
+ // hostname with the right number of characters is likely from the detector
+ // (and thus should be blocked).
+ return ((host.length() == IntranetRedirectDetector::kNumCharsInHostnames) &&
+ (host.find_first_not_of("abcdefghijklmnopqrstuvwxyz") ==
+ std::string::npos)) ?
+ net::ERR_NAME_NOT_RESOLVED :
+ ResolveUsingPrevious(host, address_family, addrlist);
+}
diff --git a/chrome/browser/intranet_redirect_detector.h b/chrome/browser/intranet_redirect_detector.h
new file mode 100644
index 0000000..f1e38ae
--- /dev/null
+++ b/chrome/browser/intranet_redirect_detector.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_INTRANET_REDIRECT_DETECTOR_H_
+#define CHROME_BROWSER_INTRANET_REDIRECT_DETECTOR_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/net/url_fetcher.h"
+#include "chrome/common/notification_registrar.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/host_resolver_proc.h"
+
+class PrefService;
+
+// This object is responsible for determining whether the user is on a network
+// that redirects requests for intranet hostnames to another site, and if so,
+// tracking what that site is (including across restarts via a pref). For
+// example, the user's ISP might convert a request for "http://query/" into a
+// 302 redirect to "http://isp.domain.com/search?q=query" in order to display
+// custom pages on typos, nonexistent sites, etc.
+//
+// We use this information in the AlternateNavURLFetcher to avoid displaying
+// infobars for these cases. Our infobars are designed to allow users to get at
+// intranet sites when they were erroneously taken to a search result page. In
+// these cases, however, users would be shown a confusing and useless infobar
+// when they really did mean to do a search.
+//
+// Consumers should call RedirectOrigin(), which is guaranteed to synchronously
+// return a value at all times (even during startup or in unittest mode). If no
+// redirection is in place, the returned GURL will be empty.
+class IntranetRedirectDetector : public URLFetcher::Delegate,
+ public NotificationObserver {
+ public:
+ // Only the main browser process loop should call this, when setting up
+ // g_browser_process->intranet_redirect_detector_. No code other than the
+ // IntranetRedirectDetector itself should actually use
+ // g_browser_process->intranet_redirect_detector() (which shouldn't be hard,
+ // since there aren't useful public functions on this object for consumers to
+ // access anyway).
+ IntranetRedirectDetector();
+ ~IntranetRedirectDetector();
+
+ // Returns the current redirect origin. This will be empty if no redirection
+ // is in place.
+ static GURL RedirectOrigin();
+
+ static void RegisterPrefs(PrefService* prefs);
+
+ // The number of characters the fetcher will use for its randomly-generated
+ // hostnames.
+ static const size_t kNumCharsInHostnames;
+
+ private:
+ typedef std::set<URLFetcher*> Fetchers;
+
+ // Called when the five second startup sleep has finished. Runs any pending
+ // fetch.
+ void FinishSleep();
+
+ // Starts the fetches to determine the redirect URL if we can currently do so.
+ void StartFetchesIfPossible();
+
+ // URLFetcher::Delegate
+ virtual void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data);
+
+ // NotificationObserver
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ NotificationRegistrar registrar_;
+ GURL redirect_origin_;
+ ScopedRunnableMethodFactory<IntranetRedirectDetector> fetcher_factory_;
+ Fetchers fetchers_;
+ std::vector<GURL> resulting_origins_;
+ bool in_startup_sleep_; // True if we're in the seven-second "no fetching"
+ // period that begins at browser start.
+ bool request_context_available_;
+ // True when the profile has been loaded and the
+ // default request context created, so we can
+ // actually do the fetch with the right data.
+
+ DISALLOW_COPY_AND_ASSIGN(IntranetRedirectDetector);
+};
+
+// This is for use in testing, where we don't want our fetches to actually go
+// over the network. It captures the requests and causes them to fail.
+class IntranetRedirectHostResolverProc : public net::HostResolverProc {
+ public:
+ explicit IntranetRedirectHostResolverProc(net::HostResolverProc* previous);
+
+ virtual int Resolve(const std::string& host,
+ net::AddressFamily address_family,
+ net::AddressList* addrlist);
+};
+
+#endif // CHROME_BROWSER_INTRANET_REDIRECT_DETECTOR_H_
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc
index f218575..7dbecf9 100644
--- a/chrome/browser/net/cookie_policy_browsertest.cc
+++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include "chrome/common/pref_service.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
+#include "net/base/mock_host_resolver.h"
class CookiePolicyBrowserTest : public InProcessBrowserTest {
public:
diff --git a/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc b/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc
index 8bbd8ac..b228af0 100644
--- a/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc
+++ b/chrome/browser/privacy_blacklist/blacklist_manager_browsertest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,6 +18,7 @@
#include "chrome/test/ui_test_utils.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
+#include "net/base/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {