Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/renderer/net/net_error_helper.h" | 5 #include "chrome/renderer/net/net_error_helper.h" |
| 6 | 6 |
| 7 #include <string> | |
|
mmenke
2013/04/01 17:44:12
This should be in the header
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 8 | |
| 9 #include "base/json/json_writer.h" | |
| 10 #include "base/stringprintf.h" | |
|
mmenke
2013/04/01 17:44:12
This doesn't seem to be used.
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 11 #include "base/utf_string_conversions.h" | |
| 7 #include "base/values.h" | 12 #include "base/values.h" |
| 8 #include "chrome/common/localized_error.h" | 13 #include "chrome/common/localized_error.h" |
| 9 #include "chrome/common/render_messages.h" | 14 #include "chrome/common/render_messages.h" |
| 10 #include "chrome/common/net/net_error_info.h" | 15 #include "chrome/common/net/net_error_info.h" |
| 16 #include "chrome/common/net/net_error_tracker.h" | |
| 11 #include "content/public/common/content_client.h" | 17 #include "content/public/common/content_client.h" |
| 12 #include "content/public/common/url_constants.h" | 18 #include "content/public/common/url_constants.h" |
| 13 #include "content/public/renderer/content_renderer_client.h" | 19 #include "content/public/renderer/content_renderer_client.h" |
| 14 #include "content/public/renderer/render_thread.h" | 20 #include "content/public/renderer/render_thread.h" |
| 15 #include "content/public/renderer/render_view.h" | 21 #include "content/public/renderer/render_view.h" |
| 16 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
| 23 #include "grit/chromium_strings.h" | |
| 24 #include "grit/generated_resources.h" | |
|
mmenke
2013/04/01 17:44:12
Don't think these are used.
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 17 #include "ipc/ipc_message.h" | 25 #include "ipc/ipc_message.h" |
| 18 #include "ipc/ipc_message_macros.h" | 26 #include "ipc/ipc_message_macros.h" |
| 19 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
| 20 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | 28 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" |
| 21 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" | 29 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" |
| 22 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h" | 30 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 33 #include "ui/base/l10n/l10n_util.h" | |
|
mmenke
2013/04/01 17:44:12
Not used
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 25 | 34 |
| 26 using base::DictionaryValue; | 35 using base::DictionaryValue; |
| 36 using base::JSONWriter; | |
| 27 using chrome_common_net::DnsProbeResult; | 37 using chrome_common_net::DnsProbeResult; |
| 38 using chrome_common_net::DnsProbeStatus; | |
| 28 using content::GetContentClient; | 39 using content::GetContentClient; |
| 29 using content::RenderThread; | 40 using content::RenderThread; |
| 30 using content::RenderView; | 41 using content::RenderView; |
| 31 using content::RenderViewObserver; | 42 using content::RenderViewObserver; |
| 32 using content::kUnreachableWebDataURL; | 43 using content::kUnreachableWebDataURL; |
| 33 | 44 |
| 34 namespace { | 45 namespace { |
| 35 | 46 |
| 36 GURL GetProvisionallyLoadingURLFromWebFrame(WebKit::WebFrame* frame) { | 47 GURL GetProvisionallyLoadingURLFromWebFrame(WebKit::WebFrame* frame) { |
| 37 return frame->provisionalDataSource()->request().url(); | 48 return frame->provisionalDataSource()->request().url(); |
| 38 } | 49 } |
| 39 | 50 |
| 40 bool IsErrorPage(const GURL& url) { | 51 bool IsErrorPage(const GURL& url) { |
| 41 return (url.spec() == kUnreachableWebDataURL); | 52 return (url.spec() == kUnreachableWebDataURL); |
| 42 } | 53 } |
| 43 | 54 |
| 44 // Returns whether |net_error| is a DNS-related error (and therefore whether | 55 bool IsDnsError(const WebKit::WebURLError& error) { |
| 45 // the tab helper should start a DNS probe after receiving it.) | 56 return std::string(error.domain.utf8()) == net::kErrorDomain && |
| 46 bool IsDnsError(int net_error) { | 57 (error.reason == net::ERR_NAME_NOT_RESOLVED || |
| 47 return net_error == net::ERR_NAME_NOT_RESOLVED || | 58 error.reason == net::ERR_NAME_RESOLUTION_FAILED); |
| 48 net_error == net::ERR_NAME_RESOLUTION_FAILED; | |
| 49 } | 59 } |
| 50 | 60 |
| 51 NetErrorTracker::FrameType GetFrameType(WebKit::WebFrame* frame) { | 61 NetErrorTracker::FrameType GetFrameType(WebKit::WebFrame* frame) { |
| 52 return frame->parent() ? NetErrorTracker::FRAME_SUB | 62 return frame->parent() ? NetErrorTracker::FRAME_SUB |
| 53 : NetErrorTracker::FRAME_MAIN; | 63 : NetErrorTracker::FRAME_MAIN; |
| 54 } | 64 } |
| 55 | 65 |
| 56 NetErrorTracker::PageType GetPageType(WebKit::WebFrame* frame) { | 66 NetErrorTracker::PageType GetPageType(WebKit::WebFrame* frame) { |
| 57 bool error_page = IsErrorPage(GetProvisionallyLoadingURLFromWebFrame(frame)); | 67 bool error_page = IsErrorPage(GetProvisionallyLoadingURLFromWebFrame(frame)); |
| 58 return error_page ? NetErrorTracker::PAGE_ERROR | 68 return error_page ? NetErrorTracker::PAGE_ERROR |
| 59 : NetErrorTracker::PAGE_NORMAL; | 69 : NetErrorTracker::PAGE_NORMAL; |
| 60 } | 70 } |
| 61 | 71 |
| 62 NetErrorTracker::ErrorType GetErrorType(const WebKit::WebURLError& error) { | 72 NetErrorTracker::ErrorType GetErrorType(const WebKit::WebURLError& error) { |
| 63 return IsDnsError(error.reason) ? NetErrorTracker::ERROR_DNS | 73 return IsDnsError(error) ? NetErrorTracker::ERROR_DNS |
| 64 : NetErrorTracker::ERROR_OTHER; | 74 : NetErrorTracker::ERROR_OTHER; |
| 65 } | |
| 66 | |
| 67 // Converts a DNS probe result into a net error. Returns OK if the error page | |
| 68 // should not be changed from the original DNS error. | |
| 69 int DnsProbeResultToNetError(DnsProbeResult result) { | |
| 70 switch (result) { | |
| 71 case chrome_common_net::DNS_PROBE_UNKNOWN: | |
| 72 return net::OK; | |
| 73 case chrome_common_net::DNS_PROBE_NO_INTERNET: | |
| 74 // TODO(ttuttle): This is not the same error as when NCN returns this; | |
| 75 // ideally we should have two separate error codes for "no network" and | |
| 76 // "network with no internet". | |
| 77 return net::ERR_INTERNET_DISCONNECTED; | |
| 78 case chrome_common_net::DNS_PROBE_BAD_CONFIG: | |
| 79 // This is unspecific enough that we should still show the full DNS error | |
| 80 // page. | |
| 81 return net::OK; | |
| 82 case chrome_common_net::DNS_PROBE_NXDOMAIN: | |
| 83 return net::ERR_NAME_NOT_RESOLVED; | |
| 84 default: | |
| 85 NOTREACHED(); | |
| 86 return net::OK; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 WebKit::WebURLError NetErrorToWebURLError(int net_error) { | |
| 91 WebKit::WebURLError error; | |
| 92 error.domain = WebKit::WebString::fromUTF8(net::kErrorDomain); | |
| 93 error.reason = net_error; | |
| 94 return error; | |
| 95 } | 75 } |
| 96 | 76 |
| 97 } // namespace | 77 } // namespace |
| 98 | 78 |
| 99 NetErrorHelper::NetErrorHelper(RenderView* render_view) | 79 NetErrorHelper::NetErrorHelper(RenderView* render_view) |
| 100 : RenderViewObserver(render_view), | 80 : RenderViewObserver(render_view), |
| 101 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(base::Bind( | 81 state_(IDLE), |
| 102 &NetErrorHelper::TrackerCallback, | 82 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_( |
|
mmenke
2013/04/01 17:44:12
It looks like we're now completely ignoring the re
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Went back to using it.
| |
| 103 base::Unretained(this)))), | 83 base::Bind(&NetErrorHelper::TrackerCallback, |
| 104 dns_error_page_state_(NetErrorTracker::DNS_ERROR_PAGE_NONE), | 84 base::Unretained(this)))) { |
| 105 updated_error_page_(false) { | |
| 106 } | 85 } |
| 107 | 86 |
| 108 NetErrorHelper::~NetErrorHelper() { | 87 NetErrorHelper::~NetErrorHelper() { |
| 109 } | 88 } |
| 110 | 89 |
| 90 // Returns whether |net_error| is a DNS-related error (and therefore whether | |
| 91 // the tab helper should start a DNS probe after receiving it.) | |
|
mmenke
2013/04/01 17:44:12
Function level documentation should be with the fu
Deprecated (see juliatuttle)
2013/04/09 20:35:49
It belonged with IsDnsError, which is declared abo
| |
| 111 void NetErrorHelper::DidStartProvisionalLoad(WebKit::WebFrame* frame) { | 92 void NetErrorHelper::DidStartProvisionalLoad(WebKit::WebFrame* frame) { |
| 112 tracker_.OnStartProvisionalLoad(GetFrameType(frame), GetPageType(frame)); | 93 tracker_.OnStartProvisionalLoad(GetFrameType(frame), GetPageType(frame)); |
|
mmenke
2013/04/01 17:44:12
state_ should be reset if this isn't an error page
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 113 } | 94 } |
| 114 | 95 |
| 115 void NetErrorHelper::DidFailProvisionalLoad(WebKit::WebFrame* frame, | 96 void NetErrorHelper::DidFailProvisionalLoad(WebKit::WebFrame* frame, |
| 116 const WebKit::WebURLError& error) { | 97 const WebKit::WebURLError& error) { |
| 117 tracker_.OnFailProvisionalLoad(GetFrameType(frame), GetErrorType(error)); | 98 tracker_.OnFailProvisionalLoad(GetFrameType(frame), GetErrorType(error)); |
| 99 | |
| 100 if (frame->parent() || !IsDnsError(error)) | |
| 101 return; | |
| 102 | |
| 103 if (state_ != IDLE) { | |
| 104 LOG(WARNING) << "DNS error in unexpected state " << state_; | |
|
mmenke
2013/04/01 17:44:12
DVLOG?
Also...Why isn't this expected? Reload an
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 105 return; | |
| 106 } | |
| 107 | |
| 108 DVLOG(1) << "Failed DNS page load; now awaiting error page load."; | |
| 109 | |
| 110 state_ = AWAITING_LOAD; | |
| 111 last_error_ = error; | |
| 118 } | 112 } |
| 119 | 113 |
| 120 void NetErrorHelper::DidCommitProvisionalLoad(WebKit::WebFrame* frame, | 114 void NetErrorHelper::DidCommitProvisionalLoad(WebKit::WebFrame* frame, |
| 121 bool is_new_navigation) { | 115 bool is_new_navigation) { |
| 122 tracker_.OnCommitProvisionalLoad(GetFrameType(frame)); | 116 tracker_.OnCommitProvisionalLoad(GetFrameType(frame)); |
| 123 } | 117 } |
| 124 | 118 |
| 125 void NetErrorHelper::DidFinishLoad(WebKit::WebFrame* frame) { | 119 void NetErrorHelper::DidFinishLoad(WebKit::WebFrame* frame) { |
| 126 tracker_.OnFinishLoad(GetFrameType(frame)); | 120 tracker_.OnFinishLoad(GetFrameType(frame)); |
| 121 | |
| 122 if (frame->parent()) | |
| 123 return; | |
| 124 | |
| 125 if (state_ == IDLE) | |
| 126 return; | |
| 127 | |
| 128 if (state_ != AWAITING_LOAD) { | |
| 129 LOG(WARNING) << "Finish load in unexpected state " << state_; | |
|
mmenke
2013/04/01 17:44:12
DVLOG?
Deprecated (see juliatuttle)
2013/04/09 20:35:49
Done.
| |
| 130 return; | |
| 131 } | |
| 132 | |
| 133 DVLOG(1) << "Finished error page load; now awaiting IPC."; | |
| 134 | |
| 135 state_ = AWAITING_INITIAL_IPC; | |
| 136 } | |
| 137 | |
| 138 void NetErrorHelper::TrackerCallback( | |
| 139 NetErrorTracker::DnsErrorPageState state) { | |
| 127 } | 140 } |
| 128 | 141 |
| 129 bool NetErrorHelper::OnMessageReceived(const IPC::Message& message) { | 142 bool NetErrorHelper::OnMessageReceived(const IPC::Message& message) { |
| 130 bool handled = true; | 143 bool handled = true; |
| 131 | 144 |
| 132 IPC_BEGIN_MESSAGE_MAP(NetErrorHelper, message) | 145 IPC_BEGIN_MESSAGE_MAP(NetErrorHelper, message) |
| 133 IPC_MESSAGE_HANDLER(ChromeViewMsg_NetErrorInfo, OnNetErrorInfo) | 146 IPC_MESSAGE_HANDLER(ChromeViewMsg_NetErrorInfo, OnNetErrorInfo) |
| 134 IPC_MESSAGE_UNHANDLED(handled = false) | 147 IPC_MESSAGE_UNHANDLED(handled = false) |
| 135 IPC_END_MESSAGE_MAP() | 148 IPC_END_MESSAGE_MAP() |
| 136 | 149 |
| 137 return handled; | 150 return handled; |
| 138 } | 151 } |
| 139 | 152 |
| 140 void NetErrorHelper::OnNetErrorInfo(int dns_probe_result) { | 153 bool NetErrorHelper::GetErrorStringsForDnsProbe( |
| 141 DVLOG(1) << "Received DNS probe result " << dns_probe_result; | 154 const WebKit::WebURLError& error, |
| 155 base::DictionaryValue* strings, | |
| 156 const std::string& locale) { | |
| 157 if (!IsDnsError(error)) | |
| 158 return false; | |
| 142 | 159 |
| 143 if (dns_probe_result < 0 || | 160 // Get the strings for a fake "DNS probe possible" error |
| 144 dns_probe_result >= chrome_common_net::DNS_PROBE_MAX) { | 161 WebKit::WebURLError fake_error; |
| 145 DLOG(WARNING) << "Ignoring DNS probe result: invalid result " | 162 fake_error.domain = WebKit::WebString::fromUTF8( |
| 146 << dns_probe_result; | 163 chrome_common_net::kDnsProbeErrorDomain); |
| 164 fake_error.reason = chrome_common_net::DNS_PROBE_ERR_POSSIBLE; | |
| 165 fake_error.unreachableURL = error.unreachableURL; | |
| 166 LocalizedError::GetStrings(fake_error, strings, locale); | |
| 167 return true; | |
| 168 } | |
| 169 | |
| 170 void NetErrorHelper::OnNetErrorInfo(int status_num, int result_num) { | |
| 171 DVLOG(1) << "Got IPC: status=" << status_num << " result=" << result_num; | |
| 172 | |
| 173 if (status_num < 0 || | |
| 174 status_num >= chrome_common_net::DNS_PROBE_STATUS_MAX) { | |
| 175 DLOG(WARNING) << "Ignoring NetErrorInfo: invalid status " << status_num; | |
| 147 NOTREACHED(); | 176 NOTREACHED(); |
| 148 return; | 177 return; |
| 149 } | 178 } |
| 150 | 179 |
| 151 if (dns_error_page_state_ != NetErrorTracker::DNS_ERROR_PAGE_LOADED) { | 180 if (result_num < 0 || |
| 152 DVLOG(1) << "Ignoring DNS probe result: not on DNS error page."; | 181 result_num >= chrome_common_net::DNS_PROBE_MAX) { |
| 182 DLOG(WARNING) << "Ignoring NetErrorInfo: invalid result " << result_num; | |
| 183 NOTREACHED(); | |
| 153 return; | 184 return; |
| 154 } | 185 } |
| 155 | 186 |
| 156 if (updated_error_page_) { | 187 DnsProbeStatus status = static_cast<DnsProbeStatus>(status_num); |
| 157 DVLOG(1) << "Ignoring DNS probe result: already updated error page."; | 188 DnsProbeResult result = static_cast<DnsProbeResult>(result_num); |
| 189 | |
| 190 if (state_ != AWAITING_INITIAL_IPC && | |
| 191 (state_ != AWAITING_PROBE_RESULT || | |
| 192 status != chrome_common_net::DNS_PROBE_FINISHED)) { | |
| 193 DLOG(WARNING) << "Ignoring NetErrorInfo: invalid status " << status_num | |
| 194 << " for state " << state_; | |
| 195 NOTREACHED(); | |
|
mmenke
2013/04/01 17:44:12
This seems reachable: If the error page is reload
Deprecated (see juliatuttle)
2013/04/09 20:35:49
We'd see the DidStart and DidCommit before we got
| |
| 158 return; | 196 return; |
| 159 } | 197 } |
| 160 | 198 |
| 161 UpdateErrorPage(static_cast<DnsProbeResult>(dns_probe_result)); | 199 if (status == chrome_common_net::DNS_PROBE_STARTED) |
| 162 updated_error_page_ = true; | 200 state_ = AWAITING_PROBE_RESULT; |
| 201 else | |
| 202 state_ = IDLE; | |
| 203 | |
| 204 last_status_ = status; | |
| 205 last_result_ = result; | |
| 206 | |
| 207 UpdateErrorPage(); | |
| 163 } | 208 } |
| 164 | 209 |
| 165 void NetErrorHelper::TrackerCallback( | 210 WebKit::WebURLError NetErrorHelper::MakeUpdatedError() { |
| 166 NetErrorTracker::DnsErrorPageState state) { | 211 WebKit::WebURLError error; |
| 167 dns_error_page_state_ = state; | |
| 168 | 212 |
| 169 if (state == NetErrorTracker::DNS_ERROR_PAGE_LOADED) | 213 switch (last_status_) { |
| 170 updated_error_page_ = false; | 214 case chrome_common_net::DNS_PROBE_STARTED: |
| 215 error.domain = WebKit::WebString::fromUTF8( | |
| 216 chrome_common_net::kDnsProbeErrorDomain); | |
| 217 error.reason = chrome_common_net::DNS_PROBE_ERR_RUNNING; | |
| 218 break; | |
| 219 | |
| 220 case chrome_common_net::DNS_PROBE_FINISHED: | |
| 221 error.domain = WebKit::WebString::fromUTF8( | |
| 222 chrome_common_net::kDnsProbeErrorDomain); | |
| 223 error.reason = chrome_common_net::DNS_PROBE_ERR_FINISHED + | |
| 224 last_result_; | |
| 225 break; | |
| 226 | |
| 227 case chrome_common_net::DNS_PROBE_NOT_RUN: | |
| 228 error.domain = last_error_.domain; | |
| 229 error.reason = last_error_.reason; | |
| 230 break; | |
| 231 | |
| 232 case chrome_common_net::DNS_PROBE_STATUS_MAX: | |
| 233 NOTREACHED(); | |
| 234 break; | |
| 235 } | |
| 236 | |
| 237 error.unreachableURL = last_error_.unreachableURL; | |
| 238 | |
| 239 return error; | |
| 171 } | 240 } |
| 172 | 241 |
| 173 void NetErrorHelper::UpdateErrorPage(DnsProbeResult dns_probe_result) { | 242 void NetErrorHelper::UpdateErrorPage() { |
| 174 DVLOG(1) << "Updating error page with result " << dns_probe_result; | |
| 175 | |
| 176 int net_error = DnsProbeResultToNetError(dns_probe_result); | |
| 177 if (net_error == net::OK) | |
| 178 return; | |
| 179 | |
| 180 DVLOG(1) << "net error code is " << net_error; | |
| 181 | |
| 182 DictionaryValue error_strings; | 243 DictionaryValue error_strings; |
| 183 LocalizedError::GetStrings(NetErrorToWebURLError(net_error), | 244 LocalizedError::GetStrings(MakeUpdatedError(), |
| 184 &error_strings, | 245 &error_strings, |
| 185 RenderThread::Get()->GetLocale()); | 246 RenderThread::Get()->GetLocale()); |
| 186 | 247 |
| 187 // TODO(ttuttle): Update error page with error_strings. | 248 std::string json; |
| 249 JSONWriter::Write(&error_strings, &json); | |
| 250 | |
| 251 std::string js = "updateForDnsProbe(" + json + ");"; | |
| 252 string16 js16; | |
| 253 if (!UTF8ToUTF16(js.c_str(), js.length(), &js16)) { | |
| 254 NOTREACHED(); | |
| 255 return; | |
| 256 } | |
| 257 | |
| 258 DVLOG(1) << "Updating error page."; | |
| 259 DVLOG(2) << "New strings: " << js; | |
| 260 | |
| 261 string16 frame_xpath; | |
| 262 render_view()->EvaluateScript(frame_xpath, js16, 0, false); | |
| 188 } | 263 } |
| OLD | NEW |