OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/common/localized_error.h" | 5 #include "chrome/common/localized_error.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
| 10 #include "base/string_util.h" |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chrome/common/extensions/extension_constants.h" | 14 #include "chrome/common/extensions/extension_constants.h" |
14 #include "chrome/common/extensions/extension_icon_set.h" | 15 #include "chrome/common/extensions/extension_icon_set.h" |
15 #include "chrome/common/extensions/extension_set.h" | 16 #include "chrome/common/extensions/extension_set.h" |
16 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
17 #include "grit/chromium_strings.h" | 18 #include "grit/chromium_strings.h" |
18 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
19 #include "net/base/escape.h" | 20 #include "net/base/escape.h" |
20 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" | 22 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" |
22 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
23 #include "webkit/glue/webkit_glue.h" | 24 #include "webkit/glue/webkit_glue.h" |
24 | 25 |
25 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
26 #include "base/win/windows_version.h" | 27 #include "base/win/windows_version.h" |
27 #endif | 28 #endif |
28 | 29 |
29 using WebKit::WebURLError; | 30 using WebKit::WebURLError; |
30 | 31 |
| 32 // Some error pages have no details. |
| 33 #define IDS_ERRORPAGES_DETAILS_NULL 0 |
| 34 |
31 namespace { | 35 namespace { |
32 | 36 |
33 static const char kRedirectLoopLearnMoreUrl[] = | 37 static const char kRedirectLoopLearnMoreUrl[] = |
34 "https://www.google.com/support/chrome/bin/answer.py?answer=95626"; | 38 "https://www.google.com/support/chrome/bin/answer.py?answer=95626"; |
35 static const char kWeakDHKeyLearnMoreUrl[] = | 39 static const char kWeakDHKeyLearnMoreUrl[] = |
36 "http://sites.google.com/a/chromium.org/dev/" | 40 "http://sites.google.com/a/chromium.org/dev/" |
37 "err_ssl_weak_server_ephemeral_dh_key"; | 41 "err_ssl_weak_server_ephemeral_dh_key"; |
38 #if defined(OS_CHROMEOS) | 42 #if defined(OS_CHROMEOS) |
39 static const char kAppWarningLearnMoreUrl[] = | 43 static const char kAppWarningLearnMoreUrl[] = |
40 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html" | 44 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html" |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 }, | 337 }, |
334 {505, | 338 {505, |
335 IDS_ERRORPAGES_TITLE_LOAD_FAILED, | 339 IDS_ERRORPAGES_TITLE_LOAD_FAILED, |
336 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR, | 340 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR, |
337 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE, | 341 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE, |
338 IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED, | 342 IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED, |
339 SUGGEST_NONE, | 343 SUGGEST_NONE, |
340 }, | 344 }, |
341 }; | 345 }; |
342 | 346 |
343 const char* HttpErrorToString(int status_code) { | |
344 switch (status_code) { | |
345 case 403: | |
346 return "Forbidden"; | |
347 case 410: | |
348 return "Gone"; | |
349 case 500: | |
350 return "Internal Server Error"; | |
351 case 501: | |
352 return "Not Implemented"; | |
353 case 502: | |
354 return "Bad Gateway"; | |
355 case 503: | |
356 return "Service Unavailable"; | |
357 case 504: | |
358 return "Gateway Timeout"; | |
359 case 505: | |
360 return "HTTP Version Not Supported"; | |
361 default: | |
362 return ""; | |
363 } | |
364 } | |
365 | |
366 string16 GetErrorDetailsString(const std::string& error_domain, | |
367 int error_code, | |
368 const string16& details) { | |
369 int error_page_template; | |
370 const char* error_string; | |
371 if (error_domain == net::kErrorDomain) { | |
372 error_page_template = IDS_ERRORPAGES_DETAILS_TEMPLATE; | |
373 error_string = net::ErrorToString(error_code); | |
374 DCHECK(error_code < 0); // Net error codes are negative. | |
375 error_code = -error_code; | |
376 } else if (error_domain == LocalizedError::kHttpErrorDomain) { | |
377 error_page_template = IDS_ERRORPAGES_HTTP_DETAILS_TEMPLATE; | |
378 error_string = HttpErrorToString(error_code); | |
379 } else { | |
380 NOTREACHED(); | |
381 return string16(); | |
382 } | |
383 return l10n_util::GetStringFUTF16( | |
384 error_page_template, | |
385 base::IntToString16(error_code), | |
386 ASCIIToUTF16(error_string), | |
387 details); | |
388 } | |
389 | |
390 const LocalizedErrorMap* FindErrorMapInArray(const LocalizedErrorMap* maps, | 347 const LocalizedErrorMap* FindErrorMapInArray(const LocalizedErrorMap* maps, |
391 size_t num_maps, | 348 size_t num_maps, |
392 int error_code) { | 349 int error_code) { |
393 for (size_t i = 0; i < num_maps; ++i) { | 350 for (size_t i = 0; i < num_maps; ++i) { |
394 if (maps[i].error_code == error_code) | 351 if (maps[i].error_code == error_code) |
395 return &maps[i]; | 352 return &maps[i]; |
396 } | 353 } |
397 return NULL; | 354 return NULL; |
398 } | 355 } |
399 | 356 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 bool rtl = LocaleIsRTL(); | 401 bool rtl = LocaleIsRTL(); |
445 error_strings->SetString("textdirection", rtl ? "rtl" : "ltr"); | 402 error_strings->SetString("textdirection", rtl ? "rtl" : "ltr"); |
446 | 403 |
447 // Grab the strings and settings that depend on the error type. Init | 404 // Grab the strings and settings that depend on the error type. Init |
448 // options with default values. | 405 // options with default values. |
449 LocalizedErrorMap options = { | 406 LocalizedErrorMap options = { |
450 0, | 407 0, |
451 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, | 408 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, |
452 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, | 409 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, |
453 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, | 410 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, |
454 IDS_ERRORPAGES_DETAILS_UNKNOWN, | 411 IDS_ERRORPAGES_DETAILS_NULL, |
455 SUGGEST_NONE, | 412 SUGGEST_NONE, |
456 }; | 413 }; |
457 | 414 |
458 const std::string error_domain = error.domain.utf8(); | 415 const std::string error_domain = error.domain.utf8(); |
459 int error_code = error.reason; | 416 int error_code = error.reason; |
460 const LocalizedErrorMap* error_map = | 417 const LocalizedErrorMap* error_map = |
461 LookupErrorMap(error_domain, error_code); | 418 LookupErrorMap(error_domain, error_code); |
462 if (error_map) | 419 if (error_map) |
463 options = *error_map; | 420 options = *error_map; |
464 | 421 |
465 if (options.suggestions != SUGGEST_NONE) { | |
466 error_strings->SetString( | |
467 "suggestionsHeading", | |
468 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HEADING)); | |
469 } | |
470 | |
471 const GURL failed_url = error.unreachableURL; | 422 const GURL failed_url = error.unreachableURL; |
472 | 423 |
473 // If we got "access denied" but the url was a file URL, then we say it was a | 424 // If we got "access denied" but the url was a file URL, then we say it was a |
474 // file instead of just using the "not available" default message. Just adding | 425 // file instead of just using the "not available" default message. Just adding |
475 // ERR_ACCESS_DENIED to the map isn't sufficient, since that message may be | 426 // ERR_ACCESS_DENIED to the map isn't sufficient, since that message may be |
476 // generated by some OSs when the operation doesn't involve a file URL. | 427 // generated by some OSs when the operation doesn't involve a file URL. |
477 if (error_domain == net::kErrorDomain && | 428 if (error_domain == net::kErrorDomain && |
478 error_code == net::ERR_ACCESS_DENIED && | 429 error_code == net::ERR_ACCESS_DENIED && |
479 failed_url.scheme() == "file") { | 430 failed_url.scheme() == "file") { |
480 options.title_resource_id = IDS_ERRORPAGES_TITLE_ACCESS_DENIED; | 431 options.title_resource_id = IDS_ERRORPAGES_TITLE_ACCESS_DENIED; |
481 options.heading_resource_id = IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED; | 432 options.heading_resource_id = IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED; |
482 options.summary_resource_id = IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED; | 433 options.summary_resource_id = IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED; |
483 options.details_resource_id = IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED; | 434 options.details_resource_id = IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED; |
484 options.suggestions = SUGGEST_NONE; | 435 options.suggestions = SUGGEST_NONE; |
485 } | 436 } |
486 | 437 |
| 438 // If there are any suggestions other than reload, populate the suggestion |
| 439 // heading (reload has a button, rather than a suggestion in the list). |
| 440 if ((options.suggestions & ~SUGGEST_RELOAD) != SUGGEST_NONE) { |
| 441 error_strings->SetString( |
| 442 "suggestionsHeading", |
| 443 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HEADING)); |
| 444 } |
| 445 |
487 string16 failed_url_string(ASCIIToUTF16(failed_url.spec())); | 446 string16 failed_url_string(ASCIIToUTF16(failed_url.spec())); |
488 // URLs are always LTR. | 447 // URLs are always LTR. |
489 if (rtl) | 448 if (rtl) |
490 base::i18n::WrapStringWithLTRFormatting(&failed_url_string); | 449 base::i18n::WrapStringWithLTRFormatting(&failed_url_string); |
491 error_strings->SetString("title", | 450 error_strings->SetString("title", |
492 l10n_util::GetStringFUTF16(options.title_resource_id, failed_url_string)); | 451 l10n_util::GetStringFUTF16(options.title_resource_id, failed_url_string)); |
493 error_strings->SetString("heading", | 452 error_strings->SetString("heading", |
494 l10n_util::GetStringUTF16(options.heading_resource_id)); | 453 l10n_util::GetStringUTF16(options.heading_resource_id)); |
495 | 454 |
496 DictionaryValue* summary = new DictionaryValue; | 455 DictionaryValue* summary = new DictionaryValue; |
497 summary->SetString("msg", | 456 summary->SetString("msg", |
498 l10n_util::GetStringUTF16(options.summary_resource_id)); | 457 l10n_util::GetStringUTF16(options.summary_resource_id)); |
499 // TODO(tc): We want the unicode url and host here since they're being | 458 // TODO(tc): We want the unicode url and host here since they're being |
500 // displayed. | 459 // displayed. |
501 summary->SetString("failedUrl", failed_url_string); | 460 summary->SetString("failedUrl", failed_url_string); |
502 summary->SetString("hostName", failed_url.host()); | 461 summary->SetString("hostName", failed_url.host()); |
503 summary->SetString("productName", | 462 summary->SetString("productName", |
504 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | 463 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
| 464 |
| 465 error_strings->SetString( |
| 466 "more", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_MORE)); |
| 467 error_strings->SetString( |
| 468 "less", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_LESS)); |
505 error_strings->Set("summary", summary); | 469 error_strings->Set("summary", summary); |
506 | 470 |
507 string16 details = l10n_util::GetStringUTF16(options.details_resource_id); | 471 if (options.details_resource_id != IDS_ERRORPAGES_DETAILS_NULL) { |
508 error_strings->SetString("details", | 472 error_strings->SetString( |
509 GetErrorDetailsString(error_domain, error_code, details)); | 473 "errorDetails", l10n_util::GetStringUTF16(options.details_resource_id)); |
| 474 } |
| 475 |
| 476 string16 error_string; |
| 477 if (error_domain == net::kErrorDomain) { |
| 478 // Non-internationalized error string, for debugging Chrome itself. |
| 479 std::string ascii_error_string = net::ErrorToString(error_code); |
| 480 // Remove the leading "net::" from the returned string. |
| 481 RemoveChars(ascii_error_string, "net:", &ascii_error_string); |
| 482 error_string = ASCIIToUTF16(ascii_error_string); |
| 483 } else { |
| 484 DCHECK_EQ(LocalizedError::kHttpErrorDomain, error_domain); |
| 485 error_string = base::IntToString16(error_code); |
| 486 } |
| 487 error_strings->SetString("errorCode", |
| 488 l10n_util::GetStringFUTF16(IDS_ERRORPAGES_ERROR_CODE, error_string)); |
510 | 489 |
511 // Platform specific instructions for diagnosing network issues on OSX and | 490 // Platform specific instructions for diagnosing network issues on OSX and |
512 // Windows. | 491 // Windows. |
513 #if defined(OS_MACOSX) || defined(OS_WIN) | 492 #if defined(OS_MACOSX) || defined(OS_WIN) |
514 if (error_domain == net::kErrorDomain && | 493 if (error_domain == net::kErrorDomain && |
515 error_code == net::ERR_INTERNET_DISCONNECTED) { | 494 error_code == net::ERR_INTERNET_DISCONNECTED) { |
516 int platform_string_id = | 495 int platform_string_id = |
517 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM; | 496 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM; |
518 #if defined(OS_WIN) | 497 #if defined(OS_WIN) |
519 // Different versions of Windows have different instructions. | 498 // Different versions of Windows have different instructions. |
(...skipping 12 matching lines...) Expand all Loading... |
532 // dependent portion of the summary section. | 511 // dependent portion of the summary section. |
533 summary->SetString("msg", | 512 summary->SetString("msg", |
534 l10n_util::GetStringFUTF16( | 513 l10n_util::GetStringFUTF16( |
535 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE, | 514 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE, |
536 l10n_util::GetStringUTF16(options.summary_resource_id), | 515 l10n_util::GetStringUTF16(options.summary_resource_id), |
537 l10n_util::GetStringUTF16(platform_string_id))); | 516 l10n_util::GetStringUTF16(platform_string_id))); |
538 } | 517 } |
539 #endif // defined(OS_MACOSX) || defined(OS_WIN) | 518 #endif // defined(OS_MACOSX) || defined(OS_WIN) |
540 | 519 |
541 if (options.suggestions & SUGGEST_RELOAD) { | 520 if (options.suggestions & SUGGEST_RELOAD) { |
542 DictionaryValue* suggest_reload = new DictionaryValue; | 521 DictionaryValue* reload_button = new DictionaryValue; |
543 suggest_reload->SetString("msg", | 522 reload_button->SetString("msg", |
544 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_RELOAD)); | 523 l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_RELOAD)); |
545 suggest_reload->SetString("reloadUrl", failed_url_string); | 524 reload_button->SetString("reloadUrl", failed_url_string); |
546 error_strings->Set("suggestionsReload", suggest_reload); | 525 error_strings->Set("reload", reload_button); |
547 } | 526 } |
548 | 527 |
549 if (options.suggestions & SUGGEST_HOSTNAME) { | 528 if (options.suggestions & SUGGEST_HOSTNAME) { |
550 // Only show the "Go to hostname" suggestion if the failed_url has a path. | 529 // Only show the "Go to hostname" suggestion if the failed_url has a path. |
551 if (std::string() == failed_url.path()) { | 530 if (std::string() == failed_url.path()) { |
552 DictionaryValue* suggest_home_page = new DictionaryValue; | 531 DictionaryValue* suggest_home_page = new DictionaryValue; |
553 suggest_home_page->SetString("suggestionsHomepageMsg", | 532 suggest_home_page->SetString("suggestionsHomepageMsg", |
554 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HOMEPAGE)); | 533 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HOMEPAGE)); |
555 string16 homepage(ASCIIToUTF16(failed_url.GetWithEmptyPath().spec())); | 534 string16 homepage(ASCIIToUTF16(failed_url.GetWithEmptyPath().spec())); |
556 // URLs are always LTR. | 535 // URLs are always LTR. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 #if defined(OS_CHROMEOS) | 705 #if defined(OS_CHROMEOS) |
727 GURL learn_more_url(kAppWarningLearnMoreUrl); | 706 GURL learn_more_url(kAppWarningLearnMoreUrl); |
728 DictionaryValue* suggest_learn_more = new DictionaryValue(); | 707 DictionaryValue* suggest_learn_more = new DictionaryValue(); |
729 suggest_learn_more->SetString("msg", | 708 suggest_learn_more->SetString("msg", |
730 l10n_util::GetStringUTF16( | 709 l10n_util::GetStringUTF16( |
731 IDS_ERRORPAGES_SUGGESTION_LEARNMORE)); | 710 IDS_ERRORPAGES_SUGGESTION_LEARNMORE)); |
732 suggest_learn_more->SetString("learnMoreUrl", learn_more_url.spec()); | 711 suggest_learn_more->SetString("learnMoreUrl", learn_more_url.spec()); |
733 error_strings->Set("suggestionsLearnMore", suggest_learn_more); | 712 error_strings->Set("suggestionsLearnMore", suggest_learn_more); |
734 #endif // defined(OS_CHROMEOS) | 713 #endif // defined(OS_CHROMEOS) |
735 } | 714 } |
OLD | NEW |