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

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

Powered by Google App Engine
This is Rietveld 408576698