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..7ed8bb555ff3a56dad265b53f16ab70a6e4f06c8 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); |
dgozman
2017/05/22 22:27:04
Do this in Disable() instead.
alex clarke (OOO till 29th)
2017/05/23 15:46:56
Done.
|
} |
// static |
@@ -762,5 +817,178 @@ 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::StartInterceptingRequests, |
+ devtools_url_request_interceptor->state().GetWeakPtr(), |
+ web_contents, weak_factory_.GetWeakPtr())); |
+ } else { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::BindOnce( |
+ &DevToolsURLRequestInterceptor::State::StopInterceptingRequests, |
+ devtools_url_request_interceptor->state().GetWeakPtr(), |
+ web_contents)); |
+ } |
+ 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 std::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 std::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 std::string& intercept_id, |
+ Maybe<std::string> url, |
+ Maybe<std::string> method, |
+ Maybe<std::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 std::string& intercept_id, |
+ const std::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 |