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/common/localized_error.h"
7 #include "base/i18n/rtl.h"
8 #include "base/logging.h"
9 #include "base/string16.h"
10 #include "base/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/common/extensions/extension_constants.h"
14 #include "chrome/common/extensions/extension_icon_set.h"
15 #include "chrome/common/extensions/extension_set.h"
16 #include "googleurl/src/gurl.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h"
19 #include "net/base/escape.h"
20 #include "net/base/net_errors.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "webkit/glue/webkit_glue.h"
26 #include "base/win/windows_version.h"
29 using WebKit::WebURLError
;
33 static const char kRedirectLoopLearnMoreUrl
[] =
34 "https://www.google.com/support/chrome/bin/answer.py?answer=95626";
35 static const char kWeakDHKeyLearnMoreUrl
[] =
36 "http://sites.google.com/a/chromium.org/dev/"
37 "err_ssl_weak_server_ephemeral_dh_key";
38 #if defined(OS_CHROMEOS)
39 static const char kAppWarningLearnMoreUrl
[] =
40 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html"
42 #endif // defined(OS_CHROMEOS)
44 enum NAV_SUGGESTIONS
{
46 SUGGEST_RELOAD
= 1 << 0,
47 SUGGEST_HOSTNAME
= 1 << 1,
48 SUGGEST_CHECK_CONNECTION
= 1 << 2,
49 SUGGEST_DNS_CONFIG
= 1 << 3,
50 SUGGEST_FIREWALL_CONFIG
= 1 << 4,
51 SUGGEST_PROXY_CONFIG
= 1 << 5,
52 SUGGEST_DISABLE_EXTENSION
= 1 << 6,
53 SUGGEST_LEARNMORE
= 1 << 7,
56 struct LocalizedErrorMap
{
58 unsigned int title_resource_id
;
59 unsigned int heading_resource_id
;
60 unsigned int summary_resource_id
;
61 unsigned int details_resource_id
;
62 int suggestions
; // Bitmap of SUGGEST_* values.
65 const LocalizedErrorMap net_error_options
[] = {
67 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
68 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
69 IDS_ERRORPAGES_SUMMARY_TIMED_OUT
,
70 IDS_ERRORPAGES_DETAILS_TIMED_OUT
,
71 SUGGEST_RELOAD
| SUGGEST_CHECK_CONNECTION
| SUGGEST_FIREWALL_CONFIG
|
74 {net::ERR_CONNECTION_TIMED_OUT
,
75 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
76 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
77 IDS_ERRORPAGES_SUMMARY_TIMED_OUT
,
78 IDS_ERRORPAGES_DETAILS_TIMED_OUT
,
79 SUGGEST_RELOAD
| SUGGEST_CHECK_CONNECTION
| SUGGEST_FIREWALL_CONFIG
|
82 {net::ERR_CONNECTION_CLOSED
,
83 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
84 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
85 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
,
86 IDS_ERRORPAGES_DETAILS_CONNECTION_CLOSED
,
89 {net::ERR_CONNECTION_RESET
,
90 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
91 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
92 IDS_ERRORPAGES_SUMMARY_CONNECTION_RESET
,
93 IDS_ERRORPAGES_DETAILS_CONNECTION_RESET
,
94 SUGGEST_RELOAD
| SUGGEST_CHECK_CONNECTION
| SUGGEST_FIREWALL_CONFIG
|
97 {net::ERR_CONNECTION_REFUSED
,
98 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
99 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
100 IDS_ERRORPAGES_SUMMARY_CONNECTION_REFUSED
,
101 IDS_ERRORPAGES_DETAILS_CONNECTION_REFUSED
,
102 SUGGEST_RELOAD
| SUGGEST_CHECK_CONNECTION
| SUGGEST_FIREWALL_CONFIG
|
103 SUGGEST_PROXY_CONFIG
,
105 {net::ERR_CONNECTION_FAILED
,
106 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
107 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
108 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
,
109 IDS_ERRORPAGES_DETAILS_CONNECTION_FAILED
,
112 {net::ERR_NAME_NOT_RESOLVED
,
113 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
114 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
115 IDS_ERRORPAGES_SUMMARY_NAME_NOT_RESOLVED
,
116 IDS_ERRORPAGES_DETAILS_NAME_NOT_RESOLVED
,
117 SUGGEST_RELOAD
| SUGGEST_CHECK_CONNECTION
| SUGGEST_DNS_CONFIG
|
118 SUGGEST_FIREWALL_CONFIG
| SUGGEST_PROXY_CONFIG
,
120 {net::ERR_ADDRESS_UNREACHABLE
,
121 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
122 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
123 IDS_ERRORPAGES_SUMMARY_ADDRESS_UNREACHABLE
,
124 IDS_ERRORPAGES_DETAILS_ADDRESS_UNREACHABLE
,
125 SUGGEST_RELOAD
| SUGGEST_FIREWALL_CONFIG
| SUGGEST_PROXY_CONFIG
,
127 {net::ERR_NETWORK_ACCESS_DENIED
,
128 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
129 IDS_ERRORPAGES_HEADING_NETWORK_ACCESS_DENIED
,
130 IDS_ERRORPAGES_SUMMARY_NETWORK_ACCESS_DENIED
,
131 IDS_ERRORPAGES_DETAILS_NETWORK_ACCESS_DENIED
,
132 SUGGEST_FIREWALL_CONFIG
,
134 {net::ERR_PROXY_CONNECTION_FAILED
,
135 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
136 IDS_ERRORPAGES_HEADING_PROXY_CONNECTION_FAILED
,
137 IDS_ERRORPAGES_SUMMARY_PROXY_CONNECTION_FAILED
,
138 IDS_ERRORPAGES_DETAILS_PROXY_CONNECTION_FAILED
,
139 SUGGEST_PROXY_CONFIG
,
141 {net::ERR_INTERNET_DISCONNECTED
,
142 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
143 IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED
,
144 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED
,
145 IDS_ERRORPAGES_DETAILS_INTERNET_DISCONNECTED
,
148 {net::ERR_FILE_NOT_FOUND
,
149 IDS_ERRORPAGES_TITLE_NOT_FOUND
,
150 IDS_ERRORPAGES_HEADING_NOT_FOUND
,
151 IDS_ERRORPAGES_SUMMARY_NOT_FOUND
,
152 IDS_ERRORPAGES_DETAILS_FILE_NOT_FOUND
,
155 {net::ERR_CACHE_MISS
,
156 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
157 IDS_ERRORPAGES_HEADING_CACHE_MISS
,
158 IDS_ERRORPAGES_SUMMARY_CACHE_MISS
,
159 IDS_ERRORPAGES_DETAILS_CACHE_MISS
,
162 {net::ERR_CACHE_READ_FAILURE
,
163 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
164 IDS_ERRORPAGES_HEADING_CACHE_READ_FAILURE
,
165 IDS_ERRORPAGES_SUMMARY_CACHE_READ_FAILURE
,
166 IDS_ERRORPAGES_DETAILS_CACHE_READ_FAILURE
,
169 {net::ERR_NETWORK_IO_SUSPENDED
,
170 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
171 IDS_ERRORPAGES_HEADING_NETWORK_IO_SUSPENDED
,
172 IDS_ERRORPAGES_SUMMARY_NETWORK_IO_SUSPENDED
,
173 IDS_ERRORPAGES_DETAILS_NETWORK_IO_SUSPENDED
,
176 {net::ERR_TOO_MANY_REDIRECTS
,
177 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
178 IDS_ERRORPAGES_HEADING_TOO_MANY_REDIRECTS
,
179 IDS_ERRORPAGES_SUMMARY_TOO_MANY_REDIRECTS
,
180 IDS_ERRORPAGES_DETAILS_TOO_MANY_REDIRECTS
,
181 SUGGEST_RELOAD
| SUGGEST_LEARNMORE
,
183 {net::ERR_EMPTY_RESPONSE
,
184 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
185 IDS_ERRORPAGES_HEADING_EMPTY_RESPONSE
,
186 IDS_ERRORPAGES_SUMMARY_EMPTY_RESPONSE
,
187 IDS_ERRORPAGES_DETAILS_EMPTY_RESPONSE
,
190 {net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH
,
191 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
192 IDS_ERRORPAGES_HEADING_DUPLICATE_HEADERS
,
193 IDS_ERRORPAGES_SUMMARY_DUPLICATE_HEADERS
,
194 IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH
,
197 {net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
,
198 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
199 IDS_ERRORPAGES_HEADING_DUPLICATE_HEADERS
,
200 IDS_ERRORPAGES_SUMMARY_DUPLICATE_HEADERS
,
201 IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
,
204 {net::ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION
,
205 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
206 IDS_ERRORPAGES_HEADING_DUPLICATE_HEADERS
,
207 IDS_ERRORPAGES_SUMMARY_DUPLICATE_HEADERS
,
208 IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_LOCATION
,
211 {net::ERR_CONTENT_LENGTH_MISMATCH
,
212 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
213 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
214 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
,
215 IDS_ERRORPAGES_DETAILS_CONNECTION_CLOSED
,
218 {net::ERR_INCOMPLETE_CHUNKED_ENCODING
,
219 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
220 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
221 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
,
222 IDS_ERRORPAGES_DETAILS_CONNECTION_CLOSED
,
225 {net::ERR_SSL_PROTOCOL_ERROR
,
226 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
227 IDS_ERRORPAGES_HEADING_SSL_PROTOCOL_ERROR
,
228 IDS_ERRORPAGES_SUMMARY_SSL_PROTOCOL_ERROR
,
229 IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR
,
232 {net::ERR_SSL_UNSAFE_NEGOTIATION
,
233 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
234 IDS_ERRORPAGES_HEADING_SSL_PROTOCOL_ERROR
,
235 IDS_ERRORPAGES_SUMMARY_SSL_PROTOCOL_ERROR
,
236 IDS_ERRORPAGES_DETAILS_SSL_UNSAFE_NEGOTIATION
,
239 {net::ERR_BAD_SSL_CLIENT_AUTH_CERT
,
240 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
241 IDS_ERRORPAGES_HEADING_BAD_SSL_CLIENT_AUTH_CERT
,
242 IDS_ERRORPAGES_SUMMARY_BAD_SSL_CLIENT_AUTH_CERT
,
243 IDS_ERRORPAGES_DETAILS_BAD_SSL_CLIENT_AUTH_CERT
,
246 {net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY
,
247 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
248 IDS_ERRORPAGES_HEADING_WEAK_SERVER_EPHEMERAL_DH_KEY
,
249 IDS_ERRORPAGES_SUMMARY_WEAK_SERVER_EPHEMERAL_DH_KEY
,
250 IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR
,
253 {net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN
,
254 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
255 IDS_ERRORPAGES_HEADING_PINNING_FAILURE
,
256 IDS_ERRORPAGES_SUMMARY_PINNING_FAILURE
,
257 IDS_ERRORPAGES_DETAILS_PINNING_FAILURE
,
260 {net::ERR_TEMPORARILY_THROTTLED
,
261 IDS_ERRORPAGES_TITLE_ACCESS_DENIED
,
262 IDS_ERRORPAGES_HEADING_ACCESS_DENIED
,
263 IDS_ERRORPAGES_SUMMARY_TEMPORARILY_THROTTLED
,
264 IDS_ERRORPAGES_DETAILS_TEMPORARILY_THROTTLED
,
267 {net::ERR_BLOCKED_BY_CLIENT
,
268 IDS_ERRORPAGES_TITLE_BLOCKED
,
269 IDS_ERRORPAGES_HEADING_BLOCKED
,
270 IDS_ERRORPAGES_SUMMARY_BLOCKED
,
271 IDS_ERRORPAGES_DETAILS_BLOCKED
,
272 SUGGEST_DISABLE_EXTENSION
,
276 const LocalizedErrorMap http_error_options
[] = {
278 IDS_ERRORPAGES_TITLE_ACCESS_DENIED
,
279 IDS_ERRORPAGES_HEADING_ACCESS_DENIED
,
280 IDS_ERRORPAGES_SUMMARY_FORBIDDEN
,
281 IDS_ERRORPAGES_DETAILS_FORBIDDEN
,
285 IDS_ERRORPAGES_TITLE_NOT_FOUND
,
286 IDS_ERRORPAGES_HEADING_NOT_FOUND
,
287 IDS_ERRORPAGES_SUMMARY_GONE
,
288 IDS_ERRORPAGES_DETAILS_GONE
,
293 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
294 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
295 IDS_ERRORPAGES_SUMMARY_INTERNAL_SERVER_ERROR
,
296 IDS_ERRORPAGES_DETAILS_INTERNAL_SERVER_ERROR
,
300 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
301 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
302 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE
,
303 IDS_ERRORPAGES_DETAILS_NOT_IMPLEMENTED
,
307 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
308 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
309 IDS_ERRORPAGES_SUMMARY_BAD_GATEWAY
,
310 IDS_ERRORPAGES_DETAILS_BAD_GATEWAY
,
314 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
315 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
316 IDS_ERRORPAGES_SUMMARY_SERVICE_UNAVAILABLE
,
317 IDS_ERRORPAGES_DETAILS_SERVICE_UNAVAILABLE
,
321 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
322 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
323 IDS_ERRORPAGES_SUMMARY_GATEWAY_TIMEOUT
,
324 IDS_ERRORPAGES_DETAILS_GATEWAY_TIMEOUT
,
328 IDS_ERRORPAGES_TITLE_LOAD_FAILED
,
329 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
,
330 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE
,
331 IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED
,
336 const char* HttpErrorToString(int status_code
) {
337 switch (status_code
) {
343 return "Internal Server Error";
345 return "Not Implemented";
347 return "Bad Gateway";
349 return "Service Unavailable";
351 return "Gateway Timeout";
353 return "HTTP Version Not Supported";
359 string16
GetErrorDetailsString(const std::string
& error_domain
,
361 const string16
& details
) {
362 int error_page_template
;
363 const char* error_string
;
364 if (error_domain
== net::kErrorDomain
) {
365 error_page_template
= IDS_ERRORPAGES_DETAILS_TEMPLATE
;
366 error_string
= net::ErrorToString(error_code
);
367 DCHECK(error_code
< 0); // Net error codes are negative.
368 error_code
= -error_code
;
369 } else if (error_domain
== LocalizedError::kHttpErrorDomain
) {
370 error_page_template
= IDS_ERRORPAGES_HTTP_DETAILS_TEMPLATE
;
371 error_string
= HttpErrorToString(error_code
);
376 return l10n_util::GetStringFUTF16(
378 base::IntToString16(error_code
),
379 ASCIIToUTF16(error_string
),
383 const LocalizedErrorMap
* FindErrorMapInArray(const LocalizedErrorMap
* maps
,
386 for (size_t i
= 0; i
< num_maps
; ++i
) {
387 if (maps
[i
].error_code
== error_code
)
393 const LocalizedErrorMap
* LookupErrorMap(const std::string
& error_domain
,
395 if (error_domain
== net::kErrorDomain
) {
396 return FindErrorMapInArray(net_error_options
,
397 arraysize(net_error_options
),
399 } else if (error_domain
== LocalizedError::kHttpErrorDomain
) {
400 return FindErrorMapInArray(http_error_options
,
401 arraysize(http_error_options
),
410 #if defined(TOOLKIT_GTK)
411 // base::i18n::IsRTL() uses the GTK text direction, which doesn't work within
412 // the renderer sandbox.
413 return base::i18n::ICUIsRTL();
415 return base::i18n::IsRTL();
419 // Returns a dictionary containing the strings for the settings menu under the
420 // wrench, and the advanced settings button.
421 DictionaryValue
* GetStandardMenuItemsText() {
422 DictionaryValue
* standard_menu_items_text
= new DictionaryValue();
423 standard_menu_items_text
->SetString("settingsTitle",
424 l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE
));
425 standard_menu_items_text
->SetString("advancedTitle",
426 l10n_util::GetStringUTF16(IDS_SETTINGS_SHOW_ADVANCED_SETTINGS
));
427 return standard_menu_items_text
;
432 const char LocalizedError::kHttpErrorDomain
[] = "http";
434 void LocalizedError::GetStrings(const WebKit::WebURLError
& error
,
435 DictionaryValue
* error_strings
,
436 const std::string
& locale
) {
437 bool rtl
= LocaleIsRTL();
438 error_strings
->SetString("textdirection", rtl
? "rtl" : "ltr");
440 // Grab the strings and settings that depend on the error type. Init
441 // options with default values.
442 LocalizedErrorMap options
= {
444 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
445 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
,
446 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
,
447 IDS_ERRORPAGES_DETAILS_UNKNOWN
,
451 const std::string error_domain
= error
.domain
.utf8();
452 int error_code
= error
.reason
;
453 const LocalizedErrorMap
* error_map
=
454 LookupErrorMap(error_domain
, error_code
);
456 options
= *error_map
;
458 if (options
.suggestions
!= SUGGEST_NONE
) {
459 error_strings
->SetString(
460 "suggestionsHeading",
461 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HEADING
));
464 const GURL failed_url
= error
.unreachableURL
;
466 // If we got "access denied" but the url was a file URL, then we say it was a
467 // file instead of just using the "not available" default message. Just adding
468 // ERR_ACCESS_DENIED to the map isn't sufficient, since that message may be
469 // generated by some OSs when the operation doesn't involve a file URL.
470 if (error_domain
== net::kErrorDomain
&&
471 error_code
== net::ERR_ACCESS_DENIED
&&
472 failed_url
.scheme() == "file") {
473 options
.title_resource_id
= IDS_ERRORPAGES_TITLE_ACCESS_DENIED
;
474 options
.heading_resource_id
= IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED
;
475 options
.summary_resource_id
= IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED
;
476 options
.details_resource_id
= IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED
;
477 options
.suggestions
= SUGGEST_NONE
;
480 string16
failed_url_string(ASCIIToUTF16(failed_url
.spec()));
481 // URLs are always LTR.
483 base::i18n::WrapStringWithLTRFormatting(&failed_url_string
);
484 error_strings
->SetString("title",
485 l10n_util::GetStringFUTF16(options
.title_resource_id
, failed_url_string
));
486 error_strings
->SetString("heading",
487 l10n_util::GetStringUTF16(options
.heading_resource_id
));
489 DictionaryValue
* summary
= new DictionaryValue
;
490 summary
->SetString("msg",
491 l10n_util::GetStringUTF16(options
.summary_resource_id
));
492 // TODO(tc): We want the unicode url and host here since they're being
494 summary
->SetString("failedUrl", failed_url_string
);
495 summary
->SetString("hostName", failed_url
.host());
496 summary
->SetString("productName",
497 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME
));
498 error_strings
->Set("summary", summary
);
500 string16 details
= l10n_util::GetStringUTF16(options
.details_resource_id
);
501 error_strings
->SetString("details",
502 GetErrorDetailsString(error_domain
, error_code
, details
));
504 // Platform specific instructions for diagnosing network issues on OSX and
506 #if defined(OS_MACOSX) || defined(OS_WIN)
507 if (error_domain
== net::kErrorDomain
&&
508 error_code
== net::ERR_INTERNET_DISCONNECTED
) {
509 int platform_string_id
=
510 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM
;
512 // Different versions of Windows have different instructions.
513 base::win::Version windows_version
= base::win::GetVersion();
514 if (windows_version
< base::win::VERSION_VISTA
) {
515 // XP, XP64, and Server 2003.
517 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM_XP
;
518 } else if (windows_version
== base::win::VERSION_VISTA
) {
521 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM_VISTA
;
523 #endif // defined(OS_WIN)
524 // Lead with the general error description, and suffix with the platform
525 // dependent portion of the summary section.
526 summary
->SetString("msg",
527 l10n_util::GetStringFUTF16(
528 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE
,
529 l10n_util::GetStringUTF16(options
.summary_resource_id
),
530 l10n_util::GetStringUTF16(platform_string_id
)));
532 #endif // defined(OS_MACOSX) || defined(OS_WIN)
534 if (options
.suggestions
& SUGGEST_RELOAD
) {
535 DictionaryValue
* suggest_reload
= new DictionaryValue
;
536 suggest_reload
->SetString("msg",
537 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_RELOAD
));
538 suggest_reload
->SetString("reloadUrl", failed_url_string
);
539 error_strings
->Set("suggestionsReload", suggest_reload
);
542 if (options
.suggestions
& SUGGEST_HOSTNAME
) {
543 // Only show the "Go to hostname" suggestion if the failed_url has a path.
544 if (std::string() == failed_url
.path()) {
545 DictionaryValue
* suggest_home_page
= new DictionaryValue
;
546 suggest_home_page
->SetString("suggestionsHomepageMsg",
547 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HOMEPAGE
));
548 string16
homepage(ASCIIToUTF16(failed_url
.GetWithEmptyPath().spec()));
549 // URLs are always LTR.
551 base::i18n::WrapStringWithLTRFormatting(&homepage
);
552 suggest_home_page
->SetString("homePage", homepage
);
553 // TODO(tc): we actually want the unicode hostname
554 suggest_home_page
->SetString("hostName", failed_url
.host());
555 error_strings
->Set("suggestionsHomepage", suggest_home_page
);
559 if (options
.suggestions
& SUGGEST_CHECK_CONNECTION
) {
560 DictionaryValue
* suggest_check_connection
= new DictionaryValue
;
561 suggest_check_connection
->SetString("msg",
562 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION
));
563 error_strings
->Set("suggestionsCheckConnection", suggest_check_connection
);
566 if (options
.suggestions
& SUGGEST_DNS_CONFIG
) {
567 DictionaryValue
* suggest_dns_config
= new DictionaryValue
;
568 suggest_dns_config
->SetString("msg",
569 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_DNS_CONFIG
));
570 error_strings
->Set("suggestionsDNSConfig", suggest_dns_config
);
572 DictionaryValue
* suggest_network_prediction
= GetStandardMenuItemsText();
573 suggest_network_prediction
->SetString("msg",
574 l10n_util::GetStringUTF16(
575 IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION
));
576 suggest_network_prediction
->SetString(
577 "noNetworkPredictionTitle",
578 l10n_util::GetStringUTF16(
579 IDS_NETWORK_PREDICTION_ENABLED_DESCRIPTION
));
580 error_strings
->Set("suggestionsDisableNetworkPrediction",
581 suggest_network_prediction
);
584 if (options
.suggestions
& SUGGEST_FIREWALL_CONFIG
) {
585 DictionaryValue
* suggest_firewall_config
= new DictionaryValue
;
586 suggest_firewall_config
->SetString("msg",
587 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_FIREWALL_CONFIG
));
588 suggest_firewall_config
->SetString("productName",
589 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME
));
590 error_strings
->Set("suggestionsFirewallConfig", suggest_firewall_config
);
593 if (options
.suggestions
& SUGGEST_PROXY_CONFIG
) {
594 #if defined(OS_CHROMEOS)
595 DictionaryValue
* suggest_proxy_config
= new DictionaryValue();
597 DictionaryValue
* suggest_proxy_config
= GetStandardMenuItemsText();
598 #endif // defined(OS_CHROMEOS)
599 suggest_proxy_config
->SetString("msg",
600 l10n_util::GetStringFUTF16(IDS_ERRORPAGES_SUGGESTION_PROXY_CONFIG
,
601 l10n_util::GetStringUTF16(
602 IDS_ERRORPAGES_SUGGESTION_PROXY_DISABLE_PLATFORM
)));
603 #if defined(OS_CHROMEOS)
604 suggest_proxy_config
->SetString("settingsTitle",
605 l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE
));
606 suggest_proxy_config
->SetString("internetTitle",
607 l10n_util::GetStringUTF16(IDS_OPTIONS_INTERNET_TAB_LABEL
));
608 suggest_proxy_config
->SetString("optionsButton",
609 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OPTIONS
));
610 suggest_proxy_config
->SetString("networkTab",
611 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_INTERNET_TAB_NETWORK
));
612 suggest_proxy_config
->SetString("proxyButton",
613 l10n_util::GetStringUTF16(
614 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CHANGE_PROXY_BUTTON
));
616 suggest_proxy_config
->SetString("proxyTitle",
617 l10n_util::GetStringUTF16(IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON
));
618 #endif // defined(OS_CHROMEOS)
619 error_strings
->Set("suggestionsProxyConfig", suggest_proxy_config
);
622 if (options
.suggestions
& SUGGEST_DISABLE_EXTENSION
) {
623 DictionaryValue
* suggestion
= new DictionaryValue
;
624 suggestion
->SetString("msg",
625 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_DISABLE_EXTENSION
));
626 suggestion
->SetString("reloadUrl", failed_url_string
);
627 error_strings
->Set("suggestionsDisableExtension", suggestion
);
630 if (options
.suggestions
& SUGGEST_LEARNMORE
) {
632 switch (options
.error_code
) {
633 case net::ERR_TOO_MANY_REDIRECTS
:
634 learn_more_url
= GURL(kRedirectLoopLearnMoreUrl
);
636 case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY
:
637 learn_more_url
= GURL(kWeakDHKeyLearnMoreUrl
);
643 if (learn_more_url
.is_valid()) {
644 // Add the language parameter to the URL.
645 std::string query
= learn_more_url
.query() + "&hl=" + locale
;
646 GURL::Replacements repl
;
647 repl
.SetQueryStr(query
);
648 learn_more_url
= learn_more_url
.ReplaceComponents(repl
);
650 DictionaryValue
* suggest_learn_more
= new DictionaryValue
;
651 suggest_learn_more
->SetString("msg",
652 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_LEARNMORE
));
653 suggest_learn_more
->SetString("learnMoreUrl", learn_more_url
.spec());
654 error_strings
->Set("suggestionsLearnMore", suggest_learn_more
);
659 string16
LocalizedError::GetErrorDetails(const WebKit::WebURLError
& error
) {
660 const LocalizedErrorMap
* error_map
=
661 LookupErrorMap(error
.domain
.utf8(), error
.reason
);
663 return l10n_util::GetStringUTF16(error_map
->details_resource_id
);
665 return l10n_util::GetStringUTF16(IDS_ERRORPAGES_DETAILS_UNKNOWN
);
668 bool LocalizedError::HasStrings(const std::string
& error_domain
,
670 return LookupErrorMap(error_domain
, error_code
) != NULL
;
673 void LocalizedError::GetFormRepostStrings(const GURL
& display_url
,
674 DictionaryValue
* error_strings
) {
675 bool rtl
= LocaleIsRTL();
676 error_strings
->SetString("textdirection", rtl
? "rtl" : "ltr");
678 string16
failed_url(ASCIIToUTF16(display_url
.spec()));
679 // URLs are always LTR.
681 base::i18n::WrapStringWithLTRFormatting(&failed_url
);
682 error_strings
->SetString(
683 "title", l10n_util::GetStringFUTF16(IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
685 error_strings
->SetString(
686 "heading", l10n_util::GetStringUTF16(IDS_HTTP_POST_WARNING_TITLE
));
687 DictionaryValue
* summary
= new DictionaryValue
;
689 "msg", l10n_util::GetStringUTF16(IDS_ERRORPAGES_HTTP_POST_WARNING
));
690 error_strings
->Set("summary", summary
);
693 void LocalizedError::GetAppErrorStrings(
694 const WebURLError
& error
,
695 const GURL
& display_url
,
696 const extensions::Extension
* app
,
697 DictionaryValue
* error_strings
) {
700 bool rtl
= LocaleIsRTL();
701 error_strings
->SetString("textdirection", rtl
? "rtl" : "ltr");
703 string16
failed_url(ASCIIToUTF16(display_url
.spec()));
704 // URLs are always LTR.
706 base::i18n::WrapStringWithLTRFormatting(&failed_url
);
707 error_strings
->SetString(
708 "url", l10n_util::GetStringFUTF16(IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
,
709 failed_url
.c_str()));
711 error_strings
->SetString("title", app
->name());
712 error_strings
->SetString("icon",
713 app
->GetIconURL(extension_misc::EXTENSION_ICON_GIGANTOR
,
714 ExtensionIconSet::MATCH_SMALLER
).spec());
715 error_strings
->SetString("name", app
->name());
716 error_strings
->SetString("msg",
717 l10n_util::GetStringUTF16(IDS_ERRORPAGES_APP_WARNING
));
719 #if defined(OS_CHROMEOS)
720 GURL
learn_more_url(kAppWarningLearnMoreUrl
);
721 DictionaryValue
* suggest_learn_more
= new DictionaryValue();
722 suggest_learn_more
->SetString("msg",
723 l10n_util::GetStringUTF16(
724 IDS_ERRORPAGES_SUGGESTION_LEARNMORE
));
725 suggest_learn_more
->SetString("learnMoreUrl", learn_more_url
.spec());
726 error_strings
->Set("suggestionsLearnMore", suggest_learn_more
);
727 #endif // defined(OS_CHROMEOS)