blob: e23bb9c14d034602bd1f52027e234a71d6ef8b30 [file] [log] [blame]
// 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.
#include "content/browser/devtools/devtools_interceptor_controller.h"
#include "base/bind.h"
#include "base/supports_user_data.h"
#include "base/task/post_task.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
namespace {
const char kDevToolsInterceptorController[] = "DevToolsInterceptorController";
}
std::unique_ptr<InterceptionHandle>
DevToolsInterceptorController::StartInterceptingRequests(
const FrameTreeNode* target_frame,
std::vector<Pattern> intercepted_patterns,
RequestInterceptedCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const base::UnguessableToken& target_id =
target_frame->devtools_frame_token();
auto filter_entry = std::make_unique<DevToolsNetworkInterceptor::FilterEntry>(
target_id, std::move(intercepted_patterns), std::move(callback));
DevToolsTargetRegistry::RegistrationHandle registration_handle =
target_registry_->RegisterWebContents(
WebContentsImpl::FromFrameTreeNode(target_frame));
std::unique_ptr<InterceptionHandle> handle(new InterceptionHandle(
std::move(registration_handle), interceptor_, filter_entry.get()));
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::AddFilterEntry, interceptor_,
std::move(filter_entry)));
return handle;
}
void DevToolsInterceptorController::ContinueInterceptedRequest(
std::string interception_id,
std::unique_ptr<Modifications> modifications,
std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::ContinueInterceptedRequest,
interceptor_, interception_id, std::move(modifications),
std::move(callback)));
}
bool DevToolsInterceptorController::ShouldCancelNavigation(
const GlobalRequestID& global_request_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto it = canceled_navigation_requests_.find(global_request_id);
if (it == canceled_navigation_requests_.end())
return false;
canceled_navigation_requests_.erase(it);
return true;
}
void DevToolsInterceptorController::GetResponseBody(
std::string interception_id,
std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::GetResponseBody, interceptor_,
std::move(interception_id), std::move(callback)));
}
void DevToolsInterceptorController::NavigationStarted(
const std::string& interception_id,
const GlobalRequestID& request_id) {
navigation_requests_[interception_id] = request_id;
}
void DevToolsInterceptorController::NavigationFinished(
const std::string& interception_id) {
navigation_requests_.erase(interception_id);
}
// static
DevToolsInterceptorController*
DevToolsInterceptorController::FromBrowserContext(BrowserContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return static_cast<DevToolsInterceptorController*>(
context->GetUserData(kDevToolsInterceptorController));
}
DevToolsInterceptorController::DevToolsInterceptorController(
base::WeakPtr<DevToolsNetworkInterceptor> interceptor,
std::unique_ptr<DevToolsTargetRegistry> target_registry,
BrowserContext* browser_context)
: interceptor_(interceptor),
target_registry_(std::move(target_registry)),
weak_factory_(this) {
browser_context->SetUserData(
kDevToolsInterceptorController,
std::unique_ptr<DevToolsInterceptorController>(this));
}
DevToolsInterceptorController::~DevToolsInterceptorController() = default;
InterceptionHandle::InterceptionHandle(
DevToolsTargetRegistry::RegistrationHandle registration,
base::WeakPtr<DevToolsNetworkInterceptor> interceptor,
DevToolsNetworkInterceptor::FilterEntry* entry)
: registration_(registration),
interceptor_(std::move(interceptor)),
entry_(entry) {}
InterceptionHandle::~InterceptionHandle() {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::RemoveFilterEntry,
interceptor_, entry_));
}
void InterceptionHandle::UpdatePatterns(
std::vector<DevToolsNetworkInterceptor::Pattern> patterns) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::UpdatePatterns, interceptor_,
base::Unretained(entry_), std::move(patterns)));
}
} // namespace content