Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |