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

Side by Side Diff: webkit/media/buffered_resource_loader.cc

Issue 10387200: Suppress pause-and-buffer behavior when the HTTP response won't satisfy future requests via cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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
« no previous file with comments | « webkit/media/buffered_resource_loader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/media/buffered_resource_loader.h" 5 #include "webkit/media/buffered_resource_loader.h"
6 6
7 #include <math.h>
8
7 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
8 #include "base/format_macros.h" 10 #include "base/format_macros.h"
11 #include "base/metrics/histogram.h"
9 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
10 #include "base/string_util.h" 13 #include "base/string_util.h"
11 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
12 #include "media/base/media_log.h" 15 #include "media/base/media_log.h"
13 #include "net/http/http_request_headers.h" 16 #include "net/http/http_request_headers.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h " 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h "
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatfo rmSupport.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatfo rmSupport.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError. h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError. h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 const GURL& url, 107 const GURL& url,
105 int64 first_byte_position, 108 int64 first_byte_position,
106 int64 last_byte_position, 109 int64 last_byte_position,
107 DeferStrategy strategy, 110 DeferStrategy strategy,
108 int bitrate, 111 int bitrate,
109 float playback_rate, 112 float playback_rate,
110 media::MediaLog* media_log) 113 media::MediaLog* media_log)
111 : buffer_(kMinBufferCapacity, kMinBufferCapacity), 114 : buffer_(kMinBufferCapacity, kMinBufferCapacity),
112 loader_failed_(false), 115 loader_failed_(false),
113 defer_strategy_(strategy), 116 defer_strategy_(strategy),
117 might_be_reused_from_cache_in_future_(true),
114 range_supported_(false), 118 range_supported_(false),
115 saved_forward_capacity_(0), 119 saved_forward_capacity_(0),
116 url_(url), 120 url_(url),
117 first_byte_position_(first_byte_position), 121 first_byte_position_(first_byte_position),
118 last_byte_position_(last_byte_position), 122 last_byte_position_(last_byte_position),
119 single_origin_(true), 123 single_origin_(true),
120 offset_(0), 124 offset_(0),
121 content_length_(kPositionNotSpecified), 125 content_length_(kPositionNotSpecified),
122 instance_size_(kPositionNotSpecified), 126 instance_size_(kPositionNotSpecified),
123 read_position_(0), 127 read_position_(0),
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 url_ = newRequest.url(); 349 url_ = newRequest.url();
346 } 350 }
347 351
348 void BufferedResourceLoader::didSendData( 352 void BufferedResourceLoader::didSendData(
349 WebURLLoader* loader, 353 WebURLLoader* loader,
350 unsigned long long bytes_sent, 354 unsigned long long bytes_sent,
351 unsigned long long total_bytes_to_be_sent) { 355 unsigned long long total_bytes_to_be_sent) {
352 NOTIMPLEMENTED(); 356 NOTIMPLEMENTED();
353 } 357 }
354 358
359 // Reasons that a cached WebURLResponse will *not* prevent a future request to
360 // the server.
361 enum OneOffReason {
362 kUseful = 0, // Yay! This response might satisfy a future request.
363 kNoData = 1, // Not 200 or 206.
364 kPre11PartialResponse = 2, // 206 but HTTP version < 1.1.
scherkus (not reviewing) 2012/05/19 02:26:24 nit: I read this as "Prell" (pee-are-eee-ell-ell)
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 ...yeah. Leaving as is.
365 kNoStrongValidatorOnPartialResponse = 3, // 206, no strong validator.
366 kNoValidatorOnFullResponse = 4, // 200, no strong or weak validator.
367 kShortMaxAge = 5, // Max age less than 1h (arbitrary value).
368 kExpiresTooSoon = 6, // Expires in less than 1h (arbitrary value).
369 kHasMustRevalidate = 7, // Response asks for revalidation.
370 kNoCache = 8, // Response included a no-cache header.
371 kMaxReason = kNoCache + 1 // Always keep equal to the greatest value plus 1.
rvargas (doing something else) 2012/05/19 01:19:41 nit: don't set a value?
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 Hah! Done.
372 };
373
374 // Return true if "response" might be used for a future request (using the disk
375 // cache). This is basically a laundry list of reasons we *know* the response
376 // won't be useful in the future.
377 static bool MightBeReusedFromCacheInFuture(const WebURLResponse& response) {
378 std::vector<OneOffReason> reasons;
379 const int code = response.httpStatusCode();
380 const int version = response.httpVersion();
381 if (code != kHttpOK && code != kHttpPartialContent)
382 reasons.push_back(kNoData);
383 if (version < WebURLResponse::HTTP_1_1 && code != kHttpOK)
scherkus (not reviewing) 2012/05/19 02:26:24 since this isn't an else branch wouldn't this stat
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 Oops; leftover from previous code.
384 reasons.push_back(kPre11PartialResponse);
385 if (!response.hasCacheValidatorFields()) {
scherkus (not reviewing) 2012/05/19 02:26:24 OOC is this is ETag && Last-Modified or ETag || La
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 || http://code.google.com/searchframe#OAMlx_jo-ck/
386 if (code == kHttpPartialContent)
387 reasons.push_back(kNoStrongValidatorOnPartialResponse);
388 else if (code == kHttpOK)
389 reasons.push_back(kNoValidatorOnFullResponse);
390 }
391 // TODO(fischman): if 206 && hasCacheValidatorFields() still need to verify
392 // one of the validators is "strong" or else still record
393 // kNoStrongValidatorOnPartialResponse.
394
395 enum { kMinimumAgeForUsefulnessInSeconds = 3600 }; // Arbitrary value.
396 if (!isnan(response.cacheControlMaxAge()) &&
397 response.cacheControlMaxAge() < kMinimumAgeForUsefulnessInSeconds) {
398 reasons.push_back(kShortMaxAge);
399 }
400 if (!isnan(response.expires()) && !isnan(response.date()) &&
401 ((response.expires() - response.date()) <
402 kMinimumAgeForUsefulnessInSeconds)) {
403 reasons.push_back(kExpiresTooSoon);
404 }
405 if (response.cacheControlContainsMustRevalidate())
406 reasons.push_back(kHasMustRevalidate);
407 if (response.cacheControlContainsNoCache())
rvargas (doing something else) 2012/05/19 01:19:41 does this check for no-store also?
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 Nope. Thought about it and thought I didn't need
408 reasons.push_back(kNoCache);
409
410 if (reasons.empty())
411 UMA_HISTOGRAM_ENUMERATION("Media.OneOffReason", kUseful, kMaxReason);
412 for (size_t i = 0; i < reasons.size(); ++i)
413 UMA_HISTOGRAM_ENUMERATION("Media.OneOffReason", reasons[i], kMaxReason);
rvargas (doing something else) 2012/05/19 01:19:41 note that there will be no way to tell what percen
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 Good point. Reworked slightly.
414
415 return reasons.empty();
416 }
417
355 void BufferedResourceLoader::didReceiveResponse( 418 void BufferedResourceLoader::didReceiveResponse(
356 WebURLLoader* loader, 419 WebURLLoader* loader,
357 const WebURLResponse& response) { 420 const WebURLResponse& response) {
358 DVLOG(1) << "didReceiveResponse: HTTP/" 421 DVLOG(1) << "didReceiveResponse: HTTP/"
359 << (response.httpVersion() == WebURLResponse::HTTP_0_9 ? "0.9" : 422 << (response.httpVersion() == WebURLResponse::HTTP_0_9 ? "0.9" :
360 response.httpVersion() == WebURLResponse::HTTP_1_0 ? "1.0" : 423 response.httpVersion() == WebURLResponse::HTTP_1_0 ? "1.0" :
361 response.httpVersion() == WebURLResponse::HTTP_1_1 ? "1.1" : 424 response.httpVersion() == WebURLResponse::HTTP_1_1 ? "1.1" :
362 "Unknown") 425 "Unknown")
363 << " " << response.httpStatusCode(); 426 << " " << response.httpStatusCode();
364 DCHECK(active_loader_.get()); 427 DCHECK(active_loader_.get());
365 428
366 // The loader may have been stopped and |start_cb| is destroyed. 429 // The loader may have been stopped and |start_cb| is destroyed.
367 // In this case we shouldn't do anything. 430 // In this case we shouldn't do anything.
368 if (start_cb_.is_null()) 431 if (start_cb_.is_null())
369 return; 432 return;
370 433
434 might_be_reused_from_cache_in_future_ =
435 MightBeReusedFromCacheInFuture(response);
scherkus (not reviewing) 2012/05/19 02:26:24 do we want to log these requests for all protocols
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 Hmm. On one hand HTTP will drown out all other st
scherkus (not reviewing) 2012/05/21 21:35:49 Maybe. For example, we report 100% buffered when W
436
371 // Expected content length can be |kPositionNotSpecified|, in that case 437 // Expected content length can be |kPositionNotSpecified|, in that case
372 // |content_length_| is not specified and this is a streaming response. 438 // |content_length_| is not specified and this is a streaming response.
373 content_length_ = response.expectedContentLength(); 439 content_length_ = response.expectedContentLength();
374 440
375 // We make a strong assumption that when we reach here we have either 441 // We make a strong assumption that when we reach here we have either
376 // received a response from HTTP/HTTPS protocol or the request was 442 // received a response from HTTP/HTTPS protocol or the request was
377 // successful (in particular range request). So we only verify the partial 443 // successful (in particular range request). So we only verify the partial
378 // response for HTTP and HTTPS protocol. 444 // response for HTTP and HTTPS protocol.
379 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { 445 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
380 bool partial_response = (response.httpStatusCode() == kHttpPartialContent); 446 bool partial_response = (response.httpStatusCode() == kHttpPartialContent);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 599 }
534 } 600 }
535 601
536 bool BufferedResourceLoader::HasSingleOrigin() const { 602 bool BufferedResourceLoader::HasSingleOrigin() const {
537 DCHECK(start_cb_.is_null()) 603 DCHECK(start_cb_.is_null())
538 << "Start() must complete before calling HasSingleOrigin()"; 604 << "Start() must complete before calling HasSingleOrigin()";
539 return single_origin_; 605 return single_origin_;
540 } 606 }
541 607
542 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { 608 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) {
609 if (!might_be_reused_from_cache_in_future_ && strategy == kNeverDefer)
scherkus (not reviewing) 2012/05/19 02:26:24 I'm this -->||<-- close to thinking we should just
Ami GONE FROM CHROMIUM 2012/05/19 03:03:02 I don't want to drop pause-and-buffer where it wor
610 strategy = kThresholdDefer;
543 defer_strategy_ = strategy; 611 defer_strategy_ = strategy;
544 UpdateDeferBehavior(); 612 UpdateDeferBehavior();
545 } 613 }
546 614
547 void BufferedResourceLoader::SetPlaybackRate(float playback_rate) { 615 void BufferedResourceLoader::SetPlaybackRate(float playback_rate) {
548 playback_rate_ = playback_rate; 616 playback_rate_ = playback_rate;
549 617
550 // This is a pause so don't bother updating the buffer window as we'll likely 618 // This is a pause so don't bother updating the buffer window as we'll likely
551 // get unpaused in the future. 619 // get unpaused in the future.
552 if (playback_rate_ == 0.0) 620 if (playback_rate_ == 0.0)
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 881
814 void BufferedResourceLoader::Log() { 882 void BufferedResourceLoader::Log() {
815 media_log_->AddEvent( 883 media_log_->AddEvent(
816 media_log_->CreateBufferedExtentsChangedEvent( 884 media_log_->CreateBufferedExtentsChangedEvent(
817 offset_ - buffer_.backward_bytes(), 885 offset_ - buffer_.backward_bytes(),
818 offset_, 886 offset_,
819 offset_ + buffer_.forward_bytes())); 887 offset_ + buffer_.forward_bytes()));
820 } 888 }
821 889
822 } // namespace webkit_media 890 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/media/buffered_resource_loader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698