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

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

Issue 2654993006: Show service worker navigation preload requests in DevTools Network tab. (Closed)
Patch Set: incorporated pfeldman's comment Created 3 years, 11 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/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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/network_handler.h ('k') | content/browser/devtools/protocol_config.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698