diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-14 16:30:31 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-14 16:30:31 +0000 |
commit | e5ca9cad8e87e39651ebfd6a98ff0d2cf10271e4 (patch) | |
tree | d518275a602088514e986866abef46e3ab45f56b /webkit/glue/media | |
parent | 99f8245a886b3c09f5326b432af8337422a7fa11 (diff) | |
download | chromium_src-e5ca9cad8e87e39651ebfd6a98ff0d2cf10271e4.zip chromium_src-e5ca9cad8e87e39651ebfd6a98ff0d2cf10271e4.tar.gz chromium_src-e5ca9cad8e87e39651ebfd6a98ff0d2cf10271e4.tar.bz2 |
Adding retry limit for BufferedResourceLoader cache misses.
This allows BufferedDataSource::Read() to fail when bad
servers close the connection right after sending the headers.
BUG=78218
TEST=BufferedDataSourceTest::BoundedCacheMisses
Review URL: http://codereview.chromium.org/7056047
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89010 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/media')
-rw-r--r-- | webkit/glue/media/buffered_data_source.cc | 11 | ||||
-rw-r--r-- | webkit/glue/media/buffered_data_source.h | 3 | ||||
-rw-r--r-- | webkit/glue/media/buffered_data_source_unittest.cc | 65 |
3 files changed, 77 insertions, 2 deletions
diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index dad922c..4e38b54 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -18,6 +18,10 @@ namespace webkit_glue { // of FFmpeg. static const int kInitialReadBufferSize = 32768; +// Number of cache misses we allow for a single Read() before signalling an +// error. +static const int kNumCacheMissRetries = 3; + static WebDataSource* NewBufferedDataSource(MessageLoop* render_loop, WebKit::WebFrame* frame) { return new BufferedDataSource(render_loop, frame); @@ -55,7 +59,8 @@ BufferedDataSource::BufferedDataSource( media_is_paused_(true), media_has_played_(false), preload_(media::METADATA), - using_range_request_(true) { + using_range_request_(true), + cache_miss_retries_left_(kNumCacheMissRetries) { } BufferedDataSource::~BufferedDataSource() {} @@ -240,6 +245,7 @@ void BufferedDataSource::ReadTask( read_position_ = position; read_size_ = read_size; read_buffer_ = buffer; + cache_miss_retries_left_ = kNumCacheMissRetries; // Call to read internal to perform the actual read. ReadInternal(); @@ -537,7 +543,8 @@ void BufferedDataSource::ReadCallback(int error) { // Stop the resource load if it failed. loader_->Stop(); - if (error == net::ERR_CACHE_MISS) { + if (error == net::ERR_CACHE_MISS && cache_miss_retries_left_ > 0) { + cache_miss_retries_left_--; render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &BufferedDataSource::RestartLoadingTask)); return; diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h index ed84436..a1444e9 100644 --- a/webkit/glue/media/buffered_data_source.h +++ b/webkit/glue/media/buffered_data_source.h @@ -205,6 +205,9 @@ class BufferedDataSource : public WebDataSource { // request. bool using_range_request_; + // Number of cache miss retries left. + int cache_miss_retries_left_; + DISALLOW_COPY_AND_ASSIGN(BufferedDataSource); }; diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc index 4e53ba0..5cdde51 100644 --- a/webkit/glue/media/buffered_data_source_unittest.cc +++ b/webkit/glue/media/buffered_data_source_unittest.cc @@ -37,6 +37,7 @@ namespace webkit_glue { static const char* kHttpUrl = "http://test"; static const char* kFileUrl = "file://test"; static const int kDataSize = 1024; +static const int kMaxCacheMissesBeforeFailTest = 20; enum NetworkState { NONE, @@ -358,6 +359,58 @@ class BufferedDataSourceTest : public testing::Test { message_loop_->RunAllPending(); } + BufferedResourceLoader* InvokeCacheMissCreateResourceLoader(int64 start, + int64 end) { + NiceMock<MockBufferedResourceLoader>* new_loader = + new NiceMock<MockBufferedResourceLoader>(); + + EXPECT_CALL(*new_loader, Start(NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll(Assign(&error_, net::OK), + Invoke(this, + &BufferedDataSourceTest::InvokeStartCallback))); + + EXPECT_CALL(*new_loader, range_supported()) + .WillRepeatedly(Return(loader_->range_supported())); + + int error = net::ERR_FAILED; + if (cache_miss_count_ < kMaxCacheMissesBeforeFailTest) { + cache_miss_count_++; + error = net::ERR_CACHE_MISS; + } + + EXPECT_CALL(*new_loader, Read(start, _, NotNull(), NotNull())) + .WillOnce(DoAll(Assign(&error_, error), + Invoke(this, + &BufferedDataSourceTest::InvokeReadCallback))); + + loader_ = new_loader; + return new_loader; + } + + void ReadDataSourceAlwaysCacheMiss(int64 position, int size) { + cache_miss_count_ = 0; + + EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1)) + .WillRepeatedly(Invoke( + this, + &BufferedDataSourceTest::InvokeCacheMissCreateResourceLoader)); + + EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull())) + .WillOnce(DoAll(Assign(&error_, net::ERR_CACHE_MISS), + Invoke(this, + &BufferedDataSourceTest::InvokeReadCallback))); + + EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError)); + + data_source_->Read( + position, size, buffer_, + NewCallback(this, &BufferedDataSourceTest::ReadCallback)); + + message_loop_->RunAllPending(); + + EXPECT_LT(cache_miss_count_, kMaxCacheMissesBeforeFailTest); + } + MOCK_METHOD1(ReadCallback, void(size_t size)); scoped_refptr<NiceMock<MockBufferedResourceLoader> > loader_; @@ -374,6 +427,8 @@ class BufferedDataSourceTest : public testing::Test { uint8 buffer_[1024]; uint8 data_[1024]; + int cache_miss_count_; + private: DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest); }; @@ -518,4 +573,14 @@ TEST_F(BufferedDataSourceTest, AbortDuringPendingRead) { EXPECT_FALSE(read_called); } +// Test that we only allow a limited number of cache misses for a +// single Read() request. +TEST_F(BufferedDataSourceTest, BoundedCacheMisses) { + InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); + + ReadDataSourceAlwaysCacheMiss(0, 10); + + StopDataSource(); +} + } // namespace webkit_glue |