| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2017 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 COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_ | 
|  | 6 #define COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_ | 
|  | 7 | 
|  | 8 #include <vector> | 
|  | 9 | 
|  | 10 #include "base/callback_forward.h" | 
|  | 11 #include "base/macros.h" | 
|  | 12 #include "base/memory/ref_counted.h" | 
|  | 13 #include "base/memory/weak_ptr.h" | 
|  | 14 #include "base/time/time.h" | 
|  | 15 #include "base/timer/timer.h" | 
|  | 16 #include "components/safe_browsing_db/database_manager.h" | 
|  | 17 #include "content/public/browser/web_contents.h" | 
|  | 18 #include "content/public/common/resource_type.h" | 
|  | 19 #include "net/log/net_log_event_type.h" | 
|  | 20 #include "net/log/net_log_with_source.h" | 
|  | 21 #include "url/gurl.h" | 
|  | 22 | 
|  | 23 namespace content { | 
|  | 24 class WebContents; | 
|  | 25 } | 
|  | 26 | 
|  | 27 namespace net { | 
|  | 28 class URLRequest; | 
|  | 29 } | 
|  | 30 | 
|  | 31 namespace security_interstitials { | 
|  | 32 struct UnsafeResource; | 
|  | 33 } | 
|  | 34 | 
|  | 35 namespace safe_browsing { | 
|  | 36 | 
|  | 37 class BaseUIManager; | 
|  | 38 class ScopedTimeoutForTesting; | 
|  | 39 | 
|  | 40 class RequestChecker final : public SafeBrowsingDatabaseManager::Client { | 
|  | 41  public: | 
|  | 42   enum DeferDecision { | 
|  | 43     DEFER,                // Should wait for permission to proceed | 
|  | 44     PROCEED_SKIPPED,      // ResourceType is exempted from checking | 
|  | 45     PROCEED_SAFE,         // Checked and safe | 
|  | 46     PROCEED_ALWAYS_ASYNC  // Checks are always async on this platform | 
|  | 47   }; | 
|  | 48 | 
|  | 49   class Delegate { | 
|  | 50    public: | 
|  | 51     // This duplicates the definition of | 
|  | 52     // content::ResourceRequestInfo::WebContentsGetter to avoid having a | 
|  | 53     // dependency on ResourceRequestInfo. | 
|  | 54     using WebContentsGetter = base::Callback<content::WebContents*(void)>; | 
|  | 55 | 
|  | 56     Delegate() {} | 
|  | 57     virtual ~Delegate() {} | 
|  | 58     virtual void MaybeDestroyPrerenderContents( | 
|  | 59         const WebContentsGetter& web_contents_getter) = 0; | 
|  | 60     virtual WebContentsGetter GetWebContentsGetterForRequest( | 
|  | 61         const net::URLRequest* request) const = 0; | 
|  | 62     virtual void StartDisplayingBlockingPage( | 
|  | 63         const security_interstitials::UnsafeResource& resource, | 
|  | 64         scoped_refptr<BaseUIManager> ui_manager) = 0; | 
|  | 65     virtual void CancelResourceLoad() = 0; | 
|  | 66     virtual void ResumeResourceRequest() = 0; | 
|  | 67 | 
|  | 68    private: | 
|  | 69     DISALLOW_COPY_AND_ASSIGN(Delegate); | 
|  | 70   }; | 
|  | 71 | 
|  | 72   RequestChecker(const net::URLRequest* request, | 
|  | 73                  content::ResourceType resource_type, | 
|  | 74                  scoped_refptr<SafeBrowsingDatabaseManager> database_manager, | 
|  | 75                  scoped_refptr<BaseUIManager> ui_manager, | 
|  | 76                  Delegate* delegate); | 
|  | 77   ~RequestChecker() final; | 
|  | 78 | 
|  | 79   // Should be called once to start checking the URL that was passed to the | 
|  | 80   // constructor. | 
|  | 81   DeferDecision CheckNewRequest(); | 
|  | 82 | 
|  | 83   // Can be called 0 or more times. Must not be called before CheckNewRequest(). | 
|  | 84   // If the previous call to CheckNewRequest() or CheckRedirect() returned | 
|  | 85   // DEFER, must not be called until Delegate::ResumeResourceRequest() has been | 
|  | 86   // called. | 
|  | 87   DeferDecision CheckRedirect(const GURL& new_url); | 
|  | 88 | 
|  | 89   // Should be called once. Must not be called before | 
|  | 90   // CheckNewRequest(). CheckRedirect() must not be called after | 
|  | 91   // ShouldDeferResponse(). As with CheckRedirect(), if the previous call to | 
|  | 92   // CheckNewRequest() or CheckRedirect() returned DEFER, ShouldDeferResponse() | 
|  | 93   // must not be called until Delegate::ResumeResourceRequest() has been called. | 
|  | 94   DeferDecision ShouldDeferResponse(); | 
|  | 95 | 
|  | 96   // SafeBrowsingDatabaseManager::Client implementation (called on IO thread): | 
|  | 97   void OnCheckBrowseUrlResult(const GURL& url, | 
|  | 98                               SBThreatType threat_type, | 
|  | 99                               const ThreatMetadata& metadata) final; | 
|  | 100 | 
|  | 101  private: | 
|  | 102   // Describes what phase of the check a throttle is in. | 
|  | 103   enum State { | 
|  | 104     // Haven't started checking or checking is complete. Not deferred. | 
|  | 105     STATE_NONE, | 
|  | 106     // We have one outstanding URL-check. Could be deferred. | 
|  | 107     STATE_CHECKING_URL, | 
|  | 108     // We're displaying a blocking page. Could be deferred. | 
|  | 109     STATE_DISPLAYING_BLOCKING_PAGE, | 
|  | 110   }; | 
|  | 111 | 
|  | 112   // Describes what stage of the request got paused by the check. | 
|  | 113   enum DeferState { | 
|  | 114     DEFERRED_NONE, | 
|  | 115     DEFERRED_START, | 
|  | 116     DEFERRED_REDIRECT, | 
|  | 117     DEFERRED_UNCHECKED_REDIRECT,  // unchecked_redirect_url_ is populated. | 
|  | 118     DEFERRED_PROCESSING, | 
|  | 119   }; | 
|  | 120 | 
|  | 121   void OnBlockingPageComplete(bool proceed); | 
|  | 122 | 
|  | 123   // Starts running |url| through the safe browsing check. If it returns DEFER | 
|  | 124   // then one of the Delegate methods will be called asynchronously. If one | 
|  | 125   // PROCEED_SKIPPED or PROCEED_SAFE is returned then it will take no further | 
|  | 126   // action. Never returns PROCEED_ALWAYS_ASYNC. | 
|  | 127   DeferDecision CheckUrl(const GURL& url); | 
|  | 128 | 
|  | 129   // Callback for when the safe browsing check (which was initiated by | 
|  | 130   // StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs. | 
|  | 131   void OnCheckUrlTimeout(); | 
|  | 132 | 
|  | 133   void ResumeRequest(); | 
|  | 134 | 
|  | 135   // For marking network events.  |name| and |value| can be null. | 
|  | 136   void BeginNetLogEvent(net::NetLogEventType type, | 
|  | 137                         const GURL& url, | 
|  | 138                         const char* name, | 
|  | 139                         const char* value); | 
|  | 140   void EndNetLogEvent(net::NetLogEventType type, | 
|  | 141                       const char* name, | 
|  | 142                       const char* value); | 
|  | 143 | 
|  | 144   State state_; | 
|  | 145   DeferState defer_state_; | 
|  | 146   const content::ResourceType resource_type_; | 
|  | 147 | 
|  | 148   // The result of the most recent safe browsing check. Only valid to read this | 
|  | 149   // when state_ != STATE_CHECKING_URL. | 
|  | 150   safe_browsing::SBThreatType threat_type_; | 
|  | 151 | 
|  | 152   // The time when we started deferring the request. | 
|  | 153   base::TimeTicks defer_start_time_; | 
|  | 154 | 
|  | 155   const net::URLRequest* request_; | 
|  | 156 | 
|  | 157   scoped_refptr<BaseUIManager> ui_manager_; | 
|  | 158 | 
|  | 159   scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; | 
|  | 160 | 
|  | 161   // Timer to abort the safe browsing check if it takes too long. | 
|  | 162   base::OneShotTimer timer_; | 
|  | 163 | 
|  | 164   // The redirect chain for this resource | 
|  | 165   std::vector<GURL> redirect_urls_; | 
|  | 166 | 
|  | 167   // If in DEFERRED_UNCHECKED_REDIRECT state, this is the | 
|  | 168   // URL we still need to check before resuming. | 
|  | 169   GURL unchecked_redirect_url_; | 
|  | 170   GURL url_being_checked_; | 
|  | 171 | 
|  | 172   net::NetLogWithSource net_log_with_source_; | 
|  | 173   Delegate* delegate_; | 
|  | 174 | 
|  | 175   base::WeakPtrFactory<RequestChecker> weak_factory_; | 
|  | 176 | 
|  | 177   DISALLOW_COPY_AND_ASSIGN(RequestChecker); | 
|  | 178 }; | 
|  | 179 | 
|  | 180 // This class can be used to locally change the timeout for checks. Thread | 
|  | 181 // hostile. | 
|  | 182 class ScopedTimeoutForTesting { | 
|  | 183  public: | 
|  | 184   explicit ScopedTimeoutForTesting(int new_timeout_ms); | 
|  | 185   ScopedTimeoutForTesting(ScopedTimeoutForTesting&& rhs); | 
|  | 186   ~ScopedTimeoutForTesting(); | 
|  | 187 | 
|  | 188  private: | 
|  | 189   int original_timeout_ms_; | 
|  | 190 | 
|  | 191   DISALLOW_COPY_AND_ASSIGN(ScopedTimeoutForTesting); | 
|  | 192 }; | 
|  | 193 | 
|  | 194 }  // namespace safe_browsing | 
|  | 195 | 
|  | 196 #endif  // COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_ | 
| OLD | NEW | 
|---|