Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / omnibox / alternate_nav_url_fetcher.cc
blob1d97190ca66b53e226e0e7726d8c5a54a9e36cb1
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/infobars/infobar_service.h"
9 #include "chrome/browser/intranet_redirect_detector.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
19 #include "net/url_request/url_fetcher.h"
20 #include "net/url_request/url_request.h"
22 using content::NavigationController;
24 AlternateNavURLFetcher::AlternateNavURLFetcher(
25 const GURL& alternate_nav_url)
26 : alternate_nav_url_(alternate_nav_url),
27 controller_(NULL),
28 state_(NOT_STARTED),
29 navigated_to_entry_(false) {
30 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
31 content::NotificationService::AllSources());
34 AlternateNavURLFetcher::~AlternateNavURLFetcher() {
37 void AlternateNavURLFetcher::Observe(
38 int type,
39 const content::NotificationSource& source,
40 const content::NotificationDetails& details) {
41 switch (type) {
42 case content::NOTIFICATION_NAV_ENTRY_PENDING: {
43 // If we've already received a notification for the same controller, we
44 // should delete ourselves as that indicates that the page is being
45 // re-loaded so this instance is now stale.
46 NavigationController* controller =
47 content::Source<NavigationController>(source).ptr();
48 if (controller_ == controller) {
49 delete this;
50 } else if (!controller_) {
51 // Start listening for the commit notification.
52 DCHECK(controller->GetPendingEntry());
53 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
54 content::Source<NavigationController>(
55 controller));
56 StartFetch(controller);
58 break;
61 case content::NOTIFICATION_NAV_ENTRY_COMMITTED:
62 // The page was navigated, we can show the infobar now if necessary.
63 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
64 content::Source<NavigationController>(controller_));
65 navigated_to_entry_ = true;
66 ShowInfobarIfPossible();
67 // WARNING: |this| may be deleted!
68 break;
70 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
71 // We have been closed. In order to prevent the URLFetcher from trying to
72 // access the controller that will be invalid, we delete ourselves.
73 // This deletes the URLFetcher and insures its callback won't be called.
74 delete this;
75 break;
77 default:
78 NOTREACHED();
82 void AlternateNavURLFetcher::OnURLFetchComplete(
83 const net::URLFetcher* source) {
84 DCHECK_EQ(fetcher_.get(), source);
85 SetStatusFromURLFetch(
86 source->GetURL(), source->GetStatus(), source->GetResponseCode());
87 ShowInfobarIfPossible();
88 // WARNING: |this| may be deleted!
91 void AlternateNavURLFetcher::StartFetch(NavigationController* controller) {
92 controller_ = controller;
93 content::WebContents* web_contents = controller_->GetWebContents();
94 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
95 content::Source<content::WebContents>(web_contents));
97 DCHECK_EQ(NOT_STARTED, state_);
98 state_ = IN_PROGRESS;
99 fetcher_.reset(net::URLFetcher::Create(GURL(alternate_nav_url_),
100 net::URLFetcher::HEAD, this));
101 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
102 fetcher_->SetRequestContext(
103 controller_->GetBrowserContext()->GetRequestContext());
104 fetcher_->SetStopOnRedirect(true);
105 fetcher_->Start();
108 void AlternateNavURLFetcher::SetStatusFromURLFetch(
109 const GURL& url,
110 const net::URLRequestStatus& status,
111 int response_code) {
112 if (status.is_success()) {
113 // HTTP 2xx, 401, and 407 all indicate that the target address exists.
114 state_ = (((response_code / 100) == 2) || (response_code == 401) ||
115 (response_code == 407)) ? SUCCEEDED : FAILED;
116 } else {
117 // If we got HTTP 3xx, we'll have auto-canceled; treat this as evidence the
118 // target address exists as long as we're not redirected to a common
119 // location every time, lest we annoy the user with infobars on everything
120 // they type. See comments on IntranetRedirectDetector.
121 if (status.status() == net::URLRequestStatus::CANCELED &&
122 (response_code / 100) == 3) {
123 const bool same_domain_or_host =
124 net::registry_controlled_domains::SameDomainOrHost(
125 url,
126 IntranetRedirectDetector::RedirectOrigin(),
127 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
128 state_ = same_domain_or_host ? FAILED : SUCCEEDED;
129 } else {
130 state_ = FAILED;
135 void AlternateNavURLFetcher::ShowInfobarIfPossible() {
136 if (navigated_to_entry_ && (state_ == SUCCEEDED)) {
137 AlternateNavInfoBarDelegate::Create(
138 InfoBarService::FromWebContents(controller_->GetWebContents()),
139 alternate_nav_url_);
140 } else if (state_ != FAILED) {
141 return;
143 delete this;