15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/view_cache_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/disk_cache.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_cache.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VIEW_CACHE_HEAD \
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "<html><meta charset=\"utf-8\">" \
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "<meta http-equiv=\"Content-Security-Policy\" " \
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "  content=\"object-src 'none'; script-src 'none' 'unsafe-eval'\">" \
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "<body><table>"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VIEW_CACHE_TAIL \
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "</table></body></html>"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string FormatEntryInfo(disk_cache::Entry* entry,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& url_prefix) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = entry->GetKey();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = GURL(url_prefix + key);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string row =
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<tr><td><a href=\"" + url.spec() + "\">" + EscapeForHTML(key) +
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "</a></td></tr>";
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return row;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewCacheHelper::ViewCacheHelper()
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(NULL),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disk_cache_(NULL),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_(NULL),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buf_len_(0),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index_(0),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_(NULL),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_state_(STATE_NONE),
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewCacheHelper::~ViewCacheHelper() {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_->Close();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::GetEntryInfoHTML(const std::string& key,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const URLRequestContext* context,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* out,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const CompletionCallback& callback) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetInfoHTML(key, context, std::string(), out, callback);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::GetContentsHTML(const URLRequestContext* context,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::string& url_prefix,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     std::string* out,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const CompletionCallback& callback) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetInfoHTML(std::string(), context, url_prefix, out, callback);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewCacheHelper::HexDump(const char *buf, size_t buf_len,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::string* result) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMaxRows = 16;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int offset = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char *p;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (buf_len) {
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::StringAppendF(result, "%08x: ", offset);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset += kMaxRows;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p = (const unsigned char *) buf;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t i;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t row_max = std::min(kMaxRows, buf_len);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // print hex codes:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < row_max; ++i)
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::StringAppendF(result, "%02x ", *p++);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = row_max; i < kMaxRows; ++i)
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      result->append("   ");
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    result->append(" ");
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // print ASCII glyphs if possible:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p = (const unsigned char *) buf;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < row_max; ++i, ++p) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*p < 0x7F && *p > 0x1F) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppendEscapedCharForHTML(*p, result);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result->push_back('.');
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->push_back('\n');
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf += row_max;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf_len -= row_max;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::GetInfoHTML(const std::string& key,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const URLRequestContext* context,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const std::string& url_prefix,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* out,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const CompletionCallback& callback) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_ = key;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = context;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_prefix_ = url_prefix;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_ = out;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_GET_BACKEND;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = DoLoop(OK);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewCacheHelper::DoCallback(int rv) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(ERR_IO_PENDING, rv);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback_.is_null());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Run(rv);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Reset();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewCacheHelper::HandleResult(int rv) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(ERR_IO_PENDING, rv);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(ERR_FAILED, rv);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null())
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoCallback(rv);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoLoop(int result) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(next_state_ != STATE_NONE);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = result;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state = next_state_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_NONE;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (state) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_GET_BACKEND:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoGetBackend();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_GET_BACKEND_COMPLETE:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoGetBackendComplete(rv);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_OPEN_NEXT_ENTRY:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoOpenNextEntry();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_OPEN_NEXT_ENTRY_COMPLETE:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoOpenNextEntryComplete(rv);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_OPEN_ENTRY:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoOpenEntry();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_OPEN_ENTRY_COMPLETE:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoOpenEntryComplete(rv);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_RESPONSE:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoReadResponse();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_RESPONSE_COMPLETE:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoReadResponseComplete(rv);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_DATA:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoReadData();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_DATA_COMPLETE:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoReadDataComplete(rv);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "bad state";
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ERR_FAILED;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != ERR_IO_PENDING)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HandleResult(rv);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoGetBackend() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_GET_BACKEND_COMPLETE;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!context_->http_transaction_factory())
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_FAILED;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpCache* http_cache = context_->http_transaction_factory()->GetCache();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!http_cache)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_FAILED;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_cache->GetBackend(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &disk_cache_, base::Bind(&ViewCacheHelper::OnIOComplete,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Unretained(this)));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoGetBackendComplete(int result) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_FAILED) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->append("no disk cache");
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(OK, result);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key_.empty()) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->assign(VIEW_CACHE_HEAD);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!iter_);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_OPEN_NEXT_ENTRY;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_OPEN_ENTRY;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoOpenNextEntry() {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_OPEN_NEXT_ENTRY_COMPLETE;
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!iter_)
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    iter_ = disk_cache_->CreateIterator();
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      iter_->OpenNextEntry(&entry_, base::Bind(&ViewCacheHelper::OnIOComplete,
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               base::Unretained(this)));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoOpenNextEntryComplete(int result) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_FAILED) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->append(VIEW_CACHE_TAIL);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(OK, result);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->append(FormatEntryInfo(entry_, url_prefix_));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_->Close();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry_ = NULL;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_OPEN_NEXT_ENTRY;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoOpenEntry() {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_OPEN_ENTRY_COMPLETE;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return disk_cache_->OpenEntry(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_, &entry_,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ViewCacheHelper::OnIOComplete, base::Unretained(this)));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoOpenEntryComplete(int result) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_FAILED) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->append("no matching cache entry for: " + EscapeForHTML(key_));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->assign(VIEW_CACHE_HEAD);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->append(EscapeForHTML(entry_->GetKey()));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_READ_RESPONSE;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoReadResponse() {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_READ_RESPONSE_COMPLETE;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buf_len_ = entry_->GetDataSize(0);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buf_len_)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buf_len_;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buf_ = new IOBuffer(buf_len_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry_->ReadData(
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buf_.get(),
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buf_len_,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ViewCacheHelper::OnIOComplete, weak_factory_.GetWeakPtr()));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoReadResponseComplete(int result) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result && result == buf_len_) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpResponseInfo response;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool truncated;
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (HttpCache::ParseResponseInfo(
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            buf_->data(), buf_len_, &response, &truncated) &&
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        response.headers.get()) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (truncated)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_->append("<pre>RESPONSE_INFO_TRUNCATED</pre>");
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_->append("<hr><pre>");
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_->append(EscapeForHTML(response.headers->GetStatusLine()));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_->push_back('\n');
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void* iter = NULL;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name, value;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_->append(EscapeForHTML(name));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_->append(": ");
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_->append(EscapeForHTML(value));
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_->push_back('\n');
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_->append("</pre>");
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  index_ = 0;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_READ_DATA;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoReadData() {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->append("<hr><pre>");
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_READ_DATA_COMPLETE;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buf_len_ = entry_->GetDataSize(index_);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buf_len_)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buf_len_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buf_ = new IOBuffer(buf_len_);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry_->ReadData(
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_,
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buf_.get(),
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buf_len_,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ViewCacheHelper::OnIOComplete, weak_factory_.GetWeakPtr()));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewCacheHelper::DoReadDataComplete(int result) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result && result == buf_len_) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HexDump(buf_->data(), buf_len_, data_);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->append("</pre>");
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  index_++;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index_ < HttpCache::kNumCacheEntryDataIndices) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_READ_DATA;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->append(VIEW_CACHE_TAIL);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_->Close();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_ = NULL;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewCacheHelper::OnIOComplete(int result) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoLoop(result);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net.
369