summaryrefslogtreecommitdiffstats
path: root/net/url_request
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-27 22:06:31 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-27 22:06:31 +0000
commitcec6f9b08dd24625cd40df548810561b5a55e7d6 (patch)
treeb3eb73f30533f31a794bf887d7da0eaaf3f13850 /net/url_request
parent28191891f2389382e4e53d004e04a74bcb1b152e (diff)
downloadchromium_src-cec6f9b08dd24625cd40df548810561b5a55e7d6.zip
chromium_src-cec6f9b08dd24625cd40df548810561b5a55e7d6.tar.gz
chromium_src-cec6f9b08dd24625cd40df548810561b5a55e7d6.tar.bz2
view-cache: Refactor ViewCacheHelper and ViewHttpCacheJobFactory
to use asynchronous interfaces. BUG=26730 TEST=unittest Review URL: http://codereview.chromium.org/2168004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48438 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request')
-rw-r--r--net/url_request/view_cache_helper.cc339
-rw-r--r--net/url_request/view_cache_helper.h113
-rw-r--r--net/url_request/view_cache_helper_unittest.cc201
3 files changed, 553 insertions, 100 deletions
diff --git a/net/url_request/view_cache_helper.cc b/net/url_request/view_cache_helper.cc
index 17dcab5..92701b7 100644
--- a/net/url_request/view_cache_helper.cc
+++ b/net/url_request/view_cache_helper.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#include "base/string_util.h"
#include "net/base/escape.h"
#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_response_headers.h"
@@ -19,7 +20,9 @@
#define VIEW_CACHE_TAIL \
"</table></body></html>"
-static void HexDump(const char *buf, size_t buf_len, std::string* result) {
+namespace {
+
+void HexDump(const char *buf, size_t buf_len, std::string* result) {
const size_t kMaxRows = 16;
int offset = 0;
@@ -56,8 +59,8 @@ static void HexDump(const char *buf, size_t buf_len, std::string* result) {
}
}
-static std::string FormatEntryInfo(disk_cache::Entry* entry,
- const std::string& url_prefix) {
+std::string FormatEntryInfo(disk_cache::Entry* entry,
+ const std::string& url_prefix) {
std::string key = entry->GetKey();
GURL url = GURL(url_prefix + key);
std::string row =
@@ -66,117 +69,271 @@ static std::string FormatEntryInfo(disk_cache::Entry* entry,
return row;
}
-static std::string FormatEntryDetails(disk_cache::Entry* entry,
- int num_entry_data_indices) {
- std::string result = EscapeForHTML(entry->GetKey());
-
- net::HttpResponseInfo response;
- bool truncated;
- if (net::HttpCache::ReadResponseInfo(entry, &response, &truncated) &&
- response.headers) {
- if (truncated)
- result.append("<pre>RESPONSE_INFO_TRUNCATED</pre>");
-
- result.append("<hr><pre>");
- result.append(EscapeForHTML(response.headers->GetStatusLine()));
- result.push_back('\n');
-
- void* iter = NULL;
- std::string name, value;
- while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) {
- result.append(EscapeForHTML(name));
- result.append(": ");
- result.append(EscapeForHTML(value));
- result.push_back('\n');
- }
- result.append("</pre>");
- }
+} // namespace.
+
+namespace net {
+
+ViewCacheHelper::~ViewCacheHelper() {
+ if (entry_)
+ entry_->Close();
+
+ // Cancel any pending entry callback.
+ entry_callback_->Cancel();
+}
+
+int ViewCacheHelper::GetEntryInfoHTML(const std::string& key,
+ URLRequestContext* context,
+ std::string* out,
+ CompletionCallback* callback) {
+ return GetInfoHTML(key, context, std::string(), out, callback);
+}
- for (int i = 0; i < num_entry_data_indices; ++i) {
- result.append("<hr><pre>");
+int ViewCacheHelper::GetContentsHTML(URLRequestContext* context,
+ const std::string& url_prefix,
+ std::string* out,
+ CompletionCallback* callback) {
+ return GetInfoHTML(std::string(), context, url_prefix, out, callback);
+}
+
+//-----------------------------------------------------------------------------
+
+int ViewCacheHelper::GetInfoHTML(const std::string& key,
+ URLRequestContext* context,
+ const std::string& url_prefix,
+ std::string* out,
+ CompletionCallback* callback) {
+ DCHECK(!callback_);
+ DCHECK(context);
+ key_ = key;
+ context_ = context;
+ url_prefix_ = url_prefix;
+ data_ = out;
+ next_state_ = STATE_GET_BACKEND;
+ int rv = DoLoop(OK);
+
+ if (rv == ERR_IO_PENDING)
+ callback_ = callback;
+
+ return rv;
+}
- int data_size = entry->GetDataSize(i);
+void ViewCacheHelper::DoCallback(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ DCHECK(callback_);
- if (data_size) {
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_size);
- if (entry->ReadData(i, 0, buffer, data_size, NULL) == data_size)
- HexDump(buffer->data(), data_size, &result);
+ CompletionCallback* c = callback_;
+ callback_ = NULL;
+ c->Run(rv);
+}
+
+void ViewCacheHelper::HandleResult(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ DCHECK_NE(ERR_FAILED, rv);
+ context_ = NULL;
+ if (callback_)
+ DoCallback(rv);
+}
+
+int ViewCacheHelper::DoLoop(int result) {
+ DCHECK(next_state_ != STATE_NONE);
+
+ int rv = result;
+ do {
+ State state = next_state_;
+ next_state_ = STATE_NONE;
+ switch (state) {
+ case STATE_GET_BACKEND:
+ DCHECK_EQ(OK, rv);
+ rv = DoGetBackend();
+ break;
+ case STATE_GET_BACKEND_COMPLETE:
+ rv = DoGetBackendComplete(rv);
+ break;
+ case STATE_OPEN_NEXT_ENTRY:
+ DCHECK_EQ(OK, rv);
+ rv = DoOpenNextEntry();
+ break;
+ case STATE_OPEN_NEXT_ENTRY_COMPLETE:
+ rv = DoOpenNextEntryComplete(rv);
+ break;
+ case STATE_OPEN_ENTRY:
+ DCHECK_EQ(OK, rv);
+ rv = DoOpenEntry();
+ break;
+ case STATE_OPEN_ENTRY_COMPLETE:
+ rv = DoOpenEntryComplete(rv);
+ break;
+ case STATE_READ_RESPONSE:
+ DCHECK_EQ(OK, rv);
+ rv = DoReadResponse();
+ break;
+ case STATE_READ_RESPONSE_COMPLETE:
+ rv = DoReadResponseComplete(rv);
+ break;
+ case STATE_READ_DATA:
+ DCHECK_EQ(OK, rv);
+ rv = DoReadData();
+ break;
+ case STATE_READ_DATA_COMPLETE:
+ rv = DoReadDataComplete(rv);
+ break;
+
+ default:
+ NOTREACHED() << "bad state";
+ rv = ERR_FAILED;
+ break;
}
+ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
- result.append("</pre>");
- }
+ if (rv != ERR_IO_PENDING)
+ HandleResult(rv);
- return result;
+ return rv;
}
-static disk_cache::Backend* GetDiskCache(URLRequestContext* context) {
- if (!context)
- return NULL;
+int ViewCacheHelper::DoGetBackend() {
+ next_state_ = STATE_GET_BACKEND_COMPLETE;
- if (!context->http_transaction_factory())
- return NULL;
+ if (!context_->http_transaction_factory())
+ return ERR_FAILED;
- net::HttpCache* http_cache = context->http_transaction_factory()->GetCache();
+ net::HttpCache* http_cache = context_->http_transaction_factory()->GetCache();
if (!http_cache)
- return NULL;
+ return ERR_FAILED;
- return http_cache->GetBackend();
+ return http_cache->GetBackend(&disk_cache_, &cache_callback_);
}
-static std::string FormatStatistics(disk_cache::Backend* disk_cache) {
- std::vector<std::pair<std::string, std::string> > stats;
- disk_cache->GetStats(&stats);
- std::string result;
+int ViewCacheHelper::DoGetBackendComplete(int result) {
+ if (result == ERR_FAILED) {
+ data_->append("no disk cache");
+ return OK;
+ }
- for (size_t index = 0; index < stats.size(); index++) {
- result.append(stats[index].first);
- result.append(": ");
- result.append(stats[index].second);
- result.append("<br/>\n");
+ DCHECK_EQ(OK, result);
+ if (key_.empty()) {
+ data_->assign(VIEW_CACHE_HEAD);
+ DCHECK(!iter_);
+ next_state_ = STATE_OPEN_NEXT_ENTRY;
+ return OK;
}
- return result;
+ next_state_ = STATE_OPEN_ENTRY;
+ return OK;
}
-// static
-void ViewCacheHelper::GetEntryInfoHTML(const std::string& key,
- URLRequestContext* context,
- const std::string& url_prefix,
- std::string* data) {
- disk_cache::Backend* disk_cache = GetDiskCache(context);
- if (!disk_cache) {
- data->assign("no disk cache");
- return;
+int ViewCacheHelper::DoOpenNextEntry() {
+ next_state_ = STATE_OPEN_NEXT_ENTRY_COMPLETE;
+ return disk_cache_->OpenNextEntry(&iter_, &entry_, &cache_callback_);
+}
+
+int ViewCacheHelper::DoOpenNextEntryComplete(int result) {
+ if (result == ERR_FAILED) {
+ data_->append(VIEW_CACHE_TAIL);
+ return OK;
}
- if (key.empty()) {
- data->assign(VIEW_CACHE_HEAD);
- void* iter = NULL;
- disk_cache::Entry* entry;
- while (disk_cache->OpenNextEntry(&iter, &entry)) {
- data->append(FormatEntryInfo(entry, url_prefix));
- entry->Close();
- }
- data->append(VIEW_CACHE_TAIL);
- } else {
- disk_cache::Entry* entry;
- if (disk_cache->OpenEntry(key, &entry)) {
- data->assign(FormatEntryDetails(
- entry, net::HttpCache::kNumCacheEntryDataIndices));
- entry->Close();
- } else {
- data->assign("no matching cache entry for: " + EscapeForHTML(key));
+ DCHECK_EQ(OK, result);
+ data_->append(FormatEntryInfo(entry_, url_prefix_));
+ entry_->Close();
+ entry_ = NULL;
+
+ next_state_ = STATE_OPEN_NEXT_ENTRY;
+ return OK;
+}
+
+int ViewCacheHelper::DoOpenEntry() {
+ next_state_ = STATE_OPEN_ENTRY_COMPLETE;
+ return disk_cache_->OpenEntry(key_, &entry_, &cache_callback_);
+}
+
+int ViewCacheHelper::DoOpenEntryComplete(int result) {
+ if (result == ERR_FAILED) {
+ data_->append("no matching cache entry for: " + EscapeForHTML(key_));
+ return OK;
+ }
+
+ data_->assign(VIEW_CACHE_HEAD);
+ data_->append(EscapeForHTML(entry_->GetKey()));
+ next_state_ = STATE_READ_RESPONSE;
+ return OK;
+}
+
+int ViewCacheHelper::DoReadResponse() {
+ next_state_ = STATE_READ_RESPONSE_COMPLETE;
+ buf_len_ = entry_->GetDataSize(0);
+ entry_callback_->AddRef();
+ if (!buf_len_)
+ return buf_len_;
+
+ buf_ = new net::IOBuffer(buf_len_);
+ return entry_->ReadData(0, 0, buf_, buf_len_, entry_callback_);
+}
+
+int ViewCacheHelper::DoReadResponseComplete(int result) {
+ entry_callback_->Release();
+ if (result && result == buf_len_) {
+ net::HttpResponseInfo response;
+ bool truncated;
+ if (net::HttpCache::ParseResponseInfo(buf_->data(), buf_len_, &response,
+ &truncated) &&
+ response.headers) {
+ if (truncated)
+ data_->append("<pre>RESPONSE_INFO_TRUNCATED</pre>");
+
+ data_->append("<hr><pre>");
+ data_->append(EscapeForHTML(response.headers->GetStatusLine()));
+ data_->push_back('\n');
+
+ void* iter = NULL;
+ std::string name, value;
+ while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) {
+ data_->append(EscapeForHTML(name));
+ data_->append(": ");
+ data_->append(EscapeForHTML(value));
+ data_->push_back('\n');
+ }
+ data_->append("</pre>");
}
}
+
+ index_ = 0;
+ next_state_ = STATE_READ_DATA;
+ return OK;
+}
+
+int ViewCacheHelper::DoReadData() {
+ data_->append("<hr><pre>");
+
+ next_state_ = STATE_READ_DATA_COMPLETE;
+ buf_len_ = entry_->GetDataSize(index_);
+ entry_callback_->AddRef();
+ if (!buf_len_)
+ return buf_len_;
+
+ buf_ = new net::IOBuffer(buf_len_);
+ return entry_->ReadData(index_, 0, buf_, buf_len_, entry_callback_);
}
-// static
-void ViewCacheHelper::GetStatisticsHTML(URLRequestContext* context,
- std::string* data) {
- disk_cache::Backend* disk_cache = GetDiskCache(context);
- if (!disk_cache) {
- data->append("no disk cache");
- return;
+int ViewCacheHelper::DoReadDataComplete(int result) {
+ entry_callback_->Release();
+ if (result && result == buf_len_) {
+ HexDump(buf_->data(), buf_len_, data_);
}
- data->append(FormatStatistics(disk_cache));
+ data_->append("</pre>");
+ index_++;
+ if (index_ < net::HttpCache::kNumCacheEntryDataIndices) {
+ next_state_ = STATE_READ_DATA;
+ } else {
+ data_->append(VIEW_CACHE_TAIL);
+ entry_->Close();
+ entry_ = NULL;
+ }
+ return OK;
}
+
+void ViewCacheHelper::OnIOComplete(int result) {
+ DoLoop(result);
+}
+
+} // namespace net.
diff --git a/net/url_request/view_cache_helper.h b/net/url_request/view_cache_helper.h
index 2648699..777775a 100644
--- a/net/url_request/view_cache_helper.h
+++ b/net/url_request/view_cache_helper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,18 +7,113 @@
#include <string>
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+
class URLRequestContext;
+namespace disk_cache {
+class Backend;
+class Entry;
+}
+
+namespace net {
+
class ViewCacheHelper {
public:
- // Formats the cache information for |key| as HTML.
- static void GetEntryInfoHTML(const std::string& key,
- URLRequestContext* context,
- const std::string& url_prefix,
- std::string* out);
-
- static void GetStatisticsHTML(URLRequestContext* context,
- std::string* out);
+ ViewCacheHelper()
+ : disk_cache_(NULL), entry_(NULL), iter_(NULL), buf_len_(0), index_(0),
+ data_(NULL), callback_(NULL), next_state_(STATE_NONE),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ cache_callback_(this, &ViewCacheHelper::OnIOComplete)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ entry_callback_(new CancelableCompletionCallback<ViewCacheHelper>(
+ this, &ViewCacheHelper::OnIOComplete))) {}
+ ~ViewCacheHelper();
+
+ // Formats the cache information for |key| as HTML. Returns a net error code.
+ // If this method returns ERR_IO_PENDING, |callback| will be notified when the
+ // operation completes. |out| must remain valid until this operation completes
+ // or the object is destroyed.
+ int GetEntryInfoHTML(const std::string& key, URLRequestContext* context,
+ std::string* out, CompletionCallback* callback);
+
+ // Formats the cache contents as HTML. Returns a net error code.
+ // If this method returns ERR_IO_PENDING, |callback| will be notified when the
+ // operation completes. |out| must remain valid until this operation completes
+ // or the object is destroyed. |url_prefix| will be prepended to each entry
+ // key as a link to the entry.
+ int GetContentsHTML(URLRequestContext* context, const std::string& url_prefix,
+ std::string* out, CompletionCallback* callback);
+
+ private:
+ enum State {
+ STATE_NONE,
+ STATE_GET_BACKEND,
+ STATE_GET_BACKEND_COMPLETE,
+ STATE_OPEN_NEXT_ENTRY,
+ STATE_OPEN_NEXT_ENTRY_COMPLETE,
+ STATE_OPEN_ENTRY,
+ STATE_OPEN_ENTRY_COMPLETE,
+ STATE_READ_RESPONSE,
+ STATE_READ_RESPONSE_COMPLETE,
+ STATE_READ_DATA,
+ STATE_READ_DATA_COMPLETE
+ };
+
+ // Implements GetEntryInfoHTML and GetContentsHTML.
+ int GetInfoHTML(const std::string& key, URLRequestContext* context,
+ const std::string& url_prefix, std::string* out,
+ CompletionCallback* callback);
+
+ // This is a helper function used to trigger a completion callback. It may
+ // only be called if callback_ is non-null.
+ void DoCallback(int rv);
+
+ // This will trigger the completion callback if appropriate.
+ void HandleResult(int rv);
+
+ // Runs the state transition loop.
+ int DoLoop(int result);
+
+ // Each of these methods corresponds to a State value. If there is an
+ // argument, the value corresponds to the return of the previous state or
+ // corresponding callback.
+ int DoGetBackend();
+ int DoGetBackendComplete(int result);
+ int DoOpenNextEntry();
+ int DoOpenNextEntryComplete(int result);
+ int DoOpenEntry();
+ int DoOpenEntryComplete(int result);
+ int DoReadResponse();
+ int DoReadResponseComplete(int result);
+ int DoReadData();
+ int DoReadDataComplete(int result);
+
+ // Called to signal completion of asynchronous IO.
+ void OnIOComplete(int result);
+
+ scoped_refptr<URLRequestContext> context_;
+ disk_cache::Backend* disk_cache_;
+ disk_cache::Entry* entry_;
+ void* iter_;
+ scoped_refptr<net::IOBuffer> buf_;
+ int buf_len_;
+ int index_;
+
+ std::string key_;
+ std::string url_prefix_;
+ std::string* data_;
+ CompletionCallback* callback_;
+
+ State next_state_;
+
+ CompletionCallbackImpl<ViewCacheHelper> cache_callback_;
+ scoped_refptr<CancelableCompletionCallback<ViewCacheHelper> > entry_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewCacheHelper);
};
+} // namespace net.
+
#endif // NET_URL_REQUEST_VIEW_CACHE_HELPER_H_
diff --git a/net/url_request/view_cache_helper_unittest.cc b/net/url_request/view_cache_helper_unittest.cc
new file mode 100644
index 0000000..e82ff15
--- /dev/null
+++ b/net/url_request/view_cache_helper_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/url_request/view_cache_helper.h"
+
+#include "base/pickle.h"
+#include "net/base/test_completion_callback.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/http/http_cache.h"
+#include "net/url_request/url_request_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestURLRequestContext : public URLRequestContext {
+ public:
+ TestURLRequestContext();
+
+ // Gets a pointer to the cache backend.
+ disk_cache::Backend* GetBackend();
+
+ private:
+ net::HttpCache cache_;
+};
+
+TestURLRequestContext::TestURLRequestContext()
+ : cache_(reinterpret_cast<net::HttpTransactionFactory*>(NULL),
+ net::HttpCache::DefaultBackend::InMemory(0)) {
+ http_transaction_factory_ = &cache_;
+}
+
+void WriteHeaders(disk_cache::Entry* entry, int flags, const std::string data) {
+ if (data.empty())
+ return;
+
+ Pickle pickle;
+ pickle.WriteInt(flags | 1); // Version 1.
+ pickle.WriteInt64(0);
+ pickle.WriteInt64(0);
+ pickle.WriteString(data);
+
+ scoped_refptr<net::WrappedIOBuffer> buf = new net::WrappedIOBuffer(
+ reinterpret_cast<const char*>(pickle.data()));
+ int len = static_cast<int>(pickle.size());
+
+ TestCompletionCallback cb;
+ int rv = entry->WriteData(0, 0, buf, len, &cb, true);
+ ASSERT_EQ(len, cb.GetResult(rv));
+}
+
+void WriteData(disk_cache::Entry* entry, int index, const std::string data) {
+ if (data.empty())
+ return;
+
+ int len = data.length();
+ scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(len));
+ memcpy(buf->data(), data.data(), data.length());
+
+ TestCompletionCallback cb;
+ int rv = entry->WriteData(index, 0, buf, len, &cb, true);
+ ASSERT_EQ(len, cb.GetResult(rv));
+}
+
+void WriteToEntry(disk_cache::Backend* cache, const std::string key,
+ const std::string data0, const std::string data1,
+ const std::string data2) {
+ TestCompletionCallback cb;
+ disk_cache::Entry* entry;
+ int rv = cache->CreateEntry(key, &entry, &cb);
+ rv = cb.GetResult(rv);
+ if (rv != net::OK) {
+ rv = cache->OpenEntry(key, &entry, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+ }
+
+ WriteHeaders(entry, 0, data0);
+ WriteData(entry, 1, data1);
+ WriteData(entry, 2, data2);
+
+ entry->Close();
+}
+
+void FillCache(URLRequestContext* context) {
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv =
+ context->http_transaction_factory()->GetCache()->GetBackend(&cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+
+ std::string empty;
+ WriteToEntry(cache, "first", "some", empty, empty);
+ WriteToEntry(cache, "second", "only hex_dumped", "same", "kind");
+ WriteToEntry(cache, "third", empty, "another", "thing");
+}
+
+} // namespace.
+
+TEST(ViewCacheHelper, EmptyCache) {
+ scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
+ net::ViewCacheHelper helper;
+
+ TestCompletionCallback cb;
+ std::string prefix, data;
+ int rv = helper.GetContentsHTML(context, prefix, &data, &cb);
+ EXPECT_EQ(net::OK, cb.GetResult(rv));
+ EXPECT_FALSE(data.empty());
+}
+
+TEST(ViewCacheHelper, ListContents) {
+ scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
+ net::ViewCacheHelper helper;
+
+ FillCache(context);
+
+ std::string prefix, data;
+ TestCompletionCallback cb;
+ int rv = helper.GetContentsHTML(context, prefix, &data, &cb);
+ EXPECT_EQ(net::OK, cb.GetResult(rv));
+
+ EXPECT_EQ(0U, data.find("<html>"));
+ EXPECT_NE(std::string::npos, data.find("</html>"));
+ EXPECT_NE(std::string::npos, data.find("first"));
+ EXPECT_NE(std::string::npos, data.find("second"));
+ EXPECT_NE(std::string::npos, data.find("third"));
+
+ EXPECT_EQ(std::string::npos, data.find("some"));
+ EXPECT_EQ(std::string::npos, data.find("same"));
+ EXPECT_EQ(std::string::npos, data.find("thing"));
+}
+
+TEST(ViewCacheHelper, DumpEntry) {
+ scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
+ net::ViewCacheHelper helper;
+
+ FillCache(context);
+
+ std::string data;
+ TestCompletionCallback cb;
+ int rv = helper.GetEntryInfoHTML("second", context, &data, &cb);
+ EXPECT_EQ(net::OK, cb.GetResult(rv));
+
+ EXPECT_EQ(0U, data.find("<html>"));
+ EXPECT_NE(std::string::npos, data.find("</html>"));
+
+ EXPECT_NE(std::string::npos, data.find("hex_dumped"));
+ EXPECT_NE(std::string::npos, data.find("same"));
+ EXPECT_NE(std::string::npos, data.find("kind"));
+
+ EXPECT_EQ(std::string::npos, data.find("first"));
+ EXPECT_EQ(std::string::npos, data.find("third"));
+ EXPECT_EQ(std::string::npos, data.find("some"));
+ EXPECT_EQ(std::string::npos, data.find("another"));
+}
+
+// Makes sure the links are correct.
+TEST(ViewCacheHelper, Prefix) {
+ scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
+ net::ViewCacheHelper helper;
+
+ FillCache(context);
+
+ std::string key, data;
+ std::string prefix("prefix:");
+ TestCompletionCallback cb;
+ int rv = helper.GetContentsHTML(context, prefix, &data, &cb);
+ EXPECT_EQ(net::OK, cb.GetResult(rv));
+
+ EXPECT_EQ(0U, data.find("<html>"));
+ EXPECT_NE(std::string::npos, data.find("</html>"));
+ EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:first\">"));
+ EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:second\">"));
+ EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:third\">"));
+}
+
+TEST(ViewCacheHelper, TruncatedFlag) {
+ scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
+ net::ViewCacheHelper helper;
+
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv =
+ context->http_transaction_factory()->GetCache()->GetBackend(&cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+
+ std::string key("the key");
+ disk_cache::Entry* entry;
+ rv = cache->CreateEntry(key, &entry, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+
+ // RESPONSE_INFO_TRUNCATED defined on response_info.cc
+ int flags = 1 << 12;
+ WriteHeaders(entry, flags, "something");
+ entry->Close();
+
+ std::string data;
+ rv = helper.GetEntryInfoHTML(key, context, &data, &cb);
+ EXPECT_EQ(net::OK, cb.GetResult(rv));
+
+ EXPECT_NE(std::string::npos, data.find("RESPONSE_INFO_TRUNCATED"));
+}