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

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  *
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsWyciwyg.h"
       8             : #include "nsWyciwygChannel.h"
       9             : #include "nsILoadGroup.h"
      10             : #include "nsNetUtil.h"
      11             : #include "nsNetCID.h"
      12             : #include "LoadContextInfo.h"
      13             : #include "nsICacheService.h" // only to initialize
      14             : #include "nsICacheStorageService.h"
      15             : #include "nsICacheStorage.h"
      16             : #include "nsICacheEntry.h"
      17             : #include "nsCharsetSource.h"
      18             : #include "nsProxyRelease.h"
      19             : #include "nsThreadUtils.h"
      20             : #include "nsIInputStream.h"
      21             : #include "nsIInputStreamPump.h"
      22             : #include "nsIOutputStream.h"
      23             : #include "nsIProgressEventSink.h"
      24             : #include "nsIURI.h"
      25             : #include "mozilla/DebugOnly.h"
      26             : #include "mozilla/Unused.h"
      27             : #include "mozilla/BasePrincipal.h"
      28             : #include "nsProxyRelease.h"
      29             : #include "nsContentSecurityManager.h"
      30             : #include "nsContentUtils.h"
      31             : 
      32             : typedef mozilla::net::LoadContextInfo LoadContextInfo;
      33             : 
      34             : // nsWyciwygChannel methods
      35           0 : nsWyciwygChannel::nsWyciwygChannel()
      36             :   : mMode(NONE),
      37             :     mStatus(NS_OK),
      38             :     mIsPending(false),
      39             :     mNeedToWriteCharset(false),
      40             :     mCharsetSource(kCharsetUninitialized),
      41             :     mContentLength(-1),
      42             :     mLoadFlags(LOAD_NORMAL),
      43           0 :     mNeedToSetSecurityInfo(false)
      44             : {
      45           0 : }
      46             : 
      47           0 : nsWyciwygChannel::~nsWyciwygChannel()
      48             : {
      49           0 :   if (mLoadInfo) {
      50             :     NS_ReleaseOnMainThread(
      51           0 :       "nsWyciwygChannel::mLoadInfo", mLoadInfo.forget(), false);
      52             :   }
      53           0 : }
      54             : 
      55           0 : NS_IMPL_ISUPPORTS(nsWyciwygChannel,
      56             :                   nsIChannel,
      57             :                   nsIRequest,
      58             :                   nsIStreamListener,
      59             :                   nsIRequestObserver,
      60             :                   nsICacheEntryOpenCallback,
      61             :                   nsIWyciwygChannel,
      62             :                   nsIPrivateBrowsingChannel)
      63             : 
      64             : nsresult
      65           0 : nsWyciwygChannel::Init(nsIURI* uri)
      66             : {
      67           0 :   NS_ENSURE_ARG_POINTER(uri);
      68             : 
      69           0 :   mURI = uri;
      70           0 :   mOriginalURI = uri;
      71             : 
      72           0 :   return NS_OK;
      73             : }
      74             : 
      75             : ///////////////////////////////////////////////////////////////////////////////
      76             : // nsIRequest methods:
      77             : ///////////////////////////////////////////////////////////////////////////////
      78             : 
      79             : NS_IMETHODIMP
      80           0 : nsWyciwygChannel::GetName(nsACString &aName)
      81             : {
      82           0 :   return mURI->GetSpec(aName);
      83             : }
      84             : 
      85             : NS_IMETHODIMP
      86           0 : nsWyciwygChannel::IsPending(bool *aIsPending)
      87             : {
      88           0 :   *aIsPending = mIsPending;
      89           0 :   return NS_OK;
      90             : }
      91             : 
      92             : NS_IMETHODIMP
      93           0 : nsWyciwygChannel::GetStatus(nsresult *aStatus)
      94             : {
      95           0 :   if (NS_SUCCEEDED(mStatus) && mPump)
      96           0 :     mPump->GetStatus(aStatus);
      97             :   else
      98           0 :     *aStatus = mStatus;
      99           0 :   return NS_OK;
     100             : }
     101             : 
     102             : NS_IMETHODIMP
     103           0 : nsWyciwygChannel::Cancel(nsresult status)
     104             : {
     105           0 :   mStatus = status;
     106           0 :   if (mPump)
     107           0 :     mPump->Cancel(status);
     108             :   // else we're waiting for OnCacheEntryAvailable
     109           0 :   return NS_OK;
     110             : }
     111             : 
     112             : NS_IMETHODIMP
     113           0 : nsWyciwygChannel::Suspend()
     114             : {
     115           0 :   if (mPump)
     116           0 :     mPump->Suspend();
     117             :   // XXX else, we'll ignore this ... and that's probably bad!
     118           0 :   return NS_OK;
     119             : }
     120             : 
     121             : NS_IMETHODIMP
     122           0 : nsWyciwygChannel::Resume()
     123             : {
     124           0 :   if (mPump)
     125           0 :     mPump->Resume();
     126             :   // XXX else, we'll ignore this ... and that's probably bad!
     127           0 :   return NS_OK;
     128             : }
     129             : 
     130             : NS_IMETHODIMP
     131           0 : nsWyciwygChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
     132             : {
     133           0 :   *aLoadGroup = mLoadGroup;
     134           0 :   NS_IF_ADDREF(*aLoadGroup);
     135           0 :   return NS_OK;
     136             : }
     137             : 
     138             : NS_IMETHODIMP
     139           0 : nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
     140             : {
     141           0 :   if (!CanSetLoadGroup(aLoadGroup)) {
     142           0 :     return NS_ERROR_FAILURE;
     143             :   }
     144             : 
     145           0 :   mLoadGroup = aLoadGroup;
     146           0 :   NS_QueryNotificationCallbacks(mCallbacks,
     147             :                                 mLoadGroup,
     148             :                                 NS_GET_IID(nsIProgressEventSink),
     149           0 :                                 getter_AddRefs(mProgressSink));
     150           0 :   UpdatePrivateBrowsing();
     151           0 :   NS_GetOriginAttributes(this, mOriginAttributes);
     152             : 
     153           0 :   return NS_OK;
     154             : }
     155             : 
     156             : NS_IMETHODIMP
     157           0 : nsWyciwygChannel::SetLoadFlags(uint32_t aLoadFlags)
     158             : {
     159           0 :   mLoadFlags = aLoadFlags;
     160           0 :   return NS_OK;
     161             : }
     162             : 
     163             : NS_IMETHODIMP
     164           0 : nsWyciwygChannel::GetLoadFlags(uint32_t * aLoadFlags)
     165             : {
     166           0 :   *aLoadFlags = mLoadFlags;
     167           0 :   return NS_OK;
     168             : }
     169             : 
     170             : NS_IMETHODIMP
     171           0 : nsWyciwygChannel::GetIsDocument(bool *aIsDocument)
     172             : {
     173           0 :   return NS_GetIsDocumentChannel(this, aIsDocument);
     174             : }
     175             : 
     176             : ////////////////////////////////////////////////////////////////////////////////
     177             : // nsIChannel methods:
     178             : ///////////////////////////////////////////////////////////////////////////////
     179             : 
     180             : NS_IMETHODIMP
     181           0 : nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI)
     182             : {
     183           0 :   *aURI = mOriginalURI;
     184           0 :   NS_ADDREF(*aURI);
     185           0 :   return NS_OK;
     186             : }
     187             : 
     188             : NS_IMETHODIMP
     189           0 : nsWyciwygChannel::SetOriginalURI(nsIURI* aURI)
     190             : {
     191           0 :   NS_ENSURE_ARG_POINTER(aURI);
     192           0 :   mOriginalURI = aURI;
     193           0 :   return NS_OK;
     194             : }
     195             : 
     196             : NS_IMETHODIMP
     197           0 : nsWyciwygChannel::GetURI(nsIURI* *aURI)
     198             : {
     199           0 :   *aURI = mURI;
     200           0 :   NS_IF_ADDREF(*aURI);
     201           0 :   return NS_OK;
     202             : }
     203             : 
     204             : NS_IMETHODIMP
     205           0 : nsWyciwygChannel::GetOwner(nsISupports **aOwner)
     206             : {
     207           0 :   NS_IF_ADDREF(*aOwner = mOwner);
     208           0 :   return NS_OK;
     209             : }
     210             : 
     211             : NS_IMETHODIMP
     212           0 : nsWyciwygChannel::SetOwner(nsISupports* aOwner)
     213             : {
     214           0 :   mOwner = aOwner;
     215           0 :   return NS_OK;
     216             : }
     217             : 
     218             : NS_IMETHODIMP
     219           0 : nsWyciwygChannel::GetLoadInfo(nsILoadInfo **aLoadInfo)
     220             : {
     221           0 :   NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
     222           0 :   return NS_OK;
     223             : }
     224             : 
     225             : NS_IMETHODIMP
     226           0 : nsWyciwygChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
     227             : {
     228           0 :   mLoadInfo = aLoadInfo;
     229           0 :   return NS_OK;
     230             : }
     231             : 
     232             : NS_IMETHODIMP
     233           0 : nsWyciwygChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks)
     234             : {
     235           0 :   *aCallbacks = mCallbacks.get();
     236           0 :   NS_IF_ADDREF(*aCallbacks);
     237           0 :   return NS_OK;
     238             : }
     239             : 
     240             : NS_IMETHODIMP
     241           0 : nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
     242             : {
     243           0 :   if (!CanSetCallbacks(aNotificationCallbacks)) {
     244           0 :     return NS_ERROR_FAILURE;
     245             :   }
     246             : 
     247           0 :   mCallbacks = aNotificationCallbacks;
     248           0 :   NS_QueryNotificationCallbacks(mCallbacks,
     249             :                                 mLoadGroup,
     250             :                                 NS_GET_IID(nsIProgressEventSink),
     251           0 :                                 getter_AddRefs(mProgressSink));
     252             : 
     253           0 :   UpdatePrivateBrowsing();
     254           0 :   NS_GetOriginAttributes(this, mOriginAttributes);
     255             : 
     256           0 :   return NS_OK;
     257             : }
     258             : 
     259             : NS_IMETHODIMP
     260           0 : nsWyciwygChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
     261             : {
     262           0 :   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
     263             : 
     264           0 :   return NS_OK;
     265             : }
     266             : 
     267             : NS_IMETHODIMP
     268           0 : nsWyciwygChannel::GetContentType(nsACString &aContentType)
     269             : {
     270           0 :   aContentType.AssignLiteral(WYCIWYG_TYPE);
     271           0 :   return NS_OK;
     272             : }
     273             : 
     274             : NS_IMETHODIMP
     275           0 : nsWyciwygChannel::SetContentType(const nsACString &aContentType)
     276             : {
     277           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     278             : }
     279             : 
     280             : NS_IMETHODIMP
     281           0 : nsWyciwygChannel::GetContentCharset(nsACString &aContentCharset)
     282             : {
     283           0 :   aContentCharset.AssignLiteral("UTF-16LE");
     284           0 :   return NS_OK;
     285             : }
     286             : 
     287             : NS_IMETHODIMP
     288           0 : nsWyciwygChannel::SetContentCharset(const nsACString &aContentCharset)
     289             : {
     290           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     291             : }
     292             : 
     293             : NS_IMETHODIMP
     294           0 : nsWyciwygChannel::GetContentDisposition(uint32_t *aContentDisposition)
     295             : {
     296           0 :   return NS_ERROR_NOT_AVAILABLE;
     297             : }
     298             : 
     299             : NS_IMETHODIMP
     300           0 : nsWyciwygChannel::SetContentDisposition(uint32_t aContentDisposition)
     301             : {
     302           0 :   return NS_ERROR_NOT_AVAILABLE;
     303             : }
     304             : 
     305             : NS_IMETHODIMP
     306           0 : nsWyciwygChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
     307             : {
     308           0 :   return NS_ERROR_NOT_AVAILABLE;
     309             : }
     310             : 
     311             : NS_IMETHODIMP
     312           0 : nsWyciwygChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
     313             : {
     314           0 :   return NS_ERROR_NOT_AVAILABLE;
     315             : }
     316             : 
     317             : NS_IMETHODIMP
     318           0 : nsWyciwygChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
     319             : {
     320           0 :   return NS_ERROR_NOT_AVAILABLE;
     321             : }
     322             : 
     323             : NS_IMETHODIMP
     324           0 : nsWyciwygChannel::GetContentLength(int64_t *aContentLength)
     325             : {
     326           0 :   *aContentLength = mContentLength;
     327           0 :   return NS_OK;
     328             : }
     329             : 
     330             : NS_IMETHODIMP
     331           0 : nsWyciwygChannel::SetContentLength(int64_t aContentLength)
     332             : {
     333           0 :   mContentLength = aContentLength;
     334             : 
     335           0 :   return NS_OK;
     336             : }
     337             : 
     338             : NS_IMETHODIMP
     339           0 : nsWyciwygChannel::Open(nsIInputStream ** aReturn)
     340             : {
     341           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     342             : }
     343             : 
     344             : NS_IMETHODIMP
     345           0 : nsWyciwygChannel::Open2(nsIInputStream** aStream)
     346             : {
     347           0 :   nsCOMPtr<nsIStreamListener> listener;
     348           0 :   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
     349           0 :   NS_ENSURE_SUCCESS(rv, rv);
     350           0 :   return Open(aStream);
     351             : }
     352             : 
     353             : NS_IMETHODIMP
     354           0 : nsWyciwygChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
     355             : {
     356           0 :   MOZ_ASSERT(!mLoadInfo ||
     357             :              mLoadInfo->GetSecurityMode() == 0 ||
     358             :              mLoadInfo->GetInitialSecurityCheckDone() ||
     359             :              (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
     360             :               nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
     361             :              "security flags in loadInfo but asyncOpen2() not called");
     362             : 
     363           0 :   LOG(("nsWyciwygChannel::AsyncOpen [this=%p]\n", this));
     364           0 :   MOZ_ASSERT(mMode == NONE, "nsWyciwygChannel already open");
     365             : 
     366           0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
     367           0 :   NS_ENSURE_TRUE(mMode == NONE, NS_ERROR_IN_PROGRESS);
     368           0 :   NS_ENSURE_ARG_POINTER(listener);
     369             : 
     370           0 :   mMode = READING;
     371             : 
     372             :   // open a cache entry for this channel...
     373             :   // mIsPending set to true since OnCacheEntryAvailable may be called
     374             :   // synchronously and fails when mIsPending found false.
     375           0 :   mIsPending = true;
     376           0 :   nsresult rv = OpenCacheEntryForReading(mURI);
     377           0 :   if (NS_FAILED(rv)) {
     378           0 :     LOG(("nsWyciwygChannel::OpenCacheEntryForReading failed [rv=%" PRIx32 "]\n",
     379             :          static_cast<uint32_t>(rv)));
     380           0 :     mIsPending = false;
     381           0 :     mCallbacks = nullptr;
     382           0 :     return rv;
     383             :   }
     384             : 
     385             :   // There is no code path that would invoke the listener sooner than
     386             :   // we get to this line in case OnCacheEntryAvailable is invoked
     387             :   // synchronously.
     388           0 :   mListener = listener;
     389           0 :   mListenerContext = ctx;
     390             : 
     391           0 :   if (mLoadGroup)
     392           0 :     mLoadGroup->AddRequest(this, nullptr);
     393             : 
     394           0 :   return NS_OK;
     395             : }
     396             : 
     397             : NS_IMETHODIMP
     398           0 : nsWyciwygChannel::AsyncOpen2(nsIStreamListener *aListener)
     399             : {
     400           0 :   nsCOMPtr<nsIStreamListener> listener = aListener;
     401           0 :   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
     402           0 :   if (NS_FAILED(rv)) {
     403           0 :     mIsPending = false;
     404           0 :     mCallbacks = nullptr;
     405           0 :     return rv;
     406             :   }
     407           0 :   return AsyncOpen(listener, nullptr);
     408             : }
     409             : 
     410             : //////////////////////////////////////////////////////////////////////////////
     411             : // nsIWyciwygChannel
     412             : //////////////////////////////////////////////////////////////////////////////
     413             : 
     414             : NS_IMETHODIMP
     415           0 : nsWyciwygChannel::WriteToCacheEntry(const nsAString &aData)
     416             : {
     417           0 :   LOG(("nsWyciwygChannel::WriteToCacheEntry [this=%p]", this));
     418             : 
     419             :   nsresult rv;
     420             : 
     421           0 :   if (mMode == READING) {
     422           0 :     LOG(("nsWyciwygChannel::WriteToCacheEntry already open for reading"));
     423           0 :     MOZ_ASSERT(false);
     424             :     return NS_ERROR_UNEXPECTED;
     425             :   }
     426             : 
     427           0 :   mMode = WRITING;
     428             : 
     429           0 :   if (!mCacheEntry) {
     430           0 :     nsresult rv = OpenCacheEntryForWriting(mURI);
     431           0 :     if (NS_FAILED(rv) || !mCacheEntry) {
     432           0 :       LOG(("  could not synchronously open cache entry for write!"));
     433           0 :       return NS_ERROR_FAILURE;
     434             :     }
     435             :   }
     436             : 
     437           0 :   if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
     438           0 :     rv = mCacheEntry->SetMetaDataElement("inhibit-persistent-caching", "1");
     439           0 :     if (NS_FAILED(rv)) return rv;
     440             :   }
     441             : 
     442           0 :   if (mNeedToSetSecurityInfo) {
     443           0 :     mCacheEntry->SetSecurityInfo(mSecurityInfo);
     444           0 :     mNeedToSetSecurityInfo = false;
     445             :   }
     446             : 
     447           0 :   if (mNeedToWriteCharset) {
     448           0 :     WriteCharsetAndSourceToCache(mCharsetSource, mCharset);
     449           0 :     mNeedToWriteCharset = false;
     450             :   }
     451             : 
     452             :   uint32_t out;
     453           0 :   if (!mCacheOutputStream) {
     454             :     // Get the outputstream from the cache entry.
     455           0 :     rv = mCacheEntry->OpenOutputStream(0, getter_AddRefs(mCacheOutputStream));
     456           0 :     if (NS_FAILED(rv)) return rv;
     457             : 
     458             :     // Write out a Byte Order Mark, so that we'll know if the data is
     459             :     // BE or LE when we go to read it.
     460           0 :     char16_t bom = 0xFEFF;
     461           0 :     rv = mCacheOutputStream->Write((char *)&bom, sizeof(bom), &out);
     462           0 :     if (NS_FAILED(rv)) return rv;
     463             :   }
     464             : 
     465           0 :   return mCacheOutputStream->Write((const char *)PromiseFlatString(aData).get(),
     466           0 :                                    aData.Length() * sizeof(char16_t), &out);
     467             : }
     468             : 
     469             : 
     470             : NS_IMETHODIMP
     471           0 : nsWyciwygChannel::CloseCacheEntry(nsresult reason)
     472             : {
     473           0 :   if (mCacheEntry) {
     474           0 :     LOG(("nsWyciwygChannel::CloseCacheEntry [this=%p ]", this));
     475           0 :     mCacheOutputStream = nullptr;
     476           0 :     mCacheInputStream = nullptr;
     477             : 
     478           0 :     if (NS_FAILED(reason)) {
     479           0 :       mCacheEntry->AsyncDoom(nullptr);
     480             :     }
     481             : 
     482           0 :     mCacheEntry = nullptr;
     483             :   }
     484           0 :   return NS_OK;
     485             : }
     486             : 
     487             : NS_IMETHODIMP
     488           0 : nsWyciwygChannel::SetSecurityInfo(nsISupports *aSecurityInfo)
     489             : {
     490           0 :   if (mMode == READING) {
     491           0 :     MOZ_ASSERT(false);
     492             :     return NS_ERROR_UNEXPECTED;
     493             :   }
     494             : 
     495           0 :   mSecurityInfo = aSecurityInfo;
     496             : 
     497           0 :   if (mCacheEntry) {
     498           0 :     return mCacheEntry->SetSecurityInfo(mSecurityInfo);
     499             :   }
     500             : 
     501           0 :   mNeedToSetSecurityInfo = true;
     502             : 
     503           0 :   return NS_OK;
     504             : }
     505             : 
     506             : NS_IMETHODIMP
     507           0 : nsWyciwygChannel::SetCharsetAndSource(int32_t aSource,
     508             :                                       const nsACString& aCharset)
     509             : {
     510           0 :   NS_ENSURE_ARG(!aCharset.IsEmpty());
     511             : 
     512           0 :   if (mCacheEntry) {
     513           0 :     WriteCharsetAndSourceToCache(mCharsetSource, mCharset);
     514             :   } else {
     515           0 :     MOZ_ASSERT(mMode != WRITING, "We must have an entry!");
     516           0 :     if (mMode == READING) {
     517           0 :       return NS_ERROR_NOT_AVAILABLE;
     518             :     }
     519           0 :     mNeedToWriteCharset = true;
     520           0 :     mCharsetSource = aSource;
     521           0 :     mCharset = aCharset;
     522             :   }
     523             : 
     524           0 :   return NS_OK;
     525             : }
     526             : 
     527             : NS_IMETHODIMP
     528           0 : nsWyciwygChannel::GetCharsetAndSource(int32_t* aSource, nsACString& aCharset)
     529             : {
     530           0 :   MOZ_ASSERT(mMode == READING);
     531             : 
     532           0 :   if (!mCacheEntry) {
     533           0 :     return NS_ERROR_NOT_AVAILABLE;
     534             :   }
     535             : 
     536           0 :   nsXPIDLCString data;
     537           0 :   mCacheEntry->GetMetaDataElement("charset", getter_Copies(data));
     538             : 
     539           0 :   if (data.IsEmpty()) {
     540           0 :     return NS_ERROR_NOT_AVAILABLE;
     541             :   }
     542             : 
     543           0 :   nsXPIDLCString sourceStr;
     544           0 :   mCacheEntry->GetMetaDataElement("charset-source", getter_Copies(sourceStr));
     545             : 
     546             :   int32_t source;
     547             :   nsresult err;
     548           0 :   source = sourceStr.ToInteger(&err);
     549           0 :   if (NS_FAILED(err) || source == 0) {
     550           0 :     return NS_ERROR_NOT_AVAILABLE;
     551             :   }
     552             : 
     553           0 :   *aSource = source;
     554           0 :   aCharset = data;
     555           0 :   return NS_OK;
     556             : }
     557             : 
     558             : //////////////////////////////////////////////////////////////////////////////
     559             : // nsICacheEntryOpenCallback
     560             : //////////////////////////////////////////////////////////////////////////////
     561             : 
     562             : NS_IMETHODIMP
     563           0 : nsWyciwygChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appCache,
     564             :                                     uint32_t* aResult)
     565             : {
     566           0 :   *aResult = ENTRY_WANTED;
     567           0 :   return NS_OK;
     568             : }
     569             : 
     570             : NS_IMETHODIMP
     571           0 : nsWyciwygChannel::OnCacheEntryAvailable(nsICacheEntry *aCacheEntry,
     572             :                                         bool aNew,
     573             :                                         nsIApplicationCache* aAppCache,
     574             :                                         nsresult aStatus)
     575             : {
     576           0 :   LOG(("nsWyciwygChannel::OnCacheEntryAvailable [this=%p entry=%p "
     577             :        "new=%d status=%" PRIx32 "]\n", this, aCacheEntry, aNew, static_cast<uint32_t>(aStatus)));
     578             : 
     579           0 :   MOZ_RELEASE_ASSERT(!aNew, "New entry must not be returned when flag "
     580             :                             "OPEN_READONLY is used!");
     581             : 
     582             :   // if the channel's already fired onStopRequest,
     583             :   // then we should ignore this event.
     584           0 :   if (!mIsPending)
     585           0 :     return NS_OK;
     586             : 
     587           0 :   if (NS_SUCCEEDED(mStatus)) {
     588           0 :     if (NS_SUCCEEDED(aStatus)) {
     589           0 :       MOZ_ASSERT(aCacheEntry);
     590           0 :       mCacheEntry = aCacheEntry;
     591           0 :       nsresult rv = ReadFromCache();
     592           0 :       if (NS_FAILED(rv)) {
     593           0 :         mStatus = rv;
     594             :       }
     595             :     } else {
     596           0 :       mStatus = aStatus;
     597             :     }
     598             :   }
     599             : 
     600           0 :   if (NS_FAILED(mStatus)) {
     601           0 :     LOG(("channel was canceled [this=%p status=%" PRIx32 "]\n", this, static_cast<uint32_t>(mStatus)));
     602             :     // Since OnCacheEntryAvailable can be called directly from AsyncOpen
     603             :     // we must dispatch.
     604           0 :     NS_DispatchToCurrentThread(
     605           0 :       mozilla::NewRunnableMethod("nsWyciwygChannel::NotifyListener",
     606             :                                  this,
     607           0 :                                  &nsWyciwygChannel::NotifyListener));
     608             :   }
     609             : 
     610           0 :   return NS_OK;
     611             : }
     612             : 
     613             : //-----------------------------------------------------------------------------
     614             : // nsWyciwygChannel::nsIStreamListener
     615             : //-----------------------------------------------------------------------------
     616             : 
     617             : NS_IMETHODIMP
     618           0 : nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx,
     619             :                                   nsIInputStream *input,
     620             :                                   uint64_t offset, uint32_t count)
     621             : {
     622           0 :   LOG(("nsWyciwygChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64 " count=%u]\n",
     623             :       this, request, offset, count));
     624             : 
     625             :   nsresult rv;
     626             : 
     627           0 :   nsCOMPtr<nsIStreamListener> listener = mListener;
     628           0 :   nsCOMPtr<nsISupports> listenerContext = mListenerContext;
     629             : 
     630           0 :   if (listener) {
     631           0 :     rv = listener->OnDataAvailable(this, listenerContext, input, offset, count);
     632             :   } else {
     633           0 :     MOZ_ASSERT(false, "We must have a listener!");
     634             :     rv = NS_ERROR_UNEXPECTED;
     635             :   }
     636             : 
     637             :   // XXX handle 64-bit stuff for real
     638           0 :   if (mProgressSink && NS_SUCCEEDED(rv)) {
     639           0 :     mProgressSink->OnProgress(this, nullptr, offset + count, mContentLength);
     640             :   }
     641             : 
     642           0 :   return rv; // let the pump cancel on failure
     643             : }
     644             : 
     645             : //////////////////////////////////////////////////////////////////////////////
     646             : // nsIRequestObserver
     647             : //////////////////////////////////////////////////////////////////////////////
     648             : 
     649             : NS_IMETHODIMP
     650           0 : nsWyciwygChannel::OnStartRequest(nsIRequest *request, nsISupports *ctx)
     651             : {
     652           0 :   LOG(("nsWyciwygChannel::OnStartRequest [this=%p request=%p]\n",
     653             :       this, request));
     654             : 
     655           0 :   nsCOMPtr<nsIStreamListener> listener = mListener;
     656           0 :   nsCOMPtr<nsISupports> listenerContext = mListenerContext;
     657             : 
     658           0 :   if (listener) {
     659           0 :     return listener->OnStartRequest(this, listenerContext);
     660             :   }
     661             : 
     662           0 :   MOZ_ASSERT(false, "We must have a listener!");
     663             :   return NS_ERROR_UNEXPECTED;
     664             : }
     665             : 
     666             : 
     667             : NS_IMETHODIMP
     668           0 : nsWyciwygChannel::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status)
     669             : {
     670           0 :   LOG(("nsWyciwygChannel::OnStopRequest [this=%p request=%p status=%" PRIu32 "]\n",
     671             :        this, request, static_cast<uint32_t>(status)));
     672             : 
     673           0 :   if (NS_SUCCEEDED(mStatus))
     674           0 :     mStatus = status;
     675             : 
     676           0 :   mIsPending = false;
     677             : 
     678           0 :   nsCOMPtr<nsIStreamListener> listener;
     679           0 :   nsCOMPtr<nsISupports> listenerContext;
     680           0 :   listener.swap(mListener);
     681           0 :   listenerContext.swap(mListenerContext);
     682             : 
     683           0 :   if (listener) {
     684           0 :     listener->OnStopRequest(this, listenerContext, mStatus);
     685             :   } else {
     686           0 :     MOZ_ASSERT(false, "We must have a listener!");
     687             :   }
     688             : 
     689           0 :   if (mLoadGroup)
     690           0 :     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
     691             : 
     692           0 :   CloseCacheEntry(mStatus);
     693           0 :   mPump = nullptr;
     694             : 
     695             :   // Drop notification callbacks to prevent cycles.
     696           0 :   mCallbacks = nullptr;
     697           0 :   mProgressSink = nullptr;
     698             : 
     699           0 :   return NS_OK;
     700             : }
     701             : 
     702             : //////////////////////////////////////////////////////////////////////////////
     703             : // Helper functions
     704             : //////////////////////////////////////////////////////////////////////////////
     705             : 
     706             : nsresult
     707           0 : nsWyciwygChannel::GetCacheStorage(nsICacheStorage **_retval)
     708             : {
     709             :   nsresult rv;
     710             : 
     711             :   nsCOMPtr<nsICacheStorageService> cacheService =
     712           0 :     do_GetService("@mozilla.org/netwerk/cache-storage-service;1", &rv);
     713           0 :   NS_ENSURE_SUCCESS(rv, rv);
     714             : 
     715           0 :   bool anonymous = mLoadFlags & LOAD_ANONYMOUS;
     716           0 :   mOriginAttributes.SyncAttributesWithPrivateBrowsing(mPrivateBrowsing);
     717           0 :   RefPtr<LoadContextInfo> loadInfo = mozilla::net::GetLoadContextInfo(anonymous, mOriginAttributes);
     718             : 
     719           0 :   if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
     720           0 :     return cacheService->MemoryCacheStorage(loadInfo, _retval);
     721             :   }
     722             : 
     723           0 :   return cacheService->DiskCacheStorage(loadInfo, false, _retval);
     724             : }
     725             : 
     726             : nsresult
     727           0 : nsWyciwygChannel::OpenCacheEntryForReading(nsIURI *aURI)
     728             : {
     729             :   nsresult rv;
     730             : 
     731           0 :   nsCOMPtr<nsICacheStorage> cacheStorage;
     732           0 :   rv = GetCacheStorage(getter_AddRefs(cacheStorage));
     733           0 :   NS_ENSURE_SUCCESS(rv, rv);
     734             : 
     735           0 :   return cacheStorage->AsyncOpenURI(aURI, EmptyCString(),
     736             :                                     nsICacheStorage::OPEN_READONLY |
     737             :                                     nsICacheStorage::CHECK_MULTITHREADED,
     738           0 :                                     this);
     739             : }
     740             : 
     741             : nsresult
     742           0 : nsWyciwygChannel::OpenCacheEntryForWriting(nsIURI *aURI)
     743             : {
     744             :   nsresult rv;
     745             : 
     746           0 :   nsCOMPtr<nsICacheStorage> cacheStorage;
     747           0 :   rv = GetCacheStorage(getter_AddRefs(cacheStorage));
     748           0 :   NS_ENSURE_SUCCESS(rv, rv);
     749             : 
     750           0 :   return cacheStorage->OpenTruncate(aURI, EmptyCString(),
     751           0 :                                     getter_AddRefs(mCacheEntry));
     752             : }
     753             : 
     754             : nsresult
     755           0 : nsWyciwygChannel::ReadFromCache()
     756             : {
     757           0 :   LOG(("nsWyciwygChannel::ReadFromCache [this=%p] ", this));
     758             : 
     759           0 :   NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE);
     760             :   nsresult rv;
     761             : 
     762             :   // Get the stored security info
     763           0 :   mCacheEntry->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
     764             : 
     765           0 :   nsAutoCString tmpStr;
     766           0 :   rv = mCacheEntry->GetMetaDataElement("inhibit-persistent-caching",
     767           0 :                                        getter_Copies(tmpStr));
     768           0 :   if (NS_SUCCEEDED(rv) && tmpStr.EqualsLiteral("1"))
     769           0 :     mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
     770             : 
     771             :   // Get a transport to the cached data...
     772           0 :   rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
     773           0 :   if (NS_FAILED(rv))
     774           0 :     return rv;
     775           0 :   NS_ENSURE_TRUE(mCacheInputStream, NS_ERROR_UNEXPECTED);
     776             : 
     777           0 :   rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mCacheInputStream);
     778           0 :   if (NS_FAILED(rv)) return rv;
     779             : 
     780             :   // Pump the cache data downstream
     781           0 :   return mPump->AsyncRead(this, nullptr);
     782             : }
     783             : 
     784             : void
     785           0 : nsWyciwygChannel::WriteCharsetAndSourceToCache(int32_t aSource,
     786             :                                                const nsCString& aCharset)
     787             : {
     788           0 :   NS_PRECONDITION(mCacheEntry, "Better have cache entry!");
     789             : 
     790           0 :   mCacheEntry->SetMetaDataElement("charset", aCharset.get());
     791             : 
     792           0 :   nsAutoCString source;
     793           0 :   source.AppendInt(aSource);
     794           0 :   mCacheEntry->SetMetaDataElement("charset-source", source.get());
     795           0 : }
     796             : 
     797             : void
     798           0 : nsWyciwygChannel::NotifyListener()
     799             : {
     800           0 :   nsCOMPtr<nsIStreamListener> listener;
     801           0 :   nsCOMPtr<nsISupports> listenerContext;
     802             : 
     803           0 :   listener.swap(mListener);
     804           0 :   listenerContext.swap(mListenerContext);
     805             : 
     806           0 :   if (listener) {
     807           0 :     listener->OnStartRequest(this, listenerContext);
     808           0 :     mIsPending = false;
     809           0 :     listener->OnStopRequest(this, listenerContext, mStatus);
     810             :   } else {
     811           0 :     MOZ_ASSERT(false, "We must have the listener!");
     812             :     mIsPending = false;
     813             :   }
     814             : 
     815           0 :   CloseCacheEntry(mStatus);
     816             : 
     817             :   // Remove ourselves from the load group.
     818           0 :   if (mLoadGroup) {
     819           0 :     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
     820             :   }
     821           0 : }
     822             : 
     823             : // vim: ts=2 sw=2

Generated by: LCOV version 1.13