| Index: content/browser/devtools/protocol/network_handler.cc
|
| diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
|
| index 2fdccaa8593f65174517d82ffb7413dd93e662a7..e7cc6485c0771847cef8945d16892f622f190d10 100644
|
| --- a/content/browser/devtools/protocol/network_handler.cc
|
| +++ b/content/browser/devtools/protocol/network_handler.cc
|
| @@ -14,6 +14,7 @@
|
| #include "base/strings/stringprintf.h"
|
| #include "base/time/time.h"
|
| #include "content/browser/devtools/devtools_session.h"
|
| +#include "content/browser/devtools/devtools_url_interceptor_request_job.h"
|
| #include "content/browser/devtools/protocol/page.h"
|
| #include "content/browser/devtools/protocol/security.h"
|
| #include "content/browser/frame_host/frame_tree_node.h"
|
| @@ -336,6 +337,30 @@ String referrerPolicy(blink::WebReferrerPolicy referrer_policy) {
|
| return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
|
| }
|
|
|
| +String referrerPolicy(net::URLRequest::ReferrerPolicy referrer_policy) {
|
| + switch (referrer_policy) {
|
| + case net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
|
| + return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
|
| + case net::URLRequest::
|
| + REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN:
|
| + return Network::Request::ReferrerPolicyEnum::
|
| + NoReferrerWhenDowngradeOriginWhenCrossOrigin;
|
| + case net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN:
|
| + return Network::Request::ReferrerPolicyEnum::
|
| + NoReferrerWhenDowngradeOriginWhenCrossOrigin;
|
| + case net::URLRequest::NEVER_CLEAR_REFERRER:
|
| + return Network::Request::ReferrerPolicyEnum::Origin;
|
| + case net::URLRequest::ORIGIN:
|
| + return Network::Request::ReferrerPolicyEnum::Origin;
|
| + case net::URLRequest::NO_REFERRER:
|
| + return Network::Request::ReferrerPolicyEnum::NoReferrer;
|
| + default:
|
| + break;
|
| + }
|
| + NOTREACHED();
|
| + return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
|
| +}
|
| +
|
| String securityState(const GURL& url, const net::CertStatus& cert_status) {
|
| if (!url.SchemeIsCryptographic())
|
| return Security::SecurityStateEnum::Neutral;
|
| @@ -346,6 +371,34 @@ String securityState(const GURL& url, const net::CertStatus& cert_status) {
|
| return Security::SecurityStateEnum::Secure;
|
| }
|
|
|
| +net::Error NetErrorFromString(const std::string& error) {
|
| + if (error == Network::ErrorReasonEnum::Failed)
|
| + return net::ERR_FAILED;
|
| + if (error == Network::ErrorReasonEnum::Aborted)
|
| + return net::ERR_ABORTED;
|
| + if (error == Network::ErrorReasonEnum::TimedOut)
|
| + return net::ERR_TIMED_OUT;
|
| + if (error == Network::ErrorReasonEnum::AccessDenied)
|
| + return net::ERR_ACCESS_DENIED;
|
| + if (error == Network::ErrorReasonEnum::ConnectionClosed)
|
| + return net::ERR_CONNECTION_CLOSED;
|
| + if (error == Network::ErrorReasonEnum::ConnectionReset)
|
| + return net::ERR_CONNECTION_RESET;
|
| + if (error == Network::ErrorReasonEnum::ConnectionRefused)
|
| + return net::ERR_CONNECTION_REFUSED;
|
| + if (error == Network::ErrorReasonEnum::ConnectionAborted)
|
| + return net::ERR_CONNECTION_ABORTED;
|
| + if (error == Network::ErrorReasonEnum::ConnectionFailed)
|
| + return net::ERR_CONNECTION_FAILED;
|
| + if (error == Network::ErrorReasonEnum::NameNotResolved)
|
| + return net::ERR_NAME_NOT_RESOLVED;
|
| + if (error == Network::ErrorReasonEnum::InternetDisconnected)
|
| + return net::ERR_INTERNET_DISCONNECTED;
|
| + if (error == Network::ErrorReasonEnum::AddressUnreachable)
|
| + return net::ERR_ADDRESS_UNREACHABLE;
|
| + return net::ERR_FAILED;
|
| +}
|
| +
|
| double timeDelta(base::TimeTicks time,
|
| base::TimeTicks start,
|
| double invalid_value = -1) {
|
| @@ -419,10 +472,12 @@ String getProtocol(const GURL& url, const ResourceResponseHead& head) {
|
| NetworkHandler::NetworkHandler()
|
| : DevToolsDomainHandler(Network::Metainfo::domainName),
|
| host_(nullptr),
|
| - enabled_(false) {
|
| -}
|
| + enabled_(false),
|
| + interception_enabled_(false),
|
| + weak_factory_(this) {}
|
|
|
| NetworkHandler::~NetworkHandler() {
|
| + EnableFetchInterception(false);
|
| }
|
|
|
| // static
|
| @@ -762,5 +817,180 @@ std::string NetworkHandler::UserAgentOverride() const {
|
| return enabled_ ? user_agent_ : std::string();
|
| }
|
|
|
| +DispatchResponse NetworkHandler::EnableFetchInterception(bool enabled) {
|
| + if (interception_enabled_ == enabled)
|
| + return Response::OK(); // Nothing to do.
|
| +
|
| + WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
|
| + if (!web_contents)
|
| + return Response::OK();
|
| +
|
| + DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
|
| + DevToolsURLRequestInterceptor::FromBrowserContext(
|
| + web_contents->GetBrowserContext());
|
| + if (!devtools_url_request_interceptor)
|
| + return Response::OK();
|
| +
|
| + if (enabled) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(&DevToolsURLRequestInterceptor::State::
|
| + StartInterceptingRequestsFrom,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(),
|
| + host_->GetRoutingID(), host_->GetFrameTreeNodeId(),
|
| + weak_factory_.GetWeakPtr()));
|
| +
|
| + } else {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(
|
| + &DevToolsURLRequestInterceptor::State::StopInterceptingRequestsFrom,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(),
|
| + host_->GetRoutingID(), host_->GetFrameTreeNodeId()));
|
| + }
|
| + interception_enabled_ = enabled;
|
| + return Response::OK();
|
| +}
|
| +
|
| +template <typename CallbackT>
|
| +void ProcessInterceptionCommandResultOnIoThread(
|
| + std::unique_ptr<CallbackT> callback,
|
| + const DevToolsURLRequestInterceptor::CommandStatus& result) {
|
| + switch (result) {
|
| + case DevToolsURLRequestInterceptor::CommandStatus::OK:
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::BindOnce(&CallbackT::sendSuccess,
|
| + base::Owned(callback.release())));
|
| + break;
|
| + case DevToolsURLRequestInterceptor::CommandStatus::UnknownInterceptionId:
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::BindOnce(&CallbackT::sendFailure,
|
| + base::Owned(callback.release()),
|
| + Response::InvalidParams("Invalid interceptId.")));
|
| + break;
|
| + case DevToolsURLRequestInterceptor::CommandStatus::CommandAlreadyProcessed:
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::BindOnce(
|
| + &CallbackT::sendFailure, base::Owned(callback.release()),
|
| + Response::InvalidParams("Response already processed.")));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void NetworkHandler::AllowRequest(
|
| + const String& intercept_id,
|
| + std::unique_ptr<AllowRequestCallback> callback) {
|
| + DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
|
| + DevToolsURLRequestInterceptor::FromBrowserContext(
|
| + WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
|
| + if (!devtools_url_request_interceptor) {
|
| + callback->sendFailure(Response::InternalError());
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(
|
| + &DevToolsURLRequestInterceptor::State::AllowRequest,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
|
| + base::BindOnce(
|
| + ProcessInterceptionCommandResultOnIoThread<AllowRequestCallback>,
|
| + base::Passed(std::move(callback)))));
|
| +}
|
| +
|
| +void NetworkHandler::BlockRequest(
|
| + const String& intercept_id,
|
| + const std::string& error_reason,
|
| + std::unique_ptr<BlockRequestCallback> callback) {
|
| + DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
|
| + DevToolsURLRequestInterceptor::FromBrowserContext(
|
| + WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
|
| + if (!devtools_url_request_interceptor) {
|
| + callback->sendFailure(Response::InternalError());
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(
|
| + &DevToolsURLRequestInterceptor::State::BlockRequest,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
|
| + NetErrorFromString(error_reason),
|
| + base::BindOnce(
|
| + ProcessInterceptionCommandResultOnIoThread<BlockRequestCallback>,
|
| + base::Passed(std::move(callback)))));
|
| +}
|
| +
|
| +void NetworkHandler::ModifyRequest(
|
| + const String& intercept_id,
|
| + Maybe<String> url,
|
| + Maybe<String> method,
|
| + Maybe<String> post_data,
|
| + Maybe<protocol::Network::Headers> headers,
|
| + std::unique_ptr<ModifyRequestCallback> callback) {
|
| + DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
|
| + DevToolsURLRequestInterceptor::FromBrowserContext(
|
| + WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
|
| + if (!devtools_url_request_interceptor) {
|
| + callback->sendFailure(Response::InternalError());
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(
|
| + &DevToolsURLRequestInterceptor::State::ModifyRequest,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
|
| + base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
|
| + std::move(url), std::move(method), std::move(post_data),
|
| + std::move(headers)),
|
| + base::BindOnce(
|
| + ProcessInterceptionCommandResultOnIoThread<ModifyRequestCallback>,
|
| + base::Passed(std::move(callback)))));
|
| +}
|
| +
|
| +void NetworkHandler::MockResponse(
|
| + const String& intercept_id,
|
| + const String& raw_response,
|
| + std::unique_ptr<MockResponseCallback> callback) {
|
| + DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
|
| + DevToolsURLRequestInterceptor::FromBrowserContext(
|
| + WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
|
| + if (!devtools_url_request_interceptor) {
|
| + callback->sendFailure(Response::InternalError());
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(
|
| + &DevToolsURLRequestInterceptor::State::MockResponse,
|
| + devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
|
| + raw_response,
|
| + base::BindOnce(
|
| + ProcessInterceptionCommandResultOnIoThread<MockResponseCallback>,
|
| + base::Passed(std::move(callback)))));
|
| +}
|
| +
|
| +// static
|
| +std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest(
|
| + const net::URLRequest* request) {
|
| + std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
|
| + for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers());
|
| + it.GetNext();) {
|
| + headers_dict->setString(it.name(), it.value());
|
| + }
|
| + // TODO(alexclarke): Support post data
|
| + return Network::Request::Create()
|
| + .SetUrl(request->url().spec())
|
| + .SetMethod(request->method())
|
| + .SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
|
| + .SetInitialPriority(resourcePriority(request->priority()))
|
| + .SetReferrerPolicy(referrerPolicy(request->referrer_policy()))
|
| + .Build();
|
| +}
|
| +
|
| } // namespace protocol
|
| } // namespace content
|
|
|