Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


\n"
      " \n"
      " \n"
      " \n");

  return NS_OK;
}

//-----------------------------------------------------------------------------
// nsIStreamListener implementation
//-----------------------------------------------------------------------------

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnStartRequest(nsIRequest* request) {
  mHexDumpState = 0;

  constexpr auto buffer = "
\n
"_ns;
  uint32_t n;
  return mOutputStream->Write(buffer.get(), buffer.Length(), &n);
}

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnDataAvailable(nsIRequest* request,
                                            nsIInputStream* aInputStream,
                                            uint64_t aOffset, uint32_t aCount) {
  uint32_t n;
  return aInputStream->ReadSegments(&nsAboutCacheEntry::Channel::PrintCacheData,
                                    this, aCount, &n);
}

/* static */
nsresult nsAboutCacheEntry::Channel::PrintCacheData(
    nsIInputStream* aInStream, void* aClosure, const char* aFromSegment,
    uint32_t aToOffset, uint32_t aCount, uint32_t* aWriteCount) {
  nsAboutCacheEntry::Channel* a =
      static_cast<nsAboutCacheEntry::Channel*>(aClosure);

  nsCString buffer;
  HexDump(&a->mHexDumpState, aFromSegment, aCount, buffer);

  uint32_t n;
  a->mOutputStream->Write(buffer.get(), buffer.Length(), &n);

  *aWriteCount = aCount;

  return NS_OK;
}

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnStopRequest(nsIRequest* request,
                                          nsresult result) {
  constexpr auto buffer = "
\n"
_ns;
  uint32_t n;
  mOutputStream->Write(buffer.get(), buffer.Length(), &n);

  CloseContent();

  return NS_OK;
}

void nsAboutCacheEntry::Channel::CloseContent() {
  constexpr auto buffer = "\n\n"_ns;
  uint32_t n;
  mOutputStream->Write(buffer.get(), buffer.Length(), &n);

  mOutputStream->Close();
  mOutputStream = nullptr;
}

\n"                 \
      " \n"                 \
      " \n"                  \
      " \n");              \
  PR_END_MACRO

nsresult nsAboutCacheEntry::Channel::WriteCacheEntryDescription(
    nsICacheEntry* entry) {
  nsresult rv;
  // This method appears to run in a situation where the run-time stack
  // should have plenty of space, so allocating a large string on the
  // stack is OK.
  nsAutoCStringN<4097> buffer;
  uint32_t n;

  nsAutoCString str;

  rv = entry->GetKey(str);
  if (NS_FAILED(rv)) return rv;

  buffer.AssignLiteral(
      "

Quelle  nsAboutCacheEntry.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <algorithm>

#include "nsAboutCacheEntry.h"

#include "CacheFileUtils.h"
#include "CacheObserver.h"
#include "mozilla/Sprintf.h"
#include "nsAboutCache.h"
#include "nsAboutProtocolUtils.h"
#include "nsContentUtils.h"
#include "nsEscape.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsICacheStorage.h"
#include "nsIPipe.h"
#include "nsITransportSecurityInfo.h"
#include "nsInputStreamPump.h"
#include "nsNetUtil.h"

using namespace mozilla::net;

#define HEXDUMP_MAX_ROWS 16

static void HexDump(uint32_t* state, const char* buf, int32_t n,
                    nsCString& result) {
  char temp[16];

  const unsigned char* p;
  while (n) {
    SprintfLiteral(temp, "%08x: ", *state);
    result.Append(temp);
    *state += HEXDUMP_MAX_ROWS;

    p = (const unsigned char*)buf;

    int32_t i, row_max = std::min(HEXDUMP_MAX_ROWS, n);

    // print hex codes:
    for (i = 0; i < row_max; ++i) {
      SprintfLiteral(temp, "%02x ", *p++);
      result.Append(temp);
    }
    for (i = row_max; i < HEXDUMP_MAX_ROWS; ++i) {
      result.AppendLiteral(" ");
    }

    // print ASCII glyphs if possible:
    p = (const unsigned char*)buf;
    for (i = 0; i < row_max; ++i, ++p) {
      switch (*p) {
        case '<':
          result.AppendLiteral("<");
          break;
        case '>':
          result.AppendLiteral(">");
          break;
        case '&':
          result.AppendLiteral("&");
          break;
        default:
          if (*p < 0x7F && *p > 0x1F) {
            result.Append(*p);
          } else {
            result.Append('.');
          }
      }
    }

    result.Append('\n');

    buf += row_max;
    n -= row_max;
  }
}

//-----------------------------------------------------------------------------
// nsAboutCacheEntry::nsISupports

NS_IMPL_ISUPPORTS(nsAboutCacheEntry, nsIAboutModule)
NS_IMPL_ISUPPORTS(nsAboutCacheEntry::Channel, nsICacheEntryOpenCallback,
                  nsICacheEntryMetaDataVisitor, nsIStreamListener, nsIRequest,
                  nsIChannel)

//-----------------------------------------------------------------------------
// nsAboutCacheEntry::nsIAboutModule

NS_IMETHODIMP
nsAboutCacheEntry::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo,
                              nsIChannel** result) {
  NS_ENSURE_ARG_POINTER(uri);
  nsresult rv;

  RefPtr<Channel> channel = new Channel();
  rv = channel->Init(uri, aLoadInfo);
  if (NS_FAILED(rv)) return rv;

  channel.forget(result);

  return NS_OK;
}

NS_IMETHODIMP
nsAboutCacheEntry::GetURIFlags(nsIURI* aURI, uint32_t* result) {
  *result = nsIAboutModule::HIDE_FROM_ABOUTABOUT |
            nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT;
  return NS_OK;
}

NS_IMETHODIMP
nsAboutCacheEntry::GetChromeURI(nsIURI* aURI, nsIURI** chromeURI) {
  return NS_ERROR_ILLEGAL_VALUE;
}

//-----------------------------------------------------------------------------
// nsAboutCacheEntry::Channel

nsresult nsAboutCacheEntry::Channel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) {
  nsresult rv;

  nsCOMPtr<nsIInputStream> stream;
  rv = GetContentStream(uri, getter_AddRefs(stream));
  if (NS_FAILED(rv)) return rv;

  rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel), uri,
                                        stream.forget(), "text/html"_ns,
                                        "utf-8"_ns, aLoadInfo);
  if (NS_FAILED(rv)) return rv;

  return NS_OK;
}

