| 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/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
| 12 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 12 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 13 #include "content/browser/devtools/devtools_session.h" | 15 #include "content/browser/devtools/devtools_session.h" |
| 16 #include "content/browser/devtools/protocol/page.h" |
| 17 #include "content/browser/devtools/protocol/security.h" |
| 14 #include "content/browser/frame_host/frame_tree_node.h" | 18 #include "content/browser/frame_host/frame_tree_node.h" |
| 15 #include "content/browser/frame_host/render_frame_host_impl.h" | 19 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 20 #include "content/common/resource_request.h" |
| 21 #include "content/common/resource_request_completion_status.h" |
| 16 #include "content/public/browser/browser_context.h" | 22 #include "content/public/browser/browser_context.h" |
| 17 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/content_browser_client.h" | 24 #include "content/public/browser/content_browser_client.h" |
| 19 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
| 20 #include "content/public/browser/resource_context.h" | 26 #include "content/public/browser/resource_context.h" |
| 21 #include "content/public/browser/site_instance.h" | 27 #include "content/public/browser/site_instance.h" |
| 22 #include "content/public/browser/storage_partition.h" | 28 #include "content/public/browser/storage_partition.h" |
| 23 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/common/content_client.h" | 30 #include "content/public/common/content_client.h" |
| 31 #include "content/public/common/content_switches.h" |
| 32 #include "content/public/common/resource_devtools_info.h" |
| 33 #include "content/public/common/resource_response.h" |
| 25 #include "net/cookies/cookie_store.h" | 34 #include "net/cookies/cookie_store.h" |
| 35 #include "net/http/http_response_headers.h" |
| 26 #include "net/url_request/url_request_context.h" | 36 #include "net/url_request/url_request_context.h" |
| 27 #include "net/url_request/url_request_context_getter.h" | 37 #include "net/url_request/url_request_context_getter.h" |
| 28 | 38 |
| 29 namespace content { | 39 namespace content { |
| 30 namespace protocol { | 40 namespace protocol { |
| 31 namespace { | 41 namespace { |
| 32 | 42 |
| 33 using ProtocolCookieArray = protocol::Array<Network::Cookie>; | 43 using ProtocolCookieArray = Array<Network::Cookie>; |
| 34 using GetCookiesCallback = protocol::Network::Backend::GetCookiesCallback; | 44 using GetCookiesCallback = Network::Backend::GetCookiesCallback; |
| 35 using GetAllCookiesCallback = protocol::Network::Backend::GetAllCookiesCallback; | 45 using GetAllCookiesCallback = Network::Backend::GetAllCookiesCallback; |
| 36 using SetCookieCallback = protocol::Network::Backend::SetCookieCallback; | 46 using SetCookieCallback = Network::Backend::SetCookieCallback; |
| 37 using DeleteCookieCallback = protocol::Network::Backend::DeleteCookieCallback; | 47 using DeleteCookieCallback = Network::Backend::DeleteCookieCallback; |
| 38 | 48 |
| 39 net::URLRequestContext* GetRequestContextOnIO( | 49 net::URLRequestContext* GetRequestContextOnIO( |
| 40 ResourceContext* resource_context, | 50 ResourceContext* resource_context, |
| 41 net::URLRequestContextGetter* context_getter, | 51 net::URLRequestContextGetter* context_getter, |
| 42 const GURL& url) { | 52 const GURL& url) { |
| 43 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 53 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 44 net::URLRequestContext* context = | 54 net::URLRequestContext* context = |
| 45 GetContentClient()->browser()->OverrideRequestContextForURL( | 55 GetContentClient()->browser()->OverrideRequestContextForURL( |
| 46 url, resource_context); | 56 url, resource_context); |
| 47 if (!context) | 57 if (!context) |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 expires, | 240 expires, |
| 231 base::Time(), | 241 base::Time(), |
| 232 secure, | 242 secure, |
| 233 http_only, | 243 http_only, |
| 234 same_site, | 244 same_site, |
| 235 are_experimental_cookie_features_enabled, | 245 are_experimental_cookie_features_enabled, |
| 236 net::COOKIE_PRIORITY_DEFAULT, | 246 net::COOKIE_PRIORITY_DEFAULT, |
| 237 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback)))); | 247 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback)))); |
| 238 } | 248 } |
| 239 | 249 |
| 240 std::vector<GURL> ComputeCookieURLs( | 250 std::vector<GURL> ComputeCookieURLs(RenderFrameHostImpl* frame_host, |
| 241 RenderFrameHostImpl* frame_host, | 251 Maybe<Array<String>>& protocol_urls) { |
| 242 Maybe<protocol::Array<String>>& protocol_urls) { | |
| 243 std::vector<GURL> urls; | 252 std::vector<GURL> urls; |
| 244 | 253 |
| 245 if (protocol_urls.isJust()) { | 254 if (protocol_urls.isJust()) { |
| 246 std::unique_ptr<protocol::Array<std::string>> actual_urls = | 255 std::unique_ptr<Array<std::string>> actual_urls = protocol_urls.takeJust(); |
| 247 protocol_urls.takeJust(); | |
| 248 | 256 |
| 249 for (size_t i = 0; i < actual_urls->length(); i++) | 257 for (size_t i = 0; i < actual_urls->length(); i++) |
| 250 urls.push_back(GURL(actual_urls->get(i))); | 258 urls.push_back(GURL(actual_urls->get(i))); |
| 251 } else { | 259 } else { |
| 252 std::queue<FrameTreeNode*> queue; | 260 std::queue<FrameTreeNode*> queue; |
| 253 queue.push(frame_host->frame_tree_node()); | 261 queue.push(frame_host->frame_tree_node()); |
| 254 while (!queue.empty()) { | 262 while (!queue.empty()) { |
| 255 FrameTreeNode* node = queue.front(); | 263 FrameTreeNode* node = queue.front(); |
| 256 queue.pop(); | 264 queue.pop(); |
| 257 | 265 |
| 258 urls.push_back(node->current_url()); | 266 urls.push_back(node->current_url()); |
| 259 for (size_t i = 0; i < node->child_count(); ++i) | 267 for (size_t i = 0; i < node->child_count(); ++i) |
| 260 queue.push(node->child_at(i)); | 268 queue.push(node->child_at(i)); |
| 261 } | 269 } |
| 262 } | 270 } |
| 263 | 271 |
| 264 return urls; | 272 return urls; |
| 265 } | 273 } |
| 266 | 274 |
| 275 String resourcePriority(net::RequestPriority priority) { |
| 276 switch (priority) { |
| 277 case net::MINIMUM_PRIORITY: |
| 278 case net::IDLE: |
| 279 return Network::ResourcePriorityEnum::VeryLow; |
| 280 case net::LOWEST: |
| 281 return Network::ResourcePriorityEnum::Low; |
| 282 case net::LOW: |
| 283 return Network::ResourcePriorityEnum::Medium; |
| 284 case net::MEDIUM: |
| 285 return Network::ResourcePriorityEnum::High; |
| 286 case net::HIGHEST: |
| 287 return Network::ResourcePriorityEnum::VeryHigh; |
| 288 } |
| 289 NOTREACHED(); |
| 290 return Network::ResourcePriorityEnum::Medium; |
| 291 } |
| 292 |
| 293 String referrerPolicy(blink::WebReferrerPolicy referrer_policy) { |
| 294 switch (referrer_policy) { |
| 295 case blink::WebReferrerPolicyAlways: |
| 296 return Network::Request::ReferrerPolicyEnum::UnsafeUrl; |
| 297 case blink::WebReferrerPolicyDefault: |
| 298 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 299 switches::kReducedReferrerGranularity)) { |
| 300 return Network::Request::ReferrerPolicyEnum:: |
| 301 NoReferrerWhenDowngradeOriginWhenCrossOrigin; |
| 302 } else { |
| 303 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; |
| 304 } |
| 305 case blink::WebReferrerPolicyNoReferrerWhenDowngrade: |
| 306 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; |
| 307 case blink::WebReferrerPolicyNever: |
| 308 return Network::Request::ReferrerPolicyEnum::NoReferrer; |
| 309 case blink::WebReferrerPolicyOrigin: |
| 310 return Network::Request::ReferrerPolicyEnum::Origin; |
| 311 case blink::WebReferrerPolicyOriginWhenCrossOrigin: |
| 312 return Network::Request::ReferrerPolicyEnum::OriginWhenCrossOrigin; |
| 313 case blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin: |
| 314 return Network::Request::ReferrerPolicyEnum:: |
| 315 NoReferrerWhenDowngradeOriginWhenCrossOrigin; |
| 316 } |
| 317 NOTREACHED(); |
| 318 return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; |
| 319 } |
| 320 |
| 321 String securityState(const GURL& url, const net::CertStatus& cert_status) { |
| 322 if (!url.SchemeIsCryptographic()) |
| 323 return Security::SecurityStateEnum::Neutral; |
| 324 if (net::IsCertStatusError(cert_status) && |
| 325 !net::IsCertStatusMinorError(cert_status)) { |
| 326 return Security::SecurityStateEnum::Insecure; |
| 327 } |
| 328 return Security::SecurityStateEnum::Secure; |
| 329 } |
| 330 |
| 331 double timeDelta(base::TimeTicks time, |
| 332 base::TimeTicks start, |
| 333 double invalid_value = -1) { |
| 334 return time.is_null() ? invalid_value : (time - start).InMillisecondsF(); |
| 335 } |
| 336 |
| 337 std::unique_ptr<Network::ResourceTiming> getTiming( |
| 338 const net::LoadTimingInfo& load_timing) { |
| 339 const base::TimeTicks kNullTicks; |
| 340 return Network::ResourceTiming::Create() |
| 341 .SetRequestTime((load_timing.request_start - kNullTicks).InSecondsF()) |
| 342 .SetProxyStart( |
| 343 timeDelta(load_timing.proxy_resolve_start, load_timing.request_start)) |
| 344 .SetProxyEnd( |
| 345 timeDelta(load_timing.proxy_resolve_end, load_timing.request_start)) |
| 346 .SetDnsStart(timeDelta(load_timing.connect_timing.dns_start, |
| 347 load_timing.request_start)) |
| 348 .SetDnsEnd(timeDelta(load_timing.connect_timing.dns_end, |
| 349 load_timing.request_start)) |
| 350 .SetConnectStart(timeDelta(load_timing.connect_timing.connect_start, |
| 351 load_timing.request_start)) |
| 352 .SetConnectEnd(timeDelta(load_timing.connect_timing.connect_end, |
| 353 load_timing.request_start)) |
| 354 .SetSslStart(timeDelta(load_timing.connect_timing.ssl_start, |
| 355 load_timing.request_start)) |
| 356 .SetSslEnd(timeDelta(load_timing.connect_timing.ssl_end, |
| 357 load_timing.request_start)) |
| 358 .SetWorkerStart(-1) |
| 359 .SetWorkerReady(-1) |
| 360 .SetSendStart( |
| 361 timeDelta(load_timing.send_start, load_timing.request_start)) |
| 362 .SetSendEnd(timeDelta(load_timing.send_end, load_timing.request_start)) |
| 363 .SetPushStart( |
| 364 timeDelta(load_timing.push_start, load_timing.request_start, 0)) |
| 365 .SetPushEnd(timeDelta(load_timing.push_end, load_timing.request_start, 0)) |
| 366 .SetReceiveHeadersEnd( |
| 367 timeDelta(load_timing.receive_headers_end, load_timing.request_start)) |
| 368 .Build(); |
| 369 } |
| 370 |
| 371 std::unique_ptr<Object> getHeaders(const base::StringPairs& pairs) { |
| 372 std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); |
| 373 for (const auto& pair : pairs) { |
| 374 headers_dict->setString(pair.first, pair.second); |
| 375 } |
| 376 return Object::fromValue(headers_dict.get(), nullptr); |
| 377 } |
| 378 |
| 379 String getProtocol(const GURL& url, const ResourceResponseHead& head) { |
| 380 std::string protocol = head.alpn_negotiated_protocol; |
| 381 if (protocol.empty() || protocol == "unknown") { |
| 382 if (head.was_fetched_via_spdy) { |
| 383 protocol = "spdy"; |
| 384 } else if (url.SchemeIsHTTPOrHTTPS()) { |
| 385 protocol = "http"; |
| 386 if (head.headers->GetHttpVersion() == net::HttpVersion(0, 9)) |
| 387 protocol = "http/0.9"; |
| 388 else if (head.headers->GetHttpVersion() == net::HttpVersion(1, 0)) |
| 389 protocol = "http/1.0"; |
| 390 else if (head.headers->GetHttpVersion() == net::HttpVersion(1, 1)) |
| 391 protocol = "http/1.1"; |
| 392 } else { |
| 393 protocol = url.scheme(); |
| 394 } |
| 395 } |
| 396 return protocol; |
| 397 } |
| 398 |
| 267 } // namespace | 399 } // namespace |
| 268 | 400 |
| 269 NetworkHandler::NetworkHandler() | 401 NetworkHandler::NetworkHandler() |
| 270 : DevToolsDomainHandler(Network::Metainfo::domainName), | 402 : DevToolsDomainHandler(Network::Metainfo::domainName), |
| 271 host_(nullptr), | 403 host_(nullptr), |
| 272 enabled_(false) { | 404 enabled_(false) { |
| 273 } | 405 } |
| 274 | 406 |
| 275 NetworkHandler::~NetworkHandler() { | 407 NetworkHandler::~NetworkHandler() { |
| 276 } | 408 } |
| 277 | 409 |
| 278 // static | 410 // static |
| 279 NetworkHandler* NetworkHandler::FromSession(DevToolsSession* session) { | 411 NetworkHandler* NetworkHandler::FromSession(DevToolsSession* session) { |
| 280 return static_cast<NetworkHandler*>( | 412 return static_cast<NetworkHandler*>( |
| 281 session->GetHandlerByName(Network::Metainfo::domainName)); | 413 session->GetHandlerByName(Network::Metainfo::domainName)); |
| 282 } | 414 } |
| 283 | 415 |
| 284 void NetworkHandler::Wire(UberDispatcher* dispatcher) { | 416 void NetworkHandler::Wire(UberDispatcher* dispatcher) { |
| 417 frontend_.reset(new Network::Frontend(dispatcher->channel())); |
| 285 Network::Dispatcher::wire(dispatcher, this); | 418 Network::Dispatcher::wire(dispatcher, this); |
| 286 } | 419 } |
| 287 | 420 |
| 288 void NetworkHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { | 421 void NetworkHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { |
| 289 host_ = host; | 422 host_ = host; |
| 290 } | 423 } |
| 291 | 424 |
| 292 Response NetworkHandler::Enable(Maybe<int> max_total_size, | 425 Response NetworkHandler::Enable(Maybe<int> max_total_size, |
| 293 Maybe<int> max_resource_size) { | 426 Maybe<int> max_resource_size) { |
| 294 enabled_ = true; | 427 enabled_ = true; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 306 GetContentClient()->browser()->ClearCache(host_); | 439 GetContentClient()->browser()->ClearCache(host_); |
| 307 return Response::OK(); | 440 return Response::OK(); |
| 308 } | 441 } |
| 309 | 442 |
| 310 Response NetworkHandler::ClearBrowserCookies() { | 443 Response NetworkHandler::ClearBrowserCookies() { |
| 311 if (host_) | 444 if (host_) |
| 312 GetContentClient()->browser()->ClearCookies(host_); | 445 GetContentClient()->browser()->ClearCookies(host_); |
| 313 return Response::OK(); | 446 return Response::OK(); |
| 314 } | 447 } |
| 315 | 448 |
| 316 void NetworkHandler::GetCookies( | 449 void NetworkHandler::GetCookies(Maybe<Array<String>> protocol_urls, |
| 317 Maybe<protocol::Array<String>> protocol_urls, | 450 std::unique_ptr<GetCookiesCallback> callback) { |
| 318 std::unique_ptr<GetCookiesCallback> callback) { | |
| 319 if (!host_) { | 451 if (!host_) { |
| 320 callback->sendFailure(Response::InternalError()); | 452 callback->sendFailure(Response::InternalError()); |
| 321 return; | 453 return; |
| 322 } | 454 } |
| 323 | 455 |
| 324 std::vector<GURL> urls = ComputeCookieURLs(host_, protocol_urls); | 456 std::vector<GURL> urls = ComputeCookieURLs(host_, protocol_urls); |
| 325 scoped_refptr<CookieRetriever> retriever = | 457 scoped_refptr<CookieRetriever> retriever = |
| 326 new CookieRetriever(std::move(callback)); | 458 new CookieRetriever(std::move(callback)); |
| 327 | 459 |
| 328 BrowserThread::PostTask( | 460 BrowserThread::PostTask( |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 } | 561 } |
| 430 user_agent_ = user_agent; | 562 user_agent_ = user_agent; |
| 431 return Response::FallThrough(); | 563 return Response::FallThrough(); |
| 432 } | 564 } |
| 433 | 565 |
| 434 Response NetworkHandler::CanEmulateNetworkConditions(bool* result) { | 566 Response NetworkHandler::CanEmulateNetworkConditions(bool* result) { |
| 435 *result = false; | 567 *result = false; |
| 436 return Response::OK(); | 568 return Response::OK(); |
| 437 } | 569 } |
| 438 | 570 |
| 571 void NetworkHandler::NavigationPreloadRequestSent( |
| 572 int worker_version_id, |
| 573 const std::string& request_id, |
| 574 const ResourceRequest& request) { |
| 575 if (!enabled_) |
| 576 return; |
| 577 const std::string version_id(base::IntToString(worker_version_id)); |
| 578 std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); |
| 579 net::HttpRequestHeaders headers; |
| 580 headers.AddHeadersFromString(request.headers); |
| 581 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) |
| 582 headers_dict->setString(it.name(), it.value()); |
| 583 frontend_->RequestWillBeSent( |
| 584 request_id, version_id /* frameId */, version_id /* loaderId */, |
| 585 "" /* documentURL */, |
| 586 Network::Request::Create() |
| 587 .SetUrl(request.url.spec()) |
| 588 .SetMethod(request.method) |
| 589 .SetHeaders(Object::fromValue(headers_dict.get(), nullptr)) |
| 590 .SetInitialPriority(resourcePriority(request.priority)) |
| 591 .SetReferrerPolicy(referrerPolicy(request.referrer_policy)) |
| 592 .Build(), |
| 593 base::TimeTicks::Now().ToInternalValue() / |
| 594 static_cast<double>(base::Time::kMicrosecondsPerSecond), |
| 595 base::Time::Now().ToDoubleT(), |
| 596 Network::Initiator::Create() |
| 597 .SetType(Network::Initiator::TypeEnum::Preload) |
| 598 .Build(), |
| 599 std::unique_ptr<Network::Response>(), |
| 600 std::string(Page::ResourceTypeEnum::Other)); |
| 601 } |
| 602 |
| 603 void NetworkHandler::NavigationPreloadResponseReceived( |
| 604 int worker_version_id, |
| 605 const std::string& request_id, |
| 606 const GURL& url, |
| 607 const ResourceResponseHead& head) { |
| 608 if (!enabled_) |
| 609 return; |
| 610 const std::string version_id(base::IntToString(worker_version_id)); |
| 611 std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); |
| 612 size_t iterator = 0; |
| 613 std::string name; |
| 614 std::string value; |
| 615 while (head.headers->EnumerateHeaderLines(&iterator, &name, &value)) |
| 616 headers_dict->setString(name, value); |
| 617 std::unique_ptr<Network::Response> response( |
| 618 Network::Response::Create() |
| 619 .SetUrl(url.spec()) |
| 620 .SetStatus(head.headers->response_code()) |
| 621 .SetStatusText(head.headers->GetStatusText()) |
| 622 .SetHeaders(Object::fromValue(headers_dict.get(), nullptr)) |
| 623 .SetMimeType(head.mime_type) |
| 624 .SetConnectionReused(head.load_timing.socket_reused) |
| 625 .SetConnectionId(head.load_timing.socket_log_id) |
| 626 .SetSecurityState(securityState(url, head.cert_status)) |
| 627 .SetEncodedDataLength(head.encoded_data_length) |
| 628 .SetTiming(getTiming(head.load_timing)) |
| 629 .SetFromDiskCache(!head.load_timing.request_start_time.is_null() && |
| 630 head.response_time < |
| 631 head.load_timing.request_start_time) |
| 632 .Build()); |
| 633 if (head.devtools_info) { |
| 634 response->SetStatus(head.devtools_info->http_status_code); |
| 635 response->SetStatusText(head.devtools_info->http_status_text); |
| 636 response->SetRequestHeaders( |
| 637 getHeaders(head.devtools_info->request_headers)); |
| 638 response->SetHeaders(getHeaders(head.devtools_info->response_headers)); |
| 639 response->SetHeadersText(head.devtools_info->response_headers_text); |
| 640 } |
| 641 response->SetProtocol(getProtocol(url, head)); |
| 642 response->SetRemoteIPAddress(head.socket_address.HostForURL()); |
| 643 response->SetRemotePort(head.socket_address.port()); |
| 644 frontend_->ResponseReceived( |
| 645 request_id, version_id /* frameId */, version_id /* loaderId */, |
| 646 base::TimeTicks::Now().ToInternalValue() / |
| 647 static_cast<double>(base::Time::kMicrosecondsPerSecond), |
| 648 Page::ResourceTypeEnum::Other, std::move(response)); |
| 649 } |
| 650 |
| 651 void NetworkHandler::NavigationPreloadCompleted( |
| 652 const std::string& request_id, |
| 653 const ResourceRequestCompletionStatus& completion_status) { |
| 654 if (!enabled_) |
| 655 return; |
| 656 if (completion_status.error_code != net::OK) { |
| 657 frontend_->LoadingFailed( |
| 658 request_id, base::TimeTicks::Now().ToInternalValue() / |
| 659 static_cast<double>(base::Time::kMicrosecondsPerSecond), |
| 660 Page::ResourceTypeEnum::Other, "Navigation Preload Error", |
| 661 completion_status.error_code == net::Error::ERR_ABORTED); |
| 662 } |
| 663 frontend_->LoadingFinished( |
| 664 request_id, base::TimeTicks::Now().ToInternalValue() / |
| 665 static_cast<double>(base::Time::kMicrosecondsPerSecond), |
| 666 completion_status.encoded_data_length); |
| 667 } |
| 668 |
| 439 std::string NetworkHandler::UserAgentOverride() const { | 669 std::string NetworkHandler::UserAgentOverride() const { |
| 440 return enabled_ ? user_agent_ : std::string(); | 670 return enabled_ ? user_agent_ : std::string(); |
| 441 } | 671 } |
| 442 | 672 |
| 443 } // namespace protocol | 673 } // namespace protocol |
| 444 } // namespace content | 674 } // namespace content |
| OLD | NEW |