Chromium Code Reviews| 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, popuplate the suggestion | |
|
eroman
2013/02/27 02:26:16
typo: populate
mmenke
2013/02/27 02:43:01
Done.
| |
| 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 |