Index: net/url_request/view_cache_helper.cc |
=================================================================== |
--- net/url_request/view_cache_helper.cc (revision 48306) |
+++ net/url_request/view_cache_helper.cc (working copy) |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2006-2010 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. |
@@ -7,6 +7,7 @@ |
#include "base/string_util.h" |
#include "net/base/escape.h" |
#include "net/base/io_buffer.h" |
+#include "net/base/net_errors.h" |
#include "net/disk_cache/disk_cache.h" |
#include "net/http/http_cache.h" |
#include "net/http/http_response_headers.h" |
@@ -19,7 +20,9 @@ |
#define VIEW_CACHE_TAIL \ |
"</table></body></html>" |
-static void HexDump(const char *buf, size_t buf_len, std::string* result) { |
+namespace { |
+ |
+void HexDump(const char *buf, size_t buf_len, std::string* result) { |
const size_t kMaxRows = 16; |
int offset = 0; |
@@ -56,8 +59,8 @@ |
} |
} |
-static std::string FormatEntryInfo(disk_cache::Entry* entry, |
- const std::string& url_prefix) { |
+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 = |
@@ -66,117 +69,271 @@ |
return row; |
} |
-static std::string FormatEntryDetails(disk_cache::Entry* entry, |
- int num_entry_data_indices) { |
- std::string result = EscapeForHTML(entry->GetKey()); |
+} // namespace. |
- net::HttpResponseInfo response; |
- bool truncated; |
- if (net::HttpCache::ReadResponseInfo(entry, &response, &truncated) && |
- response.headers) { |
- if (truncated) |
- result.append("<pre>RESPONSE_INFO_TRUNCATED</pre>"); |
+namespace net { |
- result.append("<hr><pre>"); |
- result.append(EscapeForHTML(response.headers->GetStatusLine())); |
- result.push_back('\n'); |
+ViewCacheHelper::~ViewCacheHelper() { |
+ if (entry_) |
+ entry_->Close(); |
- 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("</pre>"); |
- } |
+ // Cancel any pending entry callback. |
+ entry_callback_->Cancel(); |
+} |
- for (int i = 0; i < num_entry_data_indices; ++i) { |
- result.append("<hr><pre>"); |
+int ViewCacheHelper::GetEntryInfoHTML(const std::string& key, |
+ URLRequestContext* context, |
+ std::string* out, |
+ CompletionCallback* callback) { |
+ return GetInfoHTML(key, context, std::string(), out, callback); |
+} |
- int data_size = entry->GetDataSize(i); |
+int ViewCacheHelper::GetContentsHTML(URLRequestContext* context, |
+ const std::string& url_prefix, |
+ std::string* out, |
+ CompletionCallback* callback) { |
+ return GetInfoHTML(std::string(), context, url_prefix, out, callback); |
+} |
- if (data_size) { |
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_size); |
- if (entry->ReadData(i, 0, buffer, data_size, NULL) == data_size) |
- HexDump(buffer->data(), data_size, &result); |
+//----------------------------------------------------------------------------- |
+ |
+int ViewCacheHelper::GetInfoHTML(const std::string& key, |
+ URLRequestContext* context, |
+ const std::string& url_prefix, |
+ std::string* out, |
+ CompletionCallback* callback) { |
+ DCHECK(!callback_); |
+ DCHECK(context); |
+ key_ = key; |
+ context_ = context; |
+ url_prefix_ = url_prefix; |
+ data_ = out; |
+ next_state_ = STATE_GET_BACKEND; |
+ int rv = DoLoop(OK); |
+ |
+ if (rv == ERR_IO_PENDING) |
+ callback_ = callback; |
+ |
+ return rv; |
+} |
+ |
+void ViewCacheHelper::DoCallback(int rv) { |
+ DCHECK_NE(ERR_IO_PENDING, rv); |
+ DCHECK(callback_); |
+ |
+ CompletionCallback* c = callback_; |
+ callback_ = NULL; |
+ c->Run(rv); |
+} |
+ |
+void ViewCacheHelper::HandleResult(int rv) { |
+ DCHECK_NE(ERR_IO_PENDING, rv); |
+ DCHECK_NE(ERR_FAILED, rv); |
+ context_ = NULL; |
+ if (callback_) |
+ DoCallback(rv); |
+} |
+ |
+int ViewCacheHelper::DoLoop(int result) { |
+ DCHECK(next_state_ != STATE_NONE); |
+ |
+ int rv = result; |
+ do { |
+ State state = next_state_; |
+ next_state_ = STATE_NONE; |
+ switch (state) { |
+ case STATE_GET_BACKEND: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoGetBackend(); |
+ break; |
+ case STATE_GET_BACKEND_COMPLETE: |
+ rv = DoGetBackendComplete(rv); |
+ break; |
+ case STATE_OPEN_NEXT_ENTRY: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoOpenNextEntry(); |
+ break; |
+ case STATE_OPEN_NEXT_ENTRY_COMPLETE: |
+ rv = DoOpenNextEntryComplete(rv); |
+ break; |
+ case STATE_OPEN_ENTRY: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoOpenEntry(); |
+ break; |
+ case STATE_OPEN_ENTRY_COMPLETE: |
+ rv = DoOpenEntryComplete(rv); |
+ break; |
+ case STATE_READ_RESPONSE: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoReadResponse(); |
+ break; |
+ case STATE_READ_RESPONSE_COMPLETE: |
+ rv = DoReadResponseComplete(rv); |
+ break; |
+ case STATE_READ_DATA: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoReadData(); |
+ break; |
+ case STATE_READ_DATA_COMPLETE: |
+ rv = DoReadDataComplete(rv); |
+ break; |
+ |
+ default: |
+ NOTREACHED() << "bad state"; |
+ rv = ERR_FAILED; |
+ break; |
} |
+ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
- result.append("</pre>"); |
- } |
+ if (rv != ERR_IO_PENDING) |
+ HandleResult(rv); |
- return result; |
+ return rv; |
} |
-static disk_cache::Backend* GetDiskCache(URLRequestContext* context) { |
- if (!context) |
- return NULL; |
+int ViewCacheHelper::DoGetBackend() { |
+ next_state_ = STATE_GET_BACKEND_COMPLETE; |
- if (!context->http_transaction_factory()) |
- return NULL; |
+ if (!context_->http_transaction_factory()) |
+ return ERR_FAILED; |
- net::HttpCache* http_cache = context->http_transaction_factory()->GetCache(); |
+ net::HttpCache* http_cache = context_->http_transaction_factory()->GetCache(); |
if (!http_cache) |
- return NULL; |
+ return ERR_FAILED; |
- return http_cache->GetBackend(); |
+ return http_cache->GetBackend(&disk_cache_, &cache_callback_); |
} |
-static std::string FormatStatistics(disk_cache::Backend* disk_cache) { |
- std::vector<std::pair<std::string, std::string> > stats; |
- disk_cache->GetStats(&stats); |
- std::string result; |
+int ViewCacheHelper::DoGetBackendComplete(int result) { |
+ if (result == ERR_FAILED) { |
+ data_->append("no disk cache"); |
+ return OK; |
+ } |
- for (size_t index = 0; index < stats.size(); index++) { |
- result.append(stats[index].first); |
- result.append(": "); |
- result.append(stats[index].second); |
- result.append("<br/>\n"); |
+ DCHECK_EQ(OK, result); |
+ if (key_.empty()) { |
+ data_->assign(VIEW_CACHE_HEAD); |
+ DCHECK(!iter_); |
+ next_state_ = STATE_OPEN_NEXT_ENTRY; |
+ return OK; |
} |
- return result; |
+ next_state_ = STATE_OPEN_ENTRY; |
+ return OK; |
} |
-// 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; |
+int ViewCacheHelper::DoOpenNextEntry() { |
+ next_state_ = STATE_OPEN_NEXT_ENTRY_COMPLETE; |
+ return disk_cache_->OpenNextEntry(&iter_, &entry_, &cache_callback_); |
+} |
+ |
+int ViewCacheHelper::DoOpenNextEntryComplete(int result) { |
+ if (result == ERR_FAILED) { |
+ data_->append(VIEW_CACHE_TAIL); |
+ return OK; |
} |
- 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(); |
+ DCHECK_EQ(OK, result); |
+ data_->append(FormatEntryInfo(entry_, url_prefix_)); |
+ entry_->Close(); |
+ entry_ = NULL; |
+ |
+ next_state_ = STATE_OPEN_NEXT_ENTRY; |
+ return OK; |
+} |
+ |
+int ViewCacheHelper::DoOpenEntry() { |
+ next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
+ return disk_cache_->OpenEntry(key_, &entry_, &cache_callback_); |
+} |
+ |
+int ViewCacheHelper::DoOpenEntryComplete(int result) { |
+ if (result == ERR_FAILED) { |
+ data_->append("no matching cache entry for: " + EscapeForHTML(key_)); |
+ return OK; |
+ } |
+ |
+ data_->assign(VIEW_CACHE_HEAD); |
+ data_->append(EscapeForHTML(entry_->GetKey())); |
+ next_state_ = STATE_READ_RESPONSE; |
+ return OK; |
+} |
+ |
+int ViewCacheHelper::DoReadResponse() { |
+ next_state_ = STATE_READ_RESPONSE_COMPLETE; |
+ buf_len_ = entry_->GetDataSize(0); |
+ entry_callback_->AddRef(); |
+ if (!buf_len_) |
+ return buf_len_; |
+ |
+ buf_ = new net::IOBuffer(buf_len_); |
+ return entry_->ReadData(0, 0, buf_, buf_len_, entry_callback_); |
+} |
+ |
+int ViewCacheHelper::DoReadResponseComplete(int result) { |
+ entry_callback_->Release(); |
+ if (result && result == buf_len_) { |
+ net::HttpResponseInfo response; |
+ bool truncated; |
+ if (net::HttpCache::ParseResponseInfo(buf_->data(), buf_len_, &response, |
+ &truncated) && |
+ response.headers) { |
+ if (truncated) |
+ data_->append("<pre>RESPONSE_INFO_TRUNCATED</pre>"); |
+ |
+ data_->append("<hr><pre>"); |
+ data_->append(EscapeForHTML(response.headers->GetStatusLine())); |
+ data_->push_back('\n'); |
+ |
+ void* iter = NULL; |
+ std::string name, value; |
+ while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) { |
+ data_->append(EscapeForHTML(name)); |
+ data_->append(": "); |
+ data_->append(EscapeForHTML(value)); |
+ data_->push_back('\n'); |
+ } |
+ data_->append("</pre>"); |
} |
- 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)); |
- } |
} |
+ |
+ index_ = 0; |
+ next_state_ = STATE_READ_DATA; |
+ return OK; |
} |
-// 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; |
+int ViewCacheHelper::DoReadData() { |
+ data_->append("<hr><pre>"); |
+ |
+ next_state_ = STATE_READ_DATA_COMPLETE; |
+ buf_len_ = entry_->GetDataSize(index_); |
+ entry_callback_->AddRef(); |
+ if (!buf_len_) |
+ return buf_len_; |
+ |
+ buf_ = new net::IOBuffer(buf_len_); |
+ return entry_->ReadData(index_, 0, buf_, buf_len_, entry_callback_); |
+} |
+ |
+int ViewCacheHelper::DoReadDataComplete(int result) { |
+ entry_callback_->Release(); |
+ if (result && result == buf_len_) { |
+ HexDump(buf_->data(), buf_len_, data_); |
} |
- data->append(FormatStatistics(disk_cache)); |
+ data_->append("</pre>"); |
+ index_++; |
+ if (index_ < net::HttpCache::kNumCacheEntryDataIndices) { |
+ next_state_ = STATE_READ_DATA; |
+ } else { |
+ data_->append(VIEW_CACHE_TAIL); |
+ entry_->Close(); |
+ entry_ = NULL; |
+ } |
+ return OK; |
} |
+ |
+void ViewCacheHelper::OnIOComplete(int result) { |
+ DoLoop(result); |
+} |
+ |
+} // namespace net. |