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 |