| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "storage/browser/blob/view_blob_internals_job.h" | 5 #include "storage/browser/blob/view_blob_internals_job.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/i18n/number_formatting.h" | 13 #include "base/i18n/number_formatting.h" |
| 14 #include "base/i18n/time_formatting.h" | 14 #include "base/i18n/time_formatting.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "net/base/escape.h" | 21 #include "net/base/escape.h" |
| 22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 23 #include "net/disk_cache/disk_cache.h" | 23 #include "net/disk_cache/disk_cache.h" |
| 24 #include "net/url_request/url_request.h" | 24 #include "net/url_request/url_request.h" |
| 25 #include "storage/browser/blob/blob_data_item.h" | 25 #include "storage/browser/blob/blob_data_item.h" |
| 26 #include "storage/browser/blob/blob_storage_context.h" | 26 #include "storage/browser/blob/blob_storage_context.h" |
| 27 #include "storage/browser/blob/blob_storage_registry.h" | 27 #include "storage/browser/blob/blob_storage_registry.h" |
| 28 #include "storage/browser/blob/internal_blob_data.h" | 28 #include "storage/browser/blob/internal_blob_data.h" |
| 29 | 29 |
| 30 using BlobState = storage::BlobStorageRegistry::BlobState; |
| 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 const char kEmptyBlobStorageMessage[] = "No available blob data."; | 34 const char kEmptyBlobStorageMessage[] = "No available blob data."; |
| 33 const char kContentType[] = "Content Type: "; | 35 const char kContentType[] = "Content Type: "; |
| 34 const char kContentDisposition[] = "Content Disposition: "; | 36 const char kContentDisposition[] = "Content Disposition: "; |
| 37 const char kState[] = "State: "; |
| 35 const char kCount[] = "Count: "; | 38 const char kCount[] = "Count: "; |
| 36 const char kIndex[] = "Index: "; | 39 const char kIndex[] = "Index: "; |
| 37 const char kType[] = "Type: "; | 40 const char kType[] = "Type: "; |
| 38 const char kPath[] = "Path: "; | 41 const char kPath[] = "Path: "; |
| 39 const char kURL[] = "URL: "; | 42 const char kURL[] = "URL: "; |
| 40 const char kModificationTime[] = "Modification Time: "; | 43 const char kModificationTime[] = "Modification Time: "; |
| 41 const char kOffset[] = "Offset: "; | 44 const char kOffset[] = "Offset: "; |
| 42 const char kLength[] = "Length: "; | 45 const char kLength[] = "Length: "; |
| 43 const char kUUID[] = "Uuid: "; | 46 const char kUUID[] = "Uuid: "; |
| 44 const char kRefcount[] = "Refcount: "; | 47 const char kRefcount[] = "Refcount: "; |
| 45 | 48 |
| 46 void StartHTML(std::string* out) { | 49 void StartHTML(std::string* out) { |
| 47 out->append( | 50 out->append( |
| 48 "<!DOCTYPE HTML>" | 51 "<!DOCTYPE HTML>" |
| 49 "<html><title>Blob Storage Internals</title>" | 52 "<html><title>Blob Storage Internals</title>" |
| 50 "<meta http-equiv=\"Content-Security-Policy\"" | 53 "<meta http-equiv=\"Content-Security-Policy\"" |
| 51 " content=\"object-src 'none'; script-src 'none'\">\n" | 54 " content=\"object-src 'none'; script-src 'none'\">\n" |
| 52 "<style>\n" | 55 "<style>\n" |
| 53 "body { font-family: sans-serif; font-size: 0.8em; }\n" | 56 "body { font-family: sans-serif; font-size: 0.8em; }\n" |
| 54 "tt, code, pre { font-family: WebKitHack, monospace; }\n" | 57 "tt, code, pre { font-family: WebKitHack, monospace; }\n" |
| 55 "form { display: inline }\n" | 58 "form { display: inline }\n" |
| 56 ".subsection_body { margin: 10px 0 10px 2em; }\n" | 59 ".subsection_body { margin: 10px 0 10px 2em; }\n" |
| 57 ".subsection_title { font-weight: bold; }\n" | 60 ".subsection_title { font-weight: bold; }\n" |
| 58 "</style>\n" | 61 "</style>\n" |
| 59 "</head><body>\n\n"); | 62 "</head><body>\n\n"); |
| 60 } | 63 } |
| 61 | 64 |
| 65 std::string BlobStateToString(BlobState state) { |
| 66 switch(state) { |
| 67 case BlobState::PENDING: |
| 68 return "Pending"; |
| 69 case BlobState::COMPLETE: |
| 70 return "Complete"; |
| 71 case BlobState::BROKEN: |
| 72 return "Broken"; |
| 73 } |
| 74 } |
| 75 |
| 62 void EndHTML(std::string* out) { | 76 void EndHTML(std::string* out) { |
| 63 out->append("\n</body></html>"); | 77 out->append("\n</body></html>"); |
| 64 } | 78 } |
| 65 | 79 |
| 66 void AddHTMLBoldText(const std::string& text, std::string* out) { | 80 void AddHTMLBoldText(const std::string& text, std::string* out) { |
| 67 out->append("<b>"); | 81 out->append("<b>"); |
| 68 out->append(net::EscapeForHTML(text)); | 82 out->append(net::EscapeForHTML(text)); |
| 69 out->append("</b>"); | 83 out->append("</b>"); |
| 70 } | 84 } |
| 71 | 85 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 GenerateHTML(data); | 162 GenerateHTML(data); |
| 149 EndHTML(data); | 163 EndHTML(data); |
| 150 return net::OK; | 164 return net::OK; |
| 151 } | 165 } |
| 152 | 166 |
| 153 void ViewBlobInternalsJob::GenerateHTML(std::string* out) const { | 167 void ViewBlobInternalsJob::GenerateHTML(std::string* out) const { |
| 154 for (BlobStorageRegistry::BlobMap::const_iterator iter = | 168 for (BlobStorageRegistry::BlobMap::const_iterator iter = |
| 155 blob_storage_context_->registry_.blob_map_.begin(); | 169 blob_storage_context_->registry_.blob_map_.begin(); |
| 156 iter != blob_storage_context_->registry_.blob_map_.end(); ++iter) { | 170 iter != blob_storage_context_->registry_.blob_map_.end(); ++iter) { |
| 157 AddHTMLBoldText(iter->first, out); | 171 AddHTMLBoldText(iter->first, out); |
| 158 GenerateHTMLForBlobData(*iter->second->data, iter->second->content_type, | 172 CHECK(iter->second); |
| 173 GenerateHTMLForBlobData(*iter->second, iter->second->content_type, |
| 159 iter->second->content_disposition, | 174 iter->second->content_disposition, |
| 160 iter->second->refcount, out); | 175 iter->second->refcount, out); |
| 161 } | 176 } |
| 177 |
| 162 if (!blob_storage_context_->registry_.url_to_uuid_.empty()) { | 178 if (!blob_storage_context_->registry_.url_to_uuid_.empty()) { |
| 163 AddHorizontalRule(out); | 179 AddHorizontalRule(out); |
| 164 for (BlobStorageRegistry::URLMap::const_iterator iter = | 180 for (BlobStorageRegistry::URLMap::const_iterator iter = |
| 165 blob_storage_context_->registry_.url_to_uuid_.begin(); | 181 blob_storage_context_->registry_.url_to_uuid_.begin(); |
| 166 iter != blob_storage_context_->registry_.url_to_uuid_.end(); ++iter) { | 182 iter != blob_storage_context_->registry_.url_to_uuid_.end(); ++iter) { |
| 167 AddHTMLBoldText(iter->first.spec(), out); | 183 AddHTMLBoldText(iter->first.spec(), out); |
| 168 StartHTMLList(out); | 184 StartHTMLList(out); |
| 169 AddHTMLListItem(kUUID, iter->second, out); | 185 AddHTMLListItem(kUUID, iter->second, out); |
| 170 EndHTMLList(out); | 186 EndHTMLList(out); |
| 171 } | 187 } |
| 172 } | 188 } |
| 173 } | 189 } |
| 174 | 190 |
| 175 void ViewBlobInternalsJob::GenerateHTMLForBlobData( | 191 void ViewBlobInternalsJob::GenerateHTMLForBlobData( |
| 176 const InternalBlobData& blob_data, | 192 const BlobStorageRegistry::Entry& entry, |
| 177 const std::string& content_type, | 193 const std::string& content_type, |
| 178 const std::string& content_disposition, | 194 const std::string& content_disposition, |
| 179 int refcount, | 195 int refcount, |
| 180 std::string* out) { | 196 std::string* out) { |
| 181 StartHTMLList(out); | 197 StartHTMLList(out); |
| 182 | 198 |
| 183 AddHTMLListItem(kRefcount, base::IntToString(refcount), out); | 199 AddHTMLListItem(kRefcount, base::IntToString(refcount), out); |
| 184 if (!content_type.empty()) | 200 if (!content_type.empty()) |
| 185 AddHTMLListItem(kContentType, content_type, out); | 201 AddHTMLListItem(kContentType, content_type, out); |
| 186 if (!content_disposition.empty()) | 202 if (!content_disposition.empty()) |
| 187 AddHTMLListItem(kContentDisposition, content_disposition, out); | 203 AddHTMLListItem(kContentDisposition, content_disposition, out); |
| 188 | 204 |
| 189 bool has_multi_items = blob_data.items().size() > 1; | 205 InternalBlobData* blob_data = entry.data.get(); |
| 206 |
| 207 AddHTMLListItem(kState, BlobStateToString(entry.state), out); |
| 208 |
| 209 if (!blob_data) { |
| 210 EndHTMLList(out); |
| 211 return; |
| 212 } |
| 213 |
| 214 bool has_multi_items = blob_data->items().size() > 1; |
| 190 if (has_multi_items) { | 215 if (has_multi_items) { |
| 191 AddHTMLListItem(kCount, | 216 AddHTMLListItem(kCount, |
| 192 base::UTF16ToUTF8(base::FormatNumber(blob_data.items().size())), out); | 217 base::UTF16ToUTF8(base::FormatNumber(blob_data->items().size())), out); |
| 193 } | 218 } |
| 194 | 219 |
| 195 for (size_t i = 0; i < blob_data.items().size(); ++i) { | 220 for (size_t i = 0; i < blob_data->items().size(); ++i) { |
| 196 if (has_multi_items) { | 221 if (has_multi_items) { |
| 197 AddHTMLListItem(kIndex, base::UTF16ToUTF8(base::FormatNumber(i)), out); | 222 AddHTMLListItem(kIndex, base::UTF16ToUTF8(base::FormatNumber(i)), out); |
| 198 StartHTMLList(out); | 223 StartHTMLList(out); |
| 199 } | 224 } |
| 200 const BlobDataItem& item = *(blob_data.items().at(i)->item()); | 225 BlobDataItem* item = blob_data->items().at(i)->item().get(); |
| 226 CHECK(item); |
| 201 | 227 |
| 202 switch (item.type()) { | 228 switch (item->type()) { |
| 203 case DataElement::TYPE_BYTES: | 229 case DataElement::TYPE_BYTES: |
| 204 AddHTMLListItem(kType, "data", out); | 230 AddHTMLListItem(kType, "data", out); |
| 205 break; | 231 break; |
| 206 case DataElement::TYPE_FILE: | 232 case DataElement::TYPE_FILE: |
| 207 AddHTMLListItem(kType, "file", out); | 233 AddHTMLListItem(kType, "file", out); |
| 208 AddHTMLListItem(kPath, | 234 AddHTMLListItem(kPath, |
| 209 net::EscapeForHTML(item.path().AsUTF8Unsafe()), | 235 net::EscapeForHTML(item->path().AsUTF8Unsafe()), |
| 210 out); | 236 out); |
| 211 if (!item.expected_modification_time().is_null()) { | 237 if (!item->expected_modification_time().is_null()) { |
| 212 AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( | 238 AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( |
| 213 TimeFormatFriendlyDateAndTime(item.expected_modification_time())), | 239 TimeFormatFriendlyDateAndTime(item->expected_modification_time()))
, |
| 214 out); | 240 out); |
| 215 } | 241 } |
| 216 break; | 242 break; |
| 217 case DataElement::TYPE_BLOB: | 243 case DataElement::TYPE_BLOB: |
| 218 NOTREACHED(); // Should be flattened in the storage context. | 244 AddHTMLListItem(kType, "pending blob", out); |
| 219 break; | 245 break; |
| 220 case DataElement::TYPE_FILE_FILESYSTEM: | 246 case DataElement::TYPE_FILE_FILESYSTEM: |
| 221 AddHTMLListItem(kType, "filesystem", out); | 247 AddHTMLListItem(kType, "filesystem", out); |
| 222 AddHTMLListItem(kURL, item.filesystem_url().spec(), out); | 248 AddHTMLListItem(kURL, item->filesystem_url().spec(), out); |
| 223 if (!item.expected_modification_time().is_null()) { | 249 if (!item->expected_modification_time().is_null()) { |
| 224 AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( | 250 AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( |
| 225 TimeFormatFriendlyDateAndTime(item.expected_modification_time())), | 251 TimeFormatFriendlyDateAndTime(item->expected_modification_time()))
, |
| 226 out); | 252 out); |
| 227 } | 253 } |
| 228 break; | 254 break; |
| 229 case DataElement::TYPE_DISK_CACHE_ENTRY: | 255 case DataElement::TYPE_DISK_CACHE_ENTRY: |
| 230 AddHTMLListItem(kType, "disk cache entry", out); | 256 AddHTMLListItem(kType, "disk cache entry", out); |
| 231 AddHTMLListItem(kURL, item.disk_cache_entry()->GetKey(), out); | 257 AddHTMLListItem(kURL, item->disk_cache_entry()->GetKey(), out); |
| 232 break; | 258 break; |
| 233 case DataElement::TYPE_BYTES_DESCRIPTION: | 259 case DataElement::TYPE_BYTES_DESCRIPTION: |
| 260 AddHTMLListItem(kType, "pending data", out); |
| 234 case DataElement::TYPE_UNKNOWN: | 261 case DataElement::TYPE_UNKNOWN: |
| 235 NOTREACHED(); | 262 NOTREACHED(); |
| 236 break; | 263 break; |
| 237 } | 264 } |
| 238 if (item.offset()) { | 265 if (item->offset()) { |
| 239 AddHTMLListItem(kOffset, base::UTF16ToUTF8(base::FormatNumber( | 266 AddHTMLListItem(kOffset, base::UTF16ToUTF8(base::FormatNumber( |
| 240 static_cast<int64_t>(item.offset()))), | 267 static_cast<int64_t>(item->offset()))), |
| 241 out); | 268 out); |
| 242 } | 269 } |
| 243 if (static_cast<int64_t>(item.length()) != -1) { | 270 if (static_cast<int64_t>(item->length()) != -1) { |
| 244 AddHTMLListItem(kLength, base::UTF16ToUTF8(base::FormatNumber( | 271 AddHTMLListItem(kLength, base::UTF16ToUTF8(base::FormatNumber( |
| 245 static_cast<int64_t>(item.length()))), | 272 static_cast<int64_t>(item->length()))), |
| 246 out); | 273 out); |
| 247 } | 274 } |
| 248 | 275 |
| 249 if (has_multi_items) | 276 if (has_multi_items) |
| 250 EndHTMLList(out); | 277 EndHTMLList(out); |
| 251 } | 278 } |
| 252 | 279 |
| 253 EndHTMLList(out); | 280 EndHTMLList(out); |
| 254 } | 281 } |
| 255 | 282 |
| 256 } // namespace storage | 283 } // namespace storage |
| OLD | NEW |