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 |