// 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.

#include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"

#include <memory>
#include <string>
#include <utility>

#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_contents_client_bridge.h"
#include "android_webview/browser/aw_contents_io_thread_client.h"
#include "android_webview/browser/aw_resource_context.h"
#include "android_webview/browser/net/aw_web_resource_request.h"
#include "android_webview/browser/network_service/net_helpers.h"
#include "android_webview/browser/renderer_host/auto_login_parser.h"
#include "android_webview/browser/safe_browsing/aw_safe_browsing_resource_throttle.h"
#include "android_webview/common/url_constants.h"
#include "base/bind.h"
#include "base/task/post_task.h"
#include "components/safe_browsing/android/safe_browsing_api_handler.h"
#include "components/safe_browsing/features.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/web_contents.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_status.h"
#include "services/network/public/cpp/features.h"
#include "url/url_constants.h"

using android_webview::AwContentsIoThreadClient;
using android_webview::AwContentsClientBridge;
using android_webview::AwWebResourceRequest;
using content::BrowserThread;
using content::ResourceType;
using content::WebContents;

namespace {

base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate>::
    DestructorAtExit g_webview_resource_dispatcher_host_delegate =
        LAZY_INSTANCE_INITIALIZER;

// Called when ResourceDispathcerHost detects a download request.
// The download is already cancelled when this is called, since
// relevant for DownloadListener is already extracted.
void DownloadStartingOnUIThread(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const GURL& url,
    const std::string& user_agent,
    const std::string& content_disposition,
    const std::string& mime_type,
    int64_t content_length) {
  AwContentsClientBridge* client =
      AwContentsClientBridge::FromWebContentsGetter(web_contents_getter);
  if (!client)
    return;
  client->NewDownload(url, user_agent, content_disposition, mime_type,
                      content_length);
}

void NewLoginRequestOnUIThread(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const std::string& realm,
    const std::string& account,
    const std::string& args) {
  AwContentsClientBridge* client =
      AwContentsClientBridge::FromWebContentsGetter(web_contents_getter);
  if (!client)
    return;
  client->NewLoginRequest(realm, account, args);
}

void OnReceivedErrorOnUiThread(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const AwWebResourceRequest& request,
    int error_code,
    bool safebrowsing_hit) {
  AwContentsClientBridge* client =
      AwContentsClientBridge::FromWebContentsGetter(web_contents_getter);
  if (!client) {
    DLOG(WARNING) << "client is null, onReceivedError dropped for "
                  << request.url;
    return;
  }
  client->OnReceivedError(request, error_code, safebrowsing_hit);
}

}  // namespace

namespace android_webview {

// Calls through the IoThreadClient to check the embedders settings to determine
// if the request should be cancelled. There may not always be an IoThreadClient
// available for the |render_process_id|, |render_frame_id| pair (in the case of
// newly created pop up windows, for example) and in that case the request and
// the client callbacks will be deferred the request until a client is ready.
class IoThreadClientThrottle : public content::ResourceThrottle {
 public:
  IoThreadClientThrottle(int render_process_id,
                         int render_frame_id,
                         net::URLRequest* request);
  ~IoThreadClientThrottle() override;

  // From content::ResourceThrottle
  void WillStartRequest(bool* defer) override;
  void WillRedirectRequest(const net::RedirectInfo& redirect_info,
                           bool* defer) override;
  const char* GetNameForLogging() override;

  void OnIoThreadClientReady(int new_render_process_id,
                             int new_render_frame_id);
  bool MaybeBlockRequest();
  bool ShouldBlockRequest();
  bool GetSafeBrowsingEnabled();
  int render_process_id() const { return render_process_id_; }
  int render_frame_id() const { return render_frame_id_; }

 private:
  std::unique_ptr<AwContentsIoThreadClient> GetIoThreadClient() const;

  int render_process_id_;
  int render_frame_id_;
  net::URLRequest* request_;
};

IoThreadClientThrottle::IoThreadClientThrottle(int render_process_id,
                                               int render_frame_id,
                                               net::URLRequest* request)
    : render_process_id_(render_process_id),
      render_frame_id_(render_frame_id),
      request_(request) { }

IoThreadClientThrottle::~IoThreadClientThrottle() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  g_webview_resource_dispatcher_host_delegate.Get().
      RemovePendingThrottleOnIoThread(this);
}

const char* IoThreadClientThrottle::GetNameForLogging() {
  return "IoThreadClientThrottle";
}

std::unique_ptr<AwContentsIoThreadClient>
IoThreadClientThrottle::GetIoThreadClient() const {
  if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request_))
    return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient();

  if (render_process_id_ == -1 || render_frame_id_ == -1) {
    content::ResourceRequestInfo* resourceRequestInfo =
        content::ResourceRequestInfo::ForRequest(request_);
    if (resourceRequestInfo == nullptr) {
      return nullptr;
    }
    return AwContentsIoThreadClient::FromID(
        resourceRequestInfo->GetFrameTreeNodeId());
  }

  return AwContentsIoThreadClient::FromID(render_process_id_, render_frame_id_);
}

