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

Side by Side Diff: webkit/glue/weburlloader_impl.cc

Issue 7602023: Use a monotonic clock (TimeTicks) to report network times to WebCore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add explanation Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // An implementation of WebURLLoader in terms of ResourceLoaderBridge. 5 // An implementation of WebURLLoader in terms of ResourceLoaderBridge.
6 6
7 #include "webkit/glue/weburlloader_impl.h" 7 #include "webkit/glue/weburlloader_impl.h"
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 16 matching lines...) Expand all
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
30 #include "webkit/glue/ftp_directory_listing_response_delegate.h" 30 #include "webkit/glue/ftp_directory_listing_response_delegate.h"
31 #include "webkit/glue/multipart_response_delegate.h" 31 #include "webkit/glue/multipart_response_delegate.h"
32 #include "webkit/glue/resource_loader_bridge.h" 32 #include "webkit/glue/resource_loader_bridge.h"
33 #include "webkit/glue/webkit_glue.h" 33 #include "webkit/glue/webkit_glue.h"
34 34
35 using base::Time; 35 using base::Time;
36 using base::TimeDelta; 36 using base::TimeDelta;
37 using base::TimeTicks;
37 using WebKit::WebData; 38 using WebKit::WebData;
38 using WebKit::WebHTTPBody; 39 using WebKit::WebHTTPBody;
39 using WebKit::WebHTTPHeaderVisitor; 40 using WebKit::WebHTTPHeaderVisitor;
40 using WebKit::WebHTTPLoadInfo; 41 using WebKit::WebHTTPLoadInfo;
41 using WebKit::WebSecurityPolicy; 42 using WebKit::WebSecurityPolicy;
42 using WebKit::WebString; 43 using WebKit::WebString;
43 using WebKit::WebURL; 44 using WebKit::WebURL;
44 using WebKit::WebURLError; 45 using WebKit::WebURLError;
45 using WebKit::WebURLLoadTiming; 46 using WebKit::WebURLLoadTiming;
46 using WebKit::WebURLLoader; 47 using WebKit::WebURLLoader;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 private: 106 private:
106 int load_flags_; 107 int load_flags_;
107 std::string buffer_; 108 std::string buffer_;
108 bool has_accept_header_; 109 bool has_accept_header_;
109 }; 110 };
110 111
111 // Extracts the information from a data: url. 112 // Extracts the information from a data: url.
112 bool GetInfoFromDataURL(const GURL& url, 113 bool GetInfoFromDataURL(const GURL& url,
113 ResourceResponseInfo* info, 114 ResourceResponseInfo* info,
114 std::string* data, 115 std::string* data,
115 net::URLRequestStatus* status) { 116 net::URLRequestStatus* status,
117 TimeTicks* response_time) {
116 std::string mime_type; 118 std::string mime_type;
117 std::string charset; 119 std::string charset;
118 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { 120 if (net::DataURL::Parse(url, &mime_type, &charset, data)) {
119 *status = net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0); 121 *status = net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0);
120 // Assure same time for all time fields of data: URLs. 122 // Assure same time for all time fields of data: URLs.
121 Time now = Time::Now(); 123 Time now = Time::Now();
122 info->load_timing.base_time = now; 124 info->load_timing.base_time = now;
125 info->load_timing.base_ticks = *response_time = TimeTicks::Now();
123 info->request_time = now; 126 info->request_time = now;
124 info->response_time = now; 127 info->response_time = now;
125 info->headers = NULL; 128 info->headers = NULL;
126 info->mime_type.swap(mime_type); 129 info->mime_type.swap(mime_type);
127 info->charset.swap(charset); 130 info->charset.swap(charset);
128 info->security_info.clear(); 131 info->security_info.clear();
129 info->content_length = -1; 132 info->content_length = -1;
130 info->encoded_data_length = 0; 133 info->encoded_data_length = 0;
131 134
132 return true; 135 return true;
133 } 136 }
134 137
135 *status = net::URLRequestStatus(net::URLRequestStatus::FAILED, 138 *status = net::URLRequestStatus(net::URLRequestStatus::FAILED,
136 net::ERR_INVALID_URL); 139 net::ERR_INVALID_URL);
137 return false; 140 return false;
138 } 141 }
139 142
140 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; 143 typedef ResourceDevToolsInfo::HeadersVector HeadersVector;
141 144
142 void PopulateURLResponse( 145 void PopulateURLResponse(
143 const GURL& url, 146 const GURL& url,
144 const ResourceResponseInfo& info, 147 const ResourceResponseInfo& info,
148 const TimeTicks& initiation_time,
149 const TimeTicks& start_time,
150 const TimeTicks& end_time,
151 const TimeTicks& callback_time,
145 WebURLResponse* response) { 152 WebURLResponse* response) {
146 response->setURL(url); 153 response->setURL(url);
147 response->setResponseTime(info.response_time.ToDoubleT()); 154 response->setResponseTime(info.response_time.ToDoubleT());
148 response->setMIMEType(WebString::fromUTF8(info.mime_type)); 155 response->setMIMEType(WebString::fromUTF8(info.mime_type));
149 response->setTextEncodingName(WebString::fromUTF8(info.charset)); 156 response->setTextEncodingName(WebString::fromUTF8(info.charset));
150 response->setExpectedContentLength(info.content_length); 157 response->setExpectedContentLength(info.content_length);
151 response->setSecurityInfo(info.security_info); 158 response->setSecurityInfo(info.security_info);
152 response->setAppCacheID(info.appcache_id); 159 response->setAppCacheID(info.appcache_id);
153 response->setAppCacheManifestURL(info.appcache_manifest_url); 160 response->setAppCacheManifestURL(info.appcache_manifest_url);
154 response->setWasCached(!info.load_timing.base_time.is_null() && 161 response->setWasCached(!info.load_timing.base_time.is_null() &&
155 info.response_time < info.load_timing.base_time); 162 info.response_time < info.load_timing.base_time);
156 response->setWasFetchedViaSPDY(info.was_fetched_via_spdy); 163 response->setWasFetchedViaSPDY(info.was_fetched_via_spdy);
157 response->setWasNpnNegotiated(info.was_npn_negotiated); 164 response->setWasNpnNegotiated(info.was_npn_negotiated);
158 response->setWasAlternateProtocolAvailable( 165 response->setWasAlternateProtocolAvailable(
159 info.was_alternate_protocol_available); 166 info.was_alternate_protocol_available);
160 response->setWasFetchedViaProxy(info.was_fetched_via_proxy); 167 response->setWasFetchedViaProxy(info.was_fetched_via_proxy);
161 response->setRemoteIPAddress( 168 response->setRemoteIPAddress(
162 WebString::fromUTF8(info.socket_address.host())); 169 WebString::fromUTF8(info.socket_address.host()));
163 response->setRemotePort(info.socket_address.port()); 170 response->setRemotePort(info.socket_address.port());
164 response->setConnectionID(info.connection_id); 171 response->setConnectionID(info.connection_id);
165 response->setConnectionReused(info.connection_reused); 172 response->setConnectionReused(info.connection_reused);
166 response->setDownloadFilePath(FilePathToWebString(info.download_file_path)); 173 response->setDownloadFilePath(FilePathToWebString(info.download_file_path));
167 174
168 const ResourceLoadTimingInfo& timing_info = info.load_timing; 175 const ResourceLoadTimingInfo& timing_info = info.load_timing;
169 if (!timing_info.base_time.is_null()) { 176 if (!timing_info.base_time.is_null()) {
170 WebURLLoadTiming timing; 177 WebURLLoadTiming timing = PopulateWebURLLoadTiming(
171 timing.initialize(); 178 timing_info, initiation_time, start_time, end_time, callback_time);
172 timing.setRequestTime(timing_info.base_time.ToDoubleT());
173 timing.setProxyStart(timing_info.proxy_start);
174 timing.setProxyEnd(timing_info.proxy_end);
175 timing.setDNSStart(timing_info.dns_start);
176 timing.setDNSEnd(timing_info.dns_end);
177 timing.setConnectStart(timing_info.connect_start);
178 timing.setConnectEnd(timing_info.connect_end);
179 timing.setSSLStart(timing_info.ssl_start);
180 timing.setSSLEnd(timing_info.ssl_end);
181 timing.setSendStart(timing_info.send_start);
182 timing.setSendEnd(timing_info.send_end);
183 timing.setReceiveHeadersEnd(timing_info.receive_headers_end);
184 response->setLoadTiming(timing); 179 response->setLoadTiming(timing);
185 } 180 }
186 181
187 if (info.devtools_info.get()) { 182 if (info.devtools_info.get()) {
188 WebHTTPLoadInfo load_info; 183 WebHTTPLoadInfo load_info;
189 184
190 load_info.setHTTPStatusCode(info.devtools_info->http_status_code); 185 load_info.setHTTPStatusCode(info.devtools_info->http_status_code);
191 load_info.setHTTPStatusText(WebString::fromUTF8( 186 load_info.setHTTPStatusText(WebString::fromUTF8(
192 info.devtools_info->http_status_text)); 187 info.devtools_info->http_status_text));
193 load_info.setEncodedDataLength(info.encoded_data_length); 188 load_info.setEncodedDataLength(info.encoded_data_length);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 void Start( 257 void Start(
263 const WebURLRequest& request, 258 const WebURLRequest& request,
264 ResourceLoaderBridge::SyncLoadResponse* sync_load_response); 259 ResourceLoaderBridge::SyncLoadResponse* sync_load_response);
265 void UpdateRoutingId(int new_routing_id); 260 void UpdateRoutingId(int new_routing_id);
266 261
267 // ResourceLoaderBridge::Peer methods: 262 // ResourceLoaderBridge::Peer methods:
268 virtual void OnUploadProgress(uint64 position, uint64 size); 263 virtual void OnUploadProgress(uint64 position, uint64 size);
269 virtual bool OnReceivedRedirect( 264 virtual bool OnReceivedRedirect(
270 const GURL& new_url, 265 const GURL& new_url,
271 const ResourceResponseInfo& info, 266 const ResourceResponseInfo& info,
267 const TimeTicks& start_time,
268 const TimeTicks& end_time,
272 bool* has_new_first_party_for_cookies, 269 bool* has_new_first_party_for_cookies,
273 GURL* new_first_party_for_cookies); 270 GURL* new_first_party_for_cookies);
274 virtual void OnReceivedResponse(const ResourceResponseInfo& info); 271 virtual void OnReceivedResponse(const ResourceResponseInfo& info,
272 const TimeTicks& start_time,
273 const TimeTicks& end_time);
275 virtual void OnDownloadedData(int len); 274 virtual void OnDownloadedData(int len);
276 virtual void OnReceivedData(const char* data, 275 virtual void OnReceivedData(const char* data,
277 int data_length, 276 int data_length,
278 int encoded_data_length); 277 int encoded_data_length);
279 virtual void OnReceivedCachedMetadata(const char* data, int len); 278 virtual void OnReceivedCachedMetadata(const char* data, int len);
280 virtual void OnCompletedRequest(const net::URLRequestStatus& status, 279 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
281 const std::string& security_info, 280 const std::string& security_info,
282 const base::Time& completion_time); 281 const TimeTicks& completion_time);
283 282
284 private: 283 private:
285 friend class base::RefCounted<Context>; 284 friend class base::RefCounted<Context>;
286 ~Context() {} 285 ~Context() {}
287 286
288 // We can optimize the handling of data URLs in most cases. 287 // We can optimize the handling of data URLs in most cases.
289 bool CanHandleDataURL(const GURL& url) const; 288 bool CanHandleDataURL(const GURL& url) const;
290 void HandleDataURL(); 289 void HandleDataURL();
291 290
292 WebURLLoaderImpl* loader_; 291 WebURLLoaderImpl* loader_;
293 WebURLRequest request_; 292 WebURLRequest request_;
294 WebURLLoaderClient* client_; 293 WebURLLoaderClient* client_;
294 TimeTicks initiation_time_;
295 scoped_ptr<ResourceLoaderBridge> bridge_; 295 scoped_ptr<ResourceLoaderBridge> bridge_;
296 scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; 296 scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
297 scoped_ptr<MultipartResponseDelegate> multipart_delegate_; 297 scoped_ptr<MultipartResponseDelegate> multipart_delegate_;
298 scoped_ptr<ResourceLoaderBridge> completed_bridge_; 298 scoped_ptr<ResourceLoaderBridge> completed_bridge_;
299 }; 299 };
300 300
301 WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) 301 WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader)
302 : loader_(loader), 302 : loader_(loader),
303 client_(NULL) { 303 client_(NULL) {
304 } 304 }
(...skipping 30 matching lines...) Expand all
335 DCHECK(!bridge_.get()); 335 DCHECK(!bridge_.get());
336 336
337 request_ = request; // Save the request. 337 request_ = request; // Save the request.
338 338
339 GURL url = request.url(); 339 GURL url = request.url();
340 if (url.SchemeIs("data") && CanHandleDataURL(url)) { 340 if (url.SchemeIs("data") && CanHandleDataURL(url)) {
341 if (sync_load_response) { 341 if (sync_load_response) {
342 // This is a sync load. Do the work now. 342 // This is a sync load. Do the work now.
343 sync_load_response->url = url; 343 sync_load_response->url = url;
344 std::string data; 344 std::string data;
345 TimeTicks response_time;
345 GetInfoFromDataURL(sync_load_response->url, sync_load_response, 346 GetInfoFromDataURL(sync_load_response->url, sync_load_response,
346 &sync_load_response->data, 347 &sync_load_response->data,
347 &sync_load_response->status); 348 &sync_load_response->status, &response_time);
349 sync_load_response->start_time = response_time;
350 sync_load_response->end_time = response_time;
348 } else { 351 } else {
349 AddRef(); // Balanced in OnCompletedRequest 352 AddRef(); // Balanced in OnCompletedRequest
350 MessageLoop::current()->PostTask(FROM_HERE, 353 MessageLoop::current()->PostTask(FROM_HERE,
351 NewRunnableMethod(this, &Context::HandleDataURL)); 354 NewRunnableMethod(this, &Context::HandleDataURL));
352 } 355 }
353 return; 356 return;
354 } 357 }
355 358
356 GURL referrer_url( 359 GURL referrer_url(
357 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); 360 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 case WebHTTPBody::Element::TypeBlob: 448 case WebHTTPBody::Element::TypeBlob:
446 bridge_->AppendBlobToUpload(GURL(element.blobURL)); 449 bridge_->AppendBlobToUpload(GURL(element.blobURL));
447 break; 450 break;
448 default: 451 default:
449 NOTREACHED(); 452 NOTREACHED();
450 } 453 }
451 } 454 }
452 bridge_->SetUploadIdentifier(request.httpBody().identifier()); 455 bridge_->SetUploadIdentifier(request.httpBody().identifier());
453 } 456 }
454 457
458 initiation_time_ = TimeTicks::Now();
455 if (sync_load_response) { 459 if (sync_load_response) {
456 bridge_->SyncLoad(sync_load_response); 460 bridge_->SyncLoad(sync_load_response);
457 return; 461 return;
458 } 462 }
459 463
460 if (bridge_->Start(this)) { 464 if (bridge_->Start(this)) {
461 AddRef(); // Balanced in OnCompletedRequest 465 AddRef(); // Balanced in OnCompletedRequest
462 } else { 466 } else {
463 bridge_.reset(); 467 bridge_.reset();
464 } 468 }
465 } 469 }
466 470
467 void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { 471 void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) {
468 if (client_) 472 if (client_)
469 client_->didSendData(loader_, position, size); 473 client_->didSendData(loader_, position, size);
470 } 474 }
471 475
472 bool WebURLLoaderImpl::Context::OnReceivedRedirect( 476 bool WebURLLoaderImpl::Context::OnReceivedRedirect(
473 const GURL& new_url, 477 const GURL& new_url,
474 const ResourceResponseInfo& info, 478 const ResourceResponseInfo& info,
479 const TimeTicks& start_time,
480 const TimeTicks& end_time,
475 bool* has_new_first_party_for_cookies, 481 bool* has_new_first_party_for_cookies,
476 GURL* new_first_party_for_cookies) { 482 GURL* new_first_party_for_cookies) {
477 if (!client_) 483 if (!client_)
478 return false; 484 return false;
479 485
486 TimeTicks callback_time = TimeTicks::Now();
480 WebURLResponse response; 487 WebURLResponse response;
481 response.initialize(); 488 response.initialize();
482 PopulateURLResponse(request_.url(), info, &response); 489 PopulateURLResponse(request_.url(), info, initiation_time_, start_time,
490 end_time, callback_time, &response);
483 491
484 // TODO(darin): We lack sufficient information to construct the actual 492 // TODO(darin): We lack sufficient information to construct the actual
485 // request that resulted from the redirect. 493 // request that resulted from the redirect.
486 WebURLRequest new_request(new_url); 494 WebURLRequest new_request(new_url);
487 new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); 495 new_request.setFirstPartyForCookies(request_.firstPartyForCookies());
488 new_request.setDownloadToFile(request_.downloadToFile()); 496 new_request.setDownloadToFile(request_.downloadToFile());
489 497
490 WebString referrer_string = WebString::fromUTF8("Referer"); 498 WebString referrer_string = WebString::fromUTF8("Referer");
491 WebString referrer = request_.httpHeaderField(referrer_string); 499 WebString referrer = request_.httpHeaderField(referrer_string);
492 if (!WebSecurityPolicy::shouldHideReferrer(new_url, referrer)) 500 if (!WebSecurityPolicy::shouldHideReferrer(new_url, referrer))
(...skipping 11 matching lines...) Expand all
504 if (new_url == GURL(new_request.url())) 512 if (new_url == GURL(new_request.url()))
505 return true; 513 return true;
506 514
507 // We assume that WebKit only changes the URL to suppress a redirect, and we 515 // We assume that WebKit only changes the URL to suppress a redirect, and we
508 // assume that it does so by setting it to be invalid. 516 // assume that it does so by setting it to be invalid.
509 DCHECK(!new_request.url().isValid()); 517 DCHECK(!new_request.url().isValid());
510 return false; 518 return false;
511 } 519 }
512 520
513 void WebURLLoaderImpl::Context::OnReceivedResponse( 521 void WebURLLoaderImpl::Context::OnReceivedResponse(
514 const ResourceResponseInfo& info) { 522 const ResourceResponseInfo& info,
523 const TimeTicks& start_time,
524 const TimeTicks& end_time) {
515 if (!client_) 525 if (!client_)
516 return; 526 return;
517 527
528 TimeTicks callback_time = TimeTicks::Now();
518 WebURLResponse response; 529 WebURLResponse response;
519 response.initialize(); 530 response.initialize();
520 PopulateURLResponse(request_.url(), info, &response); 531 PopulateURLResponse(request_.url(), info, initiation_time_, start_time,
532 end_time, callback_time, &response);
521 533
522 bool show_raw_listing = (GURL(request_.url()).query() == "raw"); 534 bool show_raw_listing = (GURL(request_.url()).query() == "raw");
523 535
524 if (info.mime_type == "text/vnd.chromium.ftp-dir") { 536 if (info.mime_type == "text/vnd.chromium.ftp-dir") {
525 if (show_raw_listing) { 537 if (show_raw_listing) {
526 // Set the MIME type to plain text to prevent any active content. 538 // Set the MIME type to plain text to prevent any active content.
527 response.setMIMEType("text/plain"); 539 response.setMIMEType("text/plain");
528 } else { 540 } else {
529 // We're going to produce a parsed listing in HTML. 541 // We're going to produce a parsed listing in HTML.
530 response.setMIMEType("text/html"); 542 response.setMIMEType("text/html");
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 599
588 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( 600 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata(
589 const char* data, int len) { 601 const char* data, int len) {
590 if (client_) 602 if (client_)
591 client_->didReceiveCachedMetadata(loader_, data, len); 603 client_->didReceiveCachedMetadata(loader_, data, len);
592 } 604 }
593 605
594 void WebURLLoaderImpl::Context::OnCompletedRequest( 606 void WebURLLoaderImpl::Context::OnCompletedRequest(
595 const net::URLRequestStatus& status, 607 const net::URLRequestStatus& status,
596 const std::string& security_info, 608 const std::string& security_info,
597 const base::Time& completion_time) { 609 const TimeTicks& completion_time) {
610 TimeTicks monotonic_completion_time = std::min(completion_time,
611 TimeTicks::Now());
598 if (ftp_listing_delegate_.get()) { 612 if (ftp_listing_delegate_.get()) {
599 ftp_listing_delegate_->OnCompletedRequest(); 613 ftp_listing_delegate_->OnCompletedRequest();
600 ftp_listing_delegate_.reset(NULL); 614 ftp_listing_delegate_.reset(NULL);
601 } else if (multipart_delegate_.get()) { 615 } else if (multipart_delegate_.get()) {
602 multipart_delegate_->OnCompletedRequest(); 616 multipart_delegate_->OnCompletedRequest();
603 multipart_delegate_.reset(NULL); 617 multipart_delegate_.reset(NULL);
604 } 618 }
605 619
606 // Prevent any further IPC to the browser now that we're complete, but 620 // Prevent any further IPC to the browser now that we're complete, but
607 // don't delete it to keep any downloaded temp files alive. 621 // don't delete it to keep any downloaded temp files alive.
(...skipping 11 matching lines...) Expand all
619 error_code = status.error(); 633 error_code = status.error();
620 } 634 }
621 WebURLError error; 635 WebURLError error;
622 if (error_code == net::ERR_ABORTED) 636 if (error_code == net::ERR_ABORTED)
623 error.isCancellation = true; 637 error.isCancellation = true;
624 error.domain = WebString::fromUTF8(net::kErrorDomain); 638 error.domain = WebString::fromUTF8(net::kErrorDomain);
625 error.reason = error_code; 639 error.reason = error_code;
626 error.unreachableURL = request_.url(); 640 error.unreachableURL = request_.url();
627 client_->didFail(loader_, error); 641 client_->didFail(loader_, error);
628 } else { 642 } else {
629 client_->didFinishLoading(loader_, completion_time.ToDoubleT()); 643 client_->didFinishLoading(
644 loader_, completion_time.ToInternalValue() /
645 static_cast<double>(base::Time::kMicrosecondsPerSecond));
630 } 646 }
631 } 647 }
632 648
633 // We are done with the bridge now, and so we need to release the reference 649 // We are done with the bridge now, and so we need to release the reference
634 // to ourselves that we took on behalf of the bridge. This may cause our 650 // to ourselves that we took on behalf of the bridge. This may cause our
635 // destruction. 651 // destruction.
636 Release(); 652 Release();
637 } 653 }
638 654
639 bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { 655 bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const {
(...skipping 17 matching lines...) Expand all
657 return true; 673 return true;
658 674
659 return false; 675 return false;
660 } 676 }
661 677
662 void WebURLLoaderImpl::Context::HandleDataURL() { 678 void WebURLLoaderImpl::Context::HandleDataURL() {
663 ResourceResponseInfo info; 679 ResourceResponseInfo info;
664 net::URLRequestStatus status; 680 net::URLRequestStatus status;
665 std::string data; 681 std::string data;
666 682
667 if (GetInfoFromDataURL(request_.url(), &info, &data, &status)) { 683 TimeTicks response_time;
668 OnReceivedResponse(info); 684 if (GetInfoFromDataURL(request_.url(), &info, &data, &status,
685 &response_time)) {
686 OnReceivedResponse(info, response_time, response_time);
669 if (!data.empty()) 687 if (!data.empty())
670 OnReceivedData(data.data(), data.size(), 0); 688 OnReceivedData(data.data(), data.size(), 0);
671 } 689 }
672 690
673 OnCompletedRequest(status, info.security_info, base::Time::Now()); 691 OnCompletedRequest(status, info.security_info, TimeTicks::Now());
674 } 692 }
675 693
676 // WebURLLoaderImpl ----------------------------------------------------------- 694 // WebURLLoaderImpl -----------------------------------------------------------
677 695
678 WebURLLoaderImpl::WebURLLoaderImpl() 696 WebURLLoaderImpl::WebURLLoaderImpl()
679 : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))) { 697 : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))) {
680 } 698 }
681 699
682 WebURLLoaderImpl::~WebURLLoaderImpl() { 700 WebURLLoaderImpl::~WebURLLoaderImpl() {
683 cancel(); 701 cancel();
684 } 702 }
685 703
686 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, 704 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request,
687 WebURLResponse& response, 705 WebURLResponse& response,
688 WebURLError& error, 706 WebURLError& error,
689 WebData& data) { 707 WebData& data) {
708 TimeTicks initiation_time = TimeTicks::Now();
690 ResourceLoaderBridge::SyncLoadResponse sync_load_response; 709 ResourceLoaderBridge::SyncLoadResponse sync_load_response;
691 context_->Start(request, &sync_load_response); 710 context_->Start(request, &sync_load_response);
711 TimeTicks completion_time = TimeTicks::Now();
692 712
693 const GURL& final_url = sync_load_response.url; 713 const GURL& final_url = sync_load_response.url;
694 714
695 // TODO(tc): For file loads, we may want to include a more descriptive 715 // TODO(tc): For file loads, we may want to include a more descriptive
696 // status code or status text. 716 // status code or status text.
697 const net::URLRequestStatus::Status& status = 717 const net::URLRequestStatus::Status& status =
698 sync_load_response.status.status(); 718 sync_load_response.status.status();
699 if (status != net::URLRequestStatus::SUCCESS && 719 if (status != net::URLRequestStatus::SUCCESS &&
700 status != net::URLRequestStatus::HANDLED_EXTERNALLY) { 720 status != net::URLRequestStatus::HANDLED_EXTERNALLY) {
701 response.setURL(final_url); 721 response.setURL(final_url);
702 error.domain = WebString::fromUTF8(net::kErrorDomain); 722 error.domain = WebString::fromUTF8(net::kErrorDomain);
703 error.reason = sync_load_response.status.error(); 723 error.reason = sync_load_response.status.error();
704 error.unreachableURL = final_url; 724 error.unreachableURL = final_url;
705 return; 725 return;
706 } 726 }
707 727
708 PopulateURLResponse(final_url, sync_load_response, &response); 728 PopulateURLResponse(final_url, sync_load_response, initiation_time,
729 sync_load_response.start_time,
730 sync_load_response.end_time, completion_time, &response);
709 731
710 data.assign(sync_load_response.data.data(), 732 data.assign(sync_load_response.data.data(),
711 sync_load_response.data.size()); 733 sync_load_response.data.size());
712 } 734 }
713 735
714 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, 736 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request,
715 WebURLLoaderClient* client) { 737 WebURLLoaderClient* client) {
716 DCHECK(!context_->client()); 738 DCHECK(!context_->client());
717 739
718 context_->set_client(client); 740 context_->set_client(client);
719 context_->Start(request, NULL); 741 context_->Start(request, NULL);
720 } 742 }
721 743
722 void WebURLLoaderImpl::cancel() { 744 void WebURLLoaderImpl::cancel() {
723 context_->Cancel(); 745 context_->Cancel();
724 } 746 }
725 747
726 void WebURLLoaderImpl::setDefersLoading(bool value) { 748 void WebURLLoaderImpl::setDefersLoading(bool value) {
727 context_->SetDefersLoading(value); 749 context_->SetDefersLoading(value);
728 } 750 }
729 751
730 void WebURLLoaderImpl::UpdateRoutingId(int new_routing_id) { 752 void WebURLLoaderImpl::UpdateRoutingId(int new_routing_id) {
731 context_->UpdateRoutingId(new_routing_id); 753 context_->UpdateRoutingId(new_routing_id);
732 } 754 }
733 755
756 int64 CorrectTime(int64 raw_time, int64 numerator, int64 denominator) {
757 if (raw_time <= 0) {
758 return raw_time;
759 }
760 return numerator * raw_time / denominator;
761 }
762
763 // |timing_info| originates in the network layer, which may live in another
764 // (browser) process. These values are recorded and passed as TimeTicks. On
765 // Windows, TimeTicks do not tick consistently across processes. So one process
766 // may be slightly ahead of the other and the delta between them may drift. In
767 // practice, they usually differ by a few ms or less, and never more than 10 ms.
jar (doing other things) 2011/10/15 02:42:13 Since a common resolution is 15ms. The drift at an
James Simonsen 2011/10/18 23:15:47 We use timeGetTime() on Windows, which attempts to
jar (doing other things) 2011/11/08 03:42:49 timeGetTime() returns a DWORD, which is in units o
768 //
769 // To make things consistent for WebKit, we must correct for this cross-process
770 // skew. To do this, we record 4 times:
771 // - |initiation_time|: when this process started handling the request.
jar (doing other things) 2011/10/15 02:42:13 Is this when you *tried* to contact the browser pr
James Simonsen 2011/10/18 23:15:47 The former. I've updated the comment.
772 // - |start_time|: when the network layer (other process) started handling it.
773 // - |end_time|: when the network layer finished the request.
774 // - |callback_time|: when this process received the response from the network
775 // layer.
776 // Because of the monotonic clock, all members of |timing_info| will occur
777 // between start_time and end_time. If |start_time| and/or |end_time| are out of
778 // order wrt |initiation_time| and |callback_time|, then we adjust the bounds to
779 // fit within |initiation_time| and |callback_time|. When the bounds are
780 // adjusted, we scale all of the members of |timing_info| so that they are
781 // relatively the same time delta from |start_time| and |end_time| as they were
782 // before adjustment.
jar (doing other things) 2011/10/15 02:42:13 I'm still trying to understand the goal. Is the g
James Simonsen 2011/10/18 23:15:47 I think we're talking about the same thing, but I'
783 WebURLLoadTiming PopulateWebURLLoadTiming(
784 const ResourceLoadTimingInfo& timing_info,
785 const TimeTicks& initiation_time,
786 const TimeTicks& start_time,
787 const TimeTicks& end_time,
788 const TimeTicks& callback_time) {
789 int64 lower_bound = start_time.ToInternalValue();
jar (doing other things) 2011/10/15 02:42:13 nit: better might be int64 lower_bound = std
James Simonsen 2011/10/18 23:15:47 That has a slightly different meaning. The curren
790 if (start_time < initiation_time) {
791 lower_bound = initiation_time.ToInternalValue();
792 }
793 int64 upper_bound = end_time.ToInternalValue();
794 if (end_time > callback_time) {
795 upper_bound = callback_time.ToInternalValue();
796 }
797 if (lower_bound > upper_bound) {
798 lower_bound = upper_bound;
799 }
800
801 int64 numerator = upper_bound - lower_bound;
802 int64 denominator = (end_time - start_time).ToInternalValue();
jar (doing other things) 2011/10/15 02:42:13 Hmm... with a common 15ms granularity, I would ass
James Simonsen 2011/10/18 23:15:47 As above, we do get higher resolution numbers. Al
803 if (denominator == 0) {
804 numerator = 0;
805 denominator = 1;
806 }
807
808 int64 adjusted_base =
809 lower_bound +
810 numerator *
811 (timing_info.base_ticks - start_time).ToInternalValue() /
812 denominator;
813
814 WebURLLoadTiming timing;
815 timing.initialize();
816 timing.setRequestTime(
817 adjusted_base /
818 static_cast<double>(base::Time::kMicrosecondsPerSecond));
819 timing.setProxyStart(
820 CorrectTime(timing_info.proxy_start, numerator, denominator));
821 timing.setProxyEnd(
822 CorrectTime(timing_info.proxy_end, numerator, denominator));
823 timing.setDNSStart(
824 CorrectTime(timing_info.dns_start, numerator, denominator));
825 timing.setDNSEnd(
826 CorrectTime(timing_info.dns_end, numerator, denominator));
827 timing.setConnectStart(
828 CorrectTime(timing_info.connect_start, numerator, denominator));
829 timing.setConnectEnd(
830 CorrectTime(timing_info.connect_end, numerator, denominator));
831 timing.setSSLStart(
832 CorrectTime(timing_info.ssl_start, numerator, denominator));
833 timing.setSSLEnd(
834 CorrectTime(timing_info.ssl_end, numerator, denominator));
835 timing.setSendStart(
836 CorrectTime(timing_info.send_start, numerator, denominator));
837 timing.setSendEnd(
838 CorrectTime(timing_info.send_end, numerator, denominator));
839 timing.setReceiveHeadersEnd(
840 CorrectTime(timing_info.receive_headers_end, numerator, denominator));
841
842 return timing;
843 }
844
734 } // namespace webkit_glue 845 } // namespace webkit_glue
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698