// Copyright (c) 2006-2008 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/string_util.h" #include "net/base/escape.h" #include "net/base/io_buffer.h" #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/url_request/url_request_context.h" #define VIEW_CACHE_HEAD \ "" #define VIEW_CACHE_TAIL \ "
" static void HexDump(const char *buf, size_t buf_len, std::string* result) { const size_t kMaxRows = 16; int offset = 0; const unsigned char *p; while (buf_len) { StringAppendF(result, "%08x: ", offset); offset += kMaxRows; p = (const unsigned char *) buf; size_t i; size_t row_max = std::min(kMaxRows, buf_len); // print hex codes: for (i = 0; i < row_max; ++i) StringAppendF(result, "%02x ", *p++); for (i = row_max; i < kMaxRows; ++i) result->append(" "); // print ASCII glyphs if possible: p = (const unsigned char *) buf; for (i = 0; i < row_max; ++i, ++p) { if (*p < 0x7F && *p > 0x1F) { AppendEscapedCharForHTML(*p, result); } else { result->push_back('.'); } } result->push_back('\n'); buf += row_max; buf_len -= row_max; } } static 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 = "" + EscapeForHTML(key) + ""; 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("
RESPONSE_INFO_TRUNCATED
"); result.append("
");
    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("
"); } for (int i = 0; i < num_entry_data_indices; ++i) { result.append("
");

    int data_size = entry->GetDataSize(i);

    if (data_size) {
      scoped_refptr buffer = new net::IOBuffer(data_size);
      if (entry->ReadData(i, 0, buffer, data_size, NULL) == data_size)
        HexDump(buffer->data(), data_size, &result);
    }

    result.append("
"); } return result; } static disk_cache::Backend* GetDiskCache(URLRequestContext* context) { if (!context) return NULL; if (!context->http_transaction_factory()) return NULL; net::HttpCache* http_cache = context->http_transaction_factory()->GetCache(); if (!http_cache) return NULL; return http_cache->GetBackend(); } static std::string FormatStatistics(disk_cache::Backend* disk_cache) { std::vector > stats; disk_cache->GetStats(&stats); std::string result; for (size_t index = 0; index < stats.size(); index++) { result.append(stats[index].first); result.append(": "); result.append(stats[index].second); result.append("
\n"); } return result; } // 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; } 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)); } } } // 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; } data->append(FormatStatistics(disk_cache)); }