// Copyright (c) 2012 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 CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
#define CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_

#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/safe_browsing/database_manager.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "content/public/browser/resource_throttle.h"

class ResourceDispatcherHost;

namespace net {
class URLRequest;
}

// SafeBrowsingResourceThrottle checks that URLs are "safe" before navigating
// to them. To be considered "safe", a URL must not appear in the
// malware/phishing blacklists (see SafeBrowsingService for details).
//
// This check is done before requesting the original URL, and additionally
// before following any subsequent redirect.
//
// In the common case, the check completes synchronously (no match in the bloom
// filter), so the request's flow is un-interrupted.
//
// However if the URL fails this quick check, it has the possibility of being
// on the blacklist. Now the request is suspended (prevented from starting),
// and a more expensive safe browsing check is begun (fetches the full hashes).
//
// Note that the safe browsing check takes at most kCheckUrlTimeoutMs
// milliseconds. If it takes longer than this, then the system defaults to
// treating the URL as safe.
//
// Once the safe browsing check has completed, if the URL was decided to be
// dangerous, a warning page is thrown up and the request remains suspended.
// If on the other hand the URL was decided to be safe, the request is
// resumed.
class SafeBrowsingResourceThrottle
    : public content::ResourceThrottle,
      public SafeBrowsingDatabaseManager::Client,
      public base::SupportsWeakPtr<SafeBrowsingResourceThrottle> {
 public:
  SafeBrowsingResourceThrottle(const net::URLRequest* request,
                               bool is_subresource,
                               SafeBrowsingService* safe_browsing);

  // content::ResourceThrottle implementation (called on IO thread):
  virtual void WillStartRequest(bool* defer) OVERRIDE;
  virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
  virtual const char* GetNameForLogging() const OVERRIDE;

  // SafeBrowsingDabaseManager::Client implementation (called on IO thread):
  virtual void OnCheckBrowseUrlResult(
      const GURL& url, SBThreatType result) OVERRIDE;

 private:
  // Describes what phase of the check a throttle is in.
  enum State {
    STATE_NONE,
    STATE_CHECKING_URL,
    STATE_DISPLAYING_BLOCKING_PAGE,
  };

  // Describes what stage of the request got paused by the check.
  enum DeferState {
    DEFERRED_NONE,
    DEFERRED_START,
    DEFERRED_REDIRECT,
  };

  virtual ~SafeBrowsingResourceThrottle();

  // SafeBrowsingService::UrlCheckCallback implementation.
  void OnBlockingPageComplete(bool proceed);

  // Starts running |url| through the safe browsing check. Returns true if the
  // URL is safe to visit. Otherwise returns false and will call
  // OnBrowseUrlResult() when the check has completed.
  bool CheckUrl(const GURL& url);

  // Callback for when the safe browsing check (which was initiated by
  // StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs.
  void OnCheckUrlTimeout();

  // Starts displaying the safe browsing interstitial page.
  void StartDisplayingBlockingPage(const GURL& url, SBThreatType threat_type);

  // Resumes the request, by continuing the deferred action (either starting the
  // request, or following a redirect).
  void ResumeRequest();

  State state_;
  DeferState defer_state_;

  // The result of the most recent safe browsing check. Only valid to read this
  // when state_ != STATE_CHECKING_URL.
  SBThreatType threat_type_;

  // The time when the outstanding safe browsing check was started.
  base::TimeTicks url_check_start_time_;

  // Timer to abort the safe browsing check if it takes too long.
  base::OneShotTimer<SafeBrowsingResourceThrottle> timer_;

  // The redirect chain for this resource
  std::vector<GURL> redirect_urls_;

  GURL url_being_checked_;

  scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
  scoped_refptr<SafeBrowsingUIManager> ui_manager_;
  const net::URLRequest* request_;
  bool is_subresource_;

  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingResourceThrottle);
};


#endif  // CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
