// 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/url_request_view_cache_job.h" #include "base/string_util.h" #include "net/base/escape.h" #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache.h" #include "net/http/http_response_info.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) { std::string key = EscapeForHTML(entry->GetKey()); std::string row = "" + key + ""; return row; } static std::string FormatEntryDetails(disk_cache::Entry* entry) { std::string result = EscapeForHTML(entry->GetKey()); net::HttpResponseInfo response; net::HttpCache::ReadResponseInfo(entry, &response); if (response.headers) { 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 < 2; ++i) { result.append("
");

    int data_size = entry->GetDataSize(i);

    char* data = new char[data_size];
    if (entry->ReadData(i, 0, data, data_size, NULL) == data_size)
      HexDump(data, data_size, &result);

    result.append("
"); } return result; } 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 URLRequestJob* URLRequestViewCacheJob::Factory(URLRequest* request, const std::string& scheme) { return new URLRequestViewCacheJob(request); } bool URLRequestViewCacheJob::GetData(std::string* mime_type, std::string* charset, std::string* data) const { mime_type->assign("text/html"); charset->assign("UTF-8"); disk_cache::Backend* disk_cache = GetDiskCache(); if (!disk_cache) { data->assign("no disk cache"); return true; } if (request_->url().spec() == "view-cache:") { data->assign(VIEW_CACHE_HEAD); void* iter = NULL; disk_cache::Entry* entry; while (disk_cache->OpenNextEntry(&iter, &entry)) { data->append(FormatEntryInfo(entry)); entry->Close(); } data->append(VIEW_CACHE_TAIL); } else if (request_->url().spec() == "view-cache:stats") { data->assign(FormatStatistics(disk_cache)); } else { disk_cache::Entry* entry; if (disk_cache->OpenEntry(request_->url().path(), &entry)) { data->assign(FormatEntryDetails(entry)); entry->Close(); } else { data->assign("no matching cache entry"); } } return true; } disk_cache::Backend* URLRequestViewCacheJob::GetDiskCache() const { if (!request_->context()) return NULL; if (!request_->context()->http_transaction_factory()) return NULL; net::HttpCache* http_cache = request_->context()->http_transaction_factory()->GetCache(); if (!http_cache) return NULL; return http_cache->disk_cache(); }