Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: net/tools/cachetool/cachetool.cc

Issue 2114933002: cachetool: Implement batch mode to speed-up cache processing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: s/CommandParser/CommandMarshal/g Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <iostream> 5 #include <iostream>
6 #include <memory> 6 #include <memory>
7 7
8 #include "base/at_exit.h" 8 #include "base/at_exit.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h"
12 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 14 #include "base/run_loop.h"
14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
15 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
16 #include "net/base/test_completion_callback.h" 17 #include "net/base/test_completion_callback.h"
17 #include "net/disk_cache/disk_cache.h" 18 #include "net/disk_cache/disk_cache.h"
18 #include "net/http/http_cache.h" 19 #include "net/http/http_cache.h"
19 #include "net/http/http_response_headers.h" 20 #include "net/http/http_response_headers.h"
20 #include "net/http/http_util.h" 21 #include "net/http/http_util.h"
21 22
22 using disk_cache::Backend; 23 using disk_cache::Backend;
23 using disk_cache::Entry; 24 using disk_cache::Entry;
24 25
25 namespace { 26 namespace {
26 27
27 int kResponseInfoIndex = 0; 28 constexpr int kResponseInfoIndex = 0;
28 29
29 // Get the cache's size. 30 const char* const kCommandNames[] = {
30 bool GetSize(Backend* cache_backend) { 31 "stop", "get_size", "list_keys", "get_stream_for_key",
32 "delete_stream", "delete_key", "update_raw_headers",
33 };
34
35 // Prints the command line help.
36 void PrintHelp() {
37 std::cout << "cachetool <cache_path> <cache_backend_type> <subcommand> "
38 << std::endl
39 << std::endl;
40 std::cout << "Available cache backend types: simple, blockfile" << std::endl;
41 std::cout << "Available subcommands:" << std::endl;
42 std::cout << " batch: Starts cachetool to process serialized commands "
43 << "passed down by the standard input and return commands output "
44 << "in the stdout until the stop command is received." << std::endl;
45 std::cout << " delete_key <key>: Delete key from cache." << std::endl;
46 std::cout << " delete_stream <key> <index>: Delete a particular stream of a"
47 << " given key." << std::endl;
48 std::cout << " get_size: Calculate the total size of the cache in bytes."
49 << std::endl;
50 std::cout << " get_stream <key> <index>: Print a particular stream for a"
51 << " given key." << std::endl;
52 std::cout << " list_keys: List all keys in the cache." << std::endl;
53 std::cout << " update_raw_headers <key>: Update stdin as the key's raw "
54 << "response headers." << std::endl;
55 std::cout << " stop: Verify that the cache can be opened and return, "
56 << "confirming the cache exists and is of the right type."
57 << std::endl;
58 std::cout << "Expected values of <index> are:" << std::endl;
59 std::cout << " 0 (HTTP response headers)" << std::endl;
60 std::cout << " 1 (transport encoded content)" << std::endl;
61 std::cout << " 2 (compiled content)" << std::endl;
62 }
63
64 // Generic command input/output.
65 class CommandMarshal {
66 public:
67 CommandMarshal(Backend* cache_backend)
68 : command_failed_(false), cache_backend_(cache_backend){};
69 virtual ~CommandMarshal(){};
70
71 // Reads the next command's name to execute.
72 virtual std::string ReadCommandName() = 0;
73
74 // Reads the next parameter as an integer.
75 virtual int ReadInt() = 0;
76
77 // Reads the next parameter as stream index.
78 int ReadStreamIndex() {
79 if (has_failed())
80 return -1;
81 int index = ReadInt();
82 if (index < 0 || index > 2) {
83 ReturnFailure("Invalid stream index.");
84 return -1;
85 }
86 return index;
87 }
88
89 // Reads the next parameter as an string.
90 virtual std::string ReadString() = 0;
91
92 // Reads the next parameter from stdin as string.
93 virtual std::string ReadBufferedString() = 0;
94
95 // Communicates back an integer.
96 virtual void ReturnInt(int integer) = 0;
97
98 // Communicates back a string.
99 virtual void ReturnString(const std::string& string) = 0;
100
101 // Communicates back a buffer.
102 virtual void ReturnBuffer(net::GrowableIOBuffer* buffer) = 0;
103
104 // Communicates back command failure.
105 virtual void ReturnFailure(const std::string& error_msg) = 0;
106
107 // Communicates back command success.
108 virtual void ReturnSuccess() { DCHECK(!command_failed_); };
109
110 // Returns whether the command has failed.
111 inline bool has_failed() { return command_failed_; }
112
113 // Returns the opened cache backend.
114 Backend* cache_backend() { return cache_backend_; }
115
116 protected:
117 bool command_failed_;
118 Backend* const cache_backend_;
119 };
120
121 // Command line input/output that is user readable.
122 class ProgramArgumentCommandMarshal final : public CommandMarshal {
123 public:
124 ProgramArgumentCommandMarshal(Backend* cache_backend,
125 base::CommandLine::StringVector args)
126 : CommandMarshal(cache_backend), command_line_args_(args), args_id_(0) {}
127
128 // Implements CommandMarshal.
129 std::string ReadCommandName() override {
130 if (args_id_ == 0)
131 return ReadString();
132 else if (args_id_ == command_line_args_.size())
133 return "stop";
134 else if (!has_failed())
135 ReturnFailure("Command line arguments to long.");
136 return "";
137 }
138
139 // Implements CommandMarshal.
140 int ReadInt() override {
141 std::string interger_str = ReadString();
142 int interger = -1;
143 if (!base::StringToInt(interger_str, &interger)) {
144 ReturnFailure("Couldn't parse integer.");
145 return 0;
146 }
147 return interger;
148 }
149
150 // Implements CommandMarshal.
151 std::string ReadString() override {
152 if (args_id_ < command_line_args_.size())
153 return command_line_args_[args_id_++];
154 if (!has_failed())
155 ReturnFailure("Command line arguments to short.");
156 return "";
157 }
158
159 // Implements CommandMarshal.
160 std::string ReadBufferedString() override {
161 std::ostringstream raw_headers_stream;
162 for (std::string line; std::getline(std::cin, line);)
163 raw_headers_stream << line << std::endl;
164 return raw_headers_stream.str();
165 }
166
167 // Implements CommandMarshal.
168 void ReturnInt(int integer) override {
169 DCHECK(!has_failed());
170 std::cout << integer << std::endl;
171 }
172
173 // Implements CommandMarshal.
174 void ReturnString(const std::string& string) override {
175 DCHECK(!has_failed());
176 std::cout << string << std::endl;
177 }
178
179 // Implements CommandMarshal.
180 void ReturnBuffer(net::GrowableIOBuffer* buffer) override {
181 DCHECK(!has_failed());
182 std::cout.write(buffer->data(), buffer->offset());
183 }
184
185 // Implements CommandMarshal.
186 void ReturnFailure(const std::string& error_msg) override {
187 DCHECK(!has_failed());
188 std::cerr << error_msg << std::endl;
189 command_failed_ = true;
190 }
191
192 private:
193 const base::CommandLine::StringVector command_line_args_;
194 size_t args_id_;
195 };
196
197 // Online command input/output that receives pickled commands from stdin and
198 // returns their results back in stdout. Send the stop command to properly exit
199 // cachetool's main loop.
200 class StreamCommandMarshal final : public CommandMarshal {
201 public:
202 StreamCommandMarshal(Backend* cache_backend)
203 : CommandMarshal(cache_backend) {}
204
205 // Implements CommandMarshal.
206 std::string ReadCommandName() override {
207 if (has_failed())
208 return "";
209 std::cout.flush();
210 size_t command_id = static_cast<size_t>(std::cin.get());
211 if (command_id >= arraysize(kCommandNames)) {
212 ReturnFailure("Unknown command.");
213 return "";
214 }
215 return kCommandNames[command_id];
216 }
217
218 // Implements CommandMarshal.
219 int ReadInt() override {
220 if (has_failed())
221 return -1;
222 int integer = -1;
223 std::cin.read(reinterpret_cast<char*>(&integer), sizeof(integer));
224 return integer;
225 }
226
227 // Implements CommandMarshal.
228 std::string ReadString() override {
229 if (has_failed())
230 return "";
231 int string_size = ReadInt();
232 if (string_size <= 0) {
233 if (string_size < 0)
234 ReturnFailure("Size of string is negative.");
235 return "";
236 }
237 std::vector<char> tmp_buffer(string_size + 1);
238 std::cin.read(&tmp_buffer[0], string_size);
239 tmp_buffer[string_size] = 0;
240 return std::string(&tmp_buffer[0], string_size);
241 }
242
243 // Implements CommandMarshal.
244 std::string ReadBufferedString() override { return ReadString(); }
245
246 // Implements CommandMarshal.
247 void ReturnInt(int integer) override {
248 DCHECK(!command_failed_);
249 std::cout.write(reinterpret_cast<char*>(&integer), sizeof(integer));
250 }
251
252 // Implements CommandMarshal.
253 void ReturnString(const std::string& string) override {
254 ReturnInt(string.size());
255 std::cout.write(string.c_str(), string.size());
256 }
257
258 // Implements CommandMarshal.
259 void ReturnBuffer(net::GrowableIOBuffer* buffer) override {
260 ReturnInt(buffer->offset());
261 std::cout.write(buffer->StartOfBuffer(), buffer->offset());
262 }
263
264 // Implements CommandMarshal.
265 void ReturnFailure(const std::string& error_msg) override {
266 ReturnString(error_msg);
267 command_failed_ = true;
268 }
269
270 // Implements CommandMarshal.
271 void ReturnSuccess() override { ReturnInt(0); }
272 };
273
274 // Gets the cache's size.
275 void GetSize(CommandMarshal* command_marshal) {
31 net::TestCompletionCallback cb; 276 net::TestCompletionCallback cb;
32 int rv = cache_backend->CalculateSizeOfAllEntries(cb.callback()); 277 int rv = command_marshal->cache_backend()->CalculateSizeOfAllEntries(
278 cb.callback());
33 rv = cb.GetResult(rv); 279 rv = cb.GetResult(rv);
34 if (rv < 0) { 280 if (rv < 0)
35 std::cerr << "Couldn't get cache size." << std::endl; 281 return command_marshal->ReturnFailure("Couldn't get cache size.");
36 return false; 282 command_marshal->ReturnSuccess();
37 } 283 command_marshal->ReturnInt(rv);
38 std::cout << rv << std::endl;
39 return true;
40 } 284 }
41 285
42 // Print all of a cache's keys to stdout. 286 // Prints all of a cache's keys to stdout.
43 bool ListKeys(Backend* cache_backend) { 287 bool ListKeys(CommandMarshal* command_marshal) {
44 std::unique_ptr<Backend::Iterator> entry_iterator = 288 std::unique_ptr<Backend::Iterator> entry_iterator =
45 cache_backend->CreateIterator(); 289 command_marshal->cache_backend()->CreateIterator();
46 Entry* entry = nullptr; 290 Entry* entry = nullptr;
47 net::TestCompletionCallback cb; 291 net::TestCompletionCallback cb;
48 int rv = entry_iterator->OpenNextEntry(&entry, cb.callback()); 292 int rv = entry_iterator->OpenNextEntry(&entry, cb.callback());
293 command_marshal->ReturnSuccess();
49 while (cb.GetResult(rv) == net::OK) { 294 while (cb.GetResult(rv) == net::OK) {
50 std::string url = entry->GetKey(); 295 std::string url = entry->GetKey();
51 std::cout << url << std::endl; 296 command_marshal->ReturnString(url);
52 entry->Close(); 297 entry->Close();
53 entry = nullptr; 298 entry = nullptr;
54 rv = entry_iterator->OpenNextEntry(&entry, cb.callback()); 299 rv = entry_iterator->OpenNextEntry(&entry, cb.callback());
55 } 300 }
301 command_marshal->ReturnString("");
56 return true; 302 return true;
57 } 303 }
58 304
59 // Get a key's stream to a buffer. 305 // Gets a key's stream to a buffer.
60 scoped_refptr<net::GrowableIOBuffer> GetStreamForKeyBuffer( 306 scoped_refptr<net::GrowableIOBuffer> GetStreamForKeyBuffer(
61 Backend* cache_backend, 307 CommandMarshal* command_marshal,
62 const std::string& key, 308 const std::string& key,
63 int index) { 309 int index) {
310 DCHECK(!command_marshal->has_failed());
64 Entry* cache_entry; 311 Entry* cache_entry;
65 net::TestCompletionCallback cb; 312 net::TestCompletionCallback cb;
66 int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); 313 int rv = command_marshal->cache_backend()->OpenEntry(key, &cache_entry,
314 cb.callback());
67 if (cb.GetResult(rv) != net::OK) { 315 if (cb.GetResult(rv) != net::OK) {
68 std::cerr << "Couldn't find key's entry." << std::endl; 316 command_marshal->ReturnFailure("Couldn't find key's entry.");
69 return nullptr; 317 return nullptr;
70 } 318 }
71 319
72 const int kInitBufferSize = 8192; 320 const int kInitBufferSize = 8192;
73 scoped_refptr<net::GrowableIOBuffer> buffer(new net::GrowableIOBuffer()); 321 scoped_refptr<net::GrowableIOBuffer> buffer(new net::GrowableIOBuffer());
74 buffer->SetCapacity(kInitBufferSize); 322 buffer->SetCapacity(kInitBufferSize);
75 while (true) { 323 while (true) {
76 rv = cache_entry->ReadData(index, buffer->offset(), buffer.get(), 324 rv = cache_entry->ReadData(index, buffer->offset(), buffer.get(),
77 buffer->capacity() - buffer->offset(), 325 buffer->capacity() - buffer->offset(),
78 cb.callback()); 326 cb.callback());
79 rv = cb.GetResult(rv); 327 rv = cb.GetResult(rv);
80 if (rv < 0) { 328 if (rv < 0) {
81 cache_entry->Close(); 329 cache_entry->Close();
82 std::cerr << "Stream read error." << std::endl; 330 command_marshal->ReturnFailure("Stream read error.");
83 return nullptr; 331 return nullptr;
84 } 332 }
85 buffer->set_offset(buffer->offset() + rv); 333 buffer->set_offset(buffer->offset() + rv);
86 if (rv == 0) 334 if (rv == 0)
87 break; 335 break;
88 buffer->SetCapacity(buffer->offset() * 2); 336 buffer->SetCapacity(buffer->offset() * 2);
89 } 337 }
90 cache_entry->Close(); 338 cache_entry->Close();
91 return buffer; 339 return buffer;
92 } 340 }
93 341
94 // Print a key's stream to stdout. 342 // Prints a key's stream to stdout.
95 bool GetStreamForKey(Backend* cache_backend, 343 void GetStreamForKey(CommandMarshal* command_marshal) {
96 const std::string& key, 344 std::string key = command_marshal->ReadString();
97 int index) { 345 int index = command_marshal->ReadInt();
346 if (command_marshal->has_failed())
347 return;
98 scoped_refptr<net::GrowableIOBuffer> buffer( 348 scoped_refptr<net::GrowableIOBuffer> buffer(
99 GetStreamForKeyBuffer(cache_backend, key, index)); 349 GetStreamForKeyBuffer(command_marshal, key, index));
100 if (!buffer) 350 if (command_marshal->has_failed())
101 return false; 351 return;
102 if (index == kResponseInfoIndex) { 352 if (index == kResponseInfoIndex) {
103 net::HttpResponseInfo response_info; 353 net::HttpResponseInfo response_info;
104 bool truncated_response_info = false; 354 bool truncated_response_info = false;
105 net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(), 355 net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(),
106 &response_info, &truncated_response_info); 356 &response_info, &truncated_response_info);
107 if (truncated_response_info) { 357 if (truncated_response_info)
108 std::cerr << "Truncated HTTP response." << std::endl; 358 return command_marshal->ReturnFailure("Truncated HTTP response.");
109 return false; 359 command_marshal->ReturnSuccess();
110 } 360 command_marshal->ReturnString(
111 std::cout << net::HttpUtil::ConvertHeadersBackToHTTPResponse( 361 net::HttpUtil::ConvertHeadersBackToHTTPResponse(
112 response_info.headers->raw_headers()); 362 response_info.headers->raw_headers()));
113 } else { 363 } else {
114 std::cout.write(buffer->StartOfBuffer(), buffer->offset()); 364 command_marshal->ReturnSuccess();
365 command_marshal->ReturnBuffer(buffer.get());
115 } 366 }
116 return true;
117 } 367 }
118 368
119 // Set stdin as the key's raw response headers. 369 // Sets stdin as the key's raw response headers.
120 bool UpdateRawResponseHeaders(Backend* cache_backend, const std::string& key) { 370 void UpdateRawResponseHeaders(CommandMarshal* command_marshal) {
371 std::string key = command_marshal->ReadString();
372 std::string raw_headers = command_marshal->ReadBufferedString();
373 if (command_marshal->has_failed())
374 return;
121 scoped_refptr<net::GrowableIOBuffer> buffer( 375 scoped_refptr<net::GrowableIOBuffer> buffer(
122 GetStreamForKeyBuffer(cache_backend, key, kResponseInfoIndex)); 376 GetStreamForKeyBuffer(command_marshal, key, kResponseInfoIndex));
123 if (!buffer) 377 if (command_marshal->has_failed())
124 return false; 378 return;
125 net::HttpResponseInfo response_info; 379 net::HttpResponseInfo response_info;
126 bool truncated_response_info = false; 380 bool truncated_response_info = false;
127 net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(), 381 net::HttpCache::ParseResponseInfo(buffer->StartOfBuffer(), buffer->offset(),
128 &response_info, &truncated_response_info); 382 &response_info, &truncated_response_info);
129 if (truncated_response_info) { 383 if (truncated_response_info)
130 std::cerr << "Truncated HTTP response." << std::endl; 384 return command_marshal->ReturnFailure("Truncated HTTP response.");
131 return false; 385
132 } 386 response_info.headers = new net::HttpResponseHeaders(raw_headers);
133 std::ostringstream raw_headers_stream;
134 for (std::string line; std::getline(std::cin, line);)
135 raw_headers_stream << line << std::endl;
136 response_info.headers =
137 new net::HttpResponseHeaders(raw_headers_stream.str());
138 scoped_refptr<net::PickledIOBuffer> data(new net::PickledIOBuffer()); 387 scoped_refptr<net::PickledIOBuffer> data(new net::PickledIOBuffer());
139 response_info.Persist(data->pickle(), false, false); 388 response_info.Persist(data->pickle(), false, false);
140 data->Done(); 389 data->Done();
141 Entry* cache_entry; 390 Entry* cache_entry;
142 net::TestCompletionCallback cb; 391 net::TestCompletionCallback cb;
143 int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); 392 int rv = command_marshal->cache_backend()->OpenEntry(key, &cache_entry,
393 cb.callback());
144 CHECK(cb.GetResult(rv) == net::OK); 394 CHECK(cb.GetResult(rv) == net::OK);
145 int data_len = data->pickle()->size(); 395 int data_len = data->pickle()->size();
146 rv = cache_entry->WriteData(kResponseInfoIndex, 0, data.get(), data_len, 396 rv = cache_entry->WriteData(kResponseInfoIndex, 0, data.get(), data_len,
147 cb.callback(), true); 397 cb.callback(), true);
148 if (cb.GetResult(rv) != data_len) { 398 if (cb.GetResult(rv) != data_len)
149 std::cerr << "Couldn't write headers." << std::endl; 399 return command_marshal->ReturnFailure("Couldn't write headers.");
150 return false; 400 command_marshal->ReturnSuccess();
151 }
152 cache_entry->Close(); 401 cache_entry->Close();
153 return true;
154 } 402 }
155 403
156 // Delete a specified key stream from the cache. 404 // Deletes a specified key stream from the cache.
157 bool DeleteStreamForKey(Backend* cache_backend, 405 void DeleteStreamForKey(CommandMarshal* command_marshal) {
158 const std::string& key, 406 std::string key = command_marshal->ReadString();
159 int index) { 407 int index = command_marshal->ReadInt();
408 if (command_marshal->has_failed())
409 return;
160 Entry* cache_entry; 410 Entry* cache_entry;
161 net::TestCompletionCallback cb; 411 net::TestCompletionCallback cb;
162 int rv = cache_backend->OpenEntry(key, &cache_entry, cb.callback()); 412 int rv = command_marshal->cache_backend()->OpenEntry(key, &cache_entry,
163 if (cb.GetResult(rv) != net::OK) { 413 cb.callback());
164 std::cerr << "Couldn't find key's entry." << std::endl; 414 if (cb.GetResult(rv) != net::OK)
165 return false; 415 return command_marshal->ReturnFailure("Couldn't find key's entry.");
166 }
167 416
168 scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer("")); 417 scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer(""));
169 rv = cache_entry->WriteData(index, 0, buffer.get(), 0, cb.callback(), true); 418 rv = cache_entry->WriteData(index, 0, buffer.get(), 0, cb.callback(), true);
170 if (cb.GetResult(rv) != 0) { 419 if (cb.GetResult(rv) != net::OK)
171 std::cerr << "Couldn't delete key stream." << std::endl; 420 return command_marshal->ReturnFailure("Couldn't delete key stream.");
172 return false; 421 command_marshal->ReturnSuccess();
173 }
174 cache_entry->Close(); 422 cache_entry->Close();
175 return true;
176 } 423 }
177 424
178 // Delete a specified key from the cache. 425 // Deletes a specified key from the cache.
179 bool DeleteKey(Backend* cache_backend, const std::string& key) { 426 void DeleteKey(CommandMarshal* command_marshal) {
427 std::string key = command_marshal->ReadString();
428 if (command_marshal->has_failed())
429 return;
180 net::TestCompletionCallback cb; 430 net::TestCompletionCallback cb;
181 int rv = cache_backend->DoomEntry(key, cb.callback()); 431 int rv = command_marshal->cache_backend()->DoomEntry(key, cb.callback());
182 if (cb.GetResult(rv) != net::OK) { 432 if (cb.GetResult(rv) != net::OK)
183 std::cerr << "Couldn't delete key." << std::endl; 433 command_marshal->ReturnFailure("Couldn't delete key.");
184 return false; 434 else
185 } 435 command_marshal->ReturnSuccess();
186 return true;
187 } 436 }
188 437
189 // Parse stream index from command line argument string. 438 // Executes all command from the |command_marshal|.
190 int ParseStreamIndex(const std::string& index_arg) { 439 bool ExecuteCommands(CommandMarshal* command_marshal) {
191 int index = -1; 440 while (!command_marshal->has_failed()) {
192 if (!base::StringToInt(index_arg, &index)) { 441 std::string subcommand(command_marshal->ReadCommandName());
193 std::cerr << "<index> must be an integer." << std::endl; 442 if (command_marshal->has_failed())
194 return -1; 443 break;
195 } else if (index < 0 || index > 2) { 444 if (subcommand == "stop") {
196 std::cerr << "Invalid stream index." << std::endl; 445 command_marshal->ReturnSuccess();
197 return -1; 446 return true;
447 } else if (subcommand == "batch") {
448 StreamCommandMarshal stream_command_marshal(
449 command_marshal->cache_backend());
450 return ExecuteCommands(&stream_command_marshal);
451 } else if (subcommand == "delete_key") {
452 DeleteKey(command_marshal);
453 } else if (subcommand == "delete_stream") {
454 DeleteStreamForKey(command_marshal);
455 } else if (subcommand == "get_size") {
456 GetSize(command_marshal);
457 } else if (subcommand == "get_stream") {
458 GetStreamForKey(command_marshal);
459 } else if (subcommand == "list_keys") {
460 ListKeys(command_marshal);
461 } else if (subcommand == "update_raw_headers") {
462 UpdateRawResponseHeaders(command_marshal);
463 } else {
464 // The wrong subcommand is originated from the command line.
465 command_marshal->ReturnFailure("Unknown command.");
466 PrintHelp();
467 }
198 } 468 }
199 return index; 469 return false;
200 }
201
202 // Print the command line help.
203 void PrintHelp() {
204 std::cout << "cachetool <cache_path> <cache_backend_type> <subcommand> ..."
205 << std::endl
206 << std::endl;
207 std::cout << "Available cache backend types: simple, blockfile" << std::endl;
208 std::cout << "Available subcommands:" << std::endl;
209 std::cout << " delete_key <key>: Delete key from cache." << std::endl;
210 std::cout << " delete_stream <key> <index>: Delete a particular stream of a"
211 << " given key." << std::endl;
212 std::cout << " get_size: Calculate the total size of the cache in bytes."
213 << std::endl;
214 std::cout << " get_stream <key> <index>: Print a particular stream for a"
215 << " given key." << std::endl;
216 std::cout << " list_keys: List all keys in the cache." << std::endl;
217 std::cout << " update_raw_headers <key>: Update stdin as the key's raw "
218 << "response headers." << std::endl;
219 std::cout << " validate: Verify that the cache can be opened and return, "
220 << "confirming the cache exists and is of the right type."
221 << std::endl;
222 std::cout << "Expected values of <index> are:" << std::endl;
223 std::cout << " 0 (HTTP response headers)" << std::endl;
224 std::cout << " 1 (transport encoded content)" << std::endl;
225 std::cout << " 2 (compiled content)" << std::endl;
226 } 470 }
227 471
228 } // namespace 472 } // namespace
229 473
230 int main(int argc, char* argv[]) { 474 int main(int argc, char* argv[]) {
231 base::AtExitManager at_exit_manager; 475 base::AtExitManager at_exit_manager;
232 base::MessageLoopForIO message_loop; 476 base::MessageLoopForIO message_loop;
233 base::CommandLine::Init(argc, argv); 477 base::CommandLine::Init(argc, argv);
234 const base::CommandLine& command_line = 478 const base::CommandLine& command_line =
235 *base::CommandLine::ForCurrentProcess(); 479 *base::CommandLine::ForCurrentProcess();
236 480
237 base::CommandLine::StringVector args = command_line.GetArgs(); 481 base::CommandLine::StringVector args = command_line.GetArgs();
238 if (args.size() < 3U) { 482 if (args.size() < 3U) {
239 PrintHelp(); 483 PrintHelp();
240 return 1; 484 return 1;
241 } 485 }
242 486
243 base::FilePath cache_path(args[0]); 487 base::FilePath cache_path(args[0]);
244 std::string cache_backend_type(args[1]); 488 std::string cache_backend_type(args[1]);
245 std::string subcommand(args[2]);
246 489
247 net::BackendType backend_type; 490 net::BackendType backend_type;
248 if (cache_backend_type == "simple") { 491 if (cache_backend_type == "simple") {
249 backend_type = net::CACHE_BACKEND_SIMPLE; 492 backend_type = net::CACHE_BACKEND_SIMPLE;
250 } else if (cache_backend_type == "blockfile") { 493 } else if (cache_backend_type == "blockfile") {
251 backend_type = net::CACHE_BACKEND_BLOCKFILE; 494 backend_type = net::CACHE_BACKEND_BLOCKFILE;
252 } else { 495 } else {
253 std::cerr << "Unknown cache type." << std::endl; 496 std::cerr << "Unknown cache type." << std::endl;
254 PrintHelp(); 497 PrintHelp();
255 return 1; 498 return 1;
256 } 499 }
257 500
258 std::unique_ptr<Backend> cache_backend; 501 std::unique_ptr<Backend> cache_backend;
259 net::TestCompletionCallback cb; 502 net::TestCompletionCallback cb;
260 int rv = disk_cache::CreateCacheBackend( 503 int rv = disk_cache::CreateCacheBackend(
261 net::DISK_CACHE, backend_type, cache_path, INT_MAX, false, 504 net::DISK_CACHE, backend_type, cache_path, INT_MAX, false,
262 message_loop.task_runner(), nullptr, &cache_backend, cb.callback()); 505 message_loop.task_runner(), nullptr, &cache_backend, cb.callback());
263 if (cb.GetResult(rv) != net::OK) { 506 if (cb.GetResult(rv) != net::OK) {
264 std::cerr << "Invalid cache." << std::endl; 507 std::cerr << "Invalid cache." << std::endl;
265 return 1; 508 return 1;
266 } 509 }
267 510
268 bool successful_command; 511 ProgramArgumentCommandMarshal program_argument_marshal(
269 if (subcommand == "delete_key" && args.size() == 4) { 512 cache_backend.get(),
270 successful_command = DeleteKey(cache_backend.get(), args[3]); 513 base::CommandLine::StringVector(args.begin() + 2, args.end()));
271 } else if (subcommand == "delete_stream" && args.size() == 5) { 514 bool successful_commands = ExecuteCommands(&program_argument_marshal);
272 int index = ParseStreamIndex(args[4]); 515
273 if (index < 0)
274 return 1;
275 successful_command =
276 DeleteStreamForKey(cache_backend.get(), args[3], index);
277 } else if (subcommand == "get_size" && args.size() == 3) {
278 successful_command = GetSize(cache_backend.get());
279 } else if (subcommand == "get_stream" && args.size() == 5) {
280 int index = ParseStreamIndex(args[4]);
281 if (index < 0)
282 return 1;
283 successful_command = GetStreamForKey(cache_backend.get(), args[3], index);
284 } else if (subcommand == "list_keys" && args.size() == 3) {
285 successful_command = ListKeys(cache_backend.get());
286 } else if (subcommand == "update_raw_headers" && args.size() == 4) {
287 successful_command = UpdateRawResponseHeaders(cache_backend.get(), args[3]);
288 } else if (subcommand == "validate" && args.size() == 3) {
289 successful_command = true;
290 } else {
291 successful_command = false;
292 PrintHelp();
293 }
294 base::RunLoop().RunUntilIdle(); 516 base::RunLoop().RunUntilIdle();
295 cache_backend = nullptr; 517 cache_backend = nullptr;
296 base::RunLoop().RunUntilIdle(); 518 base::RunLoop().RunUntilIdle();
297 return !successful_command; 519 return !successful_commands;
298 } 520 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698