Chromium Code Reviews

Side by Side Diff: chrome/renderer/net/net_error_helper_core.cc

Issue 137623011: Switch to using the new Link Doctor API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Really fix ChromeOS Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
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/i18n/rtl.h"
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
9 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/strings/string16.h"
14 #include "base/values.h"
10 #include "chrome/common/localized_error.h" 15 #include "chrome/common/localized_error.h"
16 #include "grit/generated_resources.h"
11 #include "net/base/escape.h" 17 #include "net/base/escape.h"
12 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h"
13 #include "third_party/WebKit/public/platform/WebString.h" 20 #include "third_party/WebKit/public/platform/WebString.h"
14 #include "third_party/WebKit/public/platform/WebURLError.h" 21 #include "third_party/WebKit/public/platform/WebURLError.h"
22 #include "ui/base/l10n/l10n_util.h"
15 #include "url/gurl.h" 23 #include "url/gurl.h"
16 24
17 namespace { 25 namespace {
18 26
27 struct CorrectionTypeToResourceTable {
28 int resource_id;
29 const char* correction_type;
30 };
31
32 const CorrectionTypeToResourceTable kCorrectionResourceTable[] = {
33 {IDS_ERRORPAGES_SUGGESTION_VISIT_GOOGLE_CACHE, "cachedPage"},
34 // "reloadPage" is has special handling.
35 {IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL, "urlCorrection"},
36 {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "siteDomain"},
37 {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "host"},
38 {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "sitemap"},
39 {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "pathParentFolder"},
40 // "siteSearchQuery" is not yet supported.
41 // TODO(mmenke): Figure out what format "siteSearchQuery" uses for its
42 // suggestions.
43 // "webSearchQuery" has special handling.
44 {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "contentOverlap"},
45 {IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL, "emphasizedUrlCorrection"},
46 };
47
19 // Returns whether |net_error| is a DNS-related error (and therefore whether 48 // Returns whether |net_error| is a DNS-related error (and therefore whether
20 // the tab helper should start a DNS probe after receiving it.) 49 // the tab helper should start a DNS probe after receiving it.)
21 bool IsDnsError(const blink::WebURLError& error) { 50 bool IsDnsError(const blink::WebURLError& error) {
22 return error.domain.utf8() == net::kErrorDomain && 51 return error.domain.utf8() == net::kErrorDomain &&
23 (error.reason == net::ERR_NAME_NOT_RESOLVED || 52 (error.reason == net::ERR_NAME_NOT_RESOLVED ||
24 error.reason == net::ERR_NAME_RESOLUTION_FAILED); 53 error.reason == net::ERR_NAME_RESOLUTION_FAILED);
25 } 54 }
26 55
27 // If an alternate error page should be retrieved remotely for a main frame load 56 GURL SanitizeURL(const GURL& url) {
28 // that failed with |error|, returns true and sets |error_page_url| to the URL 57 GURL::Replacements remove_params;
29 // of the remote error page. 58 remove_params.ClearUsername();
30 bool GetErrorPageURL(const blink::WebURLError& error, 59 remove_params.ClearPassword();
31 const GURL& alt_error_page_url, 60 remove_params.ClearQuery();
32 GURL* error_page_url) { 61 remove_params.ClearRef();
33 if (!alt_error_page_url.is_valid()) 62 return url.ReplaceComponents(remove_params);
34 return false; 63 }
35 64
65 // If URL correction information should be retrieved remotely for a main frame
66 // load that failed with |error|, returns true and sets
67 // |fix_url_request_body| to be the body for the correcion request.
68 bool GetFixUrlRequestBody(const blink::WebURLError& error,
69 const std::string& language,
70 const std::string& country_code,
71 const std::string& api_key,
72 std::string* fix_url_request_body) {
36 // Parameter to send to the error page indicating the error type. 73 // Parameter to send to the error page indicating the error type.
37 std::string error_param; 74 std::string error_param;
38 75
39 std::string domain = error.domain.utf8(); 76 std::string domain = error.domain.utf8();
40 if (domain == "http" && error.reason == 404) { 77 if (domain == "http" && error.reason == 404) {
41 error_param = "http404"; 78 error_param = "http404";
42 } else if (IsDnsError(error)) { 79 } else if (IsDnsError(error)) {
43 error_param = "dnserror"; 80 error_param = "dnserror";
44 } else if (domain == net::kErrorDomain && 81 } else if (domain == net::kErrorDomain &&
45 (error.reason == net::ERR_CONNECTION_FAILED || 82 (error.reason == net::ERR_CONNECTION_FAILED ||
46 error.reason == net::ERR_CONNECTION_REFUSED || 83 error.reason == net::ERR_CONNECTION_REFUSED ||
47 error.reason == net::ERR_ADDRESS_UNREACHABLE || 84 error.reason == net::ERR_ADDRESS_UNREACHABLE ||
48 error.reason == net::ERR_CONNECTION_TIMED_OUT)) { 85 error.reason == net::ERR_CONNECTION_TIMED_OUT)) {
49 error_param = "connectionfailure"; 86 error_param = "connectionFailure";
50 } else { 87 } else {
51 return false; 88 return false;
52 } 89 }
53 90
54 // Don't use the Link Doctor for HTTPS (for privacy reasons). 91 // Don't use the Link Doctor for HTTPS (for privacy reasons).
55 GURL unreachable_url(error.unreachableURL); 92 GURL unreachable_url(error.unreachableURL);
56 if (unreachable_url.SchemeIsSecure()) 93 if (unreachable_url.SchemeIsSecure())
57 return false; 94 return false;
58 95
59 // Sanitize the unreachable URL. 96 // TODO(yuusuke): Change to net::FormatUrl when Link Doctor becomes
60 GURL::Replacements remove_params;
61 remove_params.ClearUsername();
62 remove_params.ClearPassword();
63 remove_params.ClearQuery();
64 remove_params.ClearRef();
65 // TODO(yuusuke): change to net::FormatUrl when Link Doctor becomes
66 // unicode-capable. 97 // unicode-capable.
67 std::string spec_to_send = 98 std::string spec_to_send = SanitizeURL(unreachable_url).spec();
68 unreachable_url.ReplaceComponents(remove_params).spec();
69 99
70 // Notify Link Doctor of the url truncation by sending of "?" at the end. 100 // Notify Link Doctor of the url truncation by sending of "?" at the end.
71 if (unreachable_url.has_query()) 101 if (unreachable_url.has_query())
72 spec_to_send.append("?"); 102 spec_to_send.append("?");
73 103
74 std::string params(alt_error_page_url.query()); 104 // Assemble request body, which is a JSON string.
75 params.append("&url="); 105 // TODO(mmenke): Investigate open sourcing the relevant protocol buffers and
76 params.append(net::EscapeQueryParamValue(spec_to_send, true)); 106 // using those directly instead.
77 params.append("&sourceid=chrome");
78 params.append("&error=");
79 params.append(error_param);
80 107
81 // Build the final url to request. 108 base::DictionaryValue request_dict;
82 GURL::Replacements link_doctor_params; 109 request_dict.SetString("method", "linkdoctor.fixurl.fixurl");
83 link_doctor_params.SetQueryStr(params); 110 request_dict.SetString("apiVersion", "v1");
84 *error_page_url = alt_error_page_url.ReplaceComponents(link_doctor_params); 111
112 base::DictionaryValue* params_dict = new base::DictionaryValue();
113 request_dict.Set("params", params_dict);
114
115 params_dict->SetString("key", api_key);
116 params_dict->SetString("urlQuery", spec_to_send);
117 params_dict->SetString("clientName", "chrome");
118 params_dict->SetString("error", error_param);
119
120 if (!language.empty())
121 params_dict->SetString("language", language);
122
123 // TODO(mmenke): Figure out if the originCountry can be set correctly.
124 // locale.getCountry() just seems to give the default country
125 // for the language resources currently in use.
126
127 if (!country_code.empty())
128 params_dict->SetString("originCountry", country_code);
129
130 base::JSONWriter::Write(&request_dict, fix_url_request_body);
85 return true; 131 return true;
86 } 132 }
87 133
134 base::string16 FormatURLForDisplay(const GURL& url, bool is_rtl,
135 const std::string accept_languages) {
136 // Translate punycode into UTF8, unescape UTF8 URLs.
137 base::string16 url_for_display(net::FormatUrl(
138 url, accept_languages, net::kFormatUrlOmitNothing,
139 net::UnescapeRule::NORMAL, NULL, NULL, NULL));
140 // URLs are always LTR.
141 if (is_rtl)
142 base::i18n::WrapStringWithLTRFormatting(&url_for_display);
143 return url_for_display;
144 }
145
146 LocalizedError::ErrorPageParams* ParseAdditionalSuggestions(
147 const std::string& data,
148 const GURL& original_url,
149 const GURL& search_url,
150 const std::string& accept_languages,
151 bool is_rtl) {
152 scoped_ptr<base::Value> parsed(base::JSONReader::Read(data));
153 if (!parsed)
154 return NULL;
155 // TODO(mmenke): Open source related protocol buffers and use them directly.
156 base::DictionaryValue* parsed_dict;
157 base::ListValue* corrections;
158 if (!parsed->GetAsDictionary(&parsed_dict))
159 return NULL;
160 if (!parsed_dict->GetList("result.UrlCorrections", &corrections))
161 return NULL;
162
163 // Version of URL for display in suggestions. It has to be sanitized first
164 // because any received suggestions will be relative to the sanitized URL.
165 base::string16 original_url_for_display =
166 FormatURLForDisplay(SanitizeURL(original_url), is_rtl, accept_languages);
167
168 scoped_ptr<LocalizedError::ErrorPageParams> params(
169 new LocalizedError::ErrorPageParams());
170 params->override_suggestions.reset(new base::ListValue());
171 scoped_ptr<base::ListValue> parsed_corrections(new base::ListValue());
172 for (base::ListValue::iterator it = corrections->begin();
173 it != corrections->end(); ++it) {
174 base::DictionaryValue* correction;
175 if (!(*it)->GetAsDictionary(&correction))
176 continue;
177
178 // Doesn't seem like a good idea to show these.
Deprecated (see juliatuttle) 2014/02/04 17:44:21 What if that's what the user was looking for? (Is
mmenke 2014/02/04 19:43:56 In my experience, FixURL isn't really that clever.
Deprecated (see juliatuttle) 2014/02/04 20:20:20 Alright. I'll tinker with it and see how clever i
mmenke 2014/02/04 20:31:09 May also want to see if we're already excluding po
179 bool is_porn;
180 if (correction->GetBoolean("isPorn", &is_porn) && is_porn)
181 continue;
182 if (correction->GetBoolean("isSoftPorn", &is_porn) && is_porn)
183 continue;
184
185 std::string correction_type;
186 std::string url_correction;
187 if (!correction->GetString("correctionType", &correction_type) ||
188 !correction->GetString("urlCorrection", &url_correction)) {
189 continue;
190 }
191
192 std::string click_tracking_url;
193 correction->GetString("clickTrackingUrl", &click_tracking_url);
194
195 if (correction_type == "reloadPage") {
196 params->suggest_reload = true;
197 continue;
198 }
199
200 if (correction_type == "webSearchQuery") {
201 // If there are mutliple searches suggested, use the first suggestion.
202 if (params->search_terms.empty()) {
203 params->search_url = search_url;
204 params->search_terms = url_correction;
205 }
206 continue;
207 }
208
209 size_t correction_index;
210 for (correction_index = 0;
211 correction_index < arraysize(kCorrectionResourceTable);
212 ++correction_index) {
213 if (correction_type !=
214 kCorrectionResourceTable[correction_index].correction_type) {
215 continue;
216 }
217 base::DictionaryValue* suggest = new base::DictionaryValue();
218 suggest->SetString("header",
219 l10n_util::GetStringUTF16(
220 kCorrectionResourceTable[correction_index].resource_id));
221 suggest->SetString("urlCorrection",
222 !click_tracking_url.empty() ? click_tracking_url :
223 url_correction);
224 suggest->SetString(
225 "urlCorrectionForDisplay",
226 FormatURLForDisplay(GURL(url_correction), is_rtl, accept_languages));
227 suggest->SetString("originalUrlForDisplay", original_url_for_display);
228 params->override_suggestions->Append(suggest);
229 break;
230 }
231 }
232
233 if (params->override_suggestions->empty() &&
234 !params->search_url.is_valid()) {
235 return NULL;
236 }
237 return params.release();
238 }
239
88 } // namespace 240 } // namespace
89 241
90 struct NetErrorHelperCore::ErrorPageInfo { 242 struct NetErrorHelperCore::ErrorPageInfo {
91 ErrorPageInfo(blink::WebURLError error, bool was_failed_post) 243 ErrorPageInfo(blink::WebURLError error, bool was_failed_post)
92 : error(error), 244 : error(error),
93 was_failed_post(was_failed_post), 245 was_failed_post(was_failed_post),
94 needs_dns_updates(false), 246 needs_dns_updates(false),
95 is_finished_loading(false) { 247 is_finished_loading(false) {
96 } 248 }
97 249
98 // Information about the failed page load. 250 // Information about the failed page load.
99 blink::WebURLError error; 251 blink::WebURLError error;
100 bool was_failed_post; 252 bool was_failed_post;
101 253
102 // Information about the status of the error page. 254 // Information about the status of the error page.
103 255
104 // True if a page is a DNS error page and has not yet received a final DNS 256 // True if a page is a DNS error page and has not yet received a final DNS
105 // probe status. 257 // probe status.
106 bool needs_dns_updates; 258 bool needs_dns_updates;
107 259
108 // URL of an alternate error page to repace this error page with, if it's a 260 // URL of the FixURL service, which will be used to request suggestions on
109 // valid URL. Request will be issued when the error page finishes loading. 261 // certain types of network errors. This is also stored by the
110 // This is done on load complete to ensure that there are two complete loads 262 // NetErrorHelperCore itself, but it stored here as well in case its modified
111 // for tests to wait for. 263 // in the middle of an error page load. Empty when no error page should be
112 GURL alternate_error_page_url; 264 // fetched, or if there's already a fetch in progress.
265 GURL link_doctor_url;
266
267 // Request body to use when requesting suggestions from the FixURL service.
268 // TODO(mmenke): Investigate loading the error page at the same time as
269 // the blank page is loading, to get rid of these.
270 std::string link_doctor_request_body;
113 271
114 // True if a page has completed loading, at which point it can receive 272 // True if a page has completed loading, at which point it can receive
115 // updates. 273 // updates.
116 bool is_finished_loading; 274 bool is_finished_loading;
117 }; 275 };
118 276
119 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) 277 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate)
120 : delegate_(delegate), 278 : delegate_(delegate),
121 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE) { 279 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE) {
122 } 280 }
123 281
124 NetErrorHelperCore::~NetErrorHelperCore() { 282 NetErrorHelperCore::~NetErrorHelperCore() {
125 } 283 }
126 284
127 void NetErrorHelperCore::OnStop() { 285 void NetErrorHelperCore::OnStop() {
128 // On stop, cancel loading the alternate error page, and prevent any pending 286 // 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 287 // 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. 288 // page when it's finished loading could abort the navigation, otherwise.
131 if (committed_error_page_info_) 289 if (committed_error_page_info_) {
132 committed_error_page_info_->alternate_error_page_url = GURL(); 290 committed_error_page_info_->link_doctor_url = GURL();
133 if (pending_error_page_info_) 291 committed_error_page_info_->link_doctor_request_body.clear();
134 pending_error_page_info_->alternate_error_page_url = GURL(); 292 }
293 if (pending_error_page_info_) {
294 pending_error_page_info_->link_doctor_url = GURL();
295 pending_error_page_info_->link_doctor_request_body.clear();
296 }
135 delegate_->CancelFetchErrorPage(); 297 delegate_->CancelFetchErrorPage();
136 } 298 }
137 299
138 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { 300 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) {
139 if (frame_type != MAIN_FRAME) 301 if (frame_type != MAIN_FRAME)
140 return; 302 return;
141 303
142 // If there's no pending error page information associated with the page load, 304 // 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. 305 // 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) { 306 if (!pending_error_page_info_ || page_type != ERROR_PAGE) {
145 OnStop(); 307 OnStop();
146 } 308 }
147 } 309 }
148 310
149 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { 311 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) {
150 if (frame_type != MAIN_FRAME) 312 if (frame_type != MAIN_FRAME)
151 return; 313 return;
152 314
153 committed_error_page_info_.reset(pending_error_page_info_.release()); 315 committed_error_page_info_.reset(pending_error_page_info_.release());
154 } 316 }
155 317
156 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { 318 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
157 if (frame_type != MAIN_FRAME || !committed_error_page_info_) 319 if (frame_type != MAIN_FRAME || !committed_error_page_info_)
158 return; 320 return;
159 321
160 committed_error_page_info_->is_finished_loading = true; 322 committed_error_page_info_->is_finished_loading = true;
161 323
162 if (committed_error_page_info_->alternate_error_page_url.is_valid()) { 324 if (committed_error_page_info_->link_doctor_url.is_valid()) {
163 // If there is another pending error page load, 325 // If there is another pending error page load, |fix_url| should have been
164 // |replace_with_alternate_error_page| should have been set to false. 326 // cleared.
165 DCHECK(!pending_error_page_info_); 327 DCHECK(!pending_error_page_info_);
166 DCHECK(!committed_error_page_info_->needs_dns_updates); 328 DCHECK(!committed_error_page_info_->needs_dns_updates);
167 GURL error_page_url;
168 delegate_->FetchErrorPage( 329 delegate_->FetchErrorPage(
169 committed_error_page_info_->alternate_error_page_url); 330 committed_error_page_info_->link_doctor_url,
331 committed_error_page_info_->link_doctor_request_body);
170 } 332 }
171 333
172 if (!committed_error_page_info_->needs_dns_updates || 334 if (!committed_error_page_info_->needs_dns_updates ||
173 last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) { 335 last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) {
174 return; 336 return;
175 } 337 }
176 DVLOG(1) << "Error page finished loading; sending saved status."; 338 DVLOG(1) << "Error page finished loading; sending saved status.";
177 UpdateErrorPage(); 339 UpdateErrorPage();
178 } 340 }
179 341
180 void NetErrorHelperCore::GetErrorHTML( 342 void NetErrorHelperCore::GetErrorHTML(
181 FrameType frame_type, 343 FrameType frame_type,
182 const blink::WebURLError& error, 344 const blink::WebURLError& error,
183 bool is_failed_post, 345 bool is_failed_post,
184 std::string* error_html) { 346 std::string* error_html) {
185 if (frame_type == MAIN_FRAME) { 347 if (frame_type == MAIN_FRAME) {
186 // If an alternate error page was going to be fetched, that should have been 348 // If an alternate error page was going to be fetched, that should have been
187 // cancelled by loading a new page load (Which has now failed to load). 349 // cancelled by loading a new page load (Which has now failed to load).
188 DCHECK(!committed_error_page_info_ || 350 DCHECK(!committed_error_page_info_ ||
189 !committed_error_page_info_->alternate_error_page_url.is_valid()); 351 !committed_error_page_info_->link_doctor_url.is_valid());
352
353 std::string link_doctor_request_body;
354
355 if (link_doctor_url_.is_valid() &&
356 GetFixUrlRequestBody(error, language_, country_code_, api_key_,
357 &link_doctor_request_body)) {
358 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
359 pending_error_page_info_->link_doctor_url = link_doctor_url_;
360 pending_error_page_info_->link_doctor_request_body =
361 link_doctor_request_body;
362 return;
363 }
190 364
191 // The last probe status needs to be reset if this is a DNS error. This 365 // The last probe status needs to be reset if this is a DNS error. This
192 // means that if a DNS error page is committed but has not yet finished 366 // means that if a DNS error page is committed but has not yet finished
193 // loading, a DNS probe status scheduled to be sent to it may be thrown 367 // loading, a DNS probe status scheduled to be sent to it may be thrown
194 // out, but since the new error page should trigger a new DNS probe, it 368 // out, but since the new error page should trigger a new DNS probe, it
195 // will just get the results for the next page load. 369 // will just get the results for the next page load.
196 if (IsDnsError(error)) 370 if (IsDnsError(error))
197 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; 371 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
198
199 GURL error_page_url;
200 if (GetErrorPageURL(error, alt_error_page_url_, &error_page_url)) {
201 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
202 pending_error_page_info_->alternate_error_page_url = error_page_url;
203 return;
204 }
205 } 372 }
206 373
207 GenerateLocalErrorPage(frame_type, error, is_failed_post, error_html); 374 GenerateLocalErrorPage(frame_type, error, is_failed_post,
375 scoped_ptr<LocalizedError::ErrorPageParams>(),
376 error_html);
208 } 377 }
209 378
210 void NetErrorHelperCore::GenerateLocalErrorPage( 379 void NetErrorHelperCore::GenerateLocalErrorPage(
211 FrameType frame_type, 380 FrameType frame_type,
212 const blink::WebURLError& error, 381 const blink::WebURLError& error,
213 bool is_failed_post, 382 bool is_failed_post,
383 scoped_ptr<LocalizedError::ErrorPageParams> params,
214 std::string* error_html) { 384 std::string* error_html) {
215 if (frame_type == MAIN_FRAME) { 385 if (frame_type == MAIN_FRAME) {
216 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post)); 386 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
217 if (IsDnsError(error)) { 387 // Skip DNS logic if suggestions were received from a remote server.
388 // TODO(mmenke): Consider integrating probe results with Link Doctor
389 // suggestions.
390 if (IsDnsError(error) && !params) {
218 // This is not strictly necessary, but waiting for a new status to be 391 // This is not strictly necessary, but waiting for a new status to be
219 // sent as a result of the DidFinishLoading call keeps the histograms 392 // sent as a result of the DidFinishLoading call keeps the histograms
220 // consistent with older versions of the code, at no real cost. 393 // consistent with older versions of the code, at no real cost.
221 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; 394 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
222 395
223 delegate_->GenerateLocalizedErrorPage( 396 delegate_->GenerateLocalizedErrorPage(
224 GetUpdatedError(error), is_failed_post, error_html); 397 GetUpdatedError(error), is_failed_post, params.Pass(),
398 error_html);
225 pending_error_page_info_->needs_dns_updates = true; 399 pending_error_page_info_->needs_dns_updates = true;
226 return; 400 return;
227 } 401 }
228 } 402 }
229 delegate_->GenerateLocalizedErrorPage(error, is_failed_post, error_html); 403
404 delegate_->GenerateLocalizedErrorPage(error, is_failed_post,
405 params.Pass(), error_html);
230 } 406 }
231 407
232 void NetErrorHelperCore::OnNetErrorInfo( 408 void NetErrorHelperCore::OnNetErrorInfo(
233 chrome_common_net::DnsProbeStatus status) { 409 chrome_common_net::DnsProbeStatus status) {
234 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status); 410 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status);
235 411
236 last_probe_status_ = status; 412 last_probe_status_ = status;
237 413
238 if (!committed_error_page_info_ || 414 if (!committed_error_page_info_ ||
239 !committed_error_page_info_->needs_dns_updates || 415 !committed_error_page_info_->needs_dns_updates ||
240 !committed_error_page_info_->is_finished_loading) { 416 !committed_error_page_info_->is_finished_loading) {
241 return; 417 return;
242 } 418 }
243 419
244 UpdateErrorPage(); 420 UpdateErrorPage();
245 } 421 }
246 422
423 void NetErrorHelperCore::OnSetLinkDoctorInfo(const GURL& link_doctor_url,
424 const std::string& language,
425 const std::string& country_code,
426 const std::string& api_key,
427 const GURL& search_url) {
428 link_doctor_url_ = link_doctor_url;
429 language_ = language;
430 country_code_ = country_code;
431 api_key_ = api_key;
432 search_url_ = search_url;
433 }
434
247 void NetErrorHelperCore::UpdateErrorPage() { 435 void NetErrorHelperCore::UpdateErrorPage() {
248 DCHECK(committed_error_page_info_->needs_dns_updates); 436 DCHECK(committed_error_page_info_->needs_dns_updates);
249 DCHECK(committed_error_page_info_->is_finished_loading); 437 DCHECK(committed_error_page_info_->is_finished_loading);
250 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, last_probe_status_); 438 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, last_probe_status_);
251 439
252 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus", 440 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus",
253 last_probe_status_, 441 last_probe_status_,
254 chrome_common_net::DNS_PROBE_MAX); 442 chrome_common_net::DNS_PROBE_MAX);
255 // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a 443 // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a
256 // final status code. Once one is reached, the page does not need further 444 // final status code. Once one is reached, the page does not need further
257 // updates. 445 // updates.
258 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED) 446 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED)
259 committed_error_page_info_->needs_dns_updates = false; 447 committed_error_page_info_->needs_dns_updates = false;
260 448
261 delegate_->UpdateErrorPage( 449 delegate_->UpdateErrorPage(
262 GetUpdatedError(committed_error_page_info_->error), 450 GetUpdatedError(committed_error_page_info_->error),
263 committed_error_page_info_->was_failed_post); 451 committed_error_page_info_->was_failed_post);
264 } 452 }
265 453
266 void NetErrorHelperCore::OnAlternateErrorPageFetched(const std::string& data) { 454 void NetErrorHelperCore::OnAlternateErrorPageFetched(
455 const std::string& data, const std::string& accept_languages, bool is_rtl) {
267 // Alternate error page load only starts when an error page finishes loading, 456 // Alternate error page load only starts when an error page finishes loading,
268 // and is cancelled with a new load 457 // and is cancelled with a new load.
269 DCHECK(!pending_error_page_info_); 458 DCHECK(!pending_error_page_info_);
270 DCHECK(committed_error_page_info_->is_finished_loading); 459 DCHECK(committed_error_page_info_->is_finished_loading);
271 460
272 const std::string* error_html = NULL; 461 scoped_ptr<LocalizedError::ErrorPageParams> params(
273 std::string generated_html; 462 ParseAdditionalSuggestions(
274 if (!data.empty()) { 463 data, GURL(committed_error_page_info_->error.unreachableURL),
275 // If the request succeeded, use the response in place of a generated error 464 search_url_, accept_languages, is_rtl));
276 // page. 465 std::string error_html;
277 pending_error_page_info_.reset( 466 GenerateLocalErrorPage(MAIN_FRAME,
278 new ErrorPageInfo(committed_error_page_info_->error, 467 committed_error_page_info_->error,
279 committed_error_page_info_->was_failed_post)); 468 committed_error_page_info_->was_failed_post,
280 error_html = &data; 469 params.Pass(),
281 } else { 470 &error_html);
282 // Otherwise, generate a local error page. |pending_error_page_info_| will
283 // be set by GenerateLocalErrorPage.
284 GenerateLocalErrorPage(MAIN_FRAME,
285 committed_error_page_info_->error,
286 committed_error_page_info_->was_failed_post,
287 &generated_html);
288 error_html = &generated_html;
289 }
290 471
291 // |error_page_info| may have been destroyed by this point, since 472 // |error_page_info| may have been destroyed by this point, since
292 // |pending_error_page_info_| was set to a new ErrorPageInfo. 473 // |pending_error_page_info_| was set to a new ErrorPageInfo.
293 474
294 // TODO(mmenke): Once the new API is in place, look into replacing this 475 // TODO(mmenke): Once the new API is in place, look into replacing this
295 // double page load by just updating the error page, like DNS 476 // double page load by just updating the error page, like DNS
296 // probes do. 477 // probes do.
297 delegate_->LoadErrorPageInMainFrame( 478 delegate_->LoadErrorPageInMainFrame(
298 *error_html, 479 error_html,
299 pending_error_page_info_->error.unreachableURL); 480 pending_error_page_info_->error.unreachableURL);
300 } 481 }
301 482
302 blink::WebURLError NetErrorHelperCore::GetUpdatedError( 483 blink::WebURLError NetErrorHelperCore::GetUpdatedError(
303 const blink::WebURLError& error) const { 484 const blink::WebURLError& error) const {
304 // If a probe didn't run or wasn't conclusive, restore the original error. 485 // If a probe didn't run or wasn't conclusive, restore the original error.
305 if (last_probe_status_ == chrome_common_net::DNS_PROBE_NOT_RUN || 486 if (last_probe_status_ == chrome_common_net::DNS_PROBE_NOT_RUN ||
306 last_probe_status_ == 487 last_probe_status_ ==
307 chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE) { 488 chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE) {
308 return error; 489 return error;
309 } 490 }
310 491
311 blink::WebURLError updated_error; 492 blink::WebURLError updated_error;
312 updated_error.domain = blink::WebString::fromUTF8( 493 updated_error.domain = blink::WebString::fromUTF8(
313 chrome_common_net::kDnsProbeErrorDomain); 494 chrome_common_net::kDnsProbeErrorDomain);
314 updated_error.reason = last_probe_status_; 495 updated_error.reason = last_probe_status_;
315 updated_error.unreachableURL = error.unreachableURL; 496 updated_error.unreachableURL = error.unreachableURL;
316 497
317 return updated_error; 498 return updated_error;
318 } 499 }
OLDNEW

Powered by Google App Engine