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

Side by Side Diff: content/browser/devtools/protocol/network_handler.cc

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Fix 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/devtools/protocol/network_handler.h" 5 #include "content/browser/devtools/protocol/network_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/barrier_closure.h" 9 #include "base/barrier_closure.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/containers/hash_tables.h" 11 #include "base/containers/hash_tables.h"
12 #include "base/process/process_handle.h" 12 #include "base/process/process_handle.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "content/browser/devtools/devtools_session.h" 16 #include "content/browser/devtools/devtools_session.h"
17 #include "content/browser/devtools/devtools_url_interceptor_request_job.h"
17 #include "content/browser/devtools/protocol/page.h" 18 #include "content/browser/devtools/protocol/page.h"
18 #include "content/browser/devtools/protocol/security.h" 19 #include "content/browser/devtools/protocol/security.h"
19 #include "content/browser/frame_host/frame_tree_node.h" 20 #include "content/browser/frame_host/frame_tree_node.h"
20 #include "content/browser/frame_host/render_frame_host_impl.h" 21 #include "content/browser/frame_host/render_frame_host_impl.h"
21 #include "content/common/navigation_params.h" 22 #include "content/common/navigation_params.h"
22 #include "content/common/resource_request.h" 23 #include "content/common/resource_request.h"
23 #include "content/common/resource_request_completion_status.h" 24 #include "content/common/resource_request_completion_status.h"
24 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/content_browser_client.h" 27 #include "content/public/browser/content_browser_client.h"
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 case blink::kWebReferrerPolicyOriginWhenCrossOrigin: 330 case blink::kWebReferrerPolicyOriginWhenCrossOrigin:
330 return Network::Request::ReferrerPolicyEnum::OriginWhenCrossOrigin; 331 return Network::Request::ReferrerPolicyEnum::OriginWhenCrossOrigin;
331 case blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin: 332 case blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin:
332 return Network::Request::ReferrerPolicyEnum:: 333 return Network::Request::ReferrerPolicyEnum::
333 NoReferrerWhenDowngradeOriginWhenCrossOrigin; 334 NoReferrerWhenDowngradeOriginWhenCrossOrigin;
334 } 335 }
335 NOTREACHED(); 336 NOTREACHED();
336 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; 337 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
337 } 338 }
338 339
340 String referrerPolicy(net::URLRequest::ReferrerPolicy referrer_policy) {
341 switch (referrer_policy) {
342 case net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
343 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
344 case net::URLRequest::
345 REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN:
346 return Network::Request::ReferrerPolicyEnum::
347 NoReferrerWhenDowngradeOriginWhenCrossOrigin;
348 case net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN:
349 return Network::Request::ReferrerPolicyEnum::
350 NoReferrerWhenDowngradeOriginWhenCrossOrigin;
351 case net::URLRequest::NEVER_CLEAR_REFERRER:
352 return Network::Request::ReferrerPolicyEnum::Origin;
353 case net::URLRequest::ORIGIN:
354 return Network::Request::ReferrerPolicyEnum::Origin;
355 case net::URLRequest::NO_REFERRER:
356 return Network::Request::ReferrerPolicyEnum::NoReferrer;
357 default:
358 break;
359 }
360 NOTREACHED();
361 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
362 }
363
339 String securityState(const GURL& url, const net::CertStatus& cert_status) { 364 String securityState(const GURL& url, const net::CertStatus& cert_status) {
340 if (!url.SchemeIsCryptographic()) 365 if (!url.SchemeIsCryptographic())
341 return Security::SecurityStateEnum::Neutral; 366 return Security::SecurityStateEnum::Neutral;
342 if (net::IsCertStatusError(cert_status) && 367 if (net::IsCertStatusError(cert_status) &&
343 !net::IsCertStatusMinorError(cert_status)) { 368 !net::IsCertStatusMinorError(cert_status)) {
344 return Security::SecurityStateEnum::Insecure; 369 return Security::SecurityStateEnum::Insecure;
345 } 370 }
346 return Security::SecurityStateEnum::Secure; 371 return Security::SecurityStateEnum::Secure;
347 } 372 }
348 373
374 net::Error NetErrorFromString(const std::string& error) {
375 if (error == Network::ErrorReasonEnum::Failed)
376 return net::ERR_FAILED;
377 if (error == Network::ErrorReasonEnum::Aborted)
378 return net::ERR_ABORTED;
379 if (error == Network::ErrorReasonEnum::TimedOut)
380 return net::ERR_TIMED_OUT;
381 if (error == Network::ErrorReasonEnum::AccessDenied)
382 return net::ERR_ACCESS_DENIED;
383 if (error == Network::ErrorReasonEnum::ConnectionClosed)
384 return net::ERR_CONNECTION_CLOSED;
385 if (error == Network::ErrorReasonEnum::ConnectionReset)
386 return net::ERR_CONNECTION_RESET;
387 if (error == Network::ErrorReasonEnum::ConnectionRefused)
388 return net::ERR_CONNECTION_REFUSED;
389 if (error == Network::ErrorReasonEnum::ConnectionAborted)
390 return net::ERR_CONNECTION_ABORTED;
391 if (error == Network::ErrorReasonEnum::ConnectionFailed)
392 return net::ERR_CONNECTION_FAILED;
393 if (error == Network::ErrorReasonEnum::NameNotResolved)
394 return net::ERR_NAME_NOT_RESOLVED;
395 if (error == Network::ErrorReasonEnum::InternetDisconnected)
396 return net::ERR_INTERNET_DISCONNECTED;
397 if (error == Network::ErrorReasonEnum::AddressUnreachable)
398 return net::ERR_ADDRESS_UNREACHABLE;
399 return net::ERR_FAILED;
400 }
401
349 double timeDelta(base::TimeTicks time, 402 double timeDelta(base::TimeTicks time,
350 base::TimeTicks start, 403 base::TimeTicks start,
351 double invalid_value = -1) { 404 double invalid_value = -1) {
352 return time.is_null() ? invalid_value : (time - start).InMillisecondsF(); 405 return time.is_null() ? invalid_value : (time - start).InMillisecondsF();
353 } 406 }
354 407
355 std::unique_ptr<Network::ResourceTiming> getTiming( 408 std::unique_ptr<Network::ResourceTiming> getTiming(
356 const net::LoadTimingInfo& load_timing) { 409 const net::LoadTimingInfo& load_timing) {
357 const base::TimeTicks kNullTicks; 410 const base::TimeTicks kNullTicks;
358 return Network::ResourceTiming::Create() 411 return Network::ResourceTiming::Create()
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 465 }
413 } 466 }
414 return protocol; 467 return protocol;
415 } 468 }
416 469
417 } // namespace 470 } // namespace
418 471
419 NetworkHandler::NetworkHandler() 472 NetworkHandler::NetworkHandler()
420 : DevToolsDomainHandler(Network::Metainfo::domainName), 473 : DevToolsDomainHandler(Network::Metainfo::domainName),
421 host_(nullptr), 474 host_(nullptr),
422 enabled_(false) { 475 enabled_(false),
423 } 476 interception_enabled_(false),
477 weak_factory_(this) {}
424 478
425 NetworkHandler::~NetworkHandler() { 479 NetworkHandler::~NetworkHandler() {
480 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.
426 } 481 }
427 482
428 // static 483 // static
429 std::vector<NetworkHandler*> NetworkHandler::ForAgentHost( 484 std::vector<NetworkHandler*> NetworkHandler::ForAgentHost(
430 DevToolsAgentHostImpl* host) { 485 DevToolsAgentHostImpl* host) {
431 return DevToolsSession::HandlersForAgentHost<NetworkHandler>( 486 return DevToolsSession::HandlersForAgentHost<NetworkHandler>(
432 host, Network::Metainfo::domainName); 487 host, Network::Metainfo::domainName);
433 } 488 }
434 489
435 void NetworkHandler::Wire(UberDispatcher* dispatcher) { 490 void NetworkHandler::Wire(UberDispatcher* dispatcher) {
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 request_id, 810 request_id,
756 base::TimeTicks::Now().ToInternalValue() / 811 base::TimeTicks::Now().ToInternalValue() /
757 static_cast<double>(base::Time::kMicrosecondsPerSecond), 812 static_cast<double>(base::Time::kMicrosecondsPerSecond),
758 Page::ResourceTypeEnum::Document, error_string, cancelled); 813 Page::ResourceTypeEnum::Document, error_string, cancelled);
759 } 814 }
760 815
761 std::string NetworkHandler::UserAgentOverride() const { 816 std::string NetworkHandler::UserAgentOverride() const {
762 return enabled_ ? user_agent_ : std::string(); 817 return enabled_ ? user_agent_ : std::string();
763 } 818 }
764 819
820 DispatchResponse NetworkHandler::EnableFetchInterception(bool enabled) {
821 if (interception_enabled_ == enabled)
822 return Response::OK(); // Nothing to do.
823
824 WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
825 if (!web_contents)
826 return Response::OK();
827
828 DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
829 DevToolsURLRequestInterceptor::FromBrowserContext(
830 web_contents->GetBrowserContext());
831 if (!devtools_url_request_interceptor)
832 return Response::OK();
833
834 if (enabled) {
835 BrowserThread::PostTask(
836 BrowserThread::IO, FROM_HERE,
837 base::BindOnce(
838 &DevToolsURLRequestInterceptor::State::StartInterceptingRequests,
839 devtools_url_request_interceptor->state().GetWeakPtr(),
840 web_contents, weak_factory_.GetWeakPtr()));
841 } else {
842 BrowserThread::PostTask(
843 BrowserThread::IO, FROM_HERE,
844 base::BindOnce(
845 &DevToolsURLRequestInterceptor::State::StopInterceptingRequests,
846 devtools_url_request_interceptor->state().GetWeakPtr(),
847 web_contents));
848 }
849 interception_enabled_ = enabled;
850 return Response::OK();
851 }
852
853 template <typename CallbackT>
854 void ProcessInterceptionCommandResultOnIoThread(
855 std::unique_ptr<CallbackT> callback,
856 const DevToolsURLRequestInterceptor::CommandStatus& result) {
857 switch (result) {
858 case DevToolsURLRequestInterceptor::CommandStatus::OK:
859 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
860 base::BindOnce(&CallbackT::sendSuccess,
861 base::Owned(callback.release())));
862 break;
863 case DevToolsURLRequestInterceptor::CommandStatus::UnknownInterceptionId:
864 BrowserThread::PostTask(
865 BrowserThread::UI, FROM_HERE,
866 base::BindOnce(&CallbackT::sendFailure,
867 base::Owned(callback.release()),
868 Response::InvalidParams("Invalid interceptId.")));
869 break;
870 case DevToolsURLRequestInterceptor::CommandStatus::CommandAlreadyProcessed:
871 BrowserThread::PostTask(
872 BrowserThread::UI, FROM_HERE,
873 base::BindOnce(
874 &CallbackT::sendFailure, base::Owned(callback.release()),
875 Response::InvalidParams("Response already processed.")));
876 break;
877 }
878 }
879
880 void NetworkHandler::AllowRequest(
881 const std::string& intercept_id,
882 std::unique_ptr<AllowRequestCallback> callback) {
883 DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
884 DevToolsURLRequestInterceptor::FromBrowserContext(
885 WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
886 if (!devtools_url_request_interceptor) {
887 callback->sendFailure(Response::InternalError());
888 return;
889 }
890
891 BrowserThread::PostTask(
892 BrowserThread::IO, FROM_HERE,
893 base::BindOnce(
894 &DevToolsURLRequestInterceptor::State::AllowRequest,
895 devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
896 base::BindOnce(
897 ProcessInterceptionCommandResultOnIoThread<AllowRequestCallback>,
898 base::Passed(std::move(callback)))));
899 }
900
901 void NetworkHandler::BlockRequest(
902 const std::string& intercept_id,
903 const std::string& error_reason,
904 std::unique_ptr<BlockRequestCallback> callback) {
905 DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
906 DevToolsURLRequestInterceptor::FromBrowserContext(
907 WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
908 if (!devtools_url_request_interceptor) {
909 callback->sendFailure(Response::InternalError());
910 return;
911 }
912
913 BrowserThread::PostTask(
914 BrowserThread::IO, FROM_HERE,
915 base::BindOnce(
916 &DevToolsURLRequestInterceptor::State::BlockRequest,
917 devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
918 NetErrorFromString(error_reason),
919 base::BindOnce(
920 ProcessInterceptionCommandResultOnIoThread<BlockRequestCallback>,
921 base::Passed(std::move(callback)))));
922 }
923
924 void NetworkHandler::ModifyRequest(
925 const std::string& intercept_id,
926 Maybe<std::string> url,
927 Maybe<std::string> method,
928 Maybe<std::string> post_data,
929 Maybe<protocol::Network::Headers> headers,
930 std::unique_ptr<ModifyRequestCallback> callback) {
931 DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
932 DevToolsURLRequestInterceptor::FromBrowserContext(
933 WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
934 if (!devtools_url_request_interceptor) {
935 callback->sendFailure(Response::InternalError());
936 return;
937 }
938
939 BrowserThread::PostTask(
940 BrowserThread::IO, FROM_HERE,
941 base::BindOnce(
942 &DevToolsURLRequestInterceptor::State::ModifyRequest,
943 devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
944 base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
945 std::move(url), std::move(method), std::move(post_data),
946 std::move(headers)),
947 base::BindOnce(
948 ProcessInterceptionCommandResultOnIoThread<ModifyRequestCallback>,
949 base::Passed(std::move(callback)))));
950 }
951
952 void NetworkHandler::MockResponse(
953 const std::string& intercept_id,
954 const std::string& raw_response,
955 std::unique_ptr<MockResponseCallback> callback) {
956 DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
957 DevToolsURLRequestInterceptor::FromBrowserContext(
958 WebContents::FromRenderFrameHost(host_)->GetBrowserContext());
959 if (!devtools_url_request_interceptor) {
960 callback->sendFailure(Response::InternalError());
961 return;
962 }
963
964 BrowserThread::PostTask(
965 BrowserThread::IO, FROM_HERE,
966 base::BindOnce(
967 &DevToolsURLRequestInterceptor::State::MockResponse,
968 devtools_url_request_interceptor->state().GetWeakPtr(), intercept_id,
969 raw_response,
970 base::BindOnce(
971 ProcessInterceptionCommandResultOnIoThread<MockResponseCallback>,
972 base::Passed(std::move(callback)))));
973 }
974
975 // static
976 std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest(
977 const net::URLRequest* request) {
978 std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
979 for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers());
980 it.GetNext();) {
981 headers_dict->setString(it.name(), it.value());
982 }
983 // TODO(alexclarke): Support post data
984 return Network::Request::Create()
985 .SetUrl(request->url().spec())
986 .SetMethod(request->method())
987 .SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
988 .SetInitialPriority(resourcePriority(request->priority()))
989 .SetReferrerPolicy(referrerPolicy(request->referrer_policy()))
990 .Build();
991 }
992
765 } // namespace protocol 993 } // namespace protocol
766 } // namespace content 994 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698