void IoThreadClientThrottle::WillStartRequest(bool* defer) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  // valid render_frame_id_ implies nonzero render_processs_id_
  DCHECK((render_frame_id_ < 1) || (render_process_id_ != 0));
  *defer = false;

  // Defer all requests of a pop up that is still not associated with Java
  // client so that the client will get a chance to override requests.
  std::unique_ptr<AwContentsIoThreadClient> io_client = GetIoThreadClient();
  if (io_client && io_client->PendingAssociation()) {
    *defer = true;
    AwResourceDispatcherHostDelegate::AddPendingThrottle(
        render_process_id_, render_frame_id_, this);
  } else {
    MaybeBlockRequest();
  }
}

void IoThreadClientThrottle::WillRedirectRequest(
    const net::RedirectInfo& redirect_info,
    bool* defer) {
  WillStartRequest(defer);
}

void IoThreadClientThrottle::OnIoThreadClientReady(int new_render_process_id,
                                                   int new_render_frame_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (!MaybeBlockRequest()) {
    Resume();
  }
}

bool IoThreadClientThrottle::MaybeBlockRequest() {
  if (ShouldBlockRequest()) {
    CancelWithError(net::ERR_ACCESS_DENIED);
    return true;
  }
  return false;
}

bool IoThreadClientThrottle::GetSafeBrowsingEnabled() {
  std::unique_ptr<AwContentsIoThreadClient> io_client = GetIoThreadClient();
  if (!io_client)
    return false;
  return io_client->GetSafeBrowsingEnabled();
}

bool IoThreadClientThrottle::ShouldBlockRequest() {
  std::unique_ptr<AwContentsIoThreadClient> io_client = GetIoThreadClient();
  if (!io_client)
    return false;

  if (ShouldBlockURL(request_->url(), io_client.get()))
    return true;

  request_->SetLoadFlags(
      UpdateLoadFlags(request_->load_flags(), io_client.get()));
  return false;
}

// static
void AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated() {
  content::ResourceDispatcherHost::Get()->SetDelegate(
      &g_webview_resource_dispatcher_host_delegate.Get());
}

AwResourceDispatcherHostDelegate::AwResourceDispatcherHostDelegate()
    : content::ResourceDispatcherHostDelegate() {}

AwResourceDispatcherHostDelegate::~AwResourceDispatcherHostDelegate() {
}

void AwResourceDispatcherHostDelegate::RequestBeginning(
    net::URLRequest* request,
    content::ResourceContext* resource_context,
    content::AppCacheService* appcache_service,
    ResourceType resource_type,
    std::vector<std::unique_ptr<content::ResourceThrottle>>* throttles) {
  content::ResourceRequestInfo* request_info =
      content::ResourceRequestInfo::ForRequest(request);

  std::unique_ptr<IoThreadClientThrottle> ioThreadThrottle =
      std::make_unique<IoThreadClientThrottle>(request_info->GetChildID(),
                                               request_info->GetRenderFrameID(),
                                               request);

  if (ioThreadThrottle->GetSafeBrowsingEnabled()) {
    DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
    if (!base::FeatureList::IsEnabled(
            safe_browsing::kCheckByURLLoaderThrottle)) {
      content::ResourceThrottle* throttle =
          MaybeCreateAwSafeBrowsingResourceThrottle(
              request, resource_type,
              AwBrowserContext::GetDefault()->GetSafeBrowsingDBManager(),
              AwBrowserContext::GetDefault()->GetSafeBrowsingUIManager(),
              AwBrowserContext::GetDefault()
                  ->GetSafeBrowsingWhitelistManager());
      if (throttle == nullptr) {
        // Should not happen
        DLOG(WARNING) << "Failed creating safebrowsing throttle";
      } else {
        throttles->push_back(base::WrapUnique(throttle));
      }
    }
  }

  // We always push the throttles here. Checking the existence of io_client
  // is racy when a popup window is created. That is because RequestBeginning
  // is called whether or not requests are blocked via BlockRequestForRoute()
  // however io_client may or may not be ready at the time depending on whether
  // webcontents is created.
  throttles->push_back(std::move(ioThreadThrottle));
}

void AwResourceDispatcherHostDelegate::RequestComplete(
    net::URLRequest* request) {
  if (request && !request->status().is_success()) {
    content::ResourceRequestInfo* request_info =
        content::ResourceRequestInfo::ForRequest(request);

    bool safebrowsing_hit = false;
    if (IsCancelledBySafeBrowsing(request)) {
      safebrowsing_hit = true;
    }
    base::PostTaskWithTraits(
        FROM_HERE, {BrowserThread::UI},
        base::BindOnce(&OnReceivedErrorOnUiThread,
                       request_info->GetWebContentsGetterForRequest(),
                       AwWebResourceRequest(*request),
                       request->status().error(), safebrowsing_hit));
  }
}

