diff options
Diffstat (limited to 'chromium/net/tools/cachetool')
-rw-r--r-- | chromium/net/tools/cachetool/cachetool.cc | 191 |
1 files changed, 143 insertions, 48 deletions
diff --git a/chromium/net/tools/cachetool/cachetool.cc b/chromium/net/tools/cachetool/cachetool.cc index c186400d9da..fde1ffce112 100644 --- a/chromium/net/tools/cachetool/cachetool.cc +++ b/chromium/net/tools/cachetool/cachetool.cc @@ -3,13 +3,14 @@ // found in the LICENSE file. #include <iostream> +#include <memory> #include "base/at_exit.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "net/base/io_buffer.h" #include "net/base/test_completion_callback.h" @@ -23,9 +24,24 @@ using disk_cache::Entry; namespace { +int kResponseInfoIndex = 0; + +// Get the cache's size. +bool GetSize(Backend* cache_backend) { + net::TestCompletionCallback cb; + int rv = cache_backend->CalculateSizeOfAllEntries(cb.callback()); + rv = cb.GetResult(rv); + if (rv < 0) { + std::cerr << "Couldn't get cache size." << std::endl; + return false; + } + std::cout << rv << std::endl; + return true; +} + // Print all of a cache's keys to stdout. bool ListKeys(Backend* cache_backend) { - scoped_ptr<Backend::Iterator> entry_iterator = + std::unique_ptr<Backend::Iterator> entry_iterator = cache_backend->CreateIterator(); Entry* entry = nullptr; net::TestCompletionCallback cb; @@ -40,19 +56,17 @@ bool ListKeys(Backend* cache_backend) { return true; } -// Print a key's stream to stdout. -bool GetKeyStream(Backend* cache_backend, const std::string& key, int index) { - if (index < 0 || index > 2) { - std::cerr << "Invalid stream index." << std::endl; - return false; - } - +// Get a key's stream to a buffer. +scoped_refptr<net::GrowableIOBuffer> GetStreamForKeyBuffer( + Backend* cache_backend, + const std::string& key, + int index) { Entry* cache_entry; net::TestCompletionCallback cb; int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); if (cb.GetResult(rv) != net::OK) { std::cerr << "Couldn't find key's entry." << std::endl; - return false; + return nullptr; } const int kInitBufferSize = 8192; @@ -66,7 +80,7 @@ bool GetKeyStream(Backend* cache_backend, const std::string& key, int index) { if (rv < 0) { cache_entry->Close(); std::cerr << "Stream read error." << std::endl; - return false; + return nullptr; } buffer->set_offset(buffer->offset() + rv); if (rv == 0) @@ -74,7 +88,18 @@ bool GetKeyStream(Backend* cache_backend, const std::string& key, int index) { buffer->SetCapacity(buffer->offset() * 2); } cache_entry->Close(); - if (index == 0) { + return buffer; +} + +// Print a key's stream to stdout. +bool GetStreamForKey(Backend* cache_backend, + const std::string& key, + int index) { + scoped_refptr<net::GrowableIOBuffer> buffer( + GetStreamForKeyBuffer(cache_backend, key, index)); + if (!buffer) + return false; + if (index == kResponseInfoIndex) { net::HttpResponseInfo response_info; bool truncated_response_info = false; net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(), @@ -91,6 +116,65 @@ bool GetKeyStream(Backend* cache_backend, const std::string& key, int index) { return true; } +// Set stdin as the key's raw response headers. +bool UpdateRawResponseHeaders(Backend* cache_backend, const std::string& key) { + scoped_refptr<net::GrowableIOBuffer> buffer( + GetStreamForKeyBuffer(cache_backend, key, kResponseInfoIndex)); + if (!buffer) + return false; + net::HttpResponseInfo response_info; + bool truncated_response_info = false; + net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(), + &response_info, &truncated_response_info); + if (truncated_response_info) { + std::cerr << "Truncated HTTP response." << std::endl; + return false; + } + std::ostringstream raw_headers_stream; + for (std::string line; std::getline(std::cin, line);) + raw_headers_stream << line << std::endl; + response_info.headers = + new net::HttpResponseHeaders(raw_headers_stream.str()); + scoped_refptr<net::PickledIOBuffer> data(new net::PickledIOBuffer()); + response_info.Persist(data->pickle(), false, false); + data->Done(); + Entry* cache_entry; + net::TestCompletionCallback cb; + int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); + CHECK(cb.GetResult(rv) == net::OK); + int data_len = data->pickle()->size(); + rv = cache_entry->WriteData(kResponseInfoIndex, 0, data.get(), data_len, + cb.callback(), true); + if (cb.GetResult(rv) != data_len) { + std::cerr << "Couldn't write headers." << std::endl; + return false; + } + cache_entry->Close(); + return true; +} + +// Delete a specified key stream from the cache. +bool DeleteStreamForKey(Backend* cache_backend, + const std::string& key, + int index) { + Entry* cache_entry; + net::TestCompletionCallback cb; + int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); + if (cb.GetResult(rv) != net::OK) { + std::cerr << "Couldn't find key's entry." << std::endl; + return false; + } + + scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer("")); + rv = cache_entry->WriteData(index, 0, buffer.get(), 0, cb.callback(), true); + if (cb.GetResult(rv) != 0) { + std::cerr << "Couldn't delete key stream." << std::endl; + return false; + } + cache_entry->Close(); + return true; +} + // Delete a specified key from the cache. bool DeleteKey(Backend* cache_backend, const std::string& key) { net::TestCompletionCallback cb; @@ -102,6 +186,19 @@ bool DeleteKey(Backend* cache_backend, const std::string& key) { return true; } +// Parse stream index from command line argument string. +int ParseStreamIndex(const std::string& index_arg) { + int index = -1; + if (!base::StringToInt(index_arg, &index)) { + std::cerr << "<index> must be an integer." << std::endl; + return -1; + } else if (index < 0 || index > 2) { + std::cerr << "Invalid stream index." << std::endl; + return -1; + } + return index; +} + // Print the command line help. void PrintHelp() { std::cout << "cachetool <cache_path> <cache_backend_type> <subcommand> ..." @@ -109,13 +206,19 @@ void PrintHelp() { << std::endl; std::cout << "Available cache backend types: simple, blockfile" << std::endl; std::cout << "Available subcommands:" << std::endl; - std::cout << " validate: Verify that the cache can be opened and return, " - << "confirming the cache exists and is of the right type." + std::cout << " delete_key <key>: Delete key from cache." << std::endl; + std::cout << " delete_stream <key> <index>: Delete a particular stream of a" + << " given key." << std::endl; + std::cout << " get_size: Calculate the total size of the cache in bytes." << std::endl; - std::cout << " list_keys: List all keys in the cache." << std::endl; std::cout << " get_stream <key> <index>: Print a particular stream for a" << " given key." << std::endl; - std::cout << " delete_key <key>: Delete key from cache." << std::endl; + std::cout << " list_keys: List all keys in the cache." << std::endl; + std::cout << " update_raw_headers <key>: Update stdin as the key's raw " + << "response headers." << std::endl; + std::cout << " validate: Verify that the cache can be opened and return, " + << "confirming the cache exists and is of the right type." + << std::endl; std::cout << "Expected values of <index> are:" << std::endl; std::cout << " 0 (HTTP response headers)" << std::endl; std::cout << " 1 (transport encoded content)" << std::endl; @@ -152,7 +255,7 @@ int main(int argc, char* argv[]) { return 1; } - scoped_ptr<Backend> cache_backend; + std::unique_ptr<Backend> cache_backend; net::TestCompletionCallback cb; int rv = disk_cache::CreateCacheBackend( net::DISK_CACHE, backend_type, cache_path, INT_MAX, false, @@ -162,42 +265,34 @@ int main(int argc, char* argv[]) { return 1; } - bool successful_command = false; - if (subcommand == "validate") { - if (args.size() != 3) { - PrintHelp(); + bool successful_command; + if (subcommand == "delete_key" && args.size() == 4) { + successful_command = DeleteKey(cache_backend.get(), args[3]); + } else if (subcommand == "delete_stream" && args.size() == 5) { + int index = ParseStreamIndex(args[4]); + if (index < 0) return 1; - } - successful_command = true; - } else if (subcommand == "list_keys") { - if (args.size() != 3) { - PrintHelp(); + successful_command = + DeleteStreamForKey(cache_backend.get(), args[3], index); + } else if (subcommand == "get_size" && args.size() == 3) { + successful_command = GetSize(cache_backend.get()); + } else if (subcommand == "get_stream" && args.size() == 5) { + int index = ParseStreamIndex(args[4]); + if (index < 0) return 1; - } + successful_command = GetStreamForKey(cache_backend.get(), args[3], index); + } else if (subcommand == "list_keys" && args.size() == 3) { successful_command = ListKeys(cache_backend.get()); - } else if (subcommand == "get_stream") { - if (args.size() != 5) { - PrintHelp(); - return 1; - } - std::string key(args[3]); - int index = 0; - if (!base::StringToInt(args[4], &index)) { - std::cerr << "<index> must be an integer." << std::endl; - PrintHelp(); - return 1; - } - successful_command = GetKeyStream(cache_backend.get(), key, index); - } else if (subcommand == "delete_key") { - if (args.size() != 4) { - PrintHelp(); - return 1; - } - std::string key(args[3]); - successful_command = DeleteKey(cache_backend.get(), key); + } else if (subcommand == "update_raw_headers" && args.size() == 4) { + successful_command = UpdateRawResponseHeaders(cache_backend.get(), args[3]); + } else if (subcommand == "validate" && args.size() == 3) { + successful_command = true; } else { - std::cerr << "Unknown subcommand." << std::endl; + successful_command = false; PrintHelp(); } + base::RunLoop().RunUntilIdle(); + cache_backend = nullptr; + base::RunLoop().RunUntilIdle(); return !successful_command; } |