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