nsresult nsAboutCacheEntry::Channel::GetContentStream(nsIURI* uri,
                                                      nsIInputStream** result) {
  nsresult rv;

  // Init: (block size, maximum length)
  nsCOMPtr<nsIAsyncInputStream> inputStream;
  NS_NewPipe2(getter_AddRefs(inputStream), getter_AddRefs(mOutputStream), true,
              false, 256, UINT32_MAX);

  constexpr auto buffer =
      "\n"
      "\n"
      "\n"
      " Content-Security-Policy\" content=\"default-src "
      "chrome:; object-src 'none'\" />\n"
      " color-scheme\" content=\"light dark\" />\n"
      " Cache entry information\n"
      " stylesheet\" "
      "href=\"chrome://global/skin/in-content/info-pages.css\" "
      "type=\"text/css\"/>\n"
      " stylesheet\" "
      "href=\"chrome://global/skin/aboutCacheEntry.css\" type=\"text/css\"/>\n"
      "\n"
      "\n"
      "

Cache entry information

\n"
_ns;
  uint32_t n;
  rv = mOutputStream->Write(buffer.get(), buffer.Length(), &n);
  if (NS_FAILED(rv)) return rv;
  if (n != buffer.Length()) return NS_ERROR_UNEXPECTED;

  rv = OpenCacheEntry(uri);
  if (NS_FAILED(rv)) return rv;

  inputStream.forget(result);
  return NS_OK;
}

nsresult nsAboutCacheEntry::Channel::OpenCacheEntry(nsIURI* uri) {
  nsresult rv;

  rv = ParseURI(uri, mStorageName, getter_AddRefs(mLoadInfo), mEnhanceId,
                getter_AddRefs(mCacheURI));
  if (NS_FAILED(rv)) return rv;

  return OpenCacheEntry();
}

nsresult nsAboutCacheEntry::Channel::OpenCacheEntry() {
  nsresult rv;

  nsCOMPtr<nsICacheStorage> storage;
  rv = nsAboutCache::GetStorage(mStorageName, mLoadInfo,
                                getter_AddRefs(storage));
  if (NS_FAILED(rv)) return rv;

  // Invokes OnCacheEntryAvailable()
  rv = storage->AsyncOpenURI(
      mCacheURI, mEnhanceId,
      nsICacheStorage::OPEN_READONLY | nsICacheStorage::OPEN_SECRETLY, this);
  if (NS_FAILED(rv)) return rv;

  return NS_OK;
}

