| Index: components/safe_browsing/request_checker.h
|
| diff --git a/components/safe_browsing/request_checker.h b/components/safe_browsing/request_checker.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1d2409c8a0731132973e12cd9bb16486e32ee87a
|
| --- /dev/null
|
| +++ b/components/safe_browsing/request_checker.h
|
| @@ -0,0 +1,196 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_
|
| +#define COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/callback_forward.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "base/time/time.h"
|
| +#include "base/timer/timer.h"
|
| +#include "components/safe_browsing_db/database_manager.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/common/resource_type.h"
|
| +#include "net/log/net_log_event_type.h"
|
| +#include "net/log/net_log_with_source.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace content {
|
| +class WebContents;
|
| +}
|
| +
|
| +namespace net {
|
| +class URLRequest;
|
| +}
|
| +
|
| +namespace security_interstitials {
|
| +struct UnsafeResource;
|
| +}
|
| +
|
| +namespace safe_browsing {
|
| +
|
| +class BaseUIManager;
|
| +class ScopedTimeoutForTesting;
|
| +
|
| +class RequestChecker final : public SafeBrowsingDatabaseManager::Client {
|
| + public:
|
| + enum DeferDecision {
|
| + DEFER, // Should wait for permission to proceed
|
| + PROCEED_SKIPPED, // ResourceType is exempted from checking
|
| + PROCEED_SAFE, // Checked and safe
|
| + PROCEED_ALWAYS_ASYNC // Checks are always async on this platform
|
| + };
|
| +
|
| + class Delegate {
|
| + public:
|
| + // This duplicates the definition of
|
| + // content::ResourceRequestInfo::WebContentsGetter to avoid having a
|
| + // dependency on ResourceRequestInfo.
|
| + using WebContentsGetter = base::Callback<content::WebContents*(void)>;
|
| +
|
| + Delegate() {}
|
| + virtual ~Delegate() {}
|
| + virtual void MaybeDestroyPrerenderContents(
|
| + const net::URLRequest* request) = 0;
|
| + virtual WebContentsGetter GetWebContentsGetterForRequest(
|
| + const net::URLRequest* request) const = 0;
|
| + virtual void StartDisplayingBlockingPage(
|
| + const security_interstitials::UnsafeResource& resource,
|
| + scoped_refptr<BaseUIManager> ui_manager) = 0;
|
| + virtual void CancelResourceLoad() = 0;
|
| + virtual void ResumeResourceRequest() = 0;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(Delegate);
|
| + };
|
| +
|
| + RequestChecker(const net::URLRequest* request,
|
| + content::ResourceType resource_type,
|
| + scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
|
| + scoped_refptr<BaseUIManager> ui_manager,
|
| + Delegate* delegate);
|
| + ~RequestChecker() final;
|
| +
|
| + // Should be called once to start checking the URL that was passed to the
|
| + // constructor.
|
| + DeferDecision CheckNewRequest();
|
| +
|
| + // Can be called 0 or more times. Must not be called before CheckNewRequest().
|
| + // If the previous call to CheckNewRequest() or CheckRedirect() returned
|
| + // DEFER, must not be called until Delegate::ResumeResourceRequest() has been
|
| + // called.
|
| + DeferDecision CheckRedirect(const GURL& new_url);
|
| +
|
| + // Should be called once. Must not be called before
|
| + // CheckNewRequest(). CheckRedirect() must not be called after
|
| + // ShouldDeferResponse(). As with CheckRedirect(), if the previous call to
|
| + // CheckNewRequest() or CheckRedirect() returned DEFER, ShouldDeferResponse()
|
| + // must not be called until Delegate::ResumeResourceRequest() has been called.
|
| + DeferDecision ShouldDeferResponse();
|
| +
|
| + // SafeBrowsingDatabaseManager::Client implementation (called on IO thread):
|
| + void OnCheckBrowseUrlResult(const GURL& url,
|
| + SBThreatType threat_type,
|
| + const ThreatMetadata& metadata) final;
|
| +
|
| + private:
|
| + // Describes what phase of the check a throttle is in.
|
| + enum State {
|
| + // Haven't started checking or checking is complete. Not deferred.
|
| + STATE_NONE,
|
| + // We have one outstanding URL-check. Could be deferred.
|
| + STATE_CHECKING_URL,
|
| + // We're displaying a blocking page. Could be deferred.
|
| + STATE_DISPLAYING_BLOCKING_PAGE,
|
| + };
|
| +
|
| + // Describes what stage of the request got paused by the check.
|
| + enum DeferState {
|
| + DEFERRED_NONE,
|
| + DEFERRED_START,
|
| + DEFERRED_REDIRECT,
|
| + DEFERRED_UNCHECKED_REDIRECT, // unchecked_redirect_url_ is populated.
|
| + DEFERRED_PROCESSING,
|
| + };
|
| +
|
| + void OnBlockingPageComplete(bool proceed);
|
| +
|
| + // Starts running |url| through the safe browsing check. If it returns DEFER
|
| + // then one of the Delegate methods will be called asynchronously. If one
|
| + // PROCEED_SKIPPED or PROCEED_SAFE is returned then it will take no further
|
| + // action. Never returns PROCEED_ALWAYS_ASYNC.
|
| + DeferDecision CheckUrl(const GURL& url);
|
| +
|
| + // Callback for when the safe browsing check (which was initiated by
|
| + // StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs.
|
| + void OnCheckUrlTimeout();
|
| +
|
| + void ResumeRequest();
|
| +
|
| + // For marking network events. |name| and |value| can be null.
|
| + void BeginNetLogEvent(net::NetLogEventType type,
|
| + const GURL& url,
|
| + const char* name,
|
| + const char* value);
|
| + void EndNetLogEvent(net::NetLogEventType type,
|
| + const char* name,
|
| + const char* value);
|
| +
|
| + State state_;
|
| + DeferState defer_state_;
|
| + const content::ResourceType resource_type_;
|
| +
|
| + // The result of the most recent safe browsing check. Only valid to read this
|
| + // when state_ != STATE_CHECKING_URL.
|
| + safe_browsing::SBThreatType threat_type_;
|
| +
|
| + // The time when we started deferring the request.
|
| + base::TimeTicks defer_start_time_;
|
| +
|
| + const net::URLRequest* request_;
|
| +
|
| + scoped_refptr<BaseUIManager> ui_manager_;
|
| +
|
| + scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
|
| +
|
| + // Timer to abort the safe browsing check if it takes too long.
|
| + base::OneShotTimer timer_;
|
| +
|
| + // The redirect chain for this resource
|
| + std::vector<GURL> redirect_urls_;
|
| +
|
| + // If in DEFERRED_UNCHECKED_REDIRECT state, this is the
|
| + // URL we still need to check before resuming.
|
| + GURL unchecked_redirect_url_;
|
| + GURL url_being_checked_;
|
| +
|
| + net::NetLogWithSource net_log_with_source_;
|
| + Delegate* delegate_;
|
| +
|
| + base::WeakPtrFactory<RequestChecker> weak_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RequestChecker);
|
| +};
|
| +
|
| +// This class can be used to locally change the timeout for checks. Thread
|
| +// hostile.
|
| +class ScopedTimeoutForTesting {
|
| + public:
|
| + explicit ScopedTimeoutForTesting(int new_timeout_ms);
|
| + ScopedTimeoutForTesting(ScopedTimeoutForTesting&& rhs);
|
| + ~ScopedTimeoutForTesting();
|
| +
|
| + private:
|
| + int original_timeout_ms_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedTimeoutForTesting);
|
| +};
|
| +
|
| +} // namespace safe_browsing
|
| +
|
| +#endif // COMPONENTS_SAFE_BROWSING_REQUEST_CHECKER_H_
|
|
|