LCOV - app.info - netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp

LCOV - code coverage report
| Current view: | directory - netwerk/protocol/wyciwyg - nsWyciwygChannel.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 324 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 68 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is mozilla.org code.
          17                 :  *
          18                 :  * The Initial Developer of the Original Code is
          19                 :  * Netscape Communications Corporation.
          20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          21                 :  * the Initial Developer. All Rights Reserved.
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   Radha Kulkarni(radha@netscape.com)
          25                 :  *   Michal Novotny <michal.novotny@gmail.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : #include "nsWyciwyg.h"
          42                 : #include "nsWyciwygChannel.h"
          43                 : #include "nsIServiceManager.h"
          44                 : #include "nsILoadGroup.h"
          45                 : #include "nsIScriptSecurityManager.h"
          46                 : #include "nsNetUtil.h"
          47                 : #include "nsContentUtils.h"
          48                 : #include "nsICacheService.h"
          49                 : #include "nsICacheSession.h"
          50                 : #include "nsIParser.h"
          51                 : #include "nsThreadUtils.h"
          52                 : #include "nsProxyRelease.h"
          53                 :
          54                 : // Must release mChannel on the main thread
          55                 : class nsWyciwygAsyncEvent : public nsRunnable {
          56                 : public:
          57               0 :   nsWyciwygAsyncEvent(nsWyciwygChannel *aChannel) : mChannel(aChannel) {}
          58                 :
          59               0 :   ~nsWyciwygAsyncEvent()
          60               0 :   {
          61               0 :     nsCOMPtr<nsIThread> thread = do_GetMainThread();
          62               0 :     NS_WARN_IF_FALSE(thread, "Couldn't get the main thread!");
          63               0 :     if (thread) {
          64               0 :       nsIWyciwygChannel *chan = static_cast<nsIWyciwygChannel *>(mChannel);
          65               0 :       mChannel.forget();
          66               0 :       NS_ProxyRelease(thread, chan);
          67                 :     }
          68               0 :   }
          69                 : protected:
          70                 :   nsRefPtr<nsWyciwygChannel> mChannel;
          71                 : };
          72                 :
          73               0 : class nsWyciwygSetCharsetandSourceEvent : public nsWyciwygAsyncEvent {
          74                 : public:
          75               0 :   nsWyciwygSetCharsetandSourceEvent(nsWyciwygChannel *aChannel)
          76               0 :     : nsWyciwygAsyncEvent(aChannel) {}
          77                 :
          78               0 :   NS_IMETHOD Run()
          79                 :   {
          80               0 :     mChannel->SetCharsetAndSourceInternal();
          81               0 :     return NS_OK;
          82                 :   }
          83                 : };
          84                 :
          85               0 : class nsWyciwygWriteEvent : public nsWyciwygAsyncEvent {
          86                 : public:
          87               0 :   nsWyciwygWriteEvent(nsWyciwygChannel *aChannel, const nsAString &aData,
          88                 :                       const nsACString &spec)
          89               0 :     : nsWyciwygAsyncEvent(aChannel), mData(aData), mSpec(spec) {}
          90                 :
          91               0 :   NS_IMETHOD Run()
          92                 :   {
          93               0 :     mChannel->WriteToCacheEntryInternal(mData, mSpec);
          94               0 :     return NS_OK;
          95                 :   }
          96                 : private:
          97                 :   nsString mData;
          98                 :   nsCString mSpec;
          99                 : };
         100                 :
         101               0 : class nsWyciwygCloseEvent : public nsWyciwygAsyncEvent {
         102                 : public:
         103               0 :   nsWyciwygCloseEvent(nsWyciwygChannel *aChannel, nsresult aReason)
         104               0 :     : nsWyciwygAsyncEvent(aChannel), mReason(aReason) {}
         105                 :
         106               0 :   NS_IMETHOD Run()
         107                 :   {
         108               0 :     mChannel->CloseCacheEntryInternal(mReason);
         109               0 :     return NS_OK;
         110                 :   }
         111                 : private:
         112                 :   nsresult mReason;
         113                 : };
         114                 :
         115                 :
         116                 : // nsWyciwygChannel methods
         117               0 : nsWyciwygChannel::nsWyciwygChannel()
         118                 :   : mStatus(NS_OK),
         119                 :     mIsPending(false),
         120                 :     mCharsetAndSourceSet(false),
         121                 :     mNeedToWriteCharset(false),
         122                 :     mCharsetSource(kCharsetUninitialized),
         123                 :     mContentLength(-1),
         124               0 :     mLoadFlags(LOAD_NORMAL)
         125                 : {
         126               0 : }
         127                 :
         128               0 : nsWyciwygChannel::~nsWyciwygChannel()
         129                 : {
         130               0 : }
         131                 :
         132               0 : NS_IMPL_THREADSAFE_ISUPPORTS6(nsWyciwygChannel,
         133                 :                               nsIChannel,
         134                 :                               nsIRequest,
         135                 :                               nsIStreamListener,
         136                 :                               nsIRequestObserver,
         137                 :                               nsICacheListener,
         138                 :                               nsIWyciwygChannel)
         139                 :
         140                 : nsresult
         141               0 : nsWyciwygChannel::Init(nsIURI* uri)
         142                 : {
         143               0 :   NS_ENSURE_ARG_POINTER(uri);
         144                 :
         145                 :   nsresult rv;
         146                 :
         147               0 :   mURI = uri;
         148               0 :   mOriginalURI = uri;
         149                 :
         150                 :   nsCOMPtr<nsICacheService> serv =
         151               0 :     do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
         152               0 :   NS_ENSURE_SUCCESS(rv, rv);
         153                 :
         154               0 :   rv = serv->GetCacheIOTarget(getter_AddRefs(mCacheIOTarget));
         155               0 :   NS_ENSURE_SUCCESS(rv, rv);
         156                 :
         157               0 :   return NS_OK;
         158                 : }
         159                 :
         160                 : ///////////////////////////////////////////////////////////////////////////////
         161                 : // nsIRequest methods:
         162                 : ///////////////////////////////////////////////////////////////////////////////
         163                 :
         164                 : NS_IMETHODIMP
         165               0 : nsWyciwygChannel::GetName(nsACString &aName)
         166                 : {
         167               0 :   return mURI->GetSpec(aName);
         168                 : }
         169                 :
         170                 : NS_IMETHODIMP
         171               0 : nsWyciwygChannel::IsPending(bool *aIsPending)
         172                 : {
         173               0 :   *aIsPending = mIsPending;
         174               0 :   return NS_OK;
         175                 : }
         176                 :
         177                 : NS_IMETHODIMP
         178               0 : nsWyciwygChannel::GetStatus(nsresult *aStatus)
         179                 : {
         180               0 :   if (NS_SUCCEEDED(mStatus) && mPump)
         181               0 :     mPump->GetStatus(aStatus);
         182                 :   else
         183               0 :     *aStatus = mStatus;
         184               0 :   return NS_OK;
         185                 : }
         186                 :
         187                 : NS_IMETHODIMP
         188               0 : nsWyciwygChannel::Cancel(nsresult status)
         189                 : {
         190               0 :   mStatus = status;
         191               0 :   if (mPump)
         192               0 :     mPump->Cancel(status);
         193                 :   // else we're waiting for OnCacheEntryAvailable
         194               0 :   return NS_OK;
         195                 : }
         196                 :
         197                 : NS_IMETHODIMP
         198               0 : nsWyciwygChannel::Suspend()
         199                 : {
         200               0 :   if (mPump)
         201               0 :     mPump->Suspend();
         202                 :   // XXX else, we'll ignore this ... and that's probably bad!
         203               0 :   return NS_OK;
         204                 : }
         205                 :
         206                 : NS_IMETHODIMP
         207               0 : nsWyciwygChannel::Resume()
         208                 : {
         209               0 :   if (mPump)
         210               0 :     mPump->Resume();
         211                 :   // XXX else, we'll ignore this ... and that's probably bad!
         212               0 :   return NS_OK;
         213                 : }
         214                 :
         215                 : NS_IMETHODIMP
         216               0 : nsWyciwygChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
         217                 : {
         218               0 :   *aLoadGroup = mLoadGroup;
         219               0 :   NS_IF_ADDREF(*aLoadGroup);
         220               0 :   return NS_OK;
         221                 : }
         222                 :
         223                 : NS_IMETHODIMP
         224               0 : nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
         225                 : {
         226               0 :   mLoadGroup = aLoadGroup;
         227                 :   NS_QueryNotificationCallbacks(mCallbacks,
         228                 :                                 mLoadGroup,
         229                 :                                 NS_GET_IID(nsIProgressEventSink),
         230               0 :                                 getter_AddRefs(mProgressSink));
         231               0 :   return NS_OK;
         232                 : }
         233                 :
         234                 : NS_IMETHODIMP
         235               0 : nsWyciwygChannel::SetLoadFlags(PRUint32 aLoadFlags)
         236                 : {
         237               0 :   mLoadFlags = aLoadFlags;
         238               0 :   return NS_OK;
         239                 : }
         240                 :
         241                 : NS_IMETHODIMP
         242               0 : nsWyciwygChannel::GetLoadFlags(PRUint32 * aLoadFlags)
         243                 : {
         244               0 :   *aLoadFlags = mLoadFlags;
         245               0 :   return NS_OK;
         246                 : }
         247                 :
         248                 : ////////////////////////////////////////////////////////////////////////////////
         249                 : // nsIChannel methods:
         250                 : ///////////////////////////////////////////////////////////////////////////////
         251                 :
         252                 : NS_IMETHODIMP
         253               0 : nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI)
         254                 : {
         255               0 :   *aURI = mOriginalURI;
         256               0 :   NS_ADDREF(*aURI);
         257               0 :   return NS_OK;
         258                 : }
         259                 :
         260                 : NS_IMETHODIMP
         261               0 : nsWyciwygChannel::SetOriginalURI(nsIURI* aURI)
         262                 : {
         263               0 :   NS_ENSURE_ARG_POINTER(aURI);
         264               0 :   mOriginalURI = aURI;
         265               0 :   return NS_OK;
         266                 : }
         267                 :
         268                 : NS_IMETHODIMP
         269               0 : nsWyciwygChannel::GetURI(nsIURI* *aURI)
         270                 : {
         271               0 :   *aURI = mURI;
         272               0 :   NS_IF_ADDREF(*aURI);
         273               0 :   return NS_OK;
         274                 : }
         275                 :
         276                 : NS_IMETHODIMP
         277               0 : nsWyciwygChannel::GetOwner(nsISupports **aOwner)
         278                 : {
         279               0 :   NS_PRECONDITION(mOwner, "Must have a principal!");
         280               0 :   NS_ENSURE_STATE(mOwner);
         281                 :
         282               0 :   NS_ADDREF(*aOwner = mOwner);
         283               0 :   return NS_OK;
         284                 : }
         285                 :
         286                 : NS_IMETHODIMP
         287               0 : nsWyciwygChannel::SetOwner(nsISupports* aOwner)
         288                 : {
         289               0 :   mOwner = aOwner;
         290               0 :   return NS_OK;
         291                 : }
         292                 :
         293                 : NS_IMETHODIMP
         294               0 : nsWyciwygChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks)
         295                 : {
         296               0 :   *aCallbacks = mCallbacks.get();
         297               0 :   NS_IF_ADDREF(*aCallbacks);
         298               0 :   return NS_OK;
         299                 : }
         300                 :
         301                 : NS_IMETHODIMP
         302               0 : nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
         303                 : {
         304               0 :   mCallbacks = aNotificationCallbacks;
         305                 :   NS_QueryNotificationCallbacks(mCallbacks,
         306                 :                                 mLoadGroup,
         307                 :                                 NS_GET_IID(nsIProgressEventSink),
         308               0 :                                 getter_AddRefs(mProgressSink));
         309               0 :   return NS_OK;
         310                 : }
         311                 :
         312                 : NS_IMETHODIMP
         313               0 : nsWyciwygChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
         314                 : {
         315               0 :   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
         316                 :
         317               0 :   return NS_OK;
         318                 : }
         319                 :
         320                 : NS_IMETHODIMP
         321               0 : nsWyciwygChannel::GetContentType(nsACString &aContentType)
         322                 : {
         323               0 :   aContentType.AssignLiteral(WYCIWYG_TYPE);
         324               0 :   return NS_OK;
         325                 : }
         326                 :
         327                 : NS_IMETHODIMP
         328               0 : nsWyciwygChannel::SetContentType(const nsACString &aContentType)
         329                 : {
         330               0 :   return NS_ERROR_NOT_IMPLEMENTED;
         331                 : }
         332                 :
         333                 : NS_IMETHODIMP
         334               0 : nsWyciwygChannel::GetContentCharset(nsACString &aContentCharset)
         335                 : {
         336               0 :   aContentCharset.Assign("UTF-16");
         337               0 :   return NS_OK;
         338                 : }
         339                 :
         340                 : NS_IMETHODIMP
         341               0 : nsWyciwygChannel::SetContentCharset(const nsACString &aContentCharset)
         342                 : {
         343               0 :   return NS_ERROR_NOT_IMPLEMENTED;
         344                 : }
         345                 :
         346                 : NS_IMETHODIMP
         347               0 : nsWyciwygChannel::GetContentDisposition(PRUint32 *aContentDisposition)
         348                 : {
         349               0 :   return NS_ERROR_NOT_AVAILABLE;
         350                 : }
         351                 :
         352                 : NS_IMETHODIMP
         353               0 : nsWyciwygChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
         354                 : {
         355               0 :   return NS_ERROR_NOT_AVAILABLE;
         356                 : }
         357                 :
         358                 : NS_IMETHODIMP
         359               0 : nsWyciwygChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
         360                 : {
         361               0 :   return NS_ERROR_NOT_AVAILABLE;
         362                 : }
         363                 :
         364                 : NS_IMETHODIMP
         365               0 : nsWyciwygChannel::GetContentLength(PRInt32 *aContentLength)
         366                 : {
         367               0 :   *aContentLength = mContentLength;
         368               0 :   return NS_OK;
         369                 : }
         370                 :
         371                 : NS_IMETHODIMP
         372               0 : nsWyciwygChannel::SetContentLength(PRInt32 aContentLength)
         373                 : {
         374               0 :   mContentLength = aContentLength;
         375                 :
         376               0 :   return NS_OK;
         377                 : }
         378                 :
         379                 : NS_IMETHODIMP
         380               0 : nsWyciwygChannel::Open(nsIInputStream ** aReturn)
         381                 : {
         382               0 :   return NS_ERROR_NOT_IMPLEMENTED;
         383                 : }
         384                 :
         385                 : NS_IMETHODIMP
         386               0 : nsWyciwygChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
         387                 : {
         388               0 :   LOG(("nsWyciwygChannel::AsyncOpen [this=%x]\n", this));
         389                 :
         390               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
         391               0 :   NS_ENSURE_ARG_POINTER(listener);
         392                 :
         393               0 :   nsCAutoString spec;
         394               0 :   mURI->GetSpec(spec);
         395                 :
         396                 :   // open a cache entry for this channel...
         397               0 :   nsresult rv = OpenCacheEntry(spec, nsICache::ACCESS_READ);
         398               0 :   if (rv == NS_ERROR_CACHE_KEY_NOT_FOUND) {
         399                 :     // Overwrite rv on purpose; if event dispatch fails we'll bail, and
         400                 :     // otherwise we'll wait until the event fires before calling back.
         401                 :     rv = NS_DispatchToCurrentThread(
         402               0 :             NS_NewRunnableMethod(this, &nsWyciwygChannel::NotifyListener));
         403                 :   }
         404                 :
         405               0 :   if (NS_FAILED(rv)) {
         406               0 :     LOG(("nsWyciwygChannel::OpenCacheEntry failed [rv=%x]\n", rv));
         407               0 :     return rv;
         408                 :   }
         409                 :
         410               0 :   mIsPending = true;
         411               0 :   mListener = listener;
         412               0 :   mListenerContext = ctx;
         413                 :
         414               0 :   if (mLoadGroup)
         415               0 :     mLoadGroup->AddRequest(this, nsnull);
         416                 :
         417               0 :   return NS_OK;
         418                 : }
         419                 :
         420                 : //////////////////////////////////////////////////////////////////////////////
         421                 : // nsIWyciwygChannel
         422                 : //////////////////////////////////////////////////////////////////////////////
         423                 :
         424                 : NS_IMETHODIMP
         425               0 : nsWyciwygChannel::WriteToCacheEntry(const nsAString &aData)
         426                 : {
         427                 :   // URIs not thread-safe, so get spec now in case we need it
         428               0 :   nsCAutoString spec;
         429               0 :   nsresult rv = mURI->GetAsciiSpec(spec);
         430               0 :   if (NS_FAILED(rv))
         431               0 :     return rv;
         432                 :
         433               0 :   return mCacheIOTarget->Dispatch(new nsWyciwygWriteEvent(this, aData, spec),
         434               0 :                                   NS_DISPATCH_NORMAL);
         435                 : }
         436                 :
         437                 : nsresult
         438               0 : nsWyciwygChannel::WriteToCacheEntryInternal(const nsAString &aData, const nsACString& spec)
         439                 : {
         440               0 :   NS_ASSERTION(IsOnCacheIOThread(), "wrong thread");
         441                 :
         442                 :   nsresult rv;
         443                 :
         444               0 :   if (!mCacheEntry) {
         445               0 :     rv = OpenCacheEntry(spec, nsICache::ACCESS_WRITE);
         446               0 :     if (NS_FAILED(rv)) return rv;
         447                 :   }
         448                 :
         449               0 :   if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
         450               0 :     rv = mCacheEntry->SetMetaDataElement("inhibit-persistent-caching", "1");
         451               0 :     if (NS_FAILED(rv)) return rv;
         452                 :   }
         453                 :
         454               0 :   if (mSecurityInfo) {
         455               0 :     mCacheEntry->SetSecurityInfo(mSecurityInfo);
         456                 :   }
         457                 :
         458               0 :   if (mNeedToWriteCharset) {
         459               0 :     WriteCharsetAndSourceToCache(mCharsetSource, mCharset);
         460               0 :     mNeedToWriteCharset = false;
         461                 :   }
         462                 :
         463                 :   PRUint32 out;
         464               0 :   if (!mCacheOutputStream) {
         465                 :     // Get the outputstream from the cache entry.
         466               0 :     rv = mCacheEntry->OpenOutputStream(0, getter_AddRefs(mCacheOutputStream));
         467               0 :     if (NS_FAILED(rv)) return rv;
         468                 :
         469                 :     // Write out a Byte Order Mark, so that we'll know if the data is
         470                 :     // BE or LE when we go to read it.
         471               0 :     PRUnichar bom = 0xFEFF;
         472               0 :     rv = mCacheOutputStream->Write((char *)&bom, sizeof(bom), &out);
         473               0 :     if (NS_FAILED(rv)) return rv;
         474                 :   }
         475                 :
         476               0 :   return mCacheOutputStream->Write((char *)PromiseFlatString(aData).get(),
         477               0 :                                    aData.Length() * sizeof(PRUnichar), &out);
         478                 : }
         479                 :
         480                 :
         481                 : NS_IMETHODIMP
         482               0 : nsWyciwygChannel::CloseCacheEntry(nsresult reason)
         483                 : {
         484               0 :   return mCacheIOTarget->Dispatch(new nsWyciwygCloseEvent(this, reason),
         485               0 :                                   NS_DISPATCH_NORMAL);
         486                 : }
         487                 :
         488                 : nsresult
         489               0 : nsWyciwygChannel::CloseCacheEntryInternal(nsresult reason)
         490                 : {
         491               0 :   NS_ASSERTION(IsOnCacheIOThread(), "wrong thread");
         492                 :
         493               0 :   if (mCacheEntry) {
         494               0 :     LOG(("nsWyciwygChannel::CloseCacheEntryInternal [this=%x ]", this));
         495               0 :     mCacheOutputStream = 0;
         496               0 :     mCacheInputStream = 0;
         497                 :
         498               0 :     if (NS_FAILED(reason))
         499               0 :       mCacheEntry->Doom();
         500                 :
         501               0 :     mCacheEntry = 0;
         502                 :   }
         503               0 :   return NS_OK;
         504                 : }
         505                 :
         506                 : NS_IMETHODIMP
         507               0 : nsWyciwygChannel::SetSecurityInfo(nsISupports *aSecurityInfo)
         508                 : {
         509               0 :   mSecurityInfo = aSecurityInfo;
         510                 :
         511               0 :   return NS_OK;
         512                 : }
         513                 :
         514                 : NS_IMETHODIMP
         515               0 : nsWyciwygChannel::SetCharsetAndSource(PRInt32 aSource,
         516                 :                                       const nsACString& aCharset)
         517                 : {
         518               0 :   NS_ENSURE_ARG(!aCharset.IsEmpty());
         519                 :
         520               0 :   mCharsetAndSourceSet = true;
         521               0 :   mCharset = aCharset;
         522               0 :   mCharsetSource = aSource;
         523                 :
         524               0 :   return mCacheIOTarget->Dispatch(new nsWyciwygSetCharsetandSourceEvent(this),
         525               0 :                                   NS_DISPATCH_NORMAL);
         526                 : }
         527                 :
         528                 : void
         529               0 : nsWyciwygChannel::SetCharsetAndSourceInternal()
         530                 : {
         531               0 :   NS_ASSERTION(IsOnCacheIOThread(), "wrong thread");
         532                 :
         533               0 :   if (mCacheEntry) {
         534               0 :     WriteCharsetAndSourceToCache(mCharsetSource, mCharset);
         535                 :   } else {
         536               0 :     mNeedToWriteCharset = true;
         537                 :   }
         538               0 : }
         539                 :
         540                 : NS_IMETHODIMP
         541               0 : nsWyciwygChannel::GetCharsetAndSource(PRInt32* aSource, nsACString& aCharset)
         542                 : {
         543               0 :   if (mCharsetAndSourceSet) {
         544               0 :     *aSource = mCharsetSource;
         545               0 :     aCharset = mCharset;
         546               0 :     return NS_OK;
         547                 :   }
         548                 :
         549               0 :   if (!mCacheEntry) {
         550               0 :     return NS_ERROR_NOT_AVAILABLE;
         551                 :   }
         552                 :
         553               0 :   nsXPIDLCString data;
         554               0 :   mCacheEntry->GetMetaDataElement("charset", getter_Copies(data));
         555                 :
         556               0 :   if (data.IsEmpty()) {
         557               0 :     return NS_ERROR_NOT_AVAILABLE;
         558                 :   }
         559                 :
         560               0 :   nsXPIDLCString sourceStr;
         561               0 :   mCacheEntry->GetMetaDataElement("charset-source", getter_Copies(sourceStr));
         562                 :
         563                 :   PRInt32 source;
         564                 :   // XXXbz ToInteger takes an PRInt32* but outputs an nsresult in it... :(
         565                 :   PRInt32 err;
         566               0 :   source = sourceStr.ToInteger(&err);
         567               0 :   if (NS_FAILED(err) || source == 0) {
         568               0 :     return NS_ERROR_NOT_AVAILABLE;
         569                 :   }
         570                 :
         571               0 :   *aSource = source;
         572               0 :   aCharset = data;
         573               0 :   return NS_OK;
         574                 : }
         575                 :
         576                 : //////////////////////////////////////////////////////////////////////////////
         577                 : // nsICachelistener
         578                 : //////////////////////////////////////////////////////////////////////////////
         579                 : NS_IMETHODIMP
         580               0 : nsWyciwygChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor * aCacheEntry, nsCacheAccessMode aMode, nsresult aStatus)
         581                 : {
         582               0 :   LOG(("nsWyciwygChannel::OnCacheEntryAvailable [this=%x entry=%x "
         583                 :        "access=%x status=%x]\n", this, aCacheEntry, aMode, aStatus));
         584                 :
         585                 :   // if the channel's already fired onStopRequest,
         586                 :   // then we should ignore this event.
         587               0 :   if (!mIsPending)
         588               0 :     return NS_OK;
         589                 :
         590                 :   // otherwise, we have to handle this event.
         591               0 :   if (NS_SUCCEEDED(aStatus))
         592               0 :     mCacheEntry = aCacheEntry;
         593               0 :   else if (NS_SUCCEEDED(mStatus))
         594               0 :     mStatus = aStatus;
         595                 :
         596                 :   nsresult rv;
         597               0 :   if (NS_FAILED(mStatus)) {
         598               0 :     LOG(("channel was canceled [this=%x status=%x]\n", this, mStatus));
         599               0 :     rv = mStatus;
         600                 :   }
         601                 :   else { // advance to the next state...
         602               0 :     rv = ReadFromCache();
         603                 :   }
         604                 :
         605                 :   // a failure from Connect means that we have to abort the channel.
         606               0 :   if (NS_FAILED(rv)) {
         607               0 :     CloseCacheEntry(rv);
         608                 :
         609               0 :     NotifyListener();
         610                 :   }
         611                 :
         612               0 :   return NS_OK;
         613                 : }
         614                 :
         615                 : //-----------------------------------------------------------------------------
         616                 : // nsWyciwygChannel::nsIStreamListener
         617                 : //-----------------------------------------------------------------------------
         618                 :
         619                 : NS_IMETHODIMP
         620               0 : nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx,
         621                 :                                   nsIInputStream *input,
         622                 :                                   PRUint32 offset, PRUint32 count)
         623                 : {
         624               0 :   LOG(("nsWyciwygChannel::OnDataAvailable [this=%x request=%x offset=%u count=%u]\n",
         625                 :       this, request, offset, count));
         626                 :
         627                 :   nsresult rv;
         628                 :
         629               0 :   rv = mListener->OnDataAvailable(this, mListenerContext, input, offset, count);
         630                 :
         631                 :   // XXX handle 64-bit stuff for real
         632               0 :   if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
         633               0 :     mProgressSink->OnProgress(this, nsnull, PRUint64(offset + count),
         634               0 :                               PRUint64(mContentLength));
         635                 :
         636               0 :   return rv; // let the pump cancel on failure
         637                 : }
         638                 :
         639                 : //////////////////////////////////////////////////////////////////////////////
         640                 : // nsIRequestObserver
         641                 : //////////////////////////////////////////////////////////////////////////////
         642                 :
         643                 : NS_IMETHODIMP
         644               0 : nsWyciwygChannel::OnStartRequest(nsIRequest *request, nsISupports *ctx)
         645                 : {
         646               0 :   LOG(("nsWyciwygChannel::OnStartRequest [this=%x request=%x\n",
         647                 :       this, request));
         648                 :
         649               0 :   return mListener->OnStartRequest(this, mListenerContext);
         650                 : }
         651                 :
         652                 :
         653                 : NS_IMETHODIMP
         654               0 : nsWyciwygChannel::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status)
         655                 : {
         656               0 :   LOG(("nsWyciwygChannel::OnStopRequest [this=%x request=%x status=%d\n",
         657                 :       this, request, status));
         658                 :
         659               0 :   if (NS_SUCCEEDED(mStatus))
         660               0 :     mStatus = status;
         661                 :
         662               0 :   mListener->OnStopRequest(this, mListenerContext, mStatus);
         663               0 :   mListener = 0;
         664               0 :   mListenerContext = 0;
         665                 :
         666               0 :   if (mLoadGroup)
         667               0 :     mLoadGroup->RemoveRequest(this, nsnull, mStatus);
         668                 :
         669               0 :   CloseCacheEntry(mStatus);
         670               0 :   mPump = 0;
         671               0 :   mIsPending = false;
         672                 :
         673                 :   // Drop notification callbacks to prevent cycles.
         674               0 :   mCallbacks = 0;
         675               0 :   mProgressSink = 0;
         676                 :
         677               0 :   return NS_OK;
         678                 : }
         679                 :
         680                 : //////////////////////////////////////////////////////////////////////////////
         681                 : // Helper functions
         682                 : //////////////////////////////////////////////////////////////////////////////
         683                 :
         684                 : nsresult
         685               0 : nsWyciwygChannel::OpenCacheEntry(const nsACString & aCacheKey,
         686                 :                                  nsCacheAccessMode aAccessMode)
         687                 : {
         688               0 :   nsresult rv = NS_ERROR_FAILURE;
         689                 :   // Get cache service
         690                 :   nsCOMPtr<nsICacheService> cacheService =
         691               0 :     do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
         692               0 :   NS_ENSURE_SUCCESS(rv, rv);
         693                 :
         694                 :   // honor security settings
         695                 :   nsCacheStoragePolicy storagePolicy;
         696               0 :   if (mLoadFlags & INHIBIT_PERSISTENT_CACHING)
         697               0 :     storagePolicy = nsICache::STORE_IN_MEMORY;
         698                 :   else
         699               0 :     storagePolicy = nsICache::STORE_ANYWHERE;
         700                 :
         701               0 :   nsCOMPtr<nsICacheSession> cacheSession;
         702                 :   // Open a stream based cache session.
         703               0 :   rv = cacheService->CreateSession("wyciwyg", storagePolicy, true,
         704               0 :                                    getter_AddRefs(cacheSession));
         705               0 :   if (!cacheSession)
         706               0 :     return NS_ERROR_FAILURE;
         707                 :
         708               0 :   if (aAccessMode == nsICache::ACCESS_WRITE)
         709               0 :     rv = cacheSession->OpenCacheEntry(aCacheKey, aAccessMode, false,
         710               0 :                                       getter_AddRefs(mCacheEntry));
         711                 :   else
         712               0 :     rv = cacheSession->AsyncOpenCacheEntry(aCacheKey, aAccessMode, this);
         713                 :
         714               0 :   return rv;
         715                 : }
         716                 :
         717                 : nsresult
         718               0 : nsWyciwygChannel::ReadFromCache()
         719                 : {
         720               0 :   LOG(("nsWyciwygChannel::ReadFromCache [this=%x] ", this));
         721                 :
         722               0 :   NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE);
         723                 :   nsresult rv;
         724                 :
         725                 :   // Get the stored security info
         726               0 :   mCacheEntry->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
         727                 :
         728               0 :   nsCAutoString tmpStr;
         729               0 :   rv = mCacheEntry->GetMetaDataElement("inhibit-persistent-caching",
         730               0 :                                        getter_Copies(tmpStr));
         731               0 :   if (NS_SUCCEEDED(rv) && tmpStr == NS_LITERAL_CSTRING("1"))
         732               0 :     mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
         733                 :
         734                 :   // Get a transport to the cached data...
         735               0 :   rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
         736               0 :   if (NS_FAILED(rv))
         737               0 :     return rv;
         738               0 :   NS_ENSURE_TRUE(mCacheInputStream, NS_ERROR_UNEXPECTED);
         739                 :
         740               0 :   rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mCacheInputStream);
         741               0 :   if (NS_FAILED(rv)) return rv;
         742                 :
         743                 :   // Pump the cache data downstream
         744               0 :   return mPump->AsyncRead(this, nsnull);
         745                 : }
         746                 :
         747                 : void
         748               0 : nsWyciwygChannel::WriteCharsetAndSourceToCache(PRInt32 aSource,
         749                 :                                                const nsCString& aCharset)
         750                 : {
         751               0 :   NS_ASSERTION(IsOnCacheIOThread(), "wrong thread");
         752               0 :   NS_PRECONDITION(mCacheEntry, "Better have cache entry!");
         753                 :
         754               0 :   mCacheEntry->SetMetaDataElement("charset", aCharset.get());
         755                 :
         756               0 :   nsCAutoString source;
         757               0 :   source.AppendInt(aSource);
         758               0 :   mCacheEntry->SetMetaDataElement("charset-source", source.get());
         759               0 : }
         760                 :
         761                 : void
         762               0 : nsWyciwygChannel::NotifyListener()
         763                 : {
         764               0 :   if (mListener) {
         765               0 :     mListener->OnStartRequest(this, mListenerContext);
         766               0 :     mListener->OnStopRequest(this, mListenerContext, mStatus);
         767               0 :     mListener = 0;
         768               0 :     mListenerContext = 0;
         769                 :   }
         770                 :
         771               0 :   mIsPending = false;
         772                 :
         773                 :   // Remove ourselves from the load group.
         774               0 :   if (mLoadGroup) {
         775               0 :     mLoadGroup->RemoveRequest(this, nsnull, mStatus);
         776                 :   }
         777               0 : }
         778                 :
         779                 : bool
         780               0 : nsWyciwygChannel::IsOnCacheIOThread()
         781                 : {
         782                 :   bool correctThread;
         783               0 :   mCacheIOTarget->IsOnCurrentThread(&correctThread);
         784               0 :   return correctThread;
         785                 : }
         786                 :
         787                 : // vim: ts=2 sw=2

Generated by: LCOV version 1.7