LCOV - code coverage report
Current view: top level - netwerk/protocol/about - nsAboutCacheEntry.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 258 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; 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/. */
       5             : 
       6             : #include "nsAboutCacheEntry.h"
       7             : 
       8             : #include "mozilla/Sprintf.h"
       9             : 
      10             : #include "nsAboutCache.h"
      11             : #include "nsICacheStorage.h"
      12             : #include "CacheObserver.h"
      13             : #include "nsNetUtil.h"
      14             : #include "nsEscape.h"
      15             : #include "nsIAsyncInputStream.h"
      16             : #include "nsIAsyncOutputStream.h"
      17             : #include "nsAboutProtocolUtils.h"
      18             : #include "nsContentUtils.h"
      19             : #include "nsInputStreamPump.h"
      20             : #include "CacheFileUtils.h"
      21             : #include <algorithm>
      22             : #include "nsIPipe.h"
      23             : 
      24             : using namespace mozilla::net;
      25             : 
      26             : #define HEXDUMP_MAX_ROWS 16
      27             : 
      28             : static void
      29           0 : HexDump(uint32_t *state, const char *buf, int32_t n, nsCString &result)
      30             : {
      31             :   char temp[16];
      32             : 
      33             :   const unsigned char *p;
      34           0 :   while (n) {
      35           0 :     SprintfLiteral(temp, "%08x:  ", *state);
      36           0 :     result.Append(temp);
      37           0 :     *state += HEXDUMP_MAX_ROWS;
      38             : 
      39           0 :     p = (const unsigned char *) buf;
      40             : 
      41           0 :     int32_t i, row_max = std::min(HEXDUMP_MAX_ROWS, n);
      42             : 
      43             :     // print hex codes:
      44           0 :     for (i = 0; i < row_max; ++i) {
      45           0 :       SprintfLiteral(temp, "%02x  ", *p++);
      46           0 :       result.Append(temp);
      47             :     }
      48           0 :     for (i = row_max; i < HEXDUMP_MAX_ROWS; ++i) {
      49           0 :       result.AppendLiteral("    ");
      50             :     }
      51             : 
      52             :     // print ASCII glyphs if possible:
      53           0 :     p = (const unsigned char *) buf;
      54           0 :     for (i = 0; i < row_max; ++i, ++p) {
      55           0 :       switch (*p) {
      56             :       case '<':
      57           0 :         result.AppendLiteral("&lt;");
      58           0 :         break;
      59             :       case '>':
      60           0 :         result.AppendLiteral("&gt;");
      61           0 :         break;
      62             :       case '&':
      63           0 :         result.AppendLiteral("&amp;");
      64           0 :         break;
      65             :       default:
      66           0 :         if (*p < 0x7F && *p > 0x1F) {
      67           0 :           result.Append(*p);
      68             :         } else {
      69           0 :           result.Append('.');
      70             :         }
      71             :       }
      72             :     }
      73             : 
      74           0 :     result.Append('\n');
      75             : 
      76           0 :     buf += row_max;
      77           0 :     n -= row_max;
      78             :   }
      79           0 : }
      80             : 
      81             : //-----------------------------------------------------------------------------
      82             : // nsAboutCacheEntry::nsISupports
      83             : 
      84           0 : NS_IMPL_ISUPPORTS(nsAboutCacheEntry,
      85             :                   nsIAboutModule)
      86           0 : NS_IMPL_ISUPPORTS(nsAboutCacheEntry::Channel,
      87             :                   nsICacheEntryOpenCallback,
      88             :                   nsICacheEntryMetaDataVisitor,
      89             :                   nsIStreamListener,
      90             :                   nsIRequest,
      91             :                   nsIChannel)
      92             : 
      93             : //-----------------------------------------------------------------------------
      94             : // nsAboutCacheEntry::nsIAboutModule
      95             : 
      96             : NS_IMETHODIMP
      97           0 : nsAboutCacheEntry::NewChannel(nsIURI* uri,
      98             :                               nsILoadInfo* aLoadInfo,
      99             :                               nsIChannel** result)
     100             : {
     101           0 :     NS_ENSURE_ARG_POINTER(uri);
     102             :     nsresult rv;
     103             : 
     104           0 :     RefPtr<Channel> channel = new Channel();
     105           0 :     rv = channel->Init(uri, aLoadInfo);
     106           0 :     if (NS_FAILED(rv)) return rv;
     107             : 
     108           0 :     channel.forget(result);
     109             : 
     110           0 :     return NS_OK;
     111             : }
     112             : 
     113             : NS_IMETHODIMP
     114           0 : nsAboutCacheEntry::GetURIFlags(nsIURI *aURI, uint32_t *result)
     115             : {
     116           0 :     *result = nsIAboutModule::HIDE_FROM_ABOUTABOUT |
     117             :               nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT;
     118           0 :     return NS_OK;
     119             : }
     120             : 
     121             : //-----------------------------------------------------------------------------
     122             : // nsAboutCacheEntry::Channel
     123             : 
     124             : nsresult
     125           0 : nsAboutCacheEntry::Channel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo)
     126             : {
     127             :     nsresult rv;
     128             : 
     129           0 :     nsCOMPtr<nsIInputStream> stream;
     130           0 :     rv = GetContentStream(uri, getter_AddRefs(stream));
     131           0 :     if (NS_FAILED(rv)) return rv;
     132             : 
     133           0 :     rv =  NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel),
     134             :                                            uri,
     135             :                                            stream,
     136           0 :                                            NS_LITERAL_CSTRING("text/html"),
     137           0 :                                            NS_LITERAL_CSTRING("utf-8"),
     138           0 :                                            aLoadInfo);
     139           0 :     if (NS_FAILED(rv)) return rv;
     140             : 
     141           0 :     return NS_OK;
     142             : }
     143             : 
     144             : nsresult
     145           0 : nsAboutCacheEntry::Channel::GetContentStream(nsIURI *uri, nsIInputStream **result)
     146             : {
     147             :     nsresult rv;
     148             : 
     149             :     // Init: (block size, maximum length)
     150           0 :     nsCOMPtr<nsIAsyncInputStream> inputStream;
     151           0 :     rv = NS_NewPipe2(getter_AddRefs(inputStream),
     152           0 :                      getter_AddRefs(mOutputStream),
     153             :                      true, false,
     154           0 :                      256, UINT32_MAX);
     155           0 :     if (NS_FAILED(rv)) return rv;
     156             : 
     157           0 :     NS_NAMED_LITERAL_CSTRING(
     158             :       buffer,
     159             :       "<!DOCTYPE html>\n"
     160             :       "<html>\n"
     161             :       "<head>\n"
     162             :       "  <title>Cache entry information</title>\n"
     163             :       "  <link rel=\"stylesheet\" "
     164             :       "href=\"chrome://global/skin/about.css\" type=\"text/css\"/>\n"
     165             :       "  <link rel=\"stylesheet\" "
     166             :       "href=\"chrome://global/skin/aboutCacheEntry.css\" type=\"text/css\"/>\n"
     167             :       "</head>\n"
     168             :       "<body>\n"
     169             :       "<h1>Cache entry information</h1>\n");
     170             :     uint32_t n;
     171           0 :     rv = mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     172           0 :     if (NS_FAILED(rv)) return rv;
     173           0 :     if (n != buffer.Length()) return NS_ERROR_UNEXPECTED;
     174             : 
     175           0 :     rv = OpenCacheEntry(uri);
     176           0 :     if (NS_FAILED(rv)) return rv;
     177             : 
     178           0 :     inputStream.forget(result);
     179           0 :     return NS_OK;
     180             : }
     181             : 
     182             : nsresult
     183           0 : nsAboutCacheEntry::Channel::OpenCacheEntry(nsIURI *uri)
     184             : {
     185             :     nsresult rv;
     186             : 
     187           0 :     rv = ParseURI(uri, mStorageName, getter_AddRefs(mLoadInfo),
     188           0 :                        mEnhanceId, getter_AddRefs(mCacheURI));
     189           0 :     if (NS_FAILED(rv)) return rv;
     190             : 
     191           0 :     if (!CacheObserver::UseNewCache() &&
     192           0 :         mLoadInfo->IsPrivate() &&
     193           0 :         mStorageName.EqualsLiteral("disk")) {
     194             :         // The cache v1 is storing all private entries in the memory-only
     195             :         // cache, so it would not be found in the v1 disk cache.
     196           0 :         mStorageName = NS_LITERAL_CSTRING("memory");
     197             :     }
     198             : 
     199           0 :     return OpenCacheEntry();
     200             : }
     201             : 
     202             : nsresult
     203           0 : nsAboutCacheEntry::Channel::OpenCacheEntry()
     204             : {
     205             :     nsresult rv;
     206             : 
     207           0 :     nsCOMPtr<nsICacheStorage> storage;
     208           0 :     rv = nsAboutCache::GetStorage(mStorageName, mLoadInfo, getter_AddRefs(storage));
     209           0 :     if (NS_FAILED(rv)) return rv;
     210             : 
     211             :     // Invokes OnCacheEntryAvailable()
     212           0 :     rv = storage->AsyncOpenURI(mCacheURI, mEnhanceId,
     213             :                                nsICacheStorage::OPEN_READONLY |
     214             :                                nsICacheStorage::OPEN_SECRETLY,
     215           0 :                                this);
     216           0 :     if (NS_FAILED(rv)) return rv;
     217             : 
     218           0 :     return NS_OK;
     219             : }
     220             : 
     221             : nsresult
     222           0 : nsAboutCacheEntry::Channel::ParseURI(nsIURI *uri,
     223             :                                      nsACString &storageName,
     224             :                                      nsILoadContextInfo **loadInfo,
     225             :                                      nsCString &enahnceID,
     226             :                                      nsIURI **cacheUri)
     227             : {
     228             :     //
     229             :     // about:cache-entry?storage=[string]&contenxt=[string]&eid=[string]&uri=[string]
     230             :     //
     231             :     nsresult rv;
     232             : 
     233           0 :     nsAutoCString path;
     234           0 :     rv = uri->GetPath(path);
     235           0 :     if (NS_FAILED(rv))
     236           0 :         return rv;
     237             : 
     238           0 :     nsACString::const_iterator keyBegin, keyEnd, valBegin, begin, end;
     239           0 :     path.BeginReading(begin);
     240           0 :     path.EndReading(end);
     241             : 
     242           0 :     keyBegin = begin; keyEnd = end;
     243           0 :     if (!FindInReadable(NS_LITERAL_CSTRING("?storage="), keyBegin, keyEnd))
     244           0 :         return NS_ERROR_FAILURE;
     245             : 
     246           0 :     valBegin = keyEnd; // the value of the storage key starts after the key
     247             : 
     248           0 :     keyBegin = keyEnd; keyEnd = end;
     249           0 :     if (!FindInReadable(NS_LITERAL_CSTRING("&context="), keyBegin, keyEnd))
     250           0 :         return NS_ERROR_FAILURE;
     251             : 
     252           0 :     storageName.Assign(Substring(valBegin, keyBegin));
     253           0 :     valBegin = keyEnd; // the value of the context key starts after the key
     254             : 
     255           0 :     keyBegin = keyEnd; keyEnd = end;
     256           0 :     if (!FindInReadable(NS_LITERAL_CSTRING("&eid="), keyBegin, keyEnd))
     257           0 :         return NS_ERROR_FAILURE;
     258             : 
     259           0 :     nsAutoCString contextKey(Substring(valBegin, keyBegin));
     260           0 :     valBegin = keyEnd; // the value of the eid key starts after the key
     261             : 
     262           0 :     keyBegin = keyEnd; keyEnd = end;
     263           0 :     if (!FindInReadable(NS_LITERAL_CSTRING("&uri="), keyBegin, keyEnd))
     264           0 :         return NS_ERROR_FAILURE;
     265             : 
     266           0 :     enahnceID.Assign(Substring(valBegin, keyBegin));
     267             : 
     268           0 :     valBegin = keyEnd; // the value of the uri key starts after the key
     269           0 :     nsAutoCString uriSpec(Substring(valBegin, end)); // uri is the last one
     270             : 
     271             :     // Uf... parsing done, now get some objects from it...
     272             : 
     273             :     nsCOMPtr<nsILoadContextInfo> info =
     274           0 :       CacheFileUtils::ParseKey(contextKey);
     275           0 :     if (!info)
     276           0 :         return NS_ERROR_FAILURE;
     277           0 :     info.forget(loadInfo);
     278             : 
     279           0 :     rv = NS_NewURI(cacheUri, uriSpec);
     280           0 :     if (NS_FAILED(rv))
     281           0 :         return rv;
     282             : 
     283           0 :     return NS_OK;
     284             : }
     285             : 
     286             : //-----------------------------------------------------------------------------
     287             : // nsICacheEntryOpenCallback implementation
     288             : //-----------------------------------------------------------------------------
     289             : 
     290             : NS_IMETHODIMP
     291           0 : nsAboutCacheEntry::Channel::OnCacheEntryCheck(nsICacheEntry *aEntry,
     292             :                                               nsIApplicationCache *aApplicationCache,
     293             :                                               uint32_t *result)
     294             : {
     295           0 :     *result = nsICacheEntryOpenCallback::ENTRY_WANTED;
     296           0 :     return NS_OK;
     297             : }
     298             : 
     299             : NS_IMETHODIMP
     300           0 : nsAboutCacheEntry::Channel::OnCacheEntryAvailable(nsICacheEntry *entry,
     301             :                                                   bool isNew,
     302             :                                                   nsIApplicationCache *aApplicationCache,
     303             :                                                   nsresult status)
     304             : {
     305             :     nsresult rv;
     306             : 
     307           0 :     mWaitingForData = false;
     308           0 :     if (entry) {
     309           0 :         rv = WriteCacheEntryDescription(entry);
     310           0 :     } else if (!CacheObserver::UseNewCache() &&
     311           0 :                !mLoadInfo->IsPrivate() &&
     312           0 :                mStorageName.EqualsLiteral("memory")) {
     313             :         // If we were not able to find the entry in the memory storage
     314             :         // try again in the disk storage.
     315             :         // This is a workaround for cache v1: when an originally disk
     316             :         // cache entry is recreated as memory-only, it's clientID doesn't
     317             :         // change and we cannot find it in "HTTP-memory-only" session.
     318             :         // "Disk" cache storage looks at "HTTP".
     319           0 :         mStorageName = NS_LITERAL_CSTRING("disk");
     320           0 :         rv = OpenCacheEntry();
     321           0 :         if (NS_SUCCEEDED(rv)) {
     322           0 :             return NS_OK;
     323             :         }
     324             :     } else {
     325           0 :         rv = WriteCacheEntryUnavailable();
     326             :     }
     327           0 :     if (NS_FAILED(rv)) return rv;
     328             : 
     329             : 
     330           0 :     if (!mWaitingForData) {
     331             :         // Data is not expected, close the output of content now.
     332           0 :         CloseContent();
     333             :     }
     334             : 
     335           0 :     return NS_OK;
     336             : }
     337             : 
     338             : //-----------------------------------------------------------------------------
     339             : // Print-out helper methods
     340             : //-----------------------------------------------------------------------------
     341             : 
     342             : #define APPEND_ROW(label, value) \
     343             :     PR_BEGIN_MACRO \
     344             :     buffer.AppendLiteral("  <tr>\n" \
     345             :                          "    <th>"); \
     346             :     buffer.AppendLiteral(label); \
     347             :     buffer.AppendLiteral(":</th>\n" \
     348             :                          "    <td>"); \
     349             :     buffer.Append(value); \
     350             :     buffer.AppendLiteral("</td>\n" \
     351             :                          "  </tr>\n"); \
     352             :     PR_END_MACRO
     353             : 
     354             : nsresult
     355           0 : nsAboutCacheEntry::Channel::WriteCacheEntryDescription(nsICacheEntry *entry)
     356             : {
     357             :     nsresult rv;
     358           0 :     nsCString buffer;
     359             :     uint32_t n;
     360             : 
     361           0 :     nsAutoCString str;
     362             : 
     363           0 :     rv = entry->GetKey(str);
     364           0 :     if (NS_FAILED(rv)) return rv;
     365             : 
     366           0 :     buffer.SetCapacity(4096);
     367             :     buffer.AssignLiteral("<table>\n"
     368             :                          "  <tr>\n"
     369             :                          "    <th>key:</th>\n"
     370           0 :                          "    <td id=\"td-key\">");
     371             : 
     372             :     // Test if the key is actually a URI
     373           0 :     nsCOMPtr<nsIURI> uri;
     374           0 :     bool isJS = false;
     375           0 :     bool isData = false;
     376             : 
     377           0 :     rv = NS_NewURI(getter_AddRefs(uri), str);
     378             :     // javascript: and data: URLs should not be linkified
     379             :     // since clicking them can cause scripts to run - bug 162584
     380           0 :     if (NS_SUCCEEDED(rv)) {
     381           0 :         uri->SchemeIs("javascript", &isJS);
     382           0 :         uri->SchemeIs("data", &isData);
     383             :     }
     384           0 :     char* escapedStr = nsEscapeHTML(str.get());
     385           0 :     if (NS_SUCCEEDED(rv) && !(isJS || isData)) {
     386           0 :         buffer.AppendLiteral("<a href=\"");
     387           0 :         buffer.Append(escapedStr);
     388           0 :         buffer.AppendLiteral("\">");
     389           0 :         buffer.Append(escapedStr);
     390           0 :         buffer.AppendLiteral("</a>");
     391           0 :         uri = nullptr;
     392             :     } else {
     393           0 :         buffer.Append(escapedStr);
     394             :     }
     395           0 :     free(escapedStr);
     396             :     buffer.AppendLiteral("</td>\n"
     397           0 :                          "  </tr>\n");
     398             : 
     399             :     // temp vars for reporting
     400             :     char timeBuf[255];
     401           0 :     uint32_t u = 0;
     402           0 :     int32_t  i = 0;
     403           0 :     nsAutoCString s;
     404             : 
     405             :     // Fetch Count
     406           0 :     s.Truncate();
     407           0 :     entry->GetFetchCount(&i);
     408           0 :     s.AppendInt(i);
     409           0 :     APPEND_ROW("fetch count", s);
     410             : 
     411             :     // Last Fetched
     412           0 :     entry->GetLastFetched(&u);
     413           0 :     if (u) {
     414           0 :         PrintTimeString(timeBuf, sizeof(timeBuf), u);
     415           0 :         APPEND_ROW("last fetched", timeBuf);
     416             :     } else {
     417           0 :         APPEND_ROW("last fetched", "No last fetch time (bug 1000338)");
     418             :     }
     419             : 
     420             :     // Last Modified
     421           0 :     entry->GetLastModified(&u);
     422           0 :     if (u) {
     423           0 :         PrintTimeString(timeBuf, sizeof(timeBuf), u);
     424           0 :         APPEND_ROW("last modified", timeBuf);
     425             :     } else {
     426           0 :         APPEND_ROW("last modified", "No last modified time (bug 1000338)");
     427             :     }
     428             : 
     429             :     // Expiration Time
     430           0 :     entry->GetExpirationTime(&u);
     431             : 
     432             :     // Bug - 633747.
     433             :     // When expiration time is 0, we show 1970-01-01 01:00:00 which is confusing.
     434             :     // So we check if time is 0, then we show a message, "Expired Immediately"
     435           0 :     if (u == 0) {
     436           0 :         APPEND_ROW("expires", "Expired Immediately");
     437           0 :     } else if (u < 0xFFFFFFFF) {
     438           0 :         PrintTimeString(timeBuf, sizeof(timeBuf), u);
     439           0 :         APPEND_ROW("expires", timeBuf);
     440             :     } else {
     441           0 :         APPEND_ROW("expires", "No expiration time");
     442             :     }
     443             : 
     444             :     // Data Size
     445           0 :     s.Truncate();
     446             :     uint32_t dataSize;
     447           0 :     if (NS_FAILED(entry->GetStorageDataSize(&dataSize)))
     448           0 :         dataSize = 0;
     449           0 :     s.AppendInt((int32_t)dataSize);     // XXX nsICacheEntryInfo interfaces should be fixed.
     450           0 :     s.AppendLiteral(" B");
     451           0 :     APPEND_ROW("Data size", s);
     452             : 
     453             :     // TODO - mayhemer
     454             :     // Here used to be a link to the disk file (in the old cache for entries that
     455             :     // did not fit any of the block files, in the new cache every time).
     456             :     // I'd rather have a small set of buttons here to action on the entry:
     457             :     // 1. save the content
     458             :     // 2. save as a complete HTTP response (response head, headers, content)
     459             :     // 3. doom the entry
     460             :     // A new bug(s) should be filed here.
     461             : 
     462             :     // Security Info
     463           0 :     nsCOMPtr<nsISupports> securityInfo;
     464           0 :     entry->GetSecurityInfo(getter_AddRefs(securityInfo));
     465           0 :     if (securityInfo) {
     466           0 :         APPEND_ROW("Security", "This is a secure document.");
     467             :     } else {
     468           0 :         APPEND_ROW("Security",
     469             :                    "This document does not have any security info associated with it.");
     470             :     }
     471             : 
     472             :     buffer.AppendLiteral("</table>\n"
     473             :                          "<hr/>\n"
     474           0 :                          "<table>\n");
     475             : 
     476           0 :     mBuffer = &buffer;  // make it available for OnMetaDataElement().
     477           0 :     entry->VisitMetaData(this);
     478           0 :     mBuffer = nullptr;
     479             : 
     480           0 :     buffer.AppendLiteral("</table>\n");
     481           0 :     mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     482           0 :     buffer.Truncate();
     483             : 
     484             :     // Provide a hexdump of the data
     485           0 :     if (!dataSize) {
     486           0 :         return NS_OK;
     487             :     }
     488             : 
     489           0 :     nsCOMPtr<nsIInputStream> stream;
     490           0 :     entry->OpenInputStream(0, getter_AddRefs(stream));
     491           0 :     if (!stream) {
     492           0 :         return NS_OK;
     493             :     }
     494             : 
     495           0 :     RefPtr<nsInputStreamPump> pump;
     496           0 :     rv = nsInputStreamPump::Create(getter_AddRefs(pump), stream);
     497           0 :     if (NS_FAILED(rv)) {
     498           0 :         return NS_OK; // just ignore
     499             :     }
     500             : 
     501           0 :     rv = pump->AsyncRead(this, nullptr);
     502           0 :     if (NS_FAILED(rv)) {
     503           0 :         return NS_OK; // just ignore
     504             :     }
     505             : 
     506           0 :     mWaitingForData = true;
     507           0 :     return NS_OK;
     508             : }
     509             : 
     510             : nsresult
     511           0 : nsAboutCacheEntry::Channel::WriteCacheEntryUnavailable()
     512             : {
     513             :     uint32_t n;
     514           0 :     NS_NAMED_LITERAL_CSTRING(buffer,
     515             :         "The cache entry you selected is not available.");
     516           0 :     mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     517           0 :     return NS_OK;
     518             : }
     519             : 
     520             : //-----------------------------------------------------------------------------
     521             : // nsICacheEntryMetaDataVisitor implementation
     522             : //-----------------------------------------------------------------------------
     523             : 
     524             : NS_IMETHODIMP
     525           0 : nsAboutCacheEntry::Channel::OnMetaDataElement(char const * key, char const * value)
     526             : {
     527           0 :     mBuffer->AppendLiteral("  <tr>\n"
     528           0 :                            "    <th>");
     529           0 :     mBuffer->Append(key);
     530           0 :     mBuffer->AppendLiteral(":</th>\n"
     531           0 :                            "    <td>");
     532           0 :     char* escapedValue = nsEscapeHTML(value);
     533           0 :     mBuffer->Append(escapedValue);
     534           0 :     free(escapedValue);
     535           0 :     mBuffer->AppendLiteral("</td>\n"
     536           0 :                            "  </tr>\n");
     537             : 
     538           0 :     return NS_OK;
     539             : }
     540             : 
     541             : //-----------------------------------------------------------------------------
     542             : // nsIStreamListener implementation
     543             : //-----------------------------------------------------------------------------
     544             : 
     545             : NS_IMETHODIMP
     546           0 : nsAboutCacheEntry::Channel::OnStartRequest(nsIRequest *request, nsISupports *ctx)
     547             : {
     548           0 :     mHexDumpState = 0;
     549             : 
     550           0 :     NS_NAMED_LITERAL_CSTRING(buffer, "<hr/>\n<pre>");
     551             :     uint32_t n;
     552           0 :     return mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     553             : }
     554             : 
     555             : NS_IMETHODIMP
     556           0 : nsAboutCacheEntry::Channel::OnDataAvailable(nsIRequest *request, nsISupports *ctx,
     557             :                                    nsIInputStream *aInputStream,
     558             :                                    uint64_t aOffset,
     559             :                                    uint32_t aCount)
     560             : {
     561             :     uint32_t n;
     562             :     return aInputStream->ReadSegments(
     563           0 :         &nsAboutCacheEntry::Channel::PrintCacheData, this, aCount, &n);
     564             : }
     565             : 
     566             : /* static */ nsresult
     567           0 : nsAboutCacheEntry::Channel::PrintCacheData(nsIInputStream *aInStream,
     568             :                                            void *aClosure,
     569             :                                            const char *aFromSegment,
     570             :                                            uint32_t aToOffset,
     571             :                                            uint32_t aCount,
     572             :                                            uint32_t *aWriteCount)
     573             : {
     574             :     nsAboutCacheEntry::Channel *a =
     575           0 :       static_cast<nsAboutCacheEntry::Channel*>(aClosure);
     576             : 
     577           0 :     nsCString buffer;
     578           0 :     HexDump(&a->mHexDumpState, aFromSegment, aCount, buffer);
     579             : 
     580             :     uint32_t n;
     581           0 :     a->mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     582             : 
     583           0 :     *aWriteCount = aCount;
     584             : 
     585           0 :     return NS_OK;
     586             : }
     587             : 
     588             : NS_IMETHODIMP
     589           0 : nsAboutCacheEntry::Channel::OnStopRequest(nsIRequest *request, nsISupports *ctx,
     590             :                                           nsresult result)
     591             : {
     592           0 :     NS_NAMED_LITERAL_CSTRING(buffer, "</pre>\n");
     593             :     uint32_t n;
     594           0 :     mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     595             : 
     596           0 :     CloseContent();
     597             : 
     598           0 :     return NS_OK;
     599             : }
     600             : 
     601             : void
     602           0 : nsAboutCacheEntry::Channel::CloseContent()
     603             : {
     604           0 :     NS_NAMED_LITERAL_CSTRING(buffer, "</body>\n</html>\n");
     605             :     uint32_t n;
     606           0 :     mOutputStream->Write(buffer.get(), buffer.Length(), &n);
     607             : 
     608           0 :     mOutputStream->Close();
     609           0 :     mOutputStream = nullptr;
     610           0 : }

Generated by: LCOV version 1.13