1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/buffered_resource_loader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bits.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_log.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/cache_util.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/http/http_byte_range.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebURLLoaderOptions.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame; 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString; 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLError; 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoader; 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoaderOptions; 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest; 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHttpOK = 200; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHttpPartialContent = 206; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define the number of bytes in a megabyte. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMegabyte = 1024 * 1024; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum capacity of the buffer in forward or backward direction. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2MB is an arbitrary limit; it just seems to be "good enough" in practice. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMinBufferCapacity = 2 * kMegabyte; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum capacity of the buffer in forward or backward direction. This is 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// effectively the largest single read the code path can handle. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 20MB is an arbitrary limit; it just seems to be "good enough" in practice. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMaxBufferCapacity = 20 * kMegabyte; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum number of bytes outside the buffer we will wait for in order to 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fulfill a read. If a read starts more than 2MB away from the data we 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// currently have in the buffer, we will not wait for buffer to reach the read's 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// location and will instead reset the request. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kForwardWaitThreshold = 2 * kMegabyte; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Computes the suggested backward and forward capacity for the buffer 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if one wants to play at |playback_rate| * the natural playback speed. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use a value of 0 for |bitrate| if it is unknown. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ComputeTargetBufferWindow(float playback_rate, int bitrate, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* out_backward_capacity, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* out_forward_capacity) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kDefaultBitrate = 200 * 1024 * 8; // 200 Kbps. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kMaxBitrate = 20 * kMegabyte * 8; // 20 Mbps. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const float kMaxPlaybackRate = 25.0; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kTargetSecondsBufferedAhead = 10; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kTargetSecondsBufferedBehind = 2; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a default bit rate if unknown and clamp to prevent overflow. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitrate <= 0) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate = kDefaultBitrate; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate = std::min(bitrate, kMaxBitrate); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only scale the buffer window for playback rates greater than 1.0 in 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // magnitude and clamp to prevent overflow. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool backward_playback = false; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate < 0.0f) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backward_playback = true; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate *= -1.0f; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate = std::max(playback_rate, 1.0f); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate = std::min(playback_rate, kMaxPlaybackRate); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_per_second = (bitrate / 8.0) * playback_rate; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clamp between kMinBufferCapacity and kMaxBufferCapacity. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_forward_capacity = std::max( 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTargetSecondsBufferedAhead * bytes_per_second, kMinBufferCapacity); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_backward_capacity = std::max( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (backward_playback) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(*out_forward_capacity, *out_backward_capacity); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferedResourceLoader::BufferedResourceLoader( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CORSMode cors_mode, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 first_byte_position, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 last_byte_position, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeferStrategy strategy, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bitrate, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float playback_rate, 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MediaLog* media_log) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : buffer_(kMinBufferCapacity, kMinBufferCapacity), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_failed_(false), 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defer_strategy_(strategy), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) might_be_reused_from_cache_in_future_(true), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_supported_(false), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_forward_capacity_(0), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_(url), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cors_mode_(cors_mode), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_byte_position_(first_byte_position), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_byte_position_(last_byte_position), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) single_origin_(true), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_(0), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_(kPositionNotSpecified), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_(kPositionNotSpecified), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_(0), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_size_(0), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_(NULL), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_offset_(0), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_offset_(0), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate_(bitrate), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate_(playback_rate), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_log_(media_log) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the initial capacity of |buffer_| based on |bitrate_| and 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |playback_rate_|. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBufferWindow(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferedResourceLoader::~BufferedResourceLoader() {} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::Start( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StartCB& start_cb, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadingStateChangedCB& loading_cb, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgressCB& progress_cb, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebFrame* frame) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we have not started. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(start_cb_.is_null()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(loading_cb_.is_null()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(progress_cb_.is_null()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!start_cb.is_null()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!loading_cb.is_null()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!progress_cb.is_null()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(frame); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_cb_ = start_cb; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_ = loading_cb; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress_cb_ = progress_cb; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_byte_position_ != kPositionNotSpecified) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(hclam): server may not support range request so |offset_| may not 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // equal to |first_byte_position_|. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ = first_byte_position_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare the request. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLRequest request(url_); 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(mkwst): Split this into video/audio. 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) request.setRequestContext(WebURLRequest::RequestContextVideo); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRangeRequest()) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.setHTTPHeaderField( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebString::fromUTF8(net::HttpRequestHeaders::kRange), 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebString::fromUTF8(net::HttpByteRange::Bounded( 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) first_byte_position_, last_byte_position_).GetHeaderValue())); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame->setReferrerForRequest(request, blink::WebURL()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable compression, compression for audio/video doesn't make sense... 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.setHTTPHeaderField( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebString::fromUTF8(net::HttpRequestHeaders::kAcceptEncoding), 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebString::fromUTF8("identity;q=1, *;q=0")); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for our test WebURLLoader. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebURLLoader> loader; 181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (test_loader_) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader = test_loader_.Pass(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoaderOptions options; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cors_mode_ == kUnspecified) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.allowCredentials = true; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.crossOriginRequestPolicy = 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoaderOptions::CrossOriginRequestPolicyAllow; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.exposeAllResponseHeaders = true; 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The author header set is empty, no preflight should go ahead. 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) options.preflightPolicy = WebURLLoaderOptions::PreventPreflight; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.crossOriginRequestPolicy = 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cors_mode_ == kUseCredentials) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.allowCredentials = true; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader.reset(frame->createAssociatedURLLoader(options)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the resource loading. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader->loadAsynchronously(request, this); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_loader_.reset(new ActiveLoader(loader.Pass())); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_.Run(kLoading); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::Stop() { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset callbacks. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_cb_.Reset(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_.Reset(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress_cb_.Reset(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb_.Reset(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel and reset any active loaders. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_loader_.reset(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::Read( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 position, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_size, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReadCB& read_cb) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(start_cb_.is_null()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(read_cb_.is_null()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_cb.is_null()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buffer); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(read_size, 0); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the parameter of reading. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb_ = read_cb; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_ = position; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_size_ = read_size; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_ = buffer; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads should immediately fail if the loader also failed. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loader_failed_) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kFailed, 0); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're attempting to read past the end of the file, return a zero 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicating EOF. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can happen with callees that read in fixed-sized amounts for parsing 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or at the end of chunked 200 responses when we discover the actual length 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the file. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_size_ != kPositionNotSpecified && 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ <= read_position_) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Appear to have seeked beyond EOS; returning 0."; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kOk, 0); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure |offset_| and |read_position_| does not differ by a large 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // amount. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_position_ > offset_ + kint32max || 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_ < offset_ + kint32min) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kCacheMiss, 0); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure |read_size_| is not too large for the buffer to ever be able to 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fulfill the read request. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_size_ > kMaxBufferCapacity) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kFailed, 0); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare the parameters. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_offset_ = read_position_ - offset_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_offset_ = first_offset_ + read_size_; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we can serve the request now, do the actual read. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanFulfillRead()) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadInternal(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDeferBehavior(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we expect the read request to be fulfilled later, expand capacity as 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary and disable deferring. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WillFulfillRead()) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance offset as much as possible to create additional capacity. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int advance = std::min(first_offset_, buffer_.forward_bytes()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = buffer_.Seek(advance); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ret); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ += advance; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_offset_ -= advance; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_offset_ -= advance; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expand capacity to accomodate a read that extends past the normal 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // capacity. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can happen when reading in a large seek index or when the 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first byte of a read request falls within kForwardWaitThreshold. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_offset_ > buffer_.forward_capacity()) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_forward_capacity_ = buffer_.forward_capacity(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.set_forward_capacity(last_offset_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we stop deferring now that there's additional capacity. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ShouldDefer()) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Capacity was not adjusted properly to prevent deferring."; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDeferBehavior(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a callback to report failure. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kCacheMiss, 0); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 BufferedResourceLoader::content_length() { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content_length_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 BufferedResourceLoader::instance_size() { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return instance_size_; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::range_supported() { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return range_supported_; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// blink::WebURLLoaderClient implementation. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::willSendRequest( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLRequest& newRequest, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebURLResponse& redirectResponse) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The load may have been stopped and |start_cb| is destroyed. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case we shouldn't do anything. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_cb_.is_null()) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the url in the request to an invalid value (empty url). 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) newRequest.setURL(blink::WebURL()); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only allow |single_origin_| if we haven't seen a different origin yet. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_origin_) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_ = newRequest.url(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didSendData( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long bytes_sent, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long total_bytes_to_be_sent) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didReceiveResponse( 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebURLResponse& response) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "didReceiveResponse: HTTP/" 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (response.httpVersion() == WebURLResponse::HTTP_0_9 ? "0.9" : 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.httpVersion() == WebURLResponse::HTTP_1_0 ? "1.0" : 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.httpVersion() == WebURLResponse::HTTP_1_1 ? "1.1" : 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unknown") 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " " << response.httpStatusCode(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(active_loader_.get()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The loader may have been stopped and |start_cb| is destroyed. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case we shouldn't do anything. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_cb_.is_null()) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 reasons = GetReasonsForUncacheability(response); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) might_be_reused_from_cache_in_future_ = reasons == 0; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Media.CacheUseful", reasons == 0); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift = 0; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_enum = base::bits::Log2Ceiling(kMaxReason); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (reasons) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(shift, max_enum); // Sanity check. 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (reasons & 0x1) { 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_ENUMERATION("Media.UncacheableReason", 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci shift, 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_enum); // PRESUBMIT_IGNORE_UMA_MAX 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reasons >>= 1; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++shift; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expected content length can be |kPositionNotSpecified|, in that case 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |content_length_| is not specified and this is a streaming response. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = response.expectedContentLength(); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We make a strong assumption that when we reach here we have either 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // received a response from HTTP/HTTPS protocol or the request was 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // successful (in particular range request). So we only verify the partial 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response for HTTP and HTTPS protocol. 396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (url_.SchemeIsHTTPOrHTTPS()) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool partial_response = (response.httpStatusCode() == kHttpPartialContent); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok_response = (response.httpStatusCode() == kHttpOK); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRangeRequest()) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see whether the server supports byte ranges. 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string accept_ranges = 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.httpHeaderField("Accept-Ranges").utf8(); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_supported_ = (accept_ranges.find("bytes") != std::string::npos); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have verified the partial response and it is correct, we will 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return kOk. It's also possible for a server to support range requests 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without advertising "Accept-Ranges: bytes". 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (partial_response && VerifyPartialResponse(response)) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_supported_ = true; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ok_response && first_byte_position_ == 0 && 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_byte_position_ == kPositionNotSpecified) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We accept a 200 response for a Range:0- request, trusting the 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accept-Ranges header, because Apache thinks that's a reasonable thing 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to return. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = content_length_; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneStart(kFailed); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = content_length_; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response.httpStatusCode() != kHttpOK) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We didn't request a range but server didn't reply with "200 OK". 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneStart(kFailed); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(instance_size_, kPositionNotSpecified); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_length_ != kPositionNotSpecified) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_byte_position_ == kPositionNotSpecified) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = content_length_; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (last_byte_position_ == kPositionNotSpecified) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = content_length_ + first_byte_position_; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calls with a successful response. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneStart(kOk); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didReceiveData( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_length, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int encoded_data_length) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "didReceiveData: " << data_length << " bytes"; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(active_loader_.get()); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(data_length, 0); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.Append(reinterpret_cast<const uint8*>(data), data_length); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is an active read request, try to fulfill the request. 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasPendingRead() && CanFulfillRead()) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadInternal(); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At last see if the buffer is full and we need to defer the downloading. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDeferBehavior(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume excess bytes from our in-memory buffer if necessary. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_.forward_bytes() > buffer_.forward_capacity()) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int excess = buffer_.forward_bytes() - buffer_.forward_capacity(); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = buffer_.Seek(excess); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(success); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ += first_offset_ + excess; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify latest progress and buffered offset. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress_cb_.Run(offset_ + buffer_.forward_bytes() - 1); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didDownloadData( 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebURLLoader* loader, 47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int dataLength, 47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int encoded_data_length) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didReceiveCachedMetadata( 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_length) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didFinishLoading( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) double finishTime, 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t total_encoded_data_length) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "didFinishLoading"; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(active_loader_.get()); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're done with the loader. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_loader_.reset(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_.Run(kLoadingFinished); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we didn't know the |instance_size_| we do now. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_size_ == kPositionNotSpecified) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = offset_ + buffer_.forward_bytes(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is a start callback, run it. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!start_cb_.is_null()) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(read_cb_.is_null()) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Shouldn't have a read callback during start"; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneStart(kOk); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't leave read callbacks hanging around. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasPendingRead()) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to fulfill with what is in the buffer. 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanFulfillRead()) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadInternal(); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kCacheMiss, 0); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::didFail( 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebURLLoader* loader, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebURLError& error) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "didFail: reason=" << error.reason 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", isCancellation=" << error.isCancellation 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", domain=" << error.domain.utf8().data() 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", localizedDescription=" 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << error.localizedDescription.utf8().data(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(active_loader_.get()); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need to continue loading after failure. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep it alive until we exit this method so that |error| remains valid. 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ActiveLoader> active_loader = active_loader_.Pass(); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_failed_ = true; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_.Run(kLoadingFailed); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't leave start callbacks hanging around. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!start_cb_.is_null()) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(read_cb_.is_null()) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Shouldn't have a read callback during start"; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneStart(kFailed); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't leave read callbacks hanging around. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasPendingRead()) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kFailed, 0); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::HasSingleOrigin() const { 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(start_cb_.is_null()) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Start() must complete before calling HasSingleOrigin()"; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_origin_; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::DidPassCORSAccessCheck() const { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(start_cb_.is_null()) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Start() must complete before calling DidPassCORSAccessCheck()"; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !loader_failed_ && cors_mode_ != kUnspecified; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!might_be_reused_from_cache_in_future_ && strategy == kNeverDefer) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strategy = kCapacityDefer; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defer_strategy_ = strategy; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDeferBehavior(); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::SetPlaybackRate(float playback_rate) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate_ = playback_rate; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a pause so don't bother updating the buffer window as we'll likely 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get unpaused in the future. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate_ == 0.0) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBufferWindow(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::SetBitrate(int bitrate) { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bitrate >= 0); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate_ = bitrate; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBufferWindow(); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper methods. 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::UpdateBufferWindow() { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int backward_capacity; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int forward_capacity; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ComputeTargetBufferWindow( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate_, bitrate_, &backward_capacity, &forward_capacity); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This does not evict data from the buffer if the new capacities are less 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than the current capacities; the new limits will be enforced after the 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // existing excess buffered data is consumed. 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.set_backward_capacity(backward_capacity); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.set_forward_capacity(forward_capacity); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::UpdateDeferBehavior() { 607b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!active_loader_) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetDeferred(ShouldDefer()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::SetDeferred(bool deferred) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_loader_->deferred() == deferred) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_loader_->SetDeferred(deferred); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_cb_.Run(deferred ? kLoadingDeferred : kLoading); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::ShouldDefer() const { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(defer_strategy_) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kNeverDefer: 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kReadThenDefer: 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(read_cb_.is_null() || last_offset_ > buffer_.forward_bytes()) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "We shouldn't stop deferring if we can fulfill the read"; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return read_cb_.is_null(); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kCapacityDefer: 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_.forward_bytes() >= buffer_.forward_capacity(); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::CanFulfillRead() const { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are reading too far in the backward direction. 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_offset_ < 0 && (first_offset_ + buffer_.backward_bytes()) < 0) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the start offset is too far ahead. 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_offset_ >= buffer_.forward_bytes()) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At the point, we verified that first byte requested is within the buffer. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request has completed, then just returns with what we have now. 649b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!active_loader_) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the resource request is still active, make sure the whole requested 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // range is covered. 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_offset_ > buffer_.forward_bytes()) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::WillFulfillRead() const { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to read too far behind. 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_offset_ < 0 && (first_offset_ + buffer_.backward_bytes()) < 0) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to read too far ahead. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((first_offset_ - buffer_.forward_bytes()) >= kForwardWaitThreshold) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The resource request has completed, there's no way we can fulfill the 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // read request. 671b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!active_loader_) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::ReadInternal() { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Seek to the first byte requested. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = buffer_.Seek(first_offset_); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ret); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then do the read. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read = buffer_.Read(read_buffer_, read_size_); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ += first_offset_ + read; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And report with what we have read. 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRead(kOk, read); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 BufferedResourceLoader::first_byte_position() const { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return first_byte_position_; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::ParseContentRange( 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& content_range_str, int64* first_byte_position, 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* last_byte_position, int64* instance_size) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kUpThroughBytesUnit = "bytes "; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_range_str.find(kUpThroughBytesUnit) != 0) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string range_spec = 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_range_str.substr(kUpThroughBytesUnit.length()); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t dash_offset = range_spec.find("-"); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t slash_offset = range_spec.find("/"); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dash_offset == std::string::npos || slash_offset == std::string::npos || 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slash_offset < dash_offset || slash_offset + 1 == range_spec.length()) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt64(range_spec.substr(0, dash_offset), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_byte_position) || 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !base::StringToInt64(range_spec.substr(dash_offset + 1, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slash_offset - dash_offset - 1), 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_byte_position)) { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slash_offset == range_spec.length() - 2 && 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_spec[slash_offset + 1] == '*') { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *instance_size = kPositionNotSpecified; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt64(range_spec.substr(slash_offset + 1), 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size)) { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*last_byte_position < *first_byte_position || 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*instance_size != kPositionNotSpecified && 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *last_byte_position >= *instance_size)) { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::VerifyPartialResponse( 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebURLResponse& response) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 first_byte_position, last_byte_position, instance_size; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseContentRange(response.httpHeaderField("Content-Range").utf8(), 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &first_byte_position, &last_byte_position, 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &instance_size)) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_size != kPositionNotSpecified) { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_size_ = instance_size; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_byte_position_ != kPositionNotSpecified && 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_byte_position_ != first_byte_position) { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(hclam): I should also check |last_byte_position|, but since 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we will never make such a request that it is ok to leave it unimplemented. 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::DoneRead(Status status, int bytes_read) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (saved_forward_capacity_) { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.set_forward_capacity(saved_forward_capacity_); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_forward_capacity_ = 0; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_ = 0; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_size_ = 0; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_ = NULL; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_offset_ = 0; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_offset_ = 0; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log(); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ResetAndReturn(&read_cb_).Run(status, bytes_read); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::DoneStart(Status status) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ResetAndReturn(&start_cb_).Run(status); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedResourceLoader::IsRangeRequest() const { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return first_byte_position_ != kPositionNotSpecified; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedResourceLoader::Log() { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_log_->AddEvent( 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_log_->CreateBufferedExtentsChangedEvent( 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ - buffer_.backward_bytes(), 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_, 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_ + buffer_.forward_bytes())); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace media 791