15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/view_blob_internals_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/number_formatting.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/time_formatting.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/blob_data.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEmptyBlobStorageMessage[] = "No available blob data."; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kContentType[] = "Content Type: "; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kContentDisposition[] = "Content Disposition: "; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCount[] = "Count: "; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIndex[] = "Index: "; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kType[] = "Type: "; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPath[] = "Path: "; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kURL[] = "URL: "; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kModificationTime[] = "Modification Time: "; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOffset[] = "Offset: "; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLength[] = "Length: "; 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kUUID[] = "Uuid: "; 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kRefcount[] = "Refcount: "; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartHTML(std::string* out) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<!DOCTYPE HTML>" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<html><title>Blob Storage Internals</title>" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<meta http-equiv=\"Content-Security-Policy\"" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " content=\"object-src 'none'; script-src 'none'\">\n" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<style>\n" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "body { font-family: sans-serif; font-size: 0.8em; }\n" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "tt, code, pre { font-family: WebKitHack, monospace; }\n" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "form { display: inline }\n" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".subsection_body { margin: 10px 0 10px 2em; }\n" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".subsection_title { font-weight: bold; }\n" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "</style>\n" 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "</head><body>\n\n"); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EndHTML(std::string* out) { 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out->append("\n</body></html>"); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddHTMLBoldText(const std::string& text, std::string* out) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append("<b>"); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append(net::EscapeForHTML(text)); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append("</b>"); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartHTMLList(std::string* out) { 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out->append("\n<ul>"); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EndHTMLList(std::string* out) { 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out->append("</ul>\n"); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddHTMLListItem(const std::string& element_title, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& element_data, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append("<li>"); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to escape element_title since constant string is passed. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append(element_title); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append(net::EscapeForHTML(element_data)); 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out->append("</li>\n"); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void AddHorizontalRule(std::string* out) { 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out->append("\n<hr>\n"); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewBlobInternalsJob::ViewBlobInternalsJob( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BlobStorageContext* blob_storage_context) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestSimpleJob(request, network_delegate), 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob_storage_context_(blob_storage_context), 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewBlobInternalsJob::~ViewBlobInternalsJob() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewBlobInternalsJob::Start() { 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FROM_HERE, 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&ViewBlobInternalsJob::StartAsync, 108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_factory_.GetWeakPtr())); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewBlobInternalsJob::IsRedirectResponse(GURL* location, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* http_status_code) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->url().has_query()) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strip the query parameters. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearQuery(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *location = request_->url().ReplaceComponents(replacements); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *http_status_code = 307; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewBlobInternalsJob::Kill() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestSimpleJob::Kill(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewBlobInternalsJob::GetData( 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* mime_type, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* charset, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* data, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mime_type->assign("text/html"); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset->assign("UTF-8"); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->clear(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartHTML(data); 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (blob_storage_context_->blob_map_.empty()) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->append(kEmptyBlobStorageMessage); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateHTML(data); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndHTML(data); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewBlobInternalsJob::GenerateHTML(std::string* out) const { 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (BlobStorageContext::BlobMap::const_iterator iter = 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob_storage_context_->blob_map_.begin(); 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) iter != blob_storage_context_->blob_map_.end(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLBoldText(iter->first, out); 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GenerateHTMLForBlobData(*(iter->second.data.get()), 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) iter->second.refcount, 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) out); 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!blob_storage_context_->public_blob_urls_.empty()) { 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddHorizontalRule(out); 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (BlobStorageContext::BlobURLMap::const_iterator iter = 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob_storage_context_->public_blob_urls_.begin(); 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) iter != blob_storage_context_->public_blob_urls_.end(); 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ++iter) { 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddHTMLBoldText(iter->first.spec(), out); 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) StartHTMLList(out); 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddHTMLListItem(kUUID, iter->second, out); 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EndHTMLList(out); 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewBlobInternalsJob::GenerateHTMLForBlobData(const BlobData& blob_data, 17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int refcount, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartHTMLList(out); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddHTMLListItem(kRefcount, base::IntToString(refcount), out); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blob_data.content_type().empty()) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kContentType, blob_data.content_type(), out); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blob_data.content_disposition().empty()) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kContentDisposition, blob_data.content_disposition(), out); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_multi_items = blob_data.items().size() > 1; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_multi_items) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kCount, 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8(base::FormatNumber(blob_data.items().size())), out); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < blob_data.items().size(); ++i) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_multi_items) { 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddHTMLListItem(kIndex, base::UTF16ToUTF8(base::FormatNumber(i)), out); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartHTMLList(out); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data.items().at(i); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type()) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_BYTES: 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kType, "data", out); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kType, "file", out); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kPath, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeForHTML(item.path().AsUTF8Unsafe()), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!item.expected_modification_time().is_null()) { 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeFormatFriendlyDateAndTime(item.expected_modification_time())), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_BLOB: 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); // Should be flattened in the storage context. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE_FILESYSTEM: 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddHTMLListItem(kType, "filesystem", out); 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddHTMLListItem(kURL, item.filesystem_url().spec(), out); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!item.expected_modification_time().is_null()) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddHTMLListItem(kModificationTime, base::UTF16ToUTF8( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeFormatFriendlyDateAndTime(item.expected_modification_time())), 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_UNKNOWN: 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item.offset()) { 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddHTMLListItem(kOffset, base::UTF16ToUTF8(base::FormatNumber( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(item.offset()))), out); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<int64>(item.length()) != -1) { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddHTMLListItem(kLength, base::UTF16ToUTF8(base::FormatNumber( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(item.length()))), out); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_multi_items) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndHTMLList(out); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndHTMLList(out); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 243