netwerk/protocol/about/nsAboutCache.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsAboutCache.h"
     7 #include "nsIInputStream.h"
     8 #include "nsIStorageStream.h"
     9 #include "nsIURI.h"
    10 #include "nsCOMPtr.h"
    11 #include "nsNetUtil.h"
    12 #include "nsEscape.h"
    13 #include "nsAboutProtocolUtils.h"
    15 #include "nsICacheService.h"
    17 NS_IMPL_ISUPPORTS(nsAboutCache, nsIAboutModule, nsICacheVisitor)
    19 NS_IMETHODIMP
    20 nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result)
    21 {
    22     NS_ENSURE_ARG_POINTER(aURI);
    23     nsresult rv;
    24     uint32_t bytesWritten;
    26     *result = nullptr;
    27     // Get the cache manager service
    28     nsCOMPtr<nsICacheService> cacheService = 
    29              do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
    30     if (NS_FAILED(rv)) return rv;
    32     nsCOMPtr<nsIStorageStream> storageStream;
    33     nsCOMPtr<nsIOutputStream> outputStream;
    35     // Init: (block size, maximum length)
    36     rv = NS_NewStorageStream(256, (uint32_t)-1, getter_AddRefs(storageStream));
    37     if (NS_FAILED(rv)) return rv;
    39     rv = storageStream->GetOutputStream(0, getter_AddRefs(outputStream));
    40     if (NS_FAILED(rv)) return rv;
    42     mBuffer.AssignLiteral(
    43       "<!DOCTYPE html>\n"
    44       "<html>\n"
    45       "<head>\n"
    46       "  <title>Information about the Cache Service</title>\n"
    47       "  <link rel=\"stylesheet\" "
    48       "href=\"chrome://global/skin/about.css\" type=\"text/css\"/>\n"
    49       "  <link rel=\"stylesheet\" "
    50       "href=\"chrome://global/skin/aboutCache.css\" type=\"text/css\"/>\n"
    51       "</head>\n"
    52       "<body class=\"aboutPageWideContainer\">\n"
    53       "<h1>Information about the Cache Service</h1>\n");
    55     outputStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten);
    57     rv = ParseURI(aURI, mDeviceID);
    58     if (NS_FAILED(rv)) return rv;
    60     mStream = outputStream;
    62     // nsCacheService::VisitEntries calls nsMemoryCacheDevice::Visit,
    63     // nsDiskCacheDevice::Visit and nsOfflineCacheDevice::Visit,
    64     // each of which call
    65     //   1. VisitDevice (for about:cache),
    66     //   2. VisitEntry in a loop (for about:cache?device=disk etc.)
    67     rv = cacheService->VisitEntries(this);
    68     mBuffer.Truncate();
    69     if (rv == NS_ERROR_NOT_AVAILABLE) {
    70         mBuffer.AppendLiteral("<h2>The cache is disabled.</h2>\n");
    71     }
    72     else if (NS_FAILED(rv)) {
    73         return rv;
    74     }
    76     if (!mDeviceID.IsEmpty()) {
    77         mBuffer.AppendLiteral("</table>\n");
    78     }
    79     mBuffer.AppendLiteral("</body>\n"
    80                           "</html>\n");
    81     outputStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten);
    83     nsCOMPtr<nsIInputStream> inStr;
    85     rv = storageStream->NewInputStream(0, getter_AddRefs(inStr));
    86     if (NS_FAILED(rv)) return rv;
    88     nsCOMPtr<nsIChannel> channel;
    89     rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aURI, inStr,
    90                                   NS_LITERAL_CSTRING("text/html"),
    91                                   NS_LITERAL_CSTRING("utf-8"));
    92     if (NS_FAILED(rv)) return rv;
    94     channel.forget(result);
    95     return rv;
    96 }
    98 NS_IMETHODIMP
    99 nsAboutCache::GetURIFlags(nsIURI *aURI, uint32_t *result)
   100 {
   101     *result = 0;
   102     return NS_OK;
   103 }
   105 NS_IMETHODIMP
   106 nsAboutCache::VisitDevice(const char *deviceID,
   107                           nsICacheDeviceInfo *deviceInfo,
   108                           bool *visitEntries)
   109 {
   110     uint32_t bytesWritten, value, entryCount;
   111     nsXPIDLCString str;
   113     *visitEntries = false;
   115     if (mDeviceID.IsEmpty() || mDeviceID.Equals(deviceID)) {
   117         // We need mStream for this
   118         if (!mStream)
   119           return NS_ERROR_FAILURE;
   121         // Write out the Cache Name
   122         deviceInfo->GetDescription(getter_Copies(str));
   124         mBuffer.AssignLiteral("<h2>");
   125         mBuffer.Append(str);
   126         mBuffer.AppendLiteral("</h2>\n"
   127                               "<table id=\"");
   128         mBuffer.Append(deviceID);
   129         mBuffer.AppendLiteral("\">\n");
   131         // Write out cache info
   132         // Number of entries
   133         mBuffer.AppendLiteral("  <tr>\n"
   134                               "    <th>Number of entries:</th>\n"
   135                               "    <td>");
   136         entryCount = 0;
   137         deviceInfo->GetEntryCount(&entryCount);
   138         mBuffer.AppendInt(entryCount);
   139         mBuffer.AppendLiteral("</td>\n"
   140                               "  </tr>\n");
   142         // Maximum storage size
   143         mBuffer.AppendLiteral("  <tr>\n"
   144                               "    <th>Maximum storage size:</th>\n"
   145                               "    <td>");
   146         value = 0;
   147         deviceInfo->GetMaximumSize(&value);
   148         mBuffer.AppendInt(value/1024);
   149         mBuffer.AppendLiteral(" KiB</td>\n"
   150                               "  </tr>\n");
   152         // Storage in use
   153         mBuffer.AppendLiteral("  <tr>\n"
   154                               "    <th>Storage in use:</th>\n"
   155                               "    <td>");
   156         value = 0;
   157         deviceInfo->GetTotalSize(&value);
   158         mBuffer.AppendInt(value/1024);
   159         mBuffer.AppendLiteral(" KiB</td>\n"
   160                               "  </tr>\n");
   162         deviceInfo->GetUsageReport(getter_Copies(str));
   163         mBuffer.Append(str);
   165         if (mDeviceID.IsEmpty()) { // The about:cache case
   166             if (entryCount != 0) { // Add the "List Cache Entries" link
   167                 mBuffer.AppendLiteral("  <tr>\n"
   168                                       "    <th><a href=\"about:cache?device=");
   169                 mBuffer.Append(deviceID);
   170                 mBuffer.AppendLiteral("\">List Cache Entries</a></th>\n"
   171                                       "  </tr>\n");
   172             }
   173             mBuffer.AppendLiteral("</table>\n");
   174         } else { // The about:cache?device=disk etc. case
   175             mBuffer.AppendLiteral("</table>\n");
   176             if (entryCount != 0) {
   177                 *visitEntries = true;
   178                 mBuffer.AppendLiteral("<hr/>\n"
   179                                       "<table id=\"entries\">\n"
   180                                       "  <colgroup>\n"
   181                                       "   <col id=\"col-key\">\n"
   182                                       "   <col id=\"col-dataSize\">\n"
   183                                       "   <col id=\"col-fetchCount\">\n"
   184                                       "   <col id=\"col-lastModified\">\n"
   185                                       "   <col id=\"col-expires\">\n"
   186                                       "  </colgroup>\n"
   187                                       "  <thead>\n"
   188                                       "    <tr>\n"
   189                                       "      <th>Key</th>\n"
   190                                       "      <th>Data size</th>\n"
   191                                       "      <th>Fetch count</th>\n"
   192                                       "      <th>Last modified</th>\n"
   193                                       "      <th>Expires</th>\n"
   194                                       "    </tr>\n"
   195                                       "  </thead>\n");
   196             }
   197         }
   199         mStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten);
   200     }
   202     return NS_OK;
   203 }
   205 NS_IMETHODIMP
   206 nsAboutCache::VisitEntry(const char *deviceID,
   207                          nsICacheEntryInfo *entryInfo,
   208                          bool *visitNext)
   209 {
   210     // We need mStream for this
   211     if (!mStream)
   212       return NS_ERROR_FAILURE;
   214     nsresult        rv;
   215     uint32_t        bytesWritten;
   216     nsAutoCString   key;
   217     nsXPIDLCString  clientID;
   218     bool            streamBased;
   220     rv = entryInfo->GetKey(key);
   221     if (NS_FAILED(rv))  return rv;
   223     rv = entryInfo->GetClientID(getter_Copies(clientID));
   224     if (NS_FAILED(rv))  return rv;
   226     rv = entryInfo->IsStreamBased(&streamBased);
   227     if (NS_FAILED(rv)) return rv;
   229     // Generate a about:cache-entry URL for this entry...
   230     nsAutoCString url;
   231     url.AssignLiteral("about:cache-entry?client=");
   232     url += clientID;
   233     url.AppendLiteral("&amp;sb=");
   234     url += streamBased ? '1' : '0';
   235     url.AppendLiteral("&amp;key=");
   236     char* escapedKey = nsEscapeHTML(key.get());
   237     url += escapedKey; // key
   239     // Entry start...
   240     mBuffer.AssignLiteral("  <tr>\n");
   242     // URI
   243     mBuffer.AppendLiteral("    <td><a href=\"");
   244     mBuffer.Append(url);
   245     mBuffer.AppendLiteral("\">");
   246     mBuffer.Append(escapedKey);
   247     nsMemory::Free(escapedKey);
   248     mBuffer.AppendLiteral("</a></td>\n");
   250     // Content length
   251     uint32_t length = 0;
   252     entryInfo->GetDataSize(&length);
   253     mBuffer.AppendLiteral("    <td>");
   254     mBuffer.AppendInt(length);
   255     mBuffer.AppendLiteral(" bytes</td>\n");
   257     // Number of accesses
   258     int32_t fetchCount = 0;
   259     entryInfo->GetFetchCount(&fetchCount);
   260     mBuffer.AppendLiteral("    <td>");
   261     mBuffer.AppendInt(fetchCount);
   262     mBuffer.AppendLiteral("</td>\n");
   264     // vars for reporting time
   265     char buf[255];
   266     uint32_t t;
   268     // Last modified time
   269     mBuffer.AppendLiteral("    <td>");
   270     entryInfo->GetLastModified(&t);
   271     if (t) {
   272         PrintTimeString(buf, sizeof(buf), t);
   273         mBuffer.Append(buf);
   274     } else
   275         mBuffer.AppendLiteral("No last modified time");
   276     mBuffer.AppendLiteral("</td>\n");
   278     // Expires time
   279     mBuffer.AppendLiteral("    <td>");
   280     entryInfo->GetExpirationTime(&t);
   281     if (t < 0xFFFFFFFF) {
   282         PrintTimeString(buf, sizeof(buf), t);
   283         mBuffer.Append(buf);
   284     } else {
   285         mBuffer.AppendLiteral("No expiration time");
   286     }
   287     mBuffer.AppendLiteral("</td>\n");
   289     // Entry is done...
   290     mBuffer.AppendLiteral("  </tr>\n");
   292     mStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten);
   294     *visitNext = true;
   295     return NS_OK;
   296 }
   299 nsresult
   300 nsAboutCache::ParseURI(nsIURI * uri, nsCString &deviceID)
   301 {
   302     //
   303     // about:cache[?device=string]
   304     //
   305     nsresult rv;
   307     deviceID.Truncate();
   309     nsAutoCString path;
   310     rv = uri->GetPath(path);
   311     if (NS_FAILED(rv)) return rv;
   313     nsACString::const_iterator start, valueStart, end;
   314     path.BeginReading(start);
   315     path.EndReading(end);
   317     valueStart = end;
   318     if (!FindInReadable(NS_LITERAL_CSTRING("?device="), start, valueStart))
   319         return NS_OK;
   321     deviceID.Assign(Substring(valueStart, end));
   322     return NS_OK;
   323 }
   326 nsresult
   327 nsAboutCache::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
   328 {
   329     nsAboutCache* about = new nsAboutCache();
   330     if (about == nullptr)
   331         return NS_ERROR_OUT_OF_MEMORY;
   332     NS_ADDREF(about);
   333     nsresult rv = about->QueryInterface(aIID, aResult);
   334     NS_RELEASE(about);
   335     return rv;
   336 }
   340 ////////////////////////////////////////////////////////////////////////////////

mercurial