Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/renderer/net/net_error_helper_core.h" | 5 #include "chrome/renderer/net/net_error_helper_core.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | |
| 10 #include "base/callback.h" | |
| 11 #include "base/location.h" | |
| 9 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 10 #include "chrome/common/localized_error.h" | 13 #include "chrome/common/localized_error.h" |
| 11 #include "net/base/escape.h" | 14 #include "net/base/escape.h" |
| 12 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 13 #include "third_party/WebKit/public/platform/WebString.h" | 16 #include "third_party/WebKit/public/platform/WebString.h" |
| 14 #include "third_party/WebKit/public/platform/WebURLError.h" | 17 #include "third_party/WebKit/public/platform/WebURLError.h" |
| 15 #include "url/gurl.h" | 18 #include "url/gurl.h" |
| 16 | 19 |
| 17 namespace { | 20 namespace { |
| 18 | 21 |
| 19 // Returns whether |net_error| is a DNS-related error (and therefore whether | 22 // Returns whether |net_error| is a DNS-related error (and therefore whether |
| 20 // the tab helper should start a DNS probe after receiving it.) | 23 // the tab helper should start a DNS probe after receiving it.) |
| 21 bool IsDnsError(const blink::WebURLError& error) { | 24 bool IsDnsError(const blink::WebURLError& error) { |
| 22 return error.domain.utf8() == net::kErrorDomain && | 25 return error.domain.utf8() == net::kErrorDomain && |
| 23 (error.reason == net::ERR_NAME_NOT_RESOLVED || | 26 (error.reason == net::ERR_NAME_NOT_RESOLVED || |
| 24 error.reason == net::ERR_NAME_RESOLUTION_FAILED); | 27 error.reason == net::ERR_NAME_RESOLUTION_FAILED); |
| 25 } | 28 } |
| 26 | 29 |
| 30 bool IsReloadableError(const blink::WebURLError& error) { | |
| 31 return error.reason != net::ERR_ABORTED; | |
|
Randy Smith (Not in Mondays)
2014/01/30 20:14:47
I believe we just want to reload on "offline like"
mmenke
2014/01/30 20:47:31
I'm not sure about those... ERR_CONNECTION_TIMED_
Randy Smith (Not in Mondays)
2014/01/30 20:57:30
I'm confused; isn't modem rebooting and random con
| |
| 32 } | |
| 33 | |
| 27 // If an alternate error page should be retrieved remotely for a main frame load | 34 // If an alternate error page should be retrieved remotely for a main frame load |
| 28 // that failed with |error|, returns true and sets |error_page_url| to the URL | 35 // that failed with |error|, returns true and sets |error_page_url| to the URL |
| 29 // of the remote error page. | 36 // of the remote error page. |
| 30 bool GetErrorPageURL(const blink::WebURLError& error, | 37 bool GetErrorPageURL(const blink::WebURLError& error, |
| 31 const GURL& alt_error_page_url, | 38 const GURL& alt_error_page_url, |
| 32 GURL* error_page_url) { | 39 GURL* error_page_url) { |
| 33 if (!alt_error_page_url.is_valid()) | 40 if (!alt_error_page_url.is_valid()) |
| 34 return false; | 41 return false; |
| 35 | 42 |
| 36 // Parameter to send to the error page indicating the error type. | 43 // Parameter to send to the error page indicating the error type. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 // for tests to wait for. | 118 // for tests to wait for. |
| 112 GURL alternate_error_page_url; | 119 GURL alternate_error_page_url; |
| 113 | 120 |
| 114 // True if a page has completed loading, at which point it can receive | 121 // True if a page has completed loading, at which point it can receive |
| 115 // updates. | 122 // updates. |
| 116 bool is_finished_loading; | 123 bool is_finished_loading; |
| 117 }; | 124 }; |
| 118 | 125 |
| 119 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) | 126 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) |
| 120 : delegate_(delegate), | 127 : delegate_(delegate), |
| 121 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE) { | 128 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE), |
| 129 auto_reload_enabled_(false), | |
|
Randy Smith (Not in Mondays)
2014/01/30 20:14:47
Why not attach this to the flag setup for this wor
Elly Fong-Jones
2014/02/05 21:12:37
Done.
| |
| 130 auto_reload_count_(0) { | |
| 122 } | 131 } |
| 123 | 132 |
| 124 NetErrorHelperCore::~NetErrorHelperCore() { | 133 NetErrorHelperCore::~NetErrorHelperCore() { |
| 125 } | 134 } |
| 126 | 135 |
| 127 void NetErrorHelperCore::OnStop() { | 136 void NetErrorHelperCore::OnStop() { |
| 128 // On stop, cancel loading the alternate error page, and prevent any pending | 137 // On stop, cancel loading the alternate error page, and prevent any pending |
| 129 // error page load from starting a new error page load. Swapping in the error | 138 // error page load from starting a new error page load. Swapping in the error |
| 130 // page when it's finished loading could abort the navigation, otherwise. | 139 // page when it's finished loading could abort the navigation, otherwise. |
| 131 if (committed_error_page_info_) | 140 if (committed_error_page_info_) |
| 132 committed_error_page_info_->alternate_error_page_url = GURL(); | 141 committed_error_page_info_->alternate_error_page_url = GURL(); |
| 133 if (pending_error_page_info_) | 142 if (pending_error_page_info_) |
| 134 pending_error_page_info_->alternate_error_page_url = GURL(); | 143 pending_error_page_info_->alternate_error_page_url = GURL(); |
| 135 delegate_->CancelFetchErrorPage(); | 144 delegate_->CancelFetchErrorPage(); |
| 145 if (auto_reload_timer_.get()) | |
| 146 auto_reload_timer_->Stop(); | |
| 147 delegate_->CancelFetchAutoReloadPage(); | |
| 136 } | 148 } |
| 137 | 149 |
| 138 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { | 150 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { |
| 139 if (frame_type != MAIN_FRAME) | 151 if (frame_type != MAIN_FRAME) |
| 140 return; | 152 return; |
| 141 | 153 |
| 142 // If there's no pending error page information associated with the page load, | 154 // If there's no pending error page information associated with the page load, |
| 143 // or the new page is not an error page, then reset pending error page state. | 155 // or the new page is not an error page, then reset pending error page state. |
| 144 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { | 156 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { |
| 145 OnStop(); | 157 OnStop(); |
| 146 } | 158 } |
| 147 } | 159 } |
| 148 | 160 |
| 149 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { | 161 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { |
| 150 if (frame_type != MAIN_FRAME) | 162 if (frame_type != MAIN_FRAME) |
| 151 return; | 163 return; |
| 152 | 164 |
| 153 committed_error_page_info_.reset(pending_error_page_info_.release()); | 165 committed_error_page_info_.reset(pending_error_page_info_.release()); |
| 154 } | 166 } |
| 155 | 167 |
| 156 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { | 168 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { |
| 157 if (frame_type != MAIN_FRAME || !committed_error_page_info_) | 169 if (frame_type != MAIN_FRAME || !committed_error_page_info_) { |
| 170 if (frame_type == MAIN_FRAME && !committed_error_page_info_) { | |
| 171 // Just finished a non-error page load. Clear the auto-reload backoff | |
| 172 // count. | |
| 173 auto_reload_count_ = 0; | |
| 174 } | |
| 158 return; | 175 return; |
| 176 } | |
| 159 | 177 |
| 160 committed_error_page_info_->is_finished_loading = true; | 178 committed_error_page_info_->is_finished_loading = true; |
| 161 | 179 |
| 162 if (committed_error_page_info_->alternate_error_page_url.is_valid()) { | 180 if (committed_error_page_info_->alternate_error_page_url.is_valid()) { |
| 163 // If there is another pending error page load, | 181 // If there is another pending error page load, |
| 164 // |replace_with_alternate_error_page| should have been set to false. | 182 // |replace_with_alternate_error_page| should have been set to false. |
| 165 DCHECK(!pending_error_page_info_); | 183 DCHECK(!pending_error_page_info_); |
| 166 DCHECK(!committed_error_page_info_->needs_dns_updates); | 184 DCHECK(!committed_error_page_info_->needs_dns_updates); |
| 167 GURL error_page_url; | 185 GURL error_page_url; |
| 168 delegate_->FetchErrorPage( | 186 delegate_->FetchErrorPage( |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 195 // will just get the results for the next page load. | 213 // will just get the results for the next page load. |
| 196 if (IsDnsError(error)) | 214 if (IsDnsError(error)) |
| 197 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; | 215 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; |
| 198 | 216 |
| 199 GURL error_page_url; | 217 GURL error_page_url; |
| 200 if (GetErrorPageURL(error, alt_error_page_url_, &error_page_url)) { | 218 if (GetErrorPageURL(error, alt_error_page_url_, &error_page_url)) { |
| 201 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post)); | 219 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post)); |
| 202 pending_error_page_info_->alternate_error_page_url = error_page_url; | 220 pending_error_page_info_->alternate_error_page_url = error_page_url; |
| 203 return; | 221 return; |
| 204 } | 222 } |
| 223 | |
| 224 if (auto_reload_enabled_) { | |
| 225 if (IsReloadableError(error)) | |
|
mmenke
2014/01/30 20:45:07
Don't want to auto reload POSTs.
mmenke
2014/01/30 20:45:07
May make more sense to trigger this when the error
mmenke
2014/01/30 20:45:07
We just try reloading eternally?
Suppose shouldn'
Elly Fong-Jones
2014/02/05 21:12:37
Done.
Elly Fong-Jones
2014/02/05 21:12:37
Done.
| |
| 226 StartAutoReload(); | |
| 227 else | |
| 228 auto_reload_count_ = 0; | |
| 229 } | |
| 205 } | 230 } |
| 206 | 231 |
| 207 GenerateLocalErrorPage(frame_type, error, is_failed_post, error_html); | 232 GenerateLocalErrorPage(frame_type, error, is_failed_post, error_html); |
| 208 } | 233 } |
| 209 | 234 |
| 210 void NetErrorHelperCore::GenerateLocalErrorPage( | 235 void NetErrorHelperCore::GenerateLocalErrorPage( |
| 211 FrameType frame_type, | 236 FrameType frame_type, |
| 212 const blink::WebURLError& error, | 237 const blink::WebURLError& error, |
| 213 bool is_failed_post, | 238 bool is_failed_post, |
| 214 std::string* error_html) { | 239 std::string* error_html) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 } | 334 } |
| 310 | 335 |
| 311 blink::WebURLError updated_error; | 336 blink::WebURLError updated_error; |
| 312 updated_error.domain = blink::WebString::fromUTF8( | 337 updated_error.domain = blink::WebString::fromUTF8( |
| 313 chrome_common_net::kDnsProbeErrorDomain); | 338 chrome_common_net::kDnsProbeErrorDomain); |
| 314 updated_error.reason = last_probe_status_; | 339 updated_error.reason = last_probe_status_; |
| 315 updated_error.unreachableURL = error.unreachableURL; | 340 updated_error.unreachableURL = error.unreachableURL; |
| 316 | 341 |
| 317 return updated_error; | 342 return updated_error; |
| 318 } | 343 } |
| 344 | |
| 345 void NetErrorHelperCore::AutoReload() { | |
| 346 if (!committed_error_page_info_) { | |
|
mmenke
2014/01/30 20:45:07
Is it possible for this to trigger because it's ta
Elly Fong-Jones
2014/02/05 21:12:37
No. The timer is only restarted in GetErrorHTML.
| |
| 347 return; | |
| 348 } | |
| 349 GURL url = committed_error_page_info_->error.unreachableURL; | |
| 350 delegate_->FetchAutoReloadPage(url); | |
| 351 } | |
| 352 | |
| 353 void NetErrorHelperCore::StartAutoReload() { | |
|
Randy Smith (Not in Mondays)
2014/01/30 20:14:47
We want the NCN indicating we're offline to overri
mmenke
2014/01/30 20:45:07
StartAutoReloadTimer?
Elly Fong-Jones
2014/02/05 21:12:37
Done.
| |
| 354 int delay = 1 << auto_reload_count_; | |
|
mmenke
2014/01/30 20:45:07
I suggest making the 1 a constant at the top of th
Elly Fong-Jones
2014/02/05 21:12:37
Moved it into a helper.
| |
| 355 auto_reload_count_++; | |
| 356 auto_reload_timer_.reset(delegate_->NewMockableOneShotTimer()); | |
| 357 auto_reload_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(delay), | |
| 358 base::Bind(&NetErrorHelperCore::AutoReload, | |
| 359 base::Unretained(this))); | |
| 360 } | |
| 361 | |
| 362 bool NetErrorHelperCore::IsAutoReloading() const { | |
| 363 return auto_reload_count_ != 0; | |
|
mmenke
2014/01/30 20:45:07
This isn't correct in the OnStop() case.
Elly Fong-Jones
2014/02/05 21:12:37
Yeah. Hm.
| |
| 364 } | |
| OLD | NEW |