OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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 "net/url_request/view_cache_helper.h" | 5 #include "net/url_request/view_cache_helper.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "net/base/escape.h" | 8 #include "net/base/escape.h" |
9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
| 10 #include "net/base/net_errors.h" |
10 #include "net/disk_cache/disk_cache.h" | 11 #include "net/disk_cache/disk_cache.h" |
11 #include "net/http/http_cache.h" | 12 #include "net/http/http_cache.h" |
12 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
13 #include "net/http/http_response_info.h" | 14 #include "net/http/http_response_info.h" |
14 #include "net/url_request/url_request_context.h" | 15 #include "net/url_request/url_request_context.h" |
15 | 16 |
16 #define VIEW_CACHE_HEAD \ | 17 #define VIEW_CACHE_HEAD \ |
17 "<html><body><table>" | 18 "<html><body><table>" |
18 | 19 |
19 #define VIEW_CACHE_TAIL \ | 20 #define VIEW_CACHE_TAIL \ |
20 "</table></body></html>" | 21 "</table></body></html>" |
21 | 22 |
22 static void HexDump(const char *buf, size_t buf_len, std::string* result) { | 23 namespace { |
| 24 |
| 25 void HexDump(const char *buf, size_t buf_len, std::string* result) { |
23 const size_t kMaxRows = 16; | 26 const size_t kMaxRows = 16; |
24 int offset = 0; | 27 int offset = 0; |
25 | 28 |
26 const unsigned char *p; | 29 const unsigned char *p; |
27 while (buf_len) { | 30 while (buf_len) { |
28 StringAppendF(result, "%08x: ", offset); | 31 StringAppendF(result, "%08x: ", offset); |
29 offset += kMaxRows; | 32 offset += kMaxRows; |
30 | 33 |
31 p = (const unsigned char *) buf; | 34 p = (const unsigned char *) buf; |
32 | 35 |
(...skipping 16 matching lines...) Expand all Loading... |
49 } | 52 } |
50 } | 53 } |
51 | 54 |
52 result->push_back('\n'); | 55 result->push_back('\n'); |
53 | 56 |
54 buf += row_max; | 57 buf += row_max; |
55 buf_len -= row_max; | 58 buf_len -= row_max; |
56 } | 59 } |
57 } | 60 } |
58 | 61 |
59 static std::string FormatEntryInfo(disk_cache::Entry* entry, | 62 std::string FormatEntryInfo(disk_cache::Entry* entry, |
60 const std::string& url_prefix) { | 63 const std::string& url_prefix) { |
61 std::string key = entry->GetKey(); | 64 std::string key = entry->GetKey(); |
62 GURL url = GURL(url_prefix + key); | 65 GURL url = GURL(url_prefix + key); |
63 std::string row = | 66 std::string row = |
64 "<tr><td><a href=\"" + url.spec() + "\">" + EscapeForHTML(key) + | 67 "<tr><td><a href=\"" + url.spec() + "\">" + EscapeForHTML(key) + |
65 "</a></td></tr>"; | 68 "</a></td></tr>"; |
66 return row; | 69 return row; |
67 } | 70 } |
68 | 71 |
69 static std::string FormatEntryDetails(disk_cache::Entry* entry, | 72 } // namespace. |
70 int num_entry_data_indices) { | 73 |
71 std::string result = EscapeForHTML(entry->GetKey()); | 74 namespace net { |
72 | 75 |
73 net::HttpResponseInfo response; | 76 ViewCacheHelper::~ViewCacheHelper() { |
74 bool truncated; | 77 if (entry_) |
75 if (net::HttpCache::ReadResponseInfo(entry, &response, &truncated) && | 78 entry_->Close(); |
76 response.headers) { | 79 |
77 if (truncated) | 80 // Cancel any pending entry callback. |
78 result.append("<pre>RESPONSE_INFO_TRUNCATED</pre>"); | 81 entry_callback_->Cancel(); |
79 | 82 } |
80 result.append("<hr><pre>"); | 83 |
81 result.append(EscapeForHTML(response.headers->GetStatusLine())); | 84 int ViewCacheHelper::GetEntryInfoHTML(const std::string& key, |
82 result.push_back('\n'); | 85 URLRequestContext* context, |
83 | 86 std::string* out, |
84 void* iter = NULL; | 87 CompletionCallback* callback) { |
85 std::string name, value; | 88 return GetInfoHTML(key, context, std::string(), out, callback); |
86 while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) { | 89 } |
87 result.append(EscapeForHTML(name)); | 90 |
88 result.append(": "); | 91 int ViewCacheHelper::GetContentsHTML(URLRequestContext* context, |
89 result.append(EscapeForHTML(value)); | 92 const std::string& url_prefix, |
90 result.push_back('\n'); | 93 std::string* out, |
| 94 CompletionCallback* callback) { |
| 95 return GetInfoHTML(std::string(), context, url_prefix, out, callback); |
| 96 } |
| 97 |
| 98 //----------------------------------------------------------------------------- |
| 99 |
| 100 int ViewCacheHelper::GetInfoHTML(const std::string& key, |
| 101 URLRequestContext* context, |
| 102 const std::string& url_prefix, |
| 103 std::string* out, |
| 104 CompletionCallback* callback) { |
| 105 DCHECK(!callback_); |
| 106 DCHECK(context); |
| 107 key_ = key; |
| 108 context_ = context; |
| 109 url_prefix_ = url_prefix; |
| 110 data_ = out; |
| 111 next_state_ = STATE_GET_BACKEND; |
| 112 int rv = DoLoop(OK); |
| 113 |
| 114 if (rv == ERR_IO_PENDING) |
| 115 callback_ = callback; |
| 116 |
| 117 return rv; |
| 118 } |
| 119 |
| 120 void ViewCacheHelper::DoCallback(int rv) { |
| 121 DCHECK_NE(ERR_IO_PENDING, rv); |
| 122 DCHECK(callback_); |
| 123 |
| 124 CompletionCallback* c = callback_; |
| 125 callback_ = NULL; |
| 126 c->Run(rv); |
| 127 } |
| 128 |
| 129 void ViewCacheHelper::HandleResult(int rv) { |
| 130 DCHECK_NE(ERR_IO_PENDING, rv); |
| 131 DCHECK_NE(ERR_FAILED, rv); |
| 132 context_ = NULL; |
| 133 if (callback_) |
| 134 DoCallback(rv); |
| 135 } |
| 136 |
| 137 int ViewCacheHelper::DoLoop(int result) { |
| 138 DCHECK(next_state_ != STATE_NONE); |
| 139 |
| 140 int rv = result; |
| 141 do { |
| 142 State state = next_state_; |
| 143 next_state_ = STATE_NONE; |
| 144 switch (state) { |
| 145 case STATE_GET_BACKEND: |
| 146 DCHECK_EQ(OK, rv); |
| 147 rv = DoGetBackend(); |
| 148 break; |
| 149 case STATE_GET_BACKEND_COMPLETE: |
| 150 rv = DoGetBackendComplete(rv); |
| 151 break; |
| 152 case STATE_OPEN_NEXT_ENTRY: |
| 153 DCHECK_EQ(OK, rv); |
| 154 rv = DoOpenNextEntry(); |
| 155 break; |
| 156 case STATE_OPEN_NEXT_ENTRY_COMPLETE: |
| 157 rv = DoOpenNextEntryComplete(rv); |
| 158 break; |
| 159 case STATE_OPEN_ENTRY: |
| 160 DCHECK_EQ(OK, rv); |
| 161 rv = DoOpenEntry(); |
| 162 break; |
| 163 case STATE_OPEN_ENTRY_COMPLETE: |
| 164 rv = DoOpenEntryComplete(rv); |
| 165 break; |
| 166 case STATE_READ_RESPONSE: |
| 167 DCHECK_EQ(OK, rv); |
| 168 rv = DoReadResponse(); |
| 169 break; |
| 170 case STATE_READ_RESPONSE_COMPLETE: |
| 171 rv = DoReadResponseComplete(rv); |
| 172 break; |
| 173 case STATE_READ_DATA: |
| 174 DCHECK_EQ(OK, rv); |
| 175 rv = DoReadData(); |
| 176 break; |
| 177 case STATE_READ_DATA_COMPLETE: |
| 178 rv = DoReadDataComplete(rv); |
| 179 break; |
| 180 |
| 181 default: |
| 182 NOTREACHED() << "bad state"; |
| 183 rv = ERR_FAILED; |
| 184 break; |
91 } | 185 } |
92 result.append("</pre>"); | 186 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
93 } | 187 |
94 | 188 if (rv != ERR_IO_PENDING) |
95 for (int i = 0; i < num_entry_data_indices; ++i) { | 189 HandleResult(rv); |
96 result.append("<hr><pre>"); | 190 |
97 | 191 return rv; |
98 int data_size = entry->GetDataSize(i); | 192 } |
99 | 193 |
100 if (data_size) { | 194 int ViewCacheHelper::DoGetBackend() { |
101 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_size); | 195 next_state_ = STATE_GET_BACKEND_COMPLETE; |
102 if (entry->ReadData(i, 0, buffer, data_size, NULL) == data_size) | 196 |
103 HexDump(buffer->data(), data_size, &result); | 197 if (!context_->http_transaction_factory()) |
| 198 return ERR_FAILED; |
| 199 |
| 200 net::HttpCache* http_cache = context_->http_transaction_factory()->GetCache(); |
| 201 if (!http_cache) |
| 202 return ERR_FAILED; |
| 203 |
| 204 return http_cache->GetBackend(&disk_cache_, &cache_callback_); |
| 205 } |
| 206 |
| 207 int ViewCacheHelper::DoGetBackendComplete(int result) { |
| 208 if (result == ERR_FAILED) { |
| 209 data_->append("no disk cache"); |
| 210 return OK; |
| 211 } |
| 212 |
| 213 DCHECK_EQ(OK, result); |
| 214 if (key_.empty()) { |
| 215 data_->assign(VIEW_CACHE_HEAD); |
| 216 DCHECK(!iter_); |
| 217 next_state_ = STATE_OPEN_NEXT_ENTRY; |
| 218 return OK; |
| 219 } |
| 220 |
| 221 next_state_ = STATE_OPEN_ENTRY; |
| 222 return OK; |
| 223 } |
| 224 |
| 225 int ViewCacheHelper::DoOpenNextEntry() { |
| 226 next_state_ = STATE_OPEN_NEXT_ENTRY_COMPLETE; |
| 227 return disk_cache_->OpenNextEntry(&iter_, &entry_, &cache_callback_); |
| 228 } |
| 229 |
| 230 int ViewCacheHelper::DoOpenNextEntryComplete(int result) { |
| 231 if (result == ERR_FAILED) { |
| 232 data_->append(VIEW_CACHE_TAIL); |
| 233 return OK; |
| 234 } |
| 235 |
| 236 DCHECK_EQ(OK, result); |
| 237 data_->append(FormatEntryInfo(entry_, url_prefix_)); |
| 238 entry_->Close(); |
| 239 entry_ = NULL; |
| 240 |
| 241 next_state_ = STATE_OPEN_NEXT_ENTRY; |
| 242 return OK; |
| 243 } |
| 244 |
| 245 int ViewCacheHelper::DoOpenEntry() { |
| 246 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
| 247 return disk_cache_->OpenEntry(key_, &entry_, &cache_callback_); |
| 248 } |
| 249 |
| 250 int ViewCacheHelper::DoOpenEntryComplete(int result) { |
| 251 if (result == ERR_FAILED) { |
| 252 data_->append("no matching cache entry for: " + EscapeForHTML(key_)); |
| 253 return OK; |
| 254 } |
| 255 |
| 256 data_->assign(VIEW_CACHE_HEAD); |
| 257 data_->append(EscapeForHTML(entry_->GetKey())); |
| 258 next_state_ = STATE_READ_RESPONSE; |
| 259 return OK; |
| 260 } |
| 261 |
| 262 int ViewCacheHelper::DoReadResponse() { |
| 263 next_state_ = STATE_READ_RESPONSE_COMPLETE; |
| 264 buf_len_ = entry_->GetDataSize(0); |
| 265 entry_callback_->AddRef(); |
| 266 if (!buf_len_) |
| 267 return buf_len_; |
| 268 |
| 269 buf_ = new net::IOBuffer(buf_len_); |
| 270 return entry_->ReadData(0, 0, buf_, buf_len_, entry_callback_); |
| 271 } |
| 272 |
| 273 int ViewCacheHelper::DoReadResponseComplete(int result) { |
| 274 entry_callback_->Release(); |
| 275 if (result && result == buf_len_) { |
| 276 net::HttpResponseInfo response; |
| 277 bool truncated; |
| 278 if (net::HttpCache::ParseResponseInfo(buf_->data(), buf_len_, &response, |
| 279 &truncated) && |
| 280 response.headers) { |
| 281 if (truncated) |
| 282 data_->append("<pre>RESPONSE_INFO_TRUNCATED</pre>"); |
| 283 |
| 284 data_->append("<hr><pre>"); |
| 285 data_->append(EscapeForHTML(response.headers->GetStatusLine())); |
| 286 data_->push_back('\n'); |
| 287 |
| 288 void* iter = NULL; |
| 289 std::string name, value; |
| 290 while (response.headers->EnumerateHeaderLines(&iter, &name, &value)) { |
| 291 data_->append(EscapeForHTML(name)); |
| 292 data_->append(": "); |
| 293 data_->append(EscapeForHTML(value)); |
| 294 data_->push_back('\n'); |
| 295 } |
| 296 data_->append("</pre>"); |
104 } | 297 } |
105 | 298 } |
106 result.append("</pre>"); | 299 |
107 } | 300 index_ = 0; |
108 | 301 next_state_ = STATE_READ_DATA; |
109 return result; | 302 return OK; |
110 } | 303 } |
111 | 304 |
112 static disk_cache::Backend* GetDiskCache(URLRequestContext* context) { | 305 int ViewCacheHelper::DoReadData() { |
113 if (!context) | 306 data_->append("<hr><pre>"); |
114 return NULL; | 307 |
115 | 308 next_state_ = STATE_READ_DATA_COMPLETE; |
116 if (!context->http_transaction_factory()) | 309 buf_len_ = entry_->GetDataSize(index_); |
117 return NULL; | 310 entry_callback_->AddRef(); |
118 | 311 if (!buf_len_) |
119 net::HttpCache* http_cache = context->http_transaction_factory()->GetCache(); | 312 return buf_len_; |
120 if (!http_cache) | 313 |
121 return NULL; | 314 buf_ = new net::IOBuffer(buf_len_); |
122 | 315 return entry_->ReadData(index_, 0, buf_, buf_len_, entry_callback_); |
123 return http_cache->GetBackend(); | 316 } |
124 } | 317 |
125 | 318 int ViewCacheHelper::DoReadDataComplete(int result) { |
126 static std::string FormatStatistics(disk_cache::Backend* disk_cache) { | 319 entry_callback_->Release(); |
127 std::vector<std::pair<std::string, std::string> > stats; | 320 if (result && result == buf_len_) { |
128 disk_cache->GetStats(&stats); | 321 HexDump(buf_->data(), buf_len_, data_); |
129 std::string result; | 322 } |
130 | 323 data_->append("</pre>"); |
131 for (size_t index = 0; index < stats.size(); index++) { | 324 index_++; |
132 result.append(stats[index].first); | 325 if (index_ < net::HttpCache::kNumCacheEntryDataIndices) { |
133 result.append(": "); | 326 next_state_ = STATE_READ_DATA; |
134 result.append(stats[index].second); | |
135 result.append("<br/>\n"); | |
136 } | |
137 | |
138 return result; | |
139 } | |
140 | |
141 // static | |
142 void ViewCacheHelper::GetEntryInfoHTML(const std::string& key, | |
143 URLRequestContext* context, | |
144 const std::string& url_prefix, | |
145 std::string* data) { | |
146 disk_cache::Backend* disk_cache = GetDiskCache(context); | |
147 if (!disk_cache) { | |
148 data->assign("no disk cache"); | |
149 return; | |
150 } | |
151 | |
152 if (key.empty()) { | |
153 data->assign(VIEW_CACHE_HEAD); | |
154 void* iter = NULL; | |
155 disk_cache::Entry* entry; | |
156 while (disk_cache->OpenNextEntry(&iter, &entry)) { | |
157 data->append(FormatEntryInfo(entry, url_prefix)); | |
158 entry->Close(); | |
159 } | |
160 data->append(VIEW_CACHE_TAIL); | |
161 } else { | 327 } else { |
162 disk_cache::Entry* entry; | 328 data_->append(VIEW_CACHE_TAIL); |
163 if (disk_cache->OpenEntry(key, &entry)) { | 329 entry_->Close(); |
164 data->assign(FormatEntryDetails( | 330 entry_ = NULL; |
165 entry, net::HttpCache::kNumCacheEntryDataIndices)); | 331 } |
166 entry->Close(); | 332 return OK; |
167 } else { | 333 } |
168 data->assign("no matching cache entry for: " + EscapeForHTML(key)); | 334 |
169 } | 335 void ViewCacheHelper::OnIOComplete(int result) { |
170 } | 336 DoLoop(result); |
171 } | 337 } |
172 | 338 |
173 // static | 339 } // namespace net. |
174 void ViewCacheHelper::GetStatisticsHTML(URLRequestContext* context, | |
175 std::string* data) { | |
176 disk_cache::Backend* disk_cache = GetDiskCache(context); | |
177 if (!disk_cache) { | |
178 data->append("no disk cache"); | |
179 return; | |
180 } | |
181 data->append(FormatStatistics(disk_cache)); | |
182 } | |
OLD | NEW |