void AwResourceDispatcherHostDelegate::DownloadStarting(
    net::URLRequest* request,
    content::ResourceContext* resource_context,
    bool is_content_initiated,
    bool must_download,
    bool is_new_request,
    std::vector<std::unique_ptr<content::ResourceThrottle>>* throttles) {
  GURL url(request->url());
  std::string user_agent;
  std::string content_disposition;
  std::string mime_type;
  int64_t content_length = request->GetExpectedContentSize();

  request->extra_request_headers().GetHeader(
      net::HttpRequestHeaders::kUserAgent, &user_agent);

  net::HttpResponseHeaders* response_headers = request->response_headers();
  if (response_headers) {
    response_headers->GetNormalizedHeader("content-disposition",
        &content_disposition);
    response_headers->GetMimeType(&mime_type);
  }

  request->Cancel();

  // POST request cannot be repeated in general, so prevent client from
  // retrying the same request, unless it is with a GET.
  if ("GET" != request->method())
    return;

  content::ResourceRequestInfo* request_info =
      content::ResourceRequestInfo::ForRequest(request);

  base::PostTaskWithTraits(
      FROM_HERE, {BrowserThread::UI},
      base::BindOnce(&DownloadStartingOnUIThread,
                     request_info->GetWebContentsGetterForRequest(), url,
                     user_agent, content_disposition, mime_type,
                     content_length));
}

void AwResourceDispatcherHostDelegate::OnResponseStarted(
    net::URLRequest* request,
    content::ResourceContext* resource_context,
    network::ResourceResponse* response) {
  content::ResourceRequestInfo* request_info =
      content::ResourceRequestInfo::ForRequest(request);
  if (!request_info) {
    DLOG(FATAL) << "Started request without associated info: " <<
        request->url();
    return;
  }

  if (request_info->GetResourceType() == content::ResourceType::kMainFrame) {
    // Check for x-auto-login header.
    HeaderData header_data;
    if (ParserHeaderInResponse(request, ALLOW_ANY_REALM, &header_data)) {
      base::PostTaskWithTraits(
          FROM_HERE, {BrowserThread::UI},
          base::BindOnce(&NewLoginRequestOnUIThread,
                         request_info->GetWebContentsGetterForRequest(),
                         header_data.realm, header_data.account,
                         header_data.args));
    }
  }
}

void AwResourceDispatcherHostDelegate::RemovePendingThrottleOnIoThread(
    IoThreadClientThrottle* throttle) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  PendingThrottleMap::iterator it =
      pending_throttles_.find(content::GlobalFrameRoutingId(
          throttle->render_process_id(), throttle->render_frame_id()));
  if (it != pending_throttles_.end()) {
    pending_throttles_.erase(it);
  }
}

// static
void AwResourceDispatcherHostDelegate::OnIoThreadClientReady(
    int new_render_process_id,
    int new_render_frame_id) {
  base::PostTaskWithTraits(
      FROM_HERE, {BrowserThread::IO},
      base::BindOnce(
          &AwResourceDispatcherHostDelegate::OnIoThreadClientReadyInternal,
          base::Unretained(
              g_webview_resource_dispatcher_host_delegate.Pointer()),
          new_render_process_id, new_render_frame_id));
}

// static
void AwResourceDispatcherHostDelegate::AddPendingThrottle(
    int render_process_id,
    int render_frame_id,
    IoThreadClientThrottle* pending_throttle) {
  base::PostTaskWithTraits(
      FROM_HERE, {BrowserThread::IO},
      base::BindOnce(
          &AwResourceDispatcherHostDelegate::AddPendingThrottleOnIoThread,
          base::Unretained(
              g_webview_resource_dispatcher_host_delegate.Pointer()),
          render_process_id, render_frame_id, pending_throttle));
}

void AwResourceDispatcherHostDelegate::AddPendingThrottleOnIoThread(
    int render_process_id,
    int render_frame_id_id,
    IoThreadClientThrottle* pending_throttle) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  pending_throttles_.insert(
      std::pair<content::GlobalFrameRoutingId, IoThreadClientThrottle*>(
          content::GlobalFrameRoutingId(render_process_id, render_frame_id_id),
          pending_throttle));
}

void AwResourceDispatcherHostDelegate::OnIoThreadClientReadyInternal(
    int new_render_process_id,
    int new_render_frame_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  PendingThrottleMap::iterator it =
      pending_throttles_.find(content::GlobalFrameRoutingId(
          new_render_process_id, new_render_frame_id));

  if (it != pending_throttles_.end()) {
    IoThreadClientThrottle* throttle = it->second;
    throttle->OnIoThreadClientReady(new_render_process_id, new_render_frame_id);
    pending_throttles_.erase(it);
  }
}

}  // namespace android_webview
