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/base64.h" | |
| 10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 11 #include "base/containers/hash_tables.h" | 12 #include "base/containers/hash_tables.h" |
| 12 #include "base/process/process_handle.h" | 13 #include "base/process/process_handle.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "content/browser/devtools/devtools_session.h" | 17 #include "content/browser/devtools/devtools_session.h" |
| 18 #include "content/browser/devtools/devtools_url_interceptor_request_job.h" | |
| 17 #include "content/browser/devtools/protocol/page.h" | 19 #include "content/browser/devtools/protocol/page.h" |
| 18 #include "content/browser/devtools/protocol/security.h" | 20 #include "content/browser/devtools/protocol/security.h" |
| 19 #include "content/browser/frame_host/frame_tree_node.h" | 21 #include "content/browser/frame_host/frame_tree_node.h" |
| 20 #include "content/browser/frame_host/render_frame_host_impl.h" | 22 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 21 #include "content/common/navigation_params.h" | 23 #include "content/common/navigation_params.h" |
| 22 #include "content/common/resource_request.h" | 24 #include "content/common/resource_request.h" |
| 23 #include "content/common/resource_request_completion_status.h" | 25 #include "content/common/resource_request_completion_status.h" |
| 24 #include "content/public/browser/browser_context.h" | 26 #include "content/public/browser/browser_context.h" |
| 25 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/browser/browsing_data_remover.h" | 28 #include "content/public/browser/browsing_data_remover.h" |
| 27 #include "content/public/browser/content_browser_client.h" | 29 #include "content/public/browser/content_browser_client.h" |
| 28 #include "content/public/browser/render_process_host.h" | 30 #include "content/public/browser/render_process_host.h" |
| 29 #include "content/public/browser/resource_context.h" | 31 #include "content/public/browser/resource_context.h" |
| 30 #include "content/public/browser/site_instance.h" | 32 #include "content/public/browser/site_instance.h" |
| 31 #include "content/public/browser/storage_partition.h" | 33 #include "content/public/browser/storage_partition.h" |
| 32 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
| 33 #include "content/public/common/content_client.h" | 35 #include "content/public/common/content_client.h" |
| 34 #include "content/public/common/content_switches.h" | 36 #include "content/public/common/content_switches.h" |
| 35 #include "content/public/common/resource_devtools_info.h" | 37 #include "content/public/common/resource_devtools_info.h" |
| 36 #include "content/public/common/resource_response.h" | 38 #include "content/public/common/resource_response.h" |
| 37 #include "net/base/net_errors.h" | 39 #include "net/base/net_errors.h" |
| 40 #include "net/base/upload_bytes_element_reader.h" | |
| 38 #include "net/cookies/cookie_store.h" | 41 #include "net/cookies/cookie_store.h" |
| 39 #include "net/http/http_response_headers.h" | 42 #include "net/http/http_response_headers.h" |
| 40 #include "net/url_request/url_request_context.h" | 43 #include "net/url_request/url_request_context.h" |
| 41 #include "net/url_request/url_request_context_getter.h" | 44 #include "net/url_request/url_request_context_getter.h" |
| 42 | 45 |
| 43 namespace content { | 46 namespace content { |
| 44 namespace protocol { | 47 namespace protocol { |
| 45 namespace { | 48 namespace { |
| 46 | 49 |
| 47 using ProtocolCookieArray = Array<Network::Cookie>; | 50 using ProtocolCookieArray = Array<Network::Cookie>; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 case blink::kWebReferrerPolicyOriginWhenCrossOrigin: | 333 case blink::kWebReferrerPolicyOriginWhenCrossOrigin: |
| 331 return Network::Request::ReferrerPolicyEnum::OriginWhenCrossOrigin; | 334 return Network::Request::ReferrerPolicyEnum::OriginWhenCrossOrigin; |
| 332 case blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin: | 335 case blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin: |
| 333 return Network::Request::ReferrerPolicyEnum:: | 336 return Network::Request::ReferrerPolicyEnum:: |
| 334 NoReferrerWhenDowngradeOriginWhenCrossOrigin; | 337 NoReferrerWhenDowngradeOriginWhenCrossOrigin; |
| 335 } | 338 } |
| 336 NOTREACHED(); | 339 NOTREACHED(); |
| 337 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; | 340 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; |
| 338 } | 341 } |
| 339 | 342 |
| 343 String referrerPolicy(net::URLRequest::ReferrerPolicy referrer_policy) { | |
| 344 switch (referrer_policy) { | |
| 345 case net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE: | |
| 346 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; | |
| 347 case net::URLRequest:: | |
| 348 REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN: | |
| 349 return Network::Request::ReferrerPolicyEnum:: | |
| 350 NoReferrerWhenDowngradeOriginWhenCrossOrigin; | |
| 351 case net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: | |
| 352 return Network::Request::ReferrerPolicyEnum:: | |
| 353 NoReferrerWhenDowngradeOriginWhenCrossOrigin; | |
| 354 case net::URLRequest::NEVER_CLEAR_REFERRER: | |
| 355 return Network::Request::ReferrerPolicyEnum::Origin; | |
| 356 case net::URLRequest::ORIGIN: | |
| 357 return Network::Request::ReferrerPolicyEnum::Origin; | |
| 358 case net::URLRequest::NO_REFERRER: | |
| 359 return Network::Request::ReferrerPolicyEnum::NoReferrer; | |
| 360 default: | |
| 361 break; | |
| 362 } | |
| 363 NOTREACHED(); | |
| 364 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; | |
| 365 } | |
| 366 | |
| 340 String securityState(const GURL& url, const net::CertStatus& cert_status) { | 367 String securityState(const GURL& url, const net::CertStatus& cert_status) { |
| 341 if (!url.SchemeIsCryptographic()) | 368 if (!url.SchemeIsCryptographic()) |
| 342 return Security::SecurityStateEnum::Neutral; | 369 return Security::SecurityStateEnum::Neutral; |
| 343 if (net::IsCertStatusError(cert_status) && | 370 if (net::IsCertStatusError(cert_status) && |
| 344 !net::IsCertStatusMinorError(cert_status)) { | 371 !net::IsCertStatusMinorError(cert_status)) { |
| 345 return Security::SecurityStateEnum::Insecure; | 372 return Security::SecurityStateEnum::Insecure; |
| 346 } | 373 } |
| 347 return Security::SecurityStateEnum::Secure; | 374 return Security::SecurityStateEnum::Secure; |
| 348 } | 375 } |
| 349 | 376 |
| 377 net::Error NetErrorFromString(const std::string& error) { | |
| 378 if (error == Network::ErrorReasonEnum::Failed) | |
| 379 return net::ERR_FAILED; | |
| 380 if (error == Network::ErrorReasonEnum::Aborted) | |
| 381 return net::ERR_ABORTED; | |
| 382 if (error == Network::ErrorReasonEnum::TimedOut) | |
| 383 return net::ERR_TIMED_OUT; | |
| 384 if (error == Network::ErrorReasonEnum::AccessDenied) | |
| 385 return net::ERR_ACCESS_DENIED; | |
| 386 if (error == Network::ErrorReasonEnum::ConnectionClosed) | |
| 387 return net::ERR_CONNECTION_CLOSED; | |
| 388 if (error == Network::ErrorReasonEnum::ConnectionReset) | |
| 389 return net::ERR_CONNECTION_RESET; | |
| 390 if (error == Network::ErrorReasonEnum::ConnectionRefused) | |
| 391 return net::ERR_CONNECTION_REFUSED; | |
| 392 if (error == Network::ErrorReasonEnum::ConnectionAborted) | |
| 393 return net::ERR_CONNECTION_ABORTED; | |
| 394 if (error == Network::ErrorReasonEnum::ConnectionFailed) | |
| 395 return net::ERR_CONNECTION_FAILED; | |
| 396 if (error == Network::ErrorReasonEnum::NameNotResolved) | |
| 397 return net::ERR_NAME_NOT_RESOLVED; | |
| 398 if (error == Network::ErrorReasonEnum::InternetDisconnected) | |
| 399 return net::ERR_INTERNET_DISCONNECTED; | |
| 400 if (error == Network::ErrorReasonEnum::AddressUnreachable) | |
| 401 return net::ERR_ADDRESS_UNREACHABLE; | |
| 402 return net::ERR_FAILED; | |
| 403 } | |
| 404 | |
| 350 double timeDelta(base::TimeTicks time, | 405 double timeDelta(base::TimeTicks time, |
| 351 base::TimeTicks start, | 406 base::TimeTicks start, |
| 352 double invalid_value = -1) { | 407 double invalid_value = -1) { |
| 353 return time.is_null() ? invalid_value : (time - start).InMillisecondsF(); | 408 return time.is_null() ? invalid_value : (time - start).InMillisecondsF(); |
| 354 } | 409 } |
| 355 | 410 |
| 356 std::unique_ptr<Network::ResourceTiming> getTiming( | 411 std::unique_ptr<Network::ResourceTiming> getTiming( |
| 357 const net::LoadTimingInfo& load_timing) { | 412 const net::LoadTimingInfo& load_timing) { |
| 358 const base::TimeTicks kNullTicks; | 413 const base::TimeTicks kNullTicks; |
| 359 return Network::ResourceTiming::Create() | 414 return Network::ResourceTiming::Create() |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 } | 468 } |
| 414 } | 469 } |
| 415 return protocol; | 470 return protocol; |
| 416 } | 471 } |
| 417 | 472 |
| 418 } // namespace | 473 } // namespace |
| 419 | 474 |
| 420 NetworkHandler::NetworkHandler() | 475 NetworkHandler::NetworkHandler() |
| 421 : DevToolsDomainHandler(Network::Metainfo::domainName), | 476 : DevToolsDomainHandler(Network::Metainfo::domainName), |
| 422 host_(nullptr), | 477 host_(nullptr), |
| 423 enabled_(false) { | 478 enabled_(false), |
| 424 } | 479 interception_enabled_(false), |
| 480 weak_factory_(this) {} | |
| 425 | 481 |
| 426 NetworkHandler::~NetworkHandler() { | 482 NetworkHandler::~NetworkHandler() { |
| 427 } | 483 } |
| 428 | 484 |
| 429 // static | 485 // static |
| 430 std::vector<NetworkHandler*> NetworkHandler::ForAgentHost( | 486 std::vector<NetworkHandler*> NetworkHandler::ForAgentHost( |
| 431 DevToolsAgentHostImpl* host) { | 487 DevToolsAgentHostImpl* host) { |
| 432 return DevToolsSession::HandlersForAgentHost<NetworkHandler>( | 488 return DevToolsSession::HandlersForAgentHost<NetworkHandler>( |
| 433 host, Network::Metainfo::domainName); | 489 host, Network::Metainfo::domainName); |
| 434 } | 490 } |
| 435 | 491 |
| 436 void NetworkHandler::Wire(UberDispatcher* dispatcher) { | 492 void NetworkHandler::Wire(UberDispatcher* dispatcher) { |
| 437 frontend_.reset(new Network::Frontend(dispatcher->channel())); | 493 frontend_.reset(new Network::Frontend(dispatcher->channel())); |
| 438 Network::Dispatcher::wire(dispatcher, this); | 494 Network::Dispatcher::wire(dispatcher, this); |
| 439 } | 495 } |
| 440 | 496 |
| 441 void NetworkHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { | 497 void NetworkHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { |
| 442 host_ = host; | 498 host_ = host; |
| 443 } | 499 } |
| 444 | 500 |
| 445 Response NetworkHandler::Enable(Maybe<int> max_total_size, | 501 Response NetworkHandler::Enable(Maybe<int> max_total_size, |
| 446 Maybe<int> max_resource_size) { | 502 Maybe<int> max_resource_size) { |
| 447 enabled_ = true; | 503 enabled_ = true; |
| 448 return Response::FallThrough(); | 504 return Response::FallThrough(); |
| 449 } | 505 } |
| 450 | 506 |
| 451 Response NetworkHandler::Disable() { | 507 Response NetworkHandler::Disable() { |
| 452 enabled_ = false; | 508 enabled_ = false; |
| 453 user_agent_ = std::string(); | 509 user_agent_ = std::string(); |
| 510 EnableFetchInterception(false); | |
| 454 return Response::FallThrough(); | 511 return Response::FallThrough(); |
| 455 } | 512 } |
| 456 | 513 |
| 457 Response NetworkHandler::ClearBrowserCache() { | 514 Response NetworkHandler::ClearBrowserCache() { |
| 458 if (host_) { | 515 if (host_) { |
| 459 content::BrowsingDataRemover* remover = | 516 content::BrowsingDataRemover* remover = |
| 460 content::BrowserContext::GetBrowsingDataRemover( | 517 content::BrowserContext::GetBrowsingDataRemover( |
| 461 host_->GetSiteInstance()->GetProcess()->GetBrowserContext()); | 518 host_->GetSiteInstance()->GetProcess()->GetBrowserContext()); |
| 462 remover->Remove(base::Time(), base::Time::Max(), | 519 remover->Remove(base::Time(), base::Time::Max(), |
| 463 content::BrowsingDataRemover::DATA_TYPE_CACHE, | 520 content::BrowsingDataRemover::DATA_TYPE_CACHE, |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 763 request_id, | 820 request_id, |
| 764 base::TimeTicks::Now().ToInternalValue() / | 821 base::TimeTicks::Now().ToInternalValue() / |
| 765 static_cast<double>(base::Time::kMicrosecondsPerSecond), | 822 static_cast<double>(base::Time::kMicrosecondsPerSecond), |
| 766 Page::ResourceTypeEnum::Document, error_string, cancelled); | 823 Page::ResourceTypeEnum::Document, error_string, cancelled); |
| 767 } | 824 } |
| 768 | 825 |
| 769 std::string NetworkHandler::UserAgentOverride() const { | 826 std::string NetworkHandler::UserAgentOverride() const { |
| 770 return enabled_ ? user_agent_ : std::string(); | 827 return enabled_ ? user_agent_ : std::string(); |
| 771 } | 828 } |
| 772 | 829 |
| 830 DispatchResponse NetworkHandler::EnableFetchInterception(bool enabled) { | |
| 831 if (interception_enabled_ == enabled) | |
| 832 return Response::OK(); // Nothing to do. | |
| 833 | |
| 834 WebContents* web_contents = WebContents::FromRenderFrameHost(host_); | |
| 835 if (!web_contents) | |
| 836 return Response::OK(); | |
| 837 | |
| 838 DevToolsURLRequestInterceptor* devtools_url_request_interceptor = | |
| 839 DevToolsURLRequestInterceptor::FromBrowserContext( | |
| 840 web_contents->GetBrowserContext()); | |
| 841 if (!devtools_url_request_interceptor) | |
| 842 return Response::OK(); | |
| 843 | |
| 844 if (enabled) { | |
| 845 BrowserThread::PostTask( | |
| 846 BrowserThread::IO, FROM_HERE, | |
| 847 base::BindOnce( | |
| 848 &DevToolsURLRequestInterceptor::State::StartInterceptingRequests, | |
| 849 devtools_url_request_interceptor->state().GetWeakPtr(), | |
|
dgozman
2017/05/25 21:29:36
It's prohibited to dereference weak pointer on the
alex clarke (OOO till 29th)
2017/05/26 19:37:03
An alternative is we can make the state ref counte
| |
| 850 web_contents, weak_factory_.GetWeakPtr())); | |
| 851 } else { | |
| 852 BrowserThread::PostTask( | |
| 853 BrowserThread::IO, FROM_HERE, | |
| 854 base::BindOnce( | |
| 855 &DevToolsURLRequestInterceptor::State::StopInterceptingRequests, | |
| 856 devtools_url_request_interceptor->state().GetWeakPtr(), | |
| 857 web_contents)); | |
| 858 } | |
| 859 interception_enabled_ = enabled; | |
| 860 return Response::OK(); | |
| 861 } | |
| 862 | |
| 863 namespace { | |
| 864 void ProcessContinueRequestResultOnIoThread( | |
| 865 std::unique_ptr<NetworkHandler::ContinueRequestCallback> callback, | |
| 866 const DevToolsURLRequestInterceptor::CommandStatus& result) { | |
| 867 switch (result) { | |
| 868 case DevToolsURLRequestInterceptor::CommandStatus::OK: | |
| 869 BrowserThread::PostTask( | |
| 870 BrowserThread::UI, FROM_HERE, | |
| 871 base::BindOnce(&NetworkHandler::ContinueRequestCallback::sendSuccess, | |
| 872 base::Owned(callback.release()))); | |
| 873 break; | |
| 874 case DevToolsURLRequestInterceptor::CommandStatus::UnknownInterceptionId: | |
| 875 BrowserThread::PostTask( | |
| 876 BrowserThread::UI, FROM_HERE, | |
| 877 base::BindOnce(&NetworkHandler::ContinueRequestCallback::sendFailure, | |
| 878 base::Owned(callback.release()), | |
| 879 Response::InvalidParams("Invalid InterceptionId."))); | |
| 880 break; | |
| 881 case DevToolsURLRequestInterceptor::CommandStatus::CommandAlreadyProcessed: | |
| 882 BrowserThread::PostTask( | |
| 883 BrowserThread::UI, FROM_HERE, | |
| 884 base::BindOnce( | |
| 885 &NetworkHandler::ContinueRequestCallback::sendFailure, | |
| 886 base::Owned(callback.release()), | |
| 887 Response::InvalidParams("Response already processed."))); | |
| 888 break; | |
| 889 } | |
| 890 } | |
| 891 | |
| 892 bool GetPostData(const net::URLRequest* request, std::string* post_data) { | |
| 893 if (!request->has_upload()) | |
| 894 return false; | |
| 895 | |
| 896 const net::UploadDataStream* stream = request->get_upload(); | |
| 897 if (!stream->GetElementReaders()) | |
| 898 return false; | |
| 899 | |
| 900 if (stream->GetElementReaders()->size() == 0) | |
| 901 return false; | |
| 902 | |
| 903 DCHECK_EQ(1u, stream->GetElementReaders()->size()); | |
|
dgozman
2017/05/25 21:29:36
Is this guaranteed by net?
alex clarke (OOO till 29th)
2017/05/26 19:37:03
Looks like no although this is the common case. I
dgozman
2017/05/30 21:44:27
IIUC, std::string += operator is smart since it us
alex clarke (OOO till 29th)
2017/05/31 15:52:02
Mmm OK that should help. I'm just worried about p
| |
| 904 const net::UploadBytesElementReader* reader = | |
| 905 (*stream->GetElementReaders())[0]->AsBytesReader(); | |
| 906 if (!reader) | |
| 907 return false; | |
| 908 *post_data = std::string(reader->bytes(), reader->length()); | |
|
dgozman
2017/05/25 21:29:36
I think we'll need to base64-encode this? Let's ha
alex clarke (OOO till 29th)
2017/05/26 19:37:03
For reference it's simple to base 64 encode that h
| |
| 909 return true; | |
| 910 } | |
| 911 } // namespace | |
| 912 | |
| 913 void NetworkHandler::ContinueRequest( | |
| 914 const std::string& interception_id, | |
| 915 Maybe<std::string> error_reason, | |
| 916 Maybe<std::string> base64_raw_response, | |
| 917 Maybe<std::string> url, | |
| 918 Maybe<std::string> method, | |
| 919 Maybe<std::string> post_data, | |
| 920 Maybe<protocol::Network::Headers> headers, | |
| 921 std::unique_ptr<ContinueRequestCallback> callback) { | |
| 922 DevToolsURLRequestInterceptor* devtools_url_request_interceptor = | |
| 923 DevToolsURLRequestInterceptor::FromBrowserContext( | |
| 924 WebContents::FromRenderFrameHost(host_)->GetBrowserContext()); | |
| 925 if (!devtools_url_request_interceptor) { | |
| 926 callback->sendFailure(Response::InternalError()); | |
| 927 return; | |
| 928 } | |
| 929 | |
| 930 base::Optional<net::Error> error; | |
| 931 if (error_reason.isJust()) | |
| 932 error = NetErrorFromString(error_reason.fromJust()); | |
| 933 | |
| 934 base::Optional<std::string> raw_response; | |
| 935 if (base64_raw_response.isJust()) { | |
| 936 std::string decoded; | |
| 937 if (!base::Base64Decode(base64_raw_response.fromJust(), &decoded)) { | |
| 938 callback->sendFailure(Response::InvalidParams("Invalid rawResponse.")); | |
| 939 return; | |
| 940 } | |
| 941 raw_response = decoded; | |
| 942 } | |
| 943 | |
| 944 BrowserThread::PostTask( | |
| 945 BrowserThread::IO, FROM_HERE, | |
| 946 base::BindOnce( | |
| 947 &DevToolsURLRequestInterceptor::State::ContinueRequest, | |
| 948 devtools_url_request_interceptor->state().GetWeakPtr(), | |
|
dgozman
2017/05/25 21:29:36
Similar thing here.
alex clarke (OOO till 29th)
2017/05/26 19:37:03
Done.
| |
| 949 interception_id, | |
| 950 base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>( | |
| 951 std::move(error), std::move(raw_response), std::move(url), | |
| 952 std::move(method), std::move(post_data), std::move(headers)), | |
| 953 base::BindOnce(ProcessContinueRequestResultOnIoThread, | |
| 954 base::Passed(std::move(callback))))); | |
| 955 } | |
| 956 | |
| 957 // static | |
| 958 std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest( | |
| 959 const net::URLRequest* request) { | |
| 960 std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); | |
| 961 for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers()); | |
| 962 it.GetNext();) { | |
| 963 headers_dict->setString(it.name(), it.value()); | |
| 964 } | |
| 965 std::unique_ptr<protocol::Network::Request> request_object = | |
| 966 Network::Request::Create() | |
| 967 .SetUrl(request->url().spec()) | |
| 968 .SetMethod(request->method()) | |
| 969 .SetHeaders(Object::fromValue(headers_dict.get(), nullptr)) | |
| 970 .SetInitialPriority(resourcePriority(request->priority())) | |
| 971 .SetReferrerPolicy(referrerPolicy(request->referrer_policy())) | |
| 972 .Build(); | |
| 973 std::string post_data; | |
| 974 if (GetPostData(request, &post_data)) | |
| 975 request_object->SetPostData(std::move(post_data)); | |
| 976 return request_object; | |
| 977 } | |
| 978 | |
| 773 } // namespace protocol | 979 } // namespace protocol |
| 774 } // namespace content | 980 } // namespace content |
| OLD | NEW |