Commit 60d94d76 authored by rvargas@google.com's avatar rvargas@google.com

HTTP Cache: Implement StopCaching(), to avoid caching

explicit downloads.

BUG=22900
TEST=net_unittests
Review URL: http://codereview.chromium.org/8569005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110737 0039d316-1c4b-4281-b951-d872f2087c98
parent e6eacf81
......@@ -183,7 +183,7 @@ int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len,
}
bool HttpCache::Transaction::AddTruncatedFlag() {
DCHECK(mode_ & WRITE);
DCHECK(mode_ & WRITE || mode_ == NONE);
// Don't set the flag for sparse entries.
if (partial_.get() && !truncated_)
......@@ -362,6 +362,16 @@ int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len,
}
void HttpCache::Transaction::StopCaching() {
// We really don't know where we are now. Hopefully there is no operation in
// progress, but nothing really prevents this method to be called after we
// returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this
// point because we need the state machine for that (and even if we are really
// free, that would be an asynchronous operation). In other words, keep the
// entry how it is (it will be marked as truncated at destruction), and let
// the next piece of code that executes know that we are now reading directly
// from the net.
if (cache_ && entry_ && (mode_ & WRITE))
mode_ = NONE;
}
void HttpCache::Transaction::DoneReading() {
......@@ -794,9 +804,9 @@ int HttpCache::Transaction::DoNetworkReadComplete(int result) {
if (!cache_)
return ERR_UNEXPECTED;
// If there is an error and we are saving the data, just tell the user about
// it and wait until the destructor runs to see if we can keep the data.
if (mode_ != NONE && result < 0)
// If there is an error or we aren't saving the data, we are done; just wait
// until the destructor runs to see if we can keep the data.
if (mode_ == NONE || result < 0)
return result;
next_state_ = STATE_CACHE_WRITE_DATA;
......
......@@ -5139,6 +5139,90 @@ TEST(HttpCache, FilterCompletion) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
}
// Tests that we stop cachining when told.
TEST(HttpCache, StopCachingDeletesEntry) {
MockHttpCache cache;
TestOldCompletionCallback callback;
MockHttpRequest request(kSimpleGET_Transaction);
{
scoped_ptr<net::HttpTransaction> trans;
int rv = cache.http_cache()->CreateTransaction(&trans);
EXPECT_EQ(net::OK, rv);
rv = trans->Start(&request, &callback, net::BoundNetLog());
EXPECT_EQ(net::OK, callback.GetResult(rv));
scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
rv = trans->Read(buf, 10, &callback);
EXPECT_EQ(callback.GetResult(rv), 10);
trans->StopCaching();
// We should be able to keep reading.
rv = trans->Read(buf, 256, &callback);
EXPECT_GT(callback.GetResult(rv), 0);
rv = trans->Read(buf, 256, &callback);
EXPECT_EQ(callback.GetResult(rv), 0);
}
// Make sure that the ActiveEntry is gone.
MessageLoop::current()->RunAllPending();
// Verify that the entry is gone.
RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(2, cache.disk_cache()->create_count());
}
// Tests that when we are told to stop caching we don't throw away valid data.
TEST(HttpCache, StopCachingSavesEntry) {
MockHttpCache cache;
TestOldCompletionCallback callback;
MockHttpRequest request(kSimpleGET_Transaction);
{
scoped_ptr<net::HttpTransaction> trans;
int rv = cache.http_cache()->CreateTransaction(&trans);
EXPECT_EQ(net::OK, rv);
// Force a response that can be resumed.
MockTransaction mock_transaction(kSimpleGET_Transaction);
AddMockTransaction(&mock_transaction);
mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
"Content-Length: 42\n"
"Etag: foo\n";
rv = trans->Start(&request, &callback, net::BoundNetLog());
EXPECT_EQ(net::OK, callback.GetResult(rv));
scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
rv = trans->Read(buf, 10, &callback);
EXPECT_EQ(callback.GetResult(rv), 10);
trans->StopCaching();
// We should be able to keep reading.
rv = trans->Read(buf, 256, &callback);
EXPECT_GT(callback.GetResult(rv), 0);
rv = trans->Read(buf, 256, &callback);
EXPECT_EQ(callback.GetResult(rv), 0);
RemoveMockTransaction(&mock_transaction);
}
// Verify that the entry is marked as incomplete.
disk_cache::Entry* entry;
ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
net::HttpResponseInfo response;
bool truncated = false;
EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
EXPECT_TRUE(truncated);
entry->Close();
}
// Tests that we detect truncated rersources from the net when there is
// a Content-Length header.
TEST(HttpCache, TruncatedByContentLength) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment