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 |
22 base::TimeDelta GetAutoReloadBackoff(size_t reloads) { | |
mmenke
2014/02/05 23:31:43
I suggest reload_count or num_reloads. I generall
mmenke
2014/02/05 23:31:43
I suggest "GetAutoReloadTime" or "GetAutoReloadTim
Elly Fong-Jones
2014/02/10 21:42:06
Done.
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
23 static const int kDelaysMs[] = { | |
24 5000, 30000, 60000, 300000, 600000, 1800000 | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
I'd like to have some UMA as to when we succeed on
| |
25 }; | |
26 if (reloads >= arraysize(kDelaysMs)) | |
27 reloads = arraysize(kDelaysMs) - 1; | |
28 return base::TimeDelta::FromMilliseconds(kDelaysMs[reloads]); | |
29 } | |
30 | |
19 // Returns whether |net_error| is a DNS-related error (and therefore whether | 31 // Returns whether |net_error| is a DNS-related error (and therefore whether |
20 // the tab helper should start a DNS probe after receiving it.) | 32 // the tab helper should start a DNS probe after receiving it.) |
21 bool IsDnsError(const blink::WebURLError& error) { | 33 bool IsDnsError(const blink::WebURLError& error) { |
22 return error.domain.utf8() == net::kErrorDomain && | 34 return error.domain.utf8() == net::kErrorDomain && |
23 (error.reason == net::ERR_NAME_NOT_RESOLVED || | 35 (error.reason == net::ERR_NAME_NOT_RESOLVED || |
24 error.reason == net::ERR_NAME_RESOLUTION_FAILED); | 36 error.reason == net::ERR_NAME_RESOLUTION_FAILED); |
25 } | 37 } |
26 | 38 |
39 bool IsReloadableError(const blink::WebURLError& error) { | |
mmenke
2014/02/05 23:31:43
You should check the error domain, too, rather tha
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
40 return error.reason != net::ERR_ABORTED; | |
41 /* | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
Why commented out?
Elly Fong-Jones
2014/02/10 21:42:06
leftover from earlier, oops
Done.
| |
42 return error.reason == net::ERR_NAME_NOT_RESOLVED || | |
43 error.reason == net::ERR_INTERNET_DISCONNECTED || | |
44 error.reason == net::ERR_ADDRESS_UNREACHABLE || | |
45 error.reason == net::ERR_CONNECTION_TIMED_OUT || | |
46 error.reason == net::ERR_NETWORK_CHANGED; | |
47 */ | |
48 } | |
49 | |
27 // If an alternate error page should be retrieved remotely for a main frame load | 50 // 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 | 51 // that failed with |error|, returns true and sets |error_page_url| to the URL |
29 // of the remote error page. | 52 // of the remote error page. |
30 bool GetErrorPageURL(const blink::WebURLError& error, | 53 bool GetErrorPageURL(const blink::WebURLError& error, |
31 const GURL& alt_error_page_url, | 54 const GURL& alt_error_page_url, |
32 GURL* error_page_url) { | 55 GURL* error_page_url) { |
33 if (!alt_error_page_url.is_valid()) | 56 if (!alt_error_page_url.is_valid()) |
34 return false; | 57 return false; |
35 | 58 |
36 // Parameter to send to the error page indicating the error type. | 59 // 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. | 134 // for tests to wait for. |
112 GURL alternate_error_page_url; | 135 GURL alternate_error_page_url; |
113 | 136 |
114 // True if a page has completed loading, at which point it can receive | 137 // True if a page has completed loading, at which point it can receive |
115 // updates. | 138 // updates. |
116 bool is_finished_loading; | 139 bool is_finished_loading; |
117 }; | 140 }; |
118 | 141 |
119 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) | 142 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) |
120 : delegate_(delegate), | 143 : delegate_(delegate), |
121 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE) { | 144 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE), |
145 auto_reload_enabled_(false), | |
146 auto_reload_count_(0) { | |
122 } | 147 } |
123 | 148 |
124 NetErrorHelperCore::~NetErrorHelperCore() { | 149 NetErrorHelperCore::~NetErrorHelperCore() { |
125 } | 150 } |
126 | 151 |
127 void NetErrorHelperCore::OnStop() { | 152 void NetErrorHelperCore::OnStop() { |
128 // On stop, cancel loading the alternate error page, and prevent any pending | 153 // 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 | 154 // 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. | 155 // page when it's finished loading could abort the navigation, otherwise. |
131 if (committed_error_page_info_) | 156 if (committed_error_page_info_) |
132 committed_error_page_info_->alternate_error_page_url = GURL(); | 157 committed_error_page_info_->alternate_error_page_url = GURL(); |
133 if (pending_error_page_info_) | 158 if (pending_error_page_info_) |
134 pending_error_page_info_->alternate_error_page_url = GURL(); | 159 pending_error_page_info_->alternate_error_page_url = GURL(); |
135 delegate_->CancelFetchErrorPage(); | 160 delegate_->CancelFetchErrorPage(); |
161 if (auto_reload_timer_.get()) | |
162 auto_reload_timer_->Stop(); | |
mmenke
2014/02/05 23:31:43
Can't these two lines just be replaced with "auto_
mmenke
2014/02/05 23:31:43
auto_reload_count_ = 0;?
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
136 } | 163 } |
137 | 164 |
138 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { | 165 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { |
139 if (frame_type != MAIN_FRAME) | 166 if (frame_type != MAIN_FRAME) |
140 return; | 167 return; |
141 | 168 |
142 // If there's no pending error page information associated with the page load, | 169 // 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. | 170 // 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) { | 171 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { |
145 OnStop(); | 172 OnStop(); |
146 } | 173 } |
147 } | 174 } |
148 | 175 |
149 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { | 176 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { |
150 if (frame_type != MAIN_FRAME) | 177 if (frame_type != MAIN_FRAME) |
151 return; | 178 return; |
152 | 179 |
153 committed_error_page_info_.reset(pending_error_page_info_.release()); | 180 committed_error_page_info_.reset(pending_error_page_info_.release()); |
154 } | 181 } |
155 | 182 |
156 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { | 183 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { |
157 if (frame_type != MAIN_FRAME || !committed_error_page_info_) | 184 if (frame_type != MAIN_FRAME || !committed_error_page_info_) { |
185 if (frame_type == MAIN_FRAME && !committed_error_page_info_) { | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
I find this cascade of conditionals confusing. Ma
Elly Fong-Jones
2014/02/10 21:42:06
Aha, good catch.
| |
186 // Just finished a non-error page load. Clear the auto-reload backoff | |
187 // count. | |
188 auto_reload_count_ = 0; | |
189 } | |
158 return; | 190 return; |
191 } | |
159 | 192 |
160 committed_error_page_info_->is_finished_loading = true; | 193 committed_error_page_info_->is_finished_loading = true; |
161 | 194 |
162 if (committed_error_page_info_->alternate_error_page_url.is_valid()) { | 195 if (committed_error_page_info_->alternate_error_page_url.is_valid()) { |
163 // If there is another pending error page load, | 196 // If there is another pending error page load, |
164 // |replace_with_alternate_error_page| should have been set to false. | 197 // |replace_with_alternate_error_page| should have been set to false. |
165 DCHECK(!pending_error_page_info_); | 198 DCHECK(!pending_error_page_info_); |
166 DCHECK(!committed_error_page_info_->needs_dns_updates); | 199 DCHECK(!committed_error_page_info_->needs_dns_updates); |
167 GURL error_page_url; | 200 GURL error_page_url; |
168 delegate_->FetchErrorPage( | 201 delegate_->FetchErrorPage( |
169 committed_error_page_info_->alternate_error_page_url); | 202 committed_error_page_info_->alternate_error_page_url); |
203 } else if (auto_reload_enabled_) { | |
204 blink::WebURLError error = committed_error_page_info_->error; | |
205 bool was_failed_post = committed_error_page_info_->was_failed_post; | |
206 if (IsReloadableError(error) && !was_failed_post) | |
207 StartAutoReloadTimer(); | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
Hmmm. My preference would be to only start the ti
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
208 else | |
209 auto_reload_count_ = 0; | |
170 } | 210 } |
171 | 211 |
172 if (!committed_error_page_info_->needs_dns_updates || | 212 if (!committed_error_page_info_->needs_dns_updates || |
173 last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) { | 213 last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) { |
174 return; | 214 return; |
175 } | 215 } |
176 DVLOG(1) << "Error page finished loading; sending saved status."; | 216 DVLOG(1) << "Error page finished loading; sending saved status."; |
177 UpdateErrorPage(); | 217 UpdateErrorPage(); |
178 } | 218 } |
179 | 219 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 } | 349 } |
310 | 350 |
311 blink::WebURLError updated_error; | 351 blink::WebURLError updated_error; |
312 updated_error.domain = blink::WebString::fromUTF8( | 352 updated_error.domain = blink::WebString::fromUTF8( |
313 chrome_common_net::kDnsProbeErrorDomain); | 353 chrome_common_net::kDnsProbeErrorDomain); |
314 updated_error.reason = last_probe_status_; | 354 updated_error.reason = last_probe_status_; |
315 updated_error.unreachableURL = error.unreachableURL; | 355 updated_error.unreachableURL = error.unreachableURL; |
316 | 356 |
317 return updated_error; | 357 return updated_error; |
318 } | 358 } |
359 | |
360 void NetErrorHelperCore::AutoReload() { | |
361 if (!committed_error_page_info_) { | |
362 return; | |
363 } | |
364 delegate_->ReloadPage(); | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
Confirming, just because I'm not sure which of the
| |
365 } | |
366 | |
367 void NetErrorHelperCore::StartAutoReloadTimer() { | |
368 base::TimeDelta delay = GetAutoReloadBackoff(auto_reload_count_); | |
369 auto_reload_count_++; | |
370 auto_reload_timer_.reset(delegate_->NewMockableOneShotTimer()); | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
It looks to me as if OneShotTimer can be re-used (
Elly Fong-Jones
2014/02/10 21:42:06
Good idea, I like it.
Done.
| |
371 auto_reload_timer_->Start(FROM_HERE, delay, | |
372 base::Bind(&NetErrorHelperCore::AutoReload, | |
373 base::Unretained(this))); | |
374 } | |
375 | |
376 bool NetErrorHelperCore::IsAutoReloading() const { | |
377 return auto_reload_count_ != 0; | |
378 } | |
379 | |
380 void NetErrorHelperCore::NetworkStateChanged(bool online) { | |
381 if (online && auto_reload_timer_->IsRunning()) { | |
Randy Smith (Not in Mondays)
2014/02/06 16:47:16
Should we stop the timer if the change was to offl
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
382 // start over | |
mmenke
2014/02/05 23:31:43
nit: Start over. (Per style guide, comments shoul
Elly Fong-Jones
2014/02/10 21:42:06
Done.
| |
383 auto_reload_count_ = 0; | |
384 auto_reload_timer_->Stop(); | |
385 StartAutoReloadTimer(); | |
386 } | |
387 } | |
OLD | NEW |