Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(992)

Unified Diff: content/browser/devtools/protocol/network_handler.cc

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Add a comment Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/devtools/protocol/network_handler.h ('k') | content/browser/devtools/protocol_config.json » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 62abd9ece33f18a6bb49276e8ef33653c28e7fee..3e44d0987a6a157023819ec86e324dff63103797 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include "base/barrier_closure.h"
+#include "base/base64.h"
#include "base/command_line.h"
#include "base/containers/hash_tables.h"
#include "base/process/process_handle.h"
@@ -14,6 +15,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"
@@ -35,6 +37,7 @@
#include "content/public/common/resource_devtools_info.h"
#include "content/public/common/resource_response.h"
#include "net/base/net_errors.h"
+#include "net/base/upload_bytes_element_reader.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context.h"
@@ -337,6 +340,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;
@@ -347,6 +374,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) {
@@ -420,8 +475,9 @@ 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() {
}
@@ -451,6 +507,7 @@ Response NetworkHandler::Enable(Maybe<int> max_total_size,
Response NetworkHandler::Disable() {
enabled_ = false;
user_agent_ = std::string();
+ EnableRequestInterception(false);
return Response::FallThrough();
}
@@ -770,5 +827,116 @@ std::string NetworkHandler::UserAgentOverride() const {
return enabled_ ? user_agent_ : std::string();
}
+DispatchResponse NetworkHandler::EnableRequestInterception(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) {
+ devtools_url_request_interceptor->state()->StartInterceptingRequests(
+ web_contents, weak_factory_.GetWeakPtr());
+ } else {
+ devtools_url_request_interceptor->state()->StopInterceptingRequests(
+ web_contents);
+ }
+ interception_enabled_ = enabled;
+ return Response::OK();
+}
+
+namespace {
+bool GetPostData(const net::URLRequest* request, std::string* post_data) {
+ if (!request->has_upload())
+ return false;
+
+ const net::UploadDataStream* stream = request->get_upload();
+ if (!stream->GetElementReaders())
+ return false;
+
+ const auto* element_readers = stream->GetElementReaders();
+ if (element_readers->empty())
+ return false;
+
+ *post_data = "";
+ for (const auto& element_reader : *element_readers) {
+ const net::UploadBytesElementReader* reader =
+ element_reader->AsBytesReader();
+ // TODO(alexclarke): This should really be base64 encoded.
+ *post_data += std::string(reader->bytes(), reader->length());
+ }
+ return true;
+}
+} // namespace
+
+// TODO(alexclarke): Support structured data as well as |base64_raw_response|.
+void NetworkHandler::ContinueInterceptedRequest(
+ const std::string& interception_id,
+ Maybe<std::string> error_reason,
+ Maybe<std::string> base64_raw_response,
+ Maybe<std::string> url,
+ Maybe<std::string> method,
+ Maybe<std::string> post_data,
+ Maybe<protocol::Network::Headers> headers,
+ std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
+ DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
+ DevToolsURLRequestInterceptor::FromBrowserContext(
+ WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
+ if (!devtools_url_request_interceptor) {
+ callback->sendFailure(Response::InternalError());
+ return;
+ }
+
+ base::Optional<net::Error> error;
+ if (error_reason.isJust())
+ error = NetErrorFromString(error_reason.fromJust());
+
+ base::Optional<std::string> raw_response;
+ if (base64_raw_response.isJust()) {
+ std::string decoded;
+ if (!base::Base64Decode(base64_raw_response.fromJust(), &decoded)) {
+ callback->sendFailure(Response::InvalidParams("Invalid rawResponse."));
+ return;
+ }
+ raw_response = decoded;
+ }
+
+ devtools_url_request_interceptor->state()->ContinueInterceptedRequest(
+ interception_id,
+ base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
+ std::move(error), std::move(raw_response), std::move(url),
+ std::move(method), std::move(post_data), std::move(headers)),
+ 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());
+ }
+ std::unique_ptr<protocol::Network::Request> request_object =
+ 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();
+ std::string post_data;
+ if (GetPostData(request, &post_data))
+ request_object->SetPostData(std::move(post_data));
+ return request_object;
+}
+
} // namespace protocol
} // namespace content
« no previous file with comments | « content/browser/devtools/protocol/network_handler.h ('k') | content/browser/devtools/protocol_config.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698