summaryrefslogtreecommitdiffstats
path: root/webkit/glue/media
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 16:30:31 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 16:30:31 +0000
commite5ca9cad8e87e39651ebfd6a98ff0d2cf10271e4 (patch)
treed518275a602088514e986866abef46e3ab45f56b /webkit/glue/media
parent99f8245a886b3c09f5326b432af8337422a7fa11 (diff)
downloadchromium_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.cc11
-rw-r--r--webkit/glue/media/buffered_data_source.h3
-rw-r--r--webkit/glue/media/buffered_data_source_unittest.cc65
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