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
3// found in the LICENSE file.
4
5#ifndef CHROME_RENDERER_NET_NET_ERROR_HELPER_H_
6#define CHROME_RENDERER_NET_NET_ERROR_HELPER_H_
7
8#include <string>
9
10#include "chrome/common/net/net_error_info.h"
11#include "content/public/renderer/render_view_observer.h"
12#include "third_party/WebKit/public/platform/WebURLError.h"
13
14namespace base {
15class DictionaryValue;
16}
17
18namespace blink {
19class WebFrame;
20}
21
22// Listens for NetErrorInfo messages from the NetErrorTabHelper on the
23// browser side and updates the error page with more details (currently, just
24// DNS probe results) if/when available.
25class NetErrorHelper : public content::RenderViewObserver {
26 public:
27  explicit NetErrorHelper(content::RenderView* render_view);
28  virtual ~NetErrorHelper();
29
30  // RenderViewObserver implementation.
31  virtual void DidStartProvisionalLoad(blink::WebFrame* frame) OVERRIDE;
32  virtual void DidFailProvisionalLoad(
33      blink::WebFrame* frame,
34      const blink::WebURLError& error) OVERRIDE;
35  virtual void DidCommitProvisionalLoad(
36      blink::WebFrame* frame,
37      bool is_new_navigation) OVERRIDE;
38  virtual void DidFinishLoad(blink::WebFrame* frame) OVERRIDE;
39
40  // IPC::Listener implementation.
41  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
42
43  // Examines |frame| and |error| to see if this is an error worthy of a DNS
44  // probe.  If it is, initializes |error_strings| based on |error|,
45  // |is_failed_post|, and |locale| with suitable strings and returns true.
46  // If not, returns false, in which case the caller should look up error
47  // strings directly using LocalizedError::GetNavigationErrorStrings.
48  static bool GetErrorStringsForDnsProbe(
49      blink::WebFrame* frame,
50      const blink::WebURLError& error,
51      bool is_failed_post,
52      const std::string& locale,
53      const std::string& accept_languages,
54      base::DictionaryValue* error_strings);
55
56 protected:
57  // These methods handle tracking the actual state of the page; this allows
58  // unit-testing of the state tracking without having to mock out WebFrames
59  // and such.
60  void OnStartLoad(bool is_main_frame, bool is_error_page);
61  void OnFailLoad(bool is_main_frame, bool is_dns_error);
62  void OnCommitLoad(bool is_main_frame);
63  void OnFinishLoad(bool is_main_frame);
64
65  void OnNetErrorInfo(int status);
66
67  // |UpdateErrorPage| is virtual so it can be mocked out in the unittest.
68  virtual void UpdateErrorPage();
69
70  // The last DnsProbeStatus received from the browser.
71  chrome_common_net::DnsProbeStatus last_probe_status_;
72
73 private:
74  blink::WebURLError GetUpdatedError() const;
75
76  // Whether the last provisional load started was for an error page.
77  bool last_start_was_error_page_;
78
79  // Whether the last provisional load failure failed with a DNS error.
80  bool last_fail_was_dns_error_;
81
82  // Ideally, this would be simply "last_commit_was_dns_error_page_".
83  //
84  // Unfortunately, that breaks if two DNS errors occur in a row; after the
85  // second failure, but before the second page commits, the helper can receive
86  // probe results.  If all it knows is that the last commit was a DNS error
87  // page, it will cheerfully forward the results for the second probe to the
88  // first page.
89  //
90  // Thus, the semantics of this flag are a little weird.  It is set whenever
91  // a DNS error page commits, and cleared whenever any other page commits,
92  // but it is also cleared whenever a DNS error occurs, to prevent the race
93  // described above.
94  bool forwarding_probe_results_;
95
96  // The last main frame error seen by the helper.
97  blink::WebURLError last_error_;
98
99  bool is_failed_post_;
100};
101
102#endif  // CHROME_RENDERER_NET_NET_ERROR_HELPER_H_
103