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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
6#define CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/memory/ref_counted.h"
12#include "base/time/time.h"
13#include "base/timer/timer.h"
14#include "chrome/browser/safe_browsing/database_manager.h"
15#include "chrome/browser/safe_browsing/ui_manager.h"
16#include "content/public/browser/resource_throttle.h"
17#include "content/public/common/resource_type.h"
18
19class ResourceDispatcherHost;
20
21namespace net {
22class URLRequest;
23}
24
25// SafeBrowsingResourceThrottle checks that URLs are "safe" before navigating
26// to them. To be considered "safe", a URL must not appear in the
27// malware/phishing blacklists (see SafeBrowsingService for details).
28//
29// This check is done before requesting the original URL, and additionally
30// before following any subsequent redirect.
31//
32// In the common case, the check completes synchronously (no match in the bloom
33// filter), so the request's flow is un-interrupted.
34//
35// However if the URL fails this quick check, it has the possibility of being
36// on the blacklist. Now the request is suspended (prevented from starting),
37// and a more expensive safe browsing check is begun (fetches the full hashes).
38//
39// Note that the safe browsing check takes at most kCheckUrlTimeoutMs
40// milliseconds. If it takes longer than this, then the system defaults to
41// treating the URL as safe.
42//
43// Once the safe browsing check has completed, if the URL was decided to be
44// dangerous, a warning page is thrown up and the request remains suspended.
45// If on the other hand the URL was decided to be safe, the request is
46// resumed.
47class SafeBrowsingResourceThrottle
48    : public content::ResourceThrottle,
49      public SafeBrowsingDatabaseManager::Client,
50      public base::SupportsWeakPtr<SafeBrowsingResourceThrottle> {
51 public:
52  SafeBrowsingResourceThrottle(const net::URLRequest* request,
53                               content::ResourceType resource_type,
54                               SafeBrowsingService* safe_browsing);
55
56  // content::ResourceThrottle implementation (called on IO thread):
57  virtual void WillStartRequest(bool* defer) OVERRIDE;
58  virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
59  virtual const char* GetNameForLogging() const OVERRIDE;
60
61  // SafeBrowsingDabaseManager::Client implementation (called on IO thread):
62  virtual void OnCheckBrowseUrlResult(const GURL& url,
63                                      SBThreatType result,
64                                      const std::string& metadata) OVERRIDE;
65
66 private:
67  // Describes what phase of the check a throttle is in.
68  enum State {
69    STATE_NONE,
70    STATE_CHECKING_URL,
71    STATE_DISPLAYING_BLOCKING_PAGE,
72  };
73
74  // Describes what stage of the request got paused by the check.
75  enum DeferState {
76    DEFERRED_NONE,
77    DEFERRED_START,
78    DEFERRED_REDIRECT,
79  };
80
81  virtual ~SafeBrowsingResourceThrottle();
82
83  // SafeBrowsingService::UrlCheckCallback implementation.
84  void OnBlockingPageComplete(bool proceed);
85
86  // Starts running |url| through the safe browsing check. Returns true if the
87  // URL is safe to visit. Otherwise returns false and will call
88  // OnBrowseUrlResult() when the check has completed.
89  bool CheckUrl(const GURL& url);
90
91  // Callback for when the safe browsing check (which was initiated by
92  // StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs.
93  void OnCheckUrlTimeout();
94
95  // Starts displaying the safe browsing interstitial page if it's not
96  // prerendering. Called on the UI thread.
97  static void StartDisplayingBlockingPage(
98      const base::WeakPtr<SafeBrowsingResourceThrottle>& throttle,
99      scoped_refptr<SafeBrowsingUIManager> ui_manager,
100      const SafeBrowsingUIManager::UnsafeResource& resource);
101
102  // Called on the IO thread if the request turned out to be for a prerendered
103  // page.
104  void Cancel();
105
106  // Resumes the request, by continuing the deferred action (either starting the
107  // request, or following a redirect).
108  void ResumeRequest();
109
110  State state_;
111  DeferState defer_state_;
112
113  // The result of the most recent safe browsing check. Only valid to read this
114  // when state_ != STATE_CHECKING_URL.
115  SBThreatType threat_type_;
116
117  // The time when the outstanding safe browsing check was started.
118  base::TimeTicks url_check_start_time_;
119
120  // Timer to abort the safe browsing check if it takes too long.
121  base::OneShotTimer<SafeBrowsingResourceThrottle> timer_;
122
123  // The redirect chain for this resource
124  std::vector<GURL> redirect_urls_;
125
126  GURL url_being_checked_;
127
128  scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
129  scoped_refptr<SafeBrowsingUIManager> ui_manager_;
130  const net::URLRequest* request_;
131  const bool is_subresource_;
132  const bool is_subframe_;
133
134  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingResourceThrottle);
135};
136
137
138#endif  // CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
139