summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd71
-rw-r--r--chrome/renderer/localized_error.cc193
-rw-r--r--chrome/renderer/localized_error.h55
-rw-r--r--chrome/renderer/navigation_state.h7
-rw-r--r--chrome/renderer/render_view.cc76
5 files changed, 324 insertions, 78 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3e594f0..5768c5d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5266,7 +5266,10 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_ERRORPAGES_TITLE_NOT_AVAILABLE" desc="Title of the error page when we can't connect to a site.">
<ph name="SITE">$1<ex>google.xom</ex></ph> is not available
</message>
- <message name="IDS_ERRORPAGES_TITLE_NOT_FOUND" desc="Title of the error page when the server returns a 404.">
+ <message name="IDS_ERRORPAGES_TITLE_ACCESS_DENIED" desc="Title in the error page when a server returns a 403. Also suitable for similar error codes.">
+ Access to <ph name="URL">$1<ex>http://www.google.com/foo/bar</ex></ph> denied.
+ </message>
+ <message name="IDS_ERRORPAGES_TITLE_NOT_FOUND" desc="Title of the error page when the server returns a 404 or 410.">
<ph name="URL">$1<ex>http://www.google.com/foo/bar</ex></ph> is not found
</message>
<message name="IDS_ERRORPAGES_TITLE_LOAD_FAILED" desc="Title of the error page when we can't load a page.">
@@ -5275,7 +5278,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_ERRORPAGES_HEADING_NOT_AVAILABLE" desc="Heading in the error page when we can't connect to a site.">
This webpage is not available.
</message>
- <message name="IDS_ERRORPAGES_HEADING_NOT_FOUND" desc="Heading in the error page when the server returns a 404.">
+ <message name="IDS_ERRORPAGES_HEADING_NOT_FOUND" desc="Heading in the error page when the server returns a 404 or 410.">
This webpage is not found.
</message>
<message name="IDS_ERRORPAGES_HEADING_TOO_MANY_REDIRECTS" desc="Heading in the error page when there are too many URL redirects.">
@@ -5297,6 +5300,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_ERRORPAGES_DETAILS_TEMPLATE" desc="On the bottom of the error page text, there is a box that includes extra information for tech savvy users.">
Error <ph name="ERROR_NUMBER">$1<ex>5</ex></ph> (<ph name="ERROR_NAME">$2<ex>net::ERR_FILE_NOT_FOUND</ex></ph>): <ph name="ERROR_TEXT">$3<ex>The requested file is not found.</ex></ph>
</message>
+ <message name="IDS_ERRORPAGES_HTTP_DETAILS_TEMPLATE" desc="On the bottom of the error page text for http errors, there is a box that includes extra information for tech savvy users.">
+ HTTP Error <ph name="ERROR_NUMBER">$1<ex>500</ex></ph> (<ph name="ERROR_NAME">$2<ex>Internal Server Error</ex></ph>): <ph name="ERROR_TEXT">$3<ex>The server encountered an internal error.</ex></ph>
+ </message>
<message name="IDS_ERRORPAGES_DETAILS_TIMED_OUT" desc="The error message displayed when a page takes too long to load.">
The operation timed out.
@@ -5320,6 +5326,67 @@ Keep your key file in a safe place. You will need it to create new versions of y
Unknown error.
</message>
+ <message name="IDS_ERRORPAGES_HEADING_ACCESS_DENIED" desc="Heading in the error page when a server returns a 403. Also suitable for similar error codes.">
+ Access to the webpage was denied.
+ </message>
+ <message name="IDS_ERRORPAGES_SUMMARY_FORBIDDEN" desc="Summary in the error page when a server returns a 403.">
+ You are not authorized to access the webpage at <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph>. You may need to log in.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_FORBIDDEN" desc="Details in the error page when a server returns a 403.">
+ The server refused to fulfill the request.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_GONE" desc="Summary of the error page when the server returns a 410.">
+ The webpage at <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph> no longer exists.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_GONE" desc="Details in the error page when a server returns a 403.">
+ The requested resource no longer exists, and there is forwarding address. This is expected to be a permanent condition.
+ </message>
+
+ <message name="IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR" desc="Heading in the error page for 5xx errors.">
+ Server error.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_INTERNAL_SERVER_ERROR" desc="Summary in the error page when the server returns a 500.">
+ The website encountered an error while retrieving <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph>.
+ It may be down for maintenance or configured incorrectly.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_INTERNAL_SERVER_ERROR" desc="The error message displayed when the server returns a 500.">
+ As unexpected condition was encountered while the server was attempting to fulfill the request.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE" desc="Summary in the error page when the server returns a 501 or 505.">
+ The website is unable to handle the request for <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph>.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_NOT_IMPLEMENTED" desc="The error message displayed when the server returns a 502.">
+ The server does have the functionality needed to fulfill the request.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED" desc="The error message displayed when the server returns a 505.">
+ The server does not support the HTTP version used in the request.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_BAD_GATEWAY" desc="Summary in the error page when the server returns a 502.">
+ An invalid response was received while attempting to load <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph>.
+ The server may be down for maintenance or configured incorrectly.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_BAD_GATEWAY" desc="The error message displayed when the server returns a 502.">
+ The gateway or proxy server received an invalid response from an upstream server.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_SERVICE_UNAVAILABLE" desc="Summary in the error page when the server returns a 503.">
+ The webpage at <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph> is currently unavailable. It may be overloaded or down for maintenance.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_SERVICE_UNAVAILABLE" desc="The error message displayed when the server returns a 503.">
+ The server is currently unable to handle the request. This code indicates this is a temporary condition, and the server will be up again after a delay.
+ </message>
+
+ <message name="IDS_ERRORPAGES_SUMMARY_GATEWAY_TIMEOUT" desc="Summary in the error page when the server returns a 504.">
+ The server for <ph name="URL">&lt;strong jscontent="failedUrl"&gt;&lt;/strong&gt;</ph> took too long to respond. It may be overloaded.
+ </message>
+ <message name="IDS_ERRORPAGES_DETAILS_GATEWAY_TIMEOUT" desc="The error message displayed when the server returns a 504.">
+ The gateway or proxy server timed out while waiting for a response from an upstream server.
+ </message>
+
<message name="IDS_ERRORPAGES_HEADING_SSL_PROTOCOL_ERROR" desc="Heading in the error page for SSL protocol errors.">
SSL connection error.
</message>
diff --git a/chrome/renderer/localized_error.cc b/chrome/renderer/localized_error.cc
index 2bf9841..394844d 100644
--- a/chrome/renderer/localized_error.cc
+++ b/chrome/renderer/localized_error.cc
@@ -33,16 +33,16 @@ enum NAV_SUGGESTIONS {
SUGGEST_LEARNMORE = 1 << 2,
};
-struct WebErrorNetErrorMap {
- const int error_code;
- const unsigned int title_resource_id;
- const unsigned int heading_resource_id;
- const unsigned int summary_resource_id;
- const unsigned int details_resource_id;
- const int suggestions; // Bitmap of SUGGEST_* values.
+struct LocalizedErrorMap {
+ int error_code;
+ unsigned int title_resource_id;
+ unsigned int heading_resource_id;
+ unsigned int summary_resource_id;
+ unsigned int details_resource_id;
+ int suggestions; // Bitmap of SUGGEST_* values.
};
-WebErrorNetErrorMap net_error_options[] = {
+const LocalizedErrorMap net_error_options[] = {
{net::ERR_TIMED_OUT,
IDS_ERRORPAGES_TITLE_NOT_AVAILABLE,
IDS_ERRORPAGES_HEADING_NOT_AVAILABLE,
@@ -115,6 +115,139 @@ WebErrorNetErrorMap net_error_options[] = {
},
};
+const LocalizedErrorMap http_error_options[] = {
+ {403,
+ IDS_ERRORPAGES_TITLE_ACCESS_DENIED,
+ IDS_ERRORPAGES_HEADING_ACCESS_DENIED,
+ IDS_ERRORPAGES_SUMMARY_FORBIDDEN,
+ IDS_ERRORPAGES_DETAILS_FORBIDDEN,
+ SUGGEST_NONE,
+ },
+ {410,
+ IDS_ERRORPAGES_TITLE_NOT_FOUND,
+ IDS_ERRORPAGES_HEADING_NOT_FOUND,
+ IDS_ERRORPAGES_SUMMARY_GONE,
+ IDS_ERRORPAGES_DETAILS_GONE,
+ SUGGEST_NONE,
+ },
+
+ {500,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_INTERNAL_SERVER_ERROR,
+ IDS_ERRORPAGES_DETAILS_INTERNAL_SERVER_ERROR,
+ SUGGEST_RELOAD,
+ },
+ {501,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE,
+ IDS_ERRORPAGES_DETAILS_NOT_IMPLEMENTED,
+ SUGGEST_NONE,
+ },
+ {502,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_BAD_GATEWAY,
+ IDS_ERRORPAGES_DETAILS_BAD_GATEWAY,
+ SUGGEST_RELOAD,
+ },
+ {503,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_SERVICE_UNAVAILABLE,
+ IDS_ERRORPAGES_DETAILS_SERVICE_UNAVAILABLE,
+ SUGGEST_RELOAD,
+ },
+ {504,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_GATEWAY_TIMEOUT,
+ IDS_ERRORPAGES_DETAILS_GATEWAY_TIMEOUT,
+ SUGGEST_RELOAD,
+ },
+ {505,
+ IDS_ERRORPAGES_TITLE_LOAD_FAILED,
+ IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR,
+ IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE,
+ IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED,
+ SUGGEST_NONE,
+ },
+};
+
+const char* HttpErrorToString(int status_code) {
+ switch (status_code) {
+ case 403:
+ return "Forbidden";
+ case 410:
+ return "Gone";
+ case 500:
+ return "Internal Server Error";
+ case 501:
+ return "Not Implemented";
+ case 502:
+ return "Bad Gateway";
+ case 503:
+ return "Service Unavailable";
+ case 504:
+ return "Gateway Timeout";
+ case 505:
+ return "HTTP Version Not Supported";
+ default:
+ return "";
+ }
+}
+
+string16 GetErrorDetailsString(const std::string& error_domain,
+ int error_code,
+ const string16& details) {
+ int error_page_template;
+ const char* error_string;
+ if (error_domain == net::kErrorDomain) {
+ error_page_template = IDS_ERRORPAGES_DETAILS_TEMPLATE;
+ DCHECK(error_code < 0); // Net error codes are negative.
+ error_code = -error_code;
+ error_string = net::ErrorToString(error_code);
+ } else if (error_domain == LocalizedError::kHttpErrorDomain) {
+ error_page_template = IDS_ERRORPAGES_HTTP_DETAILS_TEMPLATE;
+ error_string = HttpErrorToString(error_code);
+ } else {
+ NOTREACHED();
+ return string16();
+ }
+ return l10n_util::GetStringFUTF16(
+ error_page_template,
+ base::IntToString16(error_code),
+ ASCIIToUTF16(error_string),
+ details);
+}
+
+const LocalizedErrorMap* FindErrorMapInArray(const LocalizedErrorMap* maps,
+ size_t num_maps,
+ int error_code) {
+ for (size_t i = 0; i < num_maps; ++i) {
+ if (maps[i].error_code == error_code)
+ return &maps[i];
+ }
+ return NULL;
+}
+
+const LocalizedErrorMap* LookupErrorMap(const std::string& error_domain,
+ int error_code) {
+ if (error_domain == net::kErrorDomain) {
+ return FindErrorMapInArray(net_error_options,
+ arraysize(net_error_options),
+ error_code);
+ } else if (error_domain == LocalizedError::kHttpErrorDomain) {
+ return FindErrorMapInArray(http_error_options,
+ arraysize(http_error_options),
+ error_code);
+ } else {
+ NOTREACHED();
+ return NULL;
+ }
+}
+
bool LocaleIsRTL() {
#if defined(TOOLKIT_GTK)
// base::i18n::IsRTL() uses the GTK text direction, which doesn't work within
@@ -127,8 +260,10 @@ bool LocaleIsRTL() {
} // namespace
-void GetLocalizedErrorValues(const WebURLError& error,
- DictionaryValue* error_strings) {
+const char LocalizedError::kHttpErrorDomain[] = "http";
+
+void LocalizedError::GetStrings(const WebKit::WebURLError& error,
+ DictionaryValue* error_strings) {
bool rtl = LocaleIsRTL();
error_strings->SetString("textdirection", rtl ? "rtl" : "ltr");
@@ -140,7 +275,7 @@ void GetLocalizedErrorValues(const WebURLError& error,
// Grab the strings and settings that depend on the error type. Init
// options with default values.
- WebErrorNetErrorMap options = {
+ LocalizedErrorMap options = {
0,
IDS_ERRORPAGES_TITLE_NOT_AVAILABLE,
IDS_ERRORPAGES_HEADING_NOT_AVAILABLE,
@@ -148,13 +283,13 @@ void GetLocalizedErrorValues(const WebURLError& error,
IDS_ERRORPAGES_DETAILS_UNKNOWN,
SUGGEST_NONE,
};
+
+ const std::string error_domain = error.domain.utf8();
int error_code = error.reason;
- for (size_t i = 0; i < arraysize(net_error_options); ++i) {
- if (net_error_options[i].error_code == error_code) {
- memcpy(&options, &net_error_options[i], sizeof(WebErrorNetErrorMap));
- break;
- }
- }
+ const LocalizedErrorMap* error_map =
+ LookupErrorMap(error_domain, error_code);
+ if (error_map)
+ options = *error_map;
string16 suggestions_heading;
if (options.suggestions != SUGGEST_NONE) {
@@ -179,14 +314,9 @@ void GetLocalizedErrorValues(const WebURLError& error,
summary->SetString("failedUrl", failed_url);
error_strings->Set("summary", summary);
- // Error codes are expected to be negative
- DCHECK(error_code < 0);
string16 details = l10n_util::GetStringUTF16(options.details_resource_id);
error_strings->SetString("details",
- l10n_util::GetStringFUTF16(IDS_ERRORPAGES_DETAILS_TEMPLATE,
- base::IntToString16(-error_code),
- ASCIIToUTF16(net::ErrorToString(error_code)),
- details));
+ GetErrorDetailsString(error_domain, error_code, details));
if (options.suggestions & SUGGEST_RELOAD) {
DictionaryValue* suggest_reload = new DictionaryValue;
@@ -241,8 +371,13 @@ void GetLocalizedErrorValues(const WebURLError& error,
}
}
-void GetFormRepostErrorValues(const GURL& display_url,
- DictionaryValue* error_strings) {
+bool LocalizedError::HasStrings(const std::string& error_domain,
+ int error_code) {
+ return LookupErrorMap(error_domain, error_code) != NULL;
+}
+
+void LocalizedError::GetFormRepostStrings(const GURL& display_url,
+ DictionaryValue* error_strings) {
bool rtl = LocaleIsRTL();
error_strings->SetString("textdirection", rtl ? "rtl" : "ltr");
@@ -262,10 +397,10 @@ void GetFormRepostErrorValues(const GURL& display_url,
error_strings->Set("summary", summary);
}
-void GetAppErrorValues(const WebURLError& error,
- const GURL& display_url,
- const ExtensionRendererInfo* app,
- DictionaryValue* error_strings) {
+void LocalizedError::GetAppErrorStrings(const WebURLError& error,
+ const GURL& display_url,
+ const ExtensionRendererInfo* app,
+ DictionaryValue* error_strings) {
DCHECK(app);
bool rtl = LocaleIsRTL();
diff --git a/chrome/renderer/localized_error.h b/chrome/renderer/localized_error.h
index 4fa5304..1ea1c36 100644
--- a/chrome/renderer/localized_error.h
+++ b/chrome/renderer/localized_error.h
@@ -6,6 +6,10 @@
#define CHROME_RENDERER_LOCALIZED_ERROR_H_
#pragma once
+#include <string>
+
+#include "base/basictypes.h"
+
class DictionaryValue;
class ExtensionRendererInfo;
class GURL;
@@ -14,25 +18,36 @@ namespace WebKit {
struct WebURLError;
}
-// Fills |error_strings| with values to be used to build an error page used
-// on HTTP errors, like 404 or connection reset.
-void GetLocalizedErrorValues(const WebKit::WebURLError& error,
- DictionaryValue* error_strings);
-
-// Fills |error_strings| with values to be used to build an error page which
-// warns against reposting form data. This is special cased because the form
-// repost "error page" has no real error associated with it, and doesn't have
-// enough strings localized to meaningfully fill the net error template.
-void GetFormRepostErrorValues(const GURL& display_url,
- DictionaryValue* error_strings);
-
-// Fills |error_strings| with values to be used to build an error page used
-// on HTTP errors, like 404 or connection reset, but using information from
-// the associated |app| in order to make the error page look like it's more
-// part of the app.
-void GetAppErrorValues(const WebKit::WebURLError& error,
- const GURL& display_url,
- const ExtensionRendererInfo* app,
- DictionaryValue* error_strings);
+class LocalizedError {
+ public:
+ // Fills |error_strings| with values to be used to build an error page used
+ // on HTTP errors, like 404 or connection reset.
+ static void GetStrings(const WebKit::WebURLError& error,
+ DictionaryValue* strings);
+
+ // Returns true if an error page exists for the specified parameters.
+ static bool HasStrings(const std::string& error_domain, int error_code);
+
+ // Fills |error_strings| with values to be used to build an error page which
+ // warns against reposting form data. This is special cased because the form
+ // repost "error page" has no real error associated with it, and doesn't have
+ // enough strings localized to meaningfully fill the net error template.
+ static void GetFormRepostStrings(const GURL& display_url,
+ DictionaryValue* error_strings);
+
+ // Fills |error_strings| with values to be used to build an error page used
+ // on HTTP errors, like 404 or connection reset, but using information from
+ // the associated |app| in order to make the error page look like it's more
+ // part of the app.
+ static void GetAppErrorStrings(const WebKit::WebURLError& error,
+ const GURL& display_url,
+ const ExtensionRendererInfo* app,
+ DictionaryValue* error_strings);
+
+ static const char kHttpErrorDomain[];
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LocalizedError);
+};
#endif // CHROME_RENDERER_LOCALIZED_ERROR_H_
diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h
index 6923def..d9cee3e 100644
--- a/chrome/renderer/navigation_state.h
+++ b/chrome/renderer/navigation_state.h
@@ -211,6 +211,11 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
postponed_data_.append(data, data_len);
}
+ int http_status_code() const { return http_status_code_; }
+ void set_http_status_code(int http_status_code) {
+ http_status_code_ = http_status_code;
+ }
+
// Sets the cache policy. The cache policy is only used if explicitly set and
// by default is not set. You can mark a NavigationState as not having a cache
// state by way of clear_cache_policy_override.
@@ -286,6 +291,7 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
cache_policy_override_set_(false),
cache_policy_override_(WebKit::WebURLRequest::UseProtocolCachePolicy),
user_script_idle_scheduler_(NULL),
+ http_status_code_(0),
was_fetched_via_spdy_(false),
was_npn_negotiated_(false),
was_alternate_protocol_available_(false),
@@ -323,6 +329,7 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
WebKit::WebURLRequest::CachePolicy cache_policy_override_;
scoped_ptr<UserScriptIdleScheduler> user_script_idle_scheduler_;
+ int http_status_code_;
bool was_fetched_via_spdy_;
bool was_npn_negotiated_;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 721bfb6..c2810c2 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1542,18 +1542,20 @@ void RenderView::LoadNavigationErrorPage(WebFrame* frame,
if (failed_url.is_valid())
extension = ExtensionRendererInfo::GetByURL(failed_url);
if (extension) {
- GetAppErrorValues(error, failed_url, extension, &error_strings);
+ LocalizedError::GetAppErrorStrings(error, failed_url, extension,
+ &error_strings);
// TODO(erikkay): Should we use a different template for different
// error messages?
resource_id = IDR_ERROR_APP_HTML;
} else {
- if (error.reason == net::ERR_CACHE_MISS &&
+ if (error.domain == WebString::fromUTF8(net::kErrorDomain) &&
+ error.reason == net::ERR_CACHE_MISS &&
EqualsASCII(failed_request.httpMethod(), "POST")) {
- GetFormRepostErrorValues(failed_url, &error_strings);
+ LocalizedError::GetFormRepostStrings(failed_url, &error_strings);
resource_id = IDR_ERROR_NO_DETAILS_HTML;
} else {
- GetLocalizedErrorValues(error, &error_strings);
+ LocalizedError::GetStrings(error, &error_strings);
resource_id = IDR_NET_ERROR_HTML;
}
}
@@ -2957,8 +2959,7 @@ void RenderView::didFailProvisionalLoad(WebFrame* frame,
return;
// Fallback to a local error page.
- LoadNavigationErrorPage(frame, failed_request, error, std::string(),
- replace);
+ LoadNavigationErrorPage(frame, failed_request, error, std::string(), replace);
}
void RenderView::didReceiveDocumentData(
@@ -2972,10 +2973,12 @@ void RenderView::didReceiveDocumentData(
// We're going to call commitDocumentData ourselves...
prevent_default = true;
- // Continue buffering the response data for the original 404 page. If it
- // grows too large, then we'll just let it through.
+ // Continue buffering the response data for the original error page. If it
+ // grows too large, then we'll just let it through. For any error other than
+ // a 404, "too large" means any data at all.
navigation_state->append_postponed_data(data, data_len);
- if (navigation_state->postponed_data().size() >= 512) {
+ if (navigation_state->postponed_data().size() >= 512 ||
+ navigation_state->http_status_code() != 404) {
navigation_state->set_postpone_loading_data(false);
frame->commitDocumentData(navigation_state->postponed_data().data(),
navigation_state->postponed_data().size());
@@ -3245,13 +3248,14 @@ void RenderView::didReceiveResponse(
return;
// If we are in view source mode, then just let the user see the source of
- // the server's 404 error page.
+ // the server's error page.
if (frame->isViewSourceModeEnabled())
return;
NavigationState* navigation_state =
NavigationState::FromDataSource(frame->provisionalDataSource());
CHECK(navigation_state);
+ int http_status_code = response.httpStatusCode();
// Record page load flags.
navigation_state->set_was_fetched_via_spdy(response.wasFetchedViaSPDY());
@@ -3259,14 +3263,20 @@ void RenderView::didReceiveResponse(
navigation_state->set_was_alternate_protocol_available(
response.wasAlternateProtocolAvailable());
navigation_state->set_was_fetched_via_proxy(response.wasFetchedViaProxy());
+ navigation_state->set_http_status_code(http_status_code);
// Consider loading an alternate error page for 404 responses.
- if (response.httpStatusCode() != 404)
- return;
-
- // Can we even load an alternate error page for this URL?
- if (!GetAlternateErrorPageURL(response.url(), HTTP_404).is_valid())
+ if (http_status_code == 404) {
+ // Can we even load an alternate error page for this URL?
+ if (!GetAlternateErrorPageURL(response.url(), HTTP_404).is_valid())
+ return;
+ } else if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain,
+ http_status_code)) {
+ // If no corresponding error strings for a particular status code, just
+ // render any received data, regardless of whether or not the status code
+ // indicates an error.
return;
+ }
navigation_state->set_postpone_loading_data(true);
navigation_state->clear_postponed_data();
@@ -3279,21 +3289,33 @@ void RenderView::didFinishResourceLoad(
if (!navigation_state->postpone_loading_data())
return;
- // The server returned a 404 and the content was < 512 bytes (which we
+ // The server returned an error and the content was < 512 bytes (which we
// suppressed). Go ahead and fetch the alternate page content.
+ int http_status_code = navigation_state->http_status_code();
+ if (http_status_code == 404) {
+ // On 404s, try a remote search page as a fallback.
+ const GURL& frame_url = frame->url();
- const GURL& frame_url = frame->url();
+ const GURL& error_page_url = GetAlternateErrorPageURL(frame_url, HTTP_404);
+ DCHECK(error_page_url.is_valid());
- const GURL& error_page_url = GetAlternateErrorPageURL(frame_url, HTTP_404);
- DCHECK(error_page_url.is_valid());
+ WebURLError original_error;
+ original_error.unreachableURL = frame_url;
- WebURLError original_error;
- original_error.unreachableURL = frame_url;
+ navigation_state->set_alt_error_page_fetcher(
+ new AltErrorPageResourceFetcher(
+ error_page_url, frame, original_error,
+ NewCallback(this, &RenderView::AltErrorPageFinished)));
+ } else {
+ // On other errors, use an internal error page.
+ WebURLError error;
+ error.unreachableURL = frame->url();
+ error.domain = WebString::fromUTF8(LocalizedError::kHttpErrorDomain);
+ error.reason = http_status_code;
- navigation_state->set_alt_error_page_fetcher(
- new AltErrorPageResourceFetcher(
- error_page_url, frame, original_error,
- NewCallback(this, &RenderView::AltErrorPageFinished)));
+ LoadNavigationErrorPage(frame, frame->dataSource()->request(), error,
+ std::string(), true);
+ }
}
void RenderView::didFailResourceLoad(
@@ -4587,8 +4609,8 @@ void RenderView::AltErrorPageFinished(WebFrame* frame,
NavigationState::FromDataSource(frame->dataSource());
html_to_load = &navigation_state->postponed_data();
}
- LoadNavigationErrorPage(
- frame, WebURLRequest(), original_error, *html_to_load, true);
+ LoadNavigationErrorPage(frame, WebURLRequest(), original_error, *html_to_load,
+ true);
}
void RenderView::OnMoveOrResizeStarted() {