nsresult nsAboutCacheEntry::Channel::ParseURI(nsIURI* uri,
                                              nsACString& storageName,
                                              nsILoadContextInfo** loadInfo,
                                              nsCString& enahnceID,
                                              nsIURI** cacheUri) {
  //
  // about:cache-entry?storage=[string]&contenxt=[string]&eid=[string]&uri=[string]
  //
  nsresult rv;

  nsAutoCString path;
  rv = uri->GetPathQueryRef(path);
  if (NS_FAILED(rv)) return rv;

  nsACString::const_iterator keyBegin, keyEnd, valBegin, begin, end;
  path.BeginReading(begin);
  path.EndReading(end);

  keyBegin = begin;
  keyEnd = end;
  if (!FindInReadable("?storage="_ns, keyBegin, keyEnd)) {
    return NS_ERROR_FAILURE;
  }

  valBegin = keyEnd;  // the value of the storage key starts after the key

  keyBegin = keyEnd;
  keyEnd = end;
  if (!FindInReadable("&context="_ns, keyBegin, keyEnd)) {
    return NS_ERROR_FAILURE;
  }

  storageName.Assign(Substring(valBegin, keyBegin));
  valBegin = keyEnd;  // the value of the context key starts after the key

  keyBegin = keyEnd;
  keyEnd = end;
  if (!FindInReadable("&eid="_ns, keyBegin, keyEnd)) return NS_ERROR_FAILURE;

  nsAutoCString contextKey(Substring(valBegin, keyBegin));
  valBegin = keyEnd;  // the value of the eid key starts after the key

  keyBegin = keyEnd;
  keyEnd = end;
  if (!FindInReadable("&uri="_ns, keyBegin, keyEnd)) return NS_ERROR_FAILURE;

  enahnceID.Assign(Substring(valBegin, keyBegin));

  valBegin = keyEnd;  // the value of the uri key starts after the key
  nsAutoCString uriSpec(Substring(valBegin, end));  // uri is the last one

  // Uf... parsing done, now get some objects from it...

  nsCOMPtr<nsILoadContextInfo> info = CacheFileUtils::ParseKey(contextKey);
  if (!info) return NS_ERROR_FAILURE;
  info.forget(loadInfo);

  rv = NS_NewURI(cacheUri, uriSpec);
  if (NS_FAILED(rv)) return rv;

  return NS_OK;
}

//-----------------------------------------------------------------------------
// nsICacheEntryOpenCallback implementation
//-----------------------------------------------------------------------------

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnCacheEntryCheck(nsICacheEntry* aEntry,
                                              uint32_t* result) {
  *result = nsICacheEntryOpenCallback::ENTRY_WANTED;
  return NS_OK;
}

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnCacheEntryAvailable(nsICacheEntry* entry,
                                                  bool isNew, nsresult status) {
  nsresult rv;

  mWaitingForData = false;
  if (entry) {
    rv = WriteCacheEntryDescription(entry);
  } else {
    rv = WriteCacheEntryUnavailable();
  }
  if (NS_FAILED(rv)) return rv;

  if (!mWaitingForData) {
    // Data is not expected, close the output of content now.
    CloseContent();
  }

  return NS_OK;
}

//-----------------------------------------------------------------------------
// Print-out helper methods
//-----------------------------------------------------------------------------

#define APPEND_ROW(label, value) \
  PR_BEGIN_MACRO                 \
  buffer.AppendLiteral(          \
      "
");               \
  buffer.AppendLiteral(label);   \
  buffer.AppendLiteral(          \
      ":
");               \
  buffer.Append(value);          \
  buffer.AppendLiteral(          \
      "
\n"
      " \n"
      " \n"
      " \n"
      " \n");

  // temp vars for reporting
  char timeBuf[255];
  uint32_t u = 0;
  nsAutoCString s;

  // Fetch Count
  s.Truncate();
  entry->GetFetchCount(&u);
  s.AppendInt(u);
  APPEND_ROW("fetch count", s);

  // Last Fetched
  entry->GetLastFetched(&u);
  if (u) {
    PrintTimeString(timeBuf, sizeof(timeBuf), u);
    APPEND_ROW("last fetched", timeBuf);
  } else {
    APPEND_ROW("last fetched""No last fetch time (bug 1000338)");
  }

  // Last Modified
  entry->GetLastModified(&u);
  if (u) {
    PrintTimeString(timeBuf, sizeof(timeBuf), u);
    APPEND_ROW("last modified", timeBuf);
  } else {
    APPEND_ROW("last modified""No last modified time (bug 1000338)");
  }

  // Expiration Time
  entry->GetExpirationTime(&u);

  // Bug - 633747.
  // When expiration time is 0, we show 1970-01-01 01:00:00 which is confusing.
  // So we check if time is 0, then we show a message, "Expired Immediately"
  if (u == 0) {
    APPEND_ROW("expires""Expired Immediately");
  } else if (u < 0xFFFFFFFF) {
    PrintTimeString(timeBuf, sizeof(timeBuf), u);
    APPEND_ROW("expires", timeBuf);
  } else {
    APPEND_ROW("expires""No expiration time");
  }

  // Data Size
  s.Truncate();
  uint32_t dataSize;
  if (NS_FAILED(entry->GetStorageDataSize(&dataSize))) dataSize = 0;
  s.AppendInt(
      (int32_t)dataSize);  // XXX nsICacheEntryInfo interfaces should be fixed.
  s.AppendLiteral(" B");
  APPEND_ROW("Data size", s);

  // TODO - mayhemer
  // Here used to be a link to the disk file (in the old cache for entries that
  // did not fit any of the block files, in the new cache every time).
  // I'd rather have a small set of buttons here to action on the entry:
  // 1. save the content
  // 2. save as a complete HTTP response (response head, headers, content)
  // 3. doom the entry
  // A new bug(s) should be filed here.

  // Security Info
  nsCOMPtr<nsITransportSecurityInfo> securityInfo;
  entry->GetSecurityInfo(getter_AddRefs(securityInfo));
  if (securityInfo) {
    APPEND_ROW("Security""This is a secure document.");
  } else {
    APPEND_ROW(
        "Security",
        "This document does not have any security info associated with it.");
  }

  buffer.AppendLiteral(
      "
key:td-key\">");

  // Test if the key is actually a URI
  nsCOMPtr<nsIURI> uri;
  rv = NS_NewURI(getter_AddRefs(uri), str);

  nsAutoCString escapedStr;
  nsAppendEscapedHTML(str, escapedStr);

  // javascript: and data: URLs should not be linkified
  // since clicking them can cause scripts to run - bug 162584
  if (NS_SUCCEEDED(rv) &&
      !(uri->SchemeIs("javascript") || uri->SchemeIs("data"))) {
    buffer.AppendLiteral("");
    buffer.Append(escapedStr);
    buffer.AppendLiteral("\">");
    buffer.Append(escapedStr);
    buffer.AppendLiteral("
"
);
    uri = nullptr;
  } else {
    buffer.Append(escapedStr);
  }
  buffer.AppendLiteral(
      "
\n"
      "
\n"

      "\n");

  mBuffer = &buffer;  // make it available for OnMetaDataElement().
  entry->VisitMetaData(this);
  mBuffer = nullptr;

  buffer.AppendLiteral("
\n"
);
  mOutputStream->Write(buffer.get(), buffer.Length(), &n);
  buffer.Truncate();

  // Provide a hexdump of the data
  if (!dataSize) {
    return NS_OK;
  }

  nsCOMPtr<nsIInputStream> stream;
  entry->OpenInputStream(0, getter_AddRefs(stream));
  if (!stream) {
    return NS_OK;
  }

  RefPtr<nsInputStreamPump> pump;
  rv = nsInputStreamPump::Create(getter_AddRefs(pump), stream);
  if (NS_FAILED(rv)) {
    return NS_OK;  // just ignore
  }

  rv = pump->AsyncRead(this);
  if (NS_FAILED(rv)) {
    return NS_OK;  // just ignore
  }

  mWaitingForData = true;
  return NS_OK;
}

nsresult nsAboutCacheEntry::Channel::WriteCacheEntryUnavailable() {
  uint32_t n;
  constexpr auto buffer = "The cache entry you selected is not available."_ns;
  mOutputStream->Write(buffer.get(), buffer.Length(), &n);
  return NS_OK;
}

//-----------------------------------------------------------------------------
// nsICacheEntryMetaDataVisitor implementation
//-----------------------------------------------------------------------------

NS_IMETHODIMP
nsAboutCacheEntry::Channel::OnMetaDataElement(char const* key,
                                              char const* value) {
  mBuffer->AppendLiteral(
      "
");
  mBuffer->Append(key);
  mBuffer->AppendLiteral(
      ":
");
  nsAppendEscapedHTML(nsDependentCString(value), *mBuffer);
  mBuffer->AppendLiteral(
      "
Messung V0.5
C=90 H=97 G=93

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge
 




Impressum  | Ethik und Gesetz  | Haftungsausschluß  | Kontakt  | Seitenstruktur  | © 2026 JDD |