LCOV - app.info - netwerk/protocol/http/HttpChannelChild.cpp

LCOV - code coverage report
| Current view: | directory - netwerk/protocol/http - HttpChannelChild.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 566 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 112 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* vim: set sw=2 ts=8 et tw=80 : */
           3                 :
           4                 : /* ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is mozilla.org code.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  *  The Mozilla Foundation
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2009
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *   Jason Duell <jduell.mcbugs@gmail.com>
          26                 :  *   Daniel Witte <dwitte@mozilla.com>
          27                 :  *   Honza Bambas <honzab@firemni.cz>
          28                 :  *
          29                 :  * Alternatively, the contents of this file may be used under the terms of
          30                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          31                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          32                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          33                 :  * of those above. If you wish to allow use of your version of this file only
          34                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          35                 :  * use your version of this file under the terms of the MPL, indicate your
          36                 :  * decision by deleting the provisions above and replace them with the notice
          37                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          38                 :  * the provisions above, a recipient may use your version of this file under
          39                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          40                 :  *
          41                 :  * ***** END LICENSE BLOCK ***** */
          42                 :
          43                 : #include "nsHttp.h"
          44                 : #include "mozilla/dom/TabChild.h"
          45                 : #include "mozilla/net/NeckoChild.h"
          46                 : #include "mozilla/net/HttpChannelChild.h"
          47                 :
          48                 : #include "nsStringStream.h"
          49                 : #include "nsHttpHandler.h"
          50                 : #include "nsMimeTypes.h"
          51                 : #include "nsNetUtil.h"
          52                 : #include "nsSerializationHelper.h"
          53                 :
          54                 : namespace mozilla {
          55                 : namespace net {
          56                 :
          57                 : //-----------------------------------------------------------------------------
          58                 : // HttpChannelChild
          59                 : //-----------------------------------------------------------------------------
          60                 :
          61               0 : HttpChannelChild::HttpChannelChild()
          62                 :   : HttpAsyncAborter<HttpChannelChild>(this)
          63                 :   , mIsFromCache(false)
          64                 :   , mCacheEntryAvailable(false)
          65                 :   , mCacheExpirationTime(nsICache::NO_EXPIRATION_TIME)
          66                 :   , mSendResumeAt(false)
          67                 :   , mIPCOpen(false)
          68                 :   , mKeptAlive(false)
          69               0 :   , mEventQ(static_cast<nsIHttpChannel*>(this))
          70                 : {
          71               0 :   LOG(("Creating HttpChannelChild @%x\n", this));
          72               0 : }
          73                 :
          74               0 : HttpChannelChild::~HttpChannelChild()
          75                 : {
          76               0 :   LOG(("Destroying HttpChannelChild @%x\n", this));
          77               0 : }
          78                 :
          79                 : //-----------------------------------------------------------------------------
          80                 : // HttpChannelChild::nsISupports
          81                 : //-----------------------------------------------------------------------------
          82                 :
          83                 : // Override nsHashPropertyBag's AddRef: we don't need thread-safe refcnt
          84               0 : NS_IMPL_ADDREF(HttpChannelChild)
          85                 :
          86               0 : NS_IMETHODIMP_(nsrefcnt) HttpChannelChild::Release()
          87                 : {
          88               0 :   NS_PRECONDITION(0 != mRefCnt, "dup release");
          89               0 :   NS_ASSERT_OWNINGTHREAD(HttpChannelChild);
          90               0 :   --mRefCnt;
          91               0 :   NS_LOG_RELEASE(this, mRefCnt, "HttpChannelChild");
          92                 :
          93                 :   // Normally we Send_delete in OnStopRequest, but when we need to retain the
          94                 :   // remote channel for security info IPDL itself holds 1 reference, so we
          95                 :   // Send_delete when refCnt==1.  But if !mIPCOpen, then there's nobody to send
          96                 :   // to, so we fall through.
          97               0 :   if (mKeptAlive && mRefCnt == 1 && mIPCOpen) {
          98               0 :     mKeptAlive = false;
          99                 :     // Send_delete calls NeckoChild::DeallocPHttpChannel, which will release
         100                 :     // again to refcount==0
         101               0 :     PHttpChannelChild::Send__delete__(this);
         102               0 :     return 0;
         103                 :   }
         104                 :
         105               0 :   if (mRefCnt == 0) {
         106               0 :     mRefCnt = 1; /* stabilize */
         107               0 :     delete this;
         108               0 :     return 0;
         109                 :   }
         110               0 :   return mRefCnt;
         111                 : }
         112                 :
         113               0 : NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
         114               0 :   NS_INTERFACE_MAP_ENTRY(nsIRequest)
         115               0 :   NS_INTERFACE_MAP_ENTRY(nsIChannel)
         116               0 :   NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)
         117               0 :   NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
         118               0 :   NS_INTERFACE_MAP_ENTRY(nsICacheInfoChannel)
         119               0 :   NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)
         120               0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
         121               0 :   NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel)
         122               0 :   NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
         123               0 :   NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
         124               0 :   NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
         125               0 :   NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
         126               0 :   NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
         127               0 :   NS_INTERFACE_MAP_ENTRY(nsIHttpChannelChild)
         128               0 :   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAssociatedContentSecurity, GetAssociatedContentSecurity())
         129               0 : NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
         130                 :
         131                 : //-----------------------------------------------------------------------------
         132                 : // HttpChannelChild::PHttpChannelChild
         133                 : //-----------------------------------------------------------------------------
         134                 :
         135                 : void
         136               0 : HttpChannelChild::AddIPDLReference()
         137                 : {
         138               0 :   NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
         139               0 :   mIPCOpen = true;
         140               0 :   AddRef();
         141               0 : }
         142                 :
         143                 : void
         144               0 : HttpChannelChild::ReleaseIPDLReference()
         145                 : {
         146               0 :   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
         147               0 :   mIPCOpen = false;
         148               0 :   Release();
         149               0 : }
         150                 :
         151                 : class AssociateApplicationCacheEvent : public ChannelEvent
         152               0 : {
         153                 :   public:
         154               0 :     AssociateApplicationCacheEvent(HttpChannelChild* child,
         155                 :                                    const nsCString &groupID,
         156                 :                                    const nsCString &clientID)
         157                 :     : mChild(child)
         158                 :     , groupID(groupID)
         159               0 :     , clientID(clientID) {}
         160                 :
         161               0 :     void Run() { mChild->AssociateApplicationCache(groupID, clientID); }
         162                 :   private:
         163                 :     HttpChannelChild* mChild;
         164                 :     nsCString groupID;
         165                 :     nsCString clientID;
         166                 : };
         167                 :
         168                 : bool
         169               0 : HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
         170                 :                                                 const nsCString &clientID)
         171                 : {
         172               0 :   if (mEventQ.ShouldEnqueue()) {
         173               0 :     mEventQ.Enqueue(new AssociateApplicationCacheEvent(this, groupID, clientID));
         174                 :   } else {
         175               0 :     AssociateApplicationCache(groupID, clientID);
         176                 :   }
         177               0 :   return true;
         178                 : }
         179                 :
         180                 : void
         181               0 : HttpChannelChild::AssociateApplicationCache(const nsCString &groupID,
         182                 :                                             const nsCString &clientID)
         183                 : {
         184                 :   nsresult rv;
         185               0 :   mApplicationCache = do_CreateInstance(NS_APPLICATIONCACHE_CONTRACTID, &rv);
         186               0 :   if (NS_FAILED(rv))
         187               0 :     return;
         188                 :
         189               0 :   mLoadedFromApplicationCache = true;
         190               0 :   mApplicationCache->InitAsHandle(groupID, clientID);
         191                 : }
         192                 :
         193                 : class StartRequestEvent : public ChannelEvent
         194               0 : {
         195                 :  public:
         196               0 :   StartRequestEvent(HttpChannelChild* child,
         197                 :                     const nsHttpResponseHead& responseHead,
         198                 :                     const bool& useResponseHead,
         199                 :                     const nsHttpHeaderArray& requestHeaders,
         200                 :                     const bool& isFromCache,
         201                 :                     const bool& cacheEntryAvailable,
         202                 :                     const PRUint32& cacheExpirationTime,
         203                 :                     const nsCString& cachedCharset,
         204                 :                     const nsCString& securityInfoSerialization,
         205                 :                     const PRNetAddr& selfAddr,
         206                 :                     const PRNetAddr& peerAddr)
         207                 :   : mChild(child)
         208                 :   , mResponseHead(responseHead)
         209                 :   , mRequestHeaders(requestHeaders)
         210                 :   , mUseResponseHead(useResponseHead)
         211                 :   , mIsFromCache(isFromCache)
         212                 :   , mCacheEntryAvailable(cacheEntryAvailable)
         213                 :   , mCacheExpirationTime(cacheExpirationTime)
         214                 :   , mCachedCharset(cachedCharset)
         215                 :   , mSecurityInfoSerialization(securityInfoSerialization)
         216                 :   , mSelfAddr(selfAddr)
         217               0 :   , mPeerAddr(peerAddr)
         218               0 :   {}
         219                 :
         220               0 :   void Run()
         221                 :   {
         222                 :     mChild->OnStartRequest(mResponseHead, mUseResponseHead, mRequestHeaders,
         223                 :                            mIsFromCache, mCacheEntryAvailable,
         224                 :                            mCacheExpirationTime, mCachedCharset,
         225               0 :                            mSecurityInfoSerialization, mSelfAddr, mPeerAddr);
         226               0 :   }
         227                 :  private:
         228                 :   HttpChannelChild* mChild;
         229                 :   nsHttpResponseHead mResponseHead;
         230                 :   nsHttpHeaderArray mRequestHeaders;
         231                 :   bool mUseResponseHead;
         232                 :   bool mIsFromCache;
         233                 :   bool mCacheEntryAvailable;
         234                 :   PRUint32 mCacheExpirationTime;
         235                 :   nsCString mCachedCharset;
         236                 :   nsCString mSecurityInfoSerialization;
         237                 :   PRNetAddr mSelfAddr;
         238                 :   PRNetAddr mPeerAddr;
         239                 : };
         240                 :
         241                 : bool
         242               0 : HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
         243                 :                                      const bool& useResponseHead,
         244                 :                                      const nsHttpHeaderArray& requestHeaders,
         245                 :                                      const bool& isFromCache,
         246                 :                                      const bool& cacheEntryAvailable,
         247                 :                                      const PRUint32& cacheExpirationTime,
         248                 :                                      const nsCString& cachedCharset,
         249                 :                                      const nsCString& securityInfoSerialization,
         250                 :                                      const PRNetAddr& selfAddr,
         251                 :                                      const PRNetAddr& peerAddr)
         252                 : {
         253               0 :   if (mEventQ.ShouldEnqueue()) {
         254                 :     mEventQ.Enqueue(new StartRequestEvent(this, responseHead, useResponseHead,
         255                 :                                           requestHeaders, isFromCache,
         256                 :                                           cacheEntryAvailable,
         257                 :                                           cacheExpirationTime, cachedCharset,
         258                 :                                           securityInfoSerialization, selfAddr,
         259               0 :                                           peerAddr));
         260                 :   } else {
         261                 :     OnStartRequest(responseHead, useResponseHead, requestHeaders, isFromCache,
         262                 :                    cacheEntryAvailable, cacheExpirationTime, cachedCharset,
         263               0 :                    securityInfoSerialization, selfAddr, peerAddr);
         264                 :   }
         265               0 :   return true;
         266                 : }
         267                 :
         268                 : void
         269               0 : HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
         270                 :                                  const bool& useResponseHead,
         271                 :                                  const nsHttpHeaderArray& requestHeaders,
         272                 :                                  const bool& isFromCache,
         273                 :                                  const bool& cacheEntryAvailable,
         274                 :                                  const PRUint32& cacheExpirationTime,
         275                 :                                  const nsCString& cachedCharset,
         276                 :                                  const nsCString& securityInfoSerialization,
         277                 :                                  const PRNetAddr& selfAddr,
         278                 :                                  const PRNetAddr& peerAddr)
         279                 : {
         280               0 :   LOG(("HttpChannelChild::RecvOnStartRequest [this=%x]\n", this));
         281                 :
         282               0 :   if (useResponseHead && !mCanceled)
         283               0 :     mResponseHead = new nsHttpResponseHead(responseHead);
         284                 :
         285               0 :   if (!securityInfoSerialization.IsEmpty()) {
         286                 :     NS_DeserializeObject(securityInfoSerialization,
         287               0 :                          getter_AddRefs(mSecurityInfo));
         288                 :   }
         289                 :
         290               0 :   mIsFromCache = isFromCache;
         291               0 :   mCacheEntryAvailable = cacheEntryAvailable;
         292               0 :   mCacheExpirationTime = cacheExpirationTime;
         293               0 :   mCachedCharset = cachedCharset;
         294                 :
         295               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
         296                 :
         297                 :   // replace our request headers with what actually got sent in the parent
         298               0 :   mRequestHead.Headers() = requestHeaders;
         299                 :
         300                 :   // notify "http-on-examine-response" observers
         301               0 :   gHttpHandler->OnExamineResponse(this);
         302               0 :   mTracingEnabled = false;
         303                 :
         304               0 :   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
         305               0 :   if (NS_FAILED(rv)) {
         306               0 :     Cancel(rv);
         307                 :     return;
         308                 :   }
         309                 :
         310               0 :   if (mResponseHead)
         311               0 :     SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));
         312                 :
         313               0 :   rv = ApplyContentConversions();
         314               0 :   if (NS_FAILED(rv))
         315               0 :     Cancel(rv);
         316                 :
         317               0 :   mSelfAddr = selfAddr;
         318               0 :   mPeerAddr = peerAddr;
         319                 : }
         320                 :
         321                 : class TransportAndDataEvent : public ChannelEvent
         322               0 : {
         323                 :  public:
         324               0 :   TransportAndDataEvent(HttpChannelChild* child,
         325                 :                         const nsresult& status,
         326                 :                         const PRUint64& progress,
         327                 :                         const PRUint64& progressMax,
         328                 :                         const nsCString& data,
         329                 :                         const PRUint32& offset,
         330                 :                         const PRUint32& count)
         331                 :   : mChild(child)
         332                 :   , mStatus(status)
         333                 :   , mProgress(progress)
         334                 :   , mProgressMax(progressMax)
         335                 :   , mData(data)
         336                 :   , mOffset(offset)
         337               0 :   , mCount(count) {}
         338                 :
         339               0 :   void Run() { mChild->OnTransportAndData(mStatus, mProgress, mProgressMax,
         340               0 :                                           mData, mOffset, mCount); }
         341                 :  private:
         342                 :   HttpChannelChild* mChild;
         343                 :   nsresult mStatus;
         344                 :   PRUint64 mProgress;
         345                 :   PRUint64 mProgressMax;
         346                 :   nsCString mData;
         347                 :   PRUint32 mOffset;
         348                 :   PRUint32 mCount;
         349                 : };
         350                 :
         351                 : bool
         352               0 : HttpChannelChild::RecvOnTransportAndData(const nsresult& status,
         353                 :                                          const PRUint64& progress,
         354                 :                                          const PRUint64& progressMax,
         355                 :                                          const nsCString& data,
         356                 :                                          const PRUint32& offset,
         357                 :                                          const PRUint32& count)
         358                 : {
         359               0 :   if (mEventQ.ShouldEnqueue()) {
         360                 :     mEventQ.Enqueue(new TransportAndDataEvent(this, status, progress,
         361                 :                                               progressMax, data, offset,
         362               0 :                                               count));
         363                 :   } else {
         364               0 :     OnTransportAndData(status, progress, progressMax, data, offset, count);
         365                 :   }
         366               0 :   return true;
         367                 : }
         368                 :
         369                 : void
         370               0 : HttpChannelChild::OnTransportAndData(const nsresult& status,
         371                 :                                      const PRUint64 progress,
         372                 :                                      const PRUint64& progressMax,
         373                 :                                      const nsCString& data,
         374                 :                                      const PRUint32& offset,
         375                 :                                      const PRUint32& count)
         376                 : {
         377               0 :   LOG(("HttpChannelChild::OnTransportAndData [this=%x]\n", this));
         378                 :
         379               0 :   if (mCanceled)
         380               0 :     return;
         381                 :
         382                 :   // cache the progress sink so we don't have to query for it each time.
         383               0 :   if (!mProgressSink)
         384               0 :     GetCallback(mProgressSink);
         385                 :
         386                 :   // Hold queue lock throughout all three calls, else we might process a later
         387                 :   // necko msg in between them.
         388               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
         389                 :
         390                 :   // block status/progress after Cancel or OnStopRequest has been called,
         391                 :   // or if channel has LOAD_BACKGROUND set.
         392                 :   // - JDUELL: may not need mStatus/mIsPending checks, given this is always called
         393                 :   //   during OnDataAvailable, and we've already checked mCanceled.  Code
         394                 :   //   dupe'd from nsHttpChannel
         395               0 :   if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
         396               0 :       !(mLoadFlags & LOAD_BACKGROUND))
         397                 :   {
         398                 :     // OnStatus
         399                 :     //
         400               0 :     NS_ASSERTION(status == nsISocketTransport::STATUS_RECEIVING_FROM ||
         401                 :                  status == nsITransport::STATUS_READING,
         402                 :                  "unexpected status code");
         403                 :
         404               0 :     nsCAutoString host;
         405               0 :     mURI->GetHost(host);
         406               0 :     mProgressSink->OnStatus(this, nsnull, status,
         407               0 :                             NS_ConvertUTF8toUTF16(host).get());
         408                 :     // OnProgress
         409                 :     //
         410               0 :     if (progress > 0) {
         411               0 :       NS_ASSERTION(progress <= progressMax, "unexpected progress values");
         412               0 :       mProgressSink->OnProgress(this, nsnull, progress, progressMax);
         413                 :     }
         414                 :   }
         415                 :
         416                 :   // OnDataAvailable
         417                 :   //
         418                 :   // NOTE: the OnDataAvailable contract requires the client to read all the data
         419                 :   // in the inputstream.  This code relies on that ('data' will go away after
         420                 :   // this function).  Apparently the previous, non-e10s behavior was to actually
         421                 :   // support only reading part of the data, allowing later calls to read the
         422                 :   // rest.
         423               0 :   nsCOMPtr<nsIInputStream> stringStream;
         424               0 :   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
         425               0 :                                       count, NS_ASSIGNMENT_DEPEND);
         426               0 :   if (NS_FAILED(rv)) {
         427               0 :     Cancel(rv);
         428                 :     return;
         429                 :   }
         430                 :
         431               0 :   rv = mListener->OnDataAvailable(this, mListenerContext,
         432               0 :                                   stringStream, offset, count);
         433               0 :   stringStream->Close();
         434               0 :   if (NS_FAILED(rv)) {
         435               0 :     Cancel(rv);
         436                 :   }
         437                 : }
         438                 :
         439                 : class StopRequestEvent : public ChannelEvent
         440               0 : {
         441                 :  public:
         442               0 :   StopRequestEvent(HttpChannelChild* child,
         443                 :                    const nsresult& statusCode)
         444                 :   : mChild(child)
         445               0 :   , mStatusCode(statusCode) {}
         446                 :
         447               0 :   void Run() { mChild->OnStopRequest(mStatusCode); }
         448                 :  private:
         449                 :   HttpChannelChild* mChild;
         450                 :   nsresult mStatusCode;
         451                 : };
         452                 :
         453                 : bool
         454               0 : HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
         455                 : {
         456               0 :   if (mEventQ.ShouldEnqueue()) {
         457               0 :     mEventQ.Enqueue(new StopRequestEvent(this, statusCode));
         458                 :   } else {
         459               0 :     OnStopRequest(statusCode);
         460                 :   }
         461               0 :   return true;
         462                 : }
         463                 :
         464                 : void
         465               0 : HttpChannelChild::OnStopRequest(const nsresult& statusCode)
         466                 : {
         467               0 :   LOG(("HttpChannelChild::OnStopRequest [this=%x status=%u]\n",
         468                 :            this, statusCode));
         469                 :
         470               0 :   mIsPending = false;
         471                 :
         472               0 :   if (!mCanceled && NS_SUCCEEDED(mStatus))
         473               0 :     mStatus = statusCode;
         474                 :
         475                 :   { // We must flush the queue before we Send__delete__
         476                 :     // (although we really shouldn't receive any msgs after OnStop),
         477                 :     // so make sure this goes out of scope before then.
         478               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
         479                 :
         480               0 :     mListener->OnStopRequest(this, mListenerContext, mStatus);
         481                 :
         482               0 :     mListener = 0;
         483               0 :     mListenerContext = 0;
         484               0 :     mCacheEntryAvailable = false;
         485               0 :     if (mLoadGroup)
         486               0 :       mLoadGroup->RemoveRequest(this, nsnull, mStatus);
         487                 :   }
         488                 :
         489               0 :   if (mLoadFlags & LOAD_DOCUMENT_URI) {
         490                 :     // Keep IPDL channel open, but only for updating security info.
         491               0 :     mKeptAlive = true;
         492               0 :     SendDocumentChannelCleanup();
         493                 :   } else {
         494                 :     // This calls NeckoChild::DeallocPHttpChannel(), which deletes |this| if IPDL
         495                 :     // holds the last reference.  Don't rely on |this| existing after here.
         496               0 :     PHttpChannelChild::Send__delete__(this);
         497                 :   }
         498               0 : }
         499                 :
         500                 : class ProgressEvent : public ChannelEvent
         501               0 : {
         502                 :  public:
         503               0 :   ProgressEvent(HttpChannelChild* child,
         504                 :                 const PRUint64& progress,
         505                 :                 const PRUint64& progressMax)
         506                 :   : mChild(child)
         507                 :   , mProgress(progress)
         508               0 :   , mProgressMax(progressMax) {}
         509                 :
         510               0 :   void Run() { mChild->OnProgress(mProgress, mProgressMax); }
         511                 :  private:
         512                 :   HttpChannelChild* mChild;
         513                 :   PRUint64 mProgress, mProgressMax;
         514                 : };
         515                 :
         516                 : bool
         517               0 : HttpChannelChild::RecvOnProgress(const PRUint64& progress,
         518                 :                                  const PRUint64& progressMax)
         519                 : {
         520               0 :   if (mEventQ.ShouldEnqueue())  {
         521               0 :     mEventQ.Enqueue(new ProgressEvent(this, progress, progressMax));
         522                 :   } else {
         523               0 :     OnProgress(progress, progressMax);
         524                 :   }
         525               0 :   return true;
         526                 : }
         527                 :
         528                 : void
         529               0 : HttpChannelChild::OnProgress(const PRUint64& progress,
         530                 :                              const PRUint64& progressMax)
         531                 : {
         532               0 :   LOG(("HttpChannelChild::OnProgress [this=%p progress=%llu/%llu]\n",
         533                 :        this, progress, progressMax));
         534                 :
         535               0 :   if (mCanceled)
         536               0 :     return;
         537                 :
         538                 :   // cache the progress sink so we don't have to query for it each time.
         539               0 :   if (!mProgressSink)
         540               0 :     GetCallback(mProgressSink);
         541                 :
         542               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
         543                 :
         544                 :   // block socket status event after Cancel or OnStopRequest has been called,
         545                 :   // or if channel has LOAD_BACKGROUND set
         546               0 :   if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
         547               0 :       !(mLoadFlags & LOAD_BACKGROUND))
         548                 :   {
         549               0 :     if (progress > 0) {
         550               0 :       NS_ASSERTION(progress <= progressMax, "unexpected progress values");
         551               0 :       mProgressSink->OnProgress(this, nsnull, progress, progressMax);
         552                 :     }
         553                 :   }
         554                 : }
         555                 :
         556                 : class StatusEvent : public ChannelEvent
         557               0 : {
         558                 :  public:
         559               0 :   StatusEvent(HttpChannelChild* child,
         560                 :               const nsresult& status)
         561                 :   : mChild(child)
         562               0 :   , mStatus(status) {}
         563                 :
         564               0 :   void Run() { mChild->OnStatus(mStatus); }
         565                 :  private:
         566                 :   HttpChannelChild* mChild;
         567                 :   nsresult mStatus;
         568                 : };
         569                 :
         570                 : bool
         571               0 : HttpChannelChild::RecvOnStatus(const nsresult& status)
         572                 : {
         573               0 :   if (mEventQ.ShouldEnqueue()) {
         574               0 :     mEventQ.Enqueue(new StatusEvent(this, status));
         575                 :   } else {
         576               0 :     OnStatus(status);
         577                 :   }
         578               0 :   return true;
         579                 : }
         580                 :
         581                 : void
         582               0 : HttpChannelChild::OnStatus(const nsresult& status)
         583                 : {
         584               0 :   LOG(("HttpChannelChild::OnStatus [this=%p status=%x]\n", this, status));
         585                 :
         586               0 :   if (mCanceled)
         587               0 :     return;
         588                 :
         589                 :   // cache the progress sink so we don't have to query for it each time.
         590               0 :   if (!mProgressSink)
         591               0 :     GetCallback(mProgressSink);
         592                 :
         593               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
         594                 :
         595                 :   // block socket status event after Cancel or OnStopRequest has been called,
         596                 :   // or if channel has LOAD_BACKGROUND set
         597               0 :   if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
         598               0 :       !(mLoadFlags & LOAD_BACKGROUND))
         599                 :   {
         600               0 :     nsCAutoString host;
         601               0 :     mURI->GetHost(host);
         602               0 :     mProgressSink->OnStatus(this, nsnull, status,
         603               0 :                             NS_ConvertUTF8toUTF16(host).get());
         604                 :   }
         605                 : }
         606                 :
         607                 : class FailedAsyncOpenEvent : public ChannelEvent
         608               0 : {
         609                 :  public:
         610               0 :   FailedAsyncOpenEvent(HttpChannelChild* child, const nsresult& status)
         611                 :   : mChild(child)
         612               0 :   , mStatus(status) {}
         613                 :
         614               0 :   void Run() { mChild->FailedAsyncOpen(mStatus); }
         615                 :  private:
         616                 :   HttpChannelChild* mChild;
         617                 :   nsresult mStatus;
         618                 : };
         619                 :
         620                 : bool
         621               0 : HttpChannelChild::RecvFailedAsyncOpen(const nsresult& status)
         622                 : {
         623               0 :   if (mEventQ.ShouldEnqueue()) {
         624               0 :     mEventQ.Enqueue(new FailedAsyncOpenEvent(this, status));
         625                 :   } else {
         626               0 :     FailedAsyncOpen(status);
         627                 :   }
         628               0 :   return true;
         629                 : }
         630                 :
         631                 : // We need to have an implementation of this function just so that we can keep
         632                 : // all references to mCallOnResume of type HttpChannelChild:  it's not OK in C++
         633                 : // to set a member function ptr to a base class function.
         634                 : void
         635               0 : HttpChannelChild::HandleAsyncAbort()
         636                 : {
         637               0 :   HttpAsyncAborter<HttpChannelChild>::HandleAsyncAbort();
         638               0 : }
         639                 :
         640                 : void
         641               0 : HttpChannelChild::FailedAsyncOpen(const nsresult& status)
         642                 : {
         643               0 :   LOG(("HttpChannelChild::FailedAsyncOpen [this=%p status=%x]\n", this, status));
         644                 :
         645               0 :   mStatus = status;
         646               0 :   mIsPending = false;
         647                 :   // We're already being called from IPDL, therefore already "async"
         648               0 :   HandleAsyncAbort();
         649               0 : }
         650                 :
         651                 : void
         652               0 : HttpChannelChild::DoNotifyListenerCleanup()
         653                 : {
         654               0 :   if (mIPCOpen)
         655               0 :     PHttpChannelChild::Send__delete__(this);
         656               0 : }
         657                 :
         658                 : class DeleteSelfEvent : public ChannelEvent
         659               0 : {
         660                 :  public:
         661               0 :   DeleteSelfEvent(HttpChannelChild* child) : mChild(child) {}
         662               0 :   void Run() { mChild->DeleteSelf(); }
         663                 :  private:
         664                 :   HttpChannelChild* mChild;
         665                 : };
         666                 :
         667                 : bool
         668               0 : HttpChannelChild::RecvDeleteSelf()
         669                 : {
         670               0 :   if (mEventQ.ShouldEnqueue()) {
         671               0 :     mEventQ.Enqueue(new DeleteSelfEvent(this));
         672                 :   } else {
         673               0 :     DeleteSelf();
         674                 :   }
         675               0 :   return true;
         676                 : }
         677                 :
         678                 : void
         679               0 : HttpChannelChild::DeleteSelf()
         680                 : {
         681               0 :   Send__delete__(this);
         682               0 : }
         683                 :
         684                 : class Redirect1Event : public ChannelEvent
         685               0 : {
         686                 :  public:
         687               0 :   Redirect1Event(HttpChannelChild* child,
         688                 :                  const PRUint32& newChannelId,
         689                 :                  const IPC::URI& newURI,
         690                 :                  const PRUint32& redirectFlags,
         691                 :                  const nsHttpResponseHead& responseHead)
         692                 :   : mChild(child)
         693                 :   , mNewChannelId(newChannelId)
         694                 :   , mNewURI(newURI)
         695                 :   , mRedirectFlags(redirectFlags)
         696               0 :   , mResponseHead(responseHead) {}
         697                 :
         698               0 :   void Run()
         699                 :   {
         700                 :     mChild->Redirect1Begin(mNewChannelId, mNewURI, mRedirectFlags,
         701               0 :                            mResponseHead);
         702               0 :   }
         703                 :  private:
         704                 :   HttpChannelChild*   mChild;
         705                 :   PRUint32            mNewChannelId;
         706                 :   IPC::URI            mNewURI;
         707                 :   PRUint32            mRedirectFlags;
         708                 :   nsHttpResponseHead  mResponseHead;
         709                 : };
         710                 :
         711                 : bool
         712               0 : HttpChannelChild::RecvRedirect1Begin(const PRUint32& newChannelId,
         713                 :                                      const URI& newUri,
         714                 :                                      const PRUint32& redirectFlags,
         715                 :                                      const nsHttpResponseHead& responseHead)
         716                 : {
         717               0 :   if (mEventQ.ShouldEnqueue()) {
         718                 :     mEventQ.Enqueue(new Redirect1Event(this, newChannelId, newUri,
         719               0 :                                        redirectFlags, responseHead));
         720                 :   } else {
         721               0 :     Redirect1Begin(newChannelId, newUri, redirectFlags, responseHead);
         722                 :   }
         723               0 :   return true;
         724                 : }
         725                 :
         726                 : void
         727               0 : HttpChannelChild::Redirect1Begin(const PRUint32& newChannelId,
         728                 :                                  const IPC::URI& newURI,
         729                 :                                  const PRUint32& redirectFlags,
         730                 :                                  const nsHttpResponseHead& responseHead)
         731                 : {
         732                 :   nsresult rv;
         733                 :
         734               0 :   nsCOMPtr<nsIIOService> ioService;
         735               0 :   rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
         736               0 :   if (NS_FAILED(rv)) {
         737                 :     // Veto redirect.  nsHttpChannel decides to cancel or continue.
         738               0 :     OnRedirectVerifyCallback(rv);
         739                 :     return;
         740                 :   }
         741                 :
         742               0 :   nsCOMPtr<nsIURI> uri(newURI);
         743                 :
         744               0 :   nsCOMPtr<nsIChannel> newChannel;
         745               0 :   rv = ioService->NewChannelFromURI(uri, getter_AddRefs(newChannel));
         746               0 :   if (NS_FAILED(rv)) {
         747                 :     // Veto redirect.  nsHttpChannel decides to cancel or continue.
         748               0 :     OnRedirectVerifyCallback(rv);
         749                 :     return;
         750                 :   }
         751                 :
         752                 :   // We won't get OnStartRequest, set cookies here.
         753               0 :   mResponseHead = new nsHttpResponseHead(responseHead);
         754               0 :   SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));
         755                 :
         756               0 :   bool rewriteToGET = ShouldRewriteRedirectToGET(mResponseHead->Status(),
         757               0 :                                                  mRequestHead.Method());
         758                 :
         759               0 :   rv = SetupReplacementChannel(uri, newChannel, !rewriteToGET, false);
         760               0 :   if (NS_FAILED(rv)) {
         761                 :     // Veto redirect.  nsHttpChannel decides to cancel or continue.
         762               0 :     OnRedirectVerifyCallback(rv);
         763                 :     return;
         764                 :   }
         765                 :
         766               0 :   mRedirectChannelChild = do_QueryInterface(newChannel);
         767               0 :   if (mRedirectChannelChild) {
         768               0 :     mRedirectChannelChild->ConnectParent(newChannelId);
         769                 :   } else {
         770               0 :     NS_ERROR("Redirecting to a protocol that doesn't support universal protocol redirect");
         771                 :   }
         772                 :
         773                 :   rv = gHttpHandler->AsyncOnChannelRedirect(this,
         774                 :                                             newChannel,
         775               0 :                                             redirectFlags);
         776               0 :   if (NS_FAILED(rv))
         777               0 :     OnRedirectVerifyCallback(rv);
         778                 : }
         779                 :
         780                 : class Redirect3Event : public ChannelEvent
         781               0 : {
         782                 :  public:
         783               0 :   Redirect3Event(HttpChannelChild* child) : mChild(child) {}
         784               0 :   void Run() { mChild->Redirect3Complete(); }
         785                 :  private:
         786                 :   HttpChannelChild* mChild;
         787                 : };
         788                 :
         789                 : bool
         790               0 : HttpChannelChild::RecvRedirect3Complete()
         791                 : {
         792               0 :   if (mEventQ.ShouldEnqueue()) {
         793               0 :     mEventQ.Enqueue(new Redirect3Event(this));
         794                 :   } else {
         795               0 :     Redirect3Complete();
         796                 :   }
         797               0 :   return true;
         798                 : }
         799                 :
         800                 : void
         801               0 : HttpChannelChild::Redirect3Complete()
         802                 : {
         803               0 :   nsresult rv = NS_OK;
         804                 :
         805                 :   // Chrome channel has been AsyncOpen'd.  Reflect this in child.
         806               0 :   if (mRedirectChannelChild)
         807               0 :     rv = mRedirectChannelChild->CompleteRedirectSetup(mListener,
         808               0 :                                                       mListenerContext);
         809                 :
         810                 :   // Redirecting to new channel: shut this down and init new channel
         811               0 :   if (mLoadGroup)
         812               0 :     mLoadGroup->RemoveRequest(this, nsnull, NS_BINDING_ABORTED);
         813                 :
         814               0 :   if (NS_FAILED(rv))
         815               0 :     NS_WARNING("CompleteRedirectSetup failed, HttpChannelChild already open?");
         816                 :
         817                 :   // Release ref to new channel.
         818               0 :   mRedirectChannelChild = nsnull;
         819               0 : }
         820                 :
         821                 : //-----------------------------------------------------------------------------
         822                 : // HttpChannelChild::nsIChildChannel
         823                 : //-----------------------------------------------------------------------------
         824                 :
         825                 : NS_IMETHODIMP
         826               0 : HttpChannelChild::ConnectParent(PRUint32 id)
         827                 : {
         828               0 :   mozilla::dom::TabChild* tabChild = nsnull;
         829               0 :   nsCOMPtr<nsITabChild> iTabChild;
         830               0 :   GetCallback(iTabChild);
         831               0 :   if (iTabChild) {
         832               0 :     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
         833                 :   }
         834                 :
         835                 :   // The socket transport in the chrome process now holds a logical ref to us
         836                 :   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
         837               0 :   AddIPDLReference();
         838                 :
         839               0 :   if (!gNeckoChild->SendPHttpChannelConstructor(this, tabChild))
         840               0 :     return NS_ERROR_FAILURE;
         841                 :
         842               0 :   if (!SendConnectChannel(id))
         843               0 :     return NS_ERROR_FAILURE;
         844                 :
         845               0 :   return NS_OK;
         846                 : }
         847                 :
         848                 : NS_IMETHODIMP
         849               0 : HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
         850                 :                                         nsISupports *aContext)
         851                 : {
         852               0 :   LOG(("HttpChannelChild::FinishRedirectSetup [this=%x]\n", this));
         853                 :
         854               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
         855               0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
         856                 :
         857                 :   /*
         858                 :    * No need to check for cancel: we don't get here if nsHttpChannel canceled
         859                 :    * before AsyncOpen(); if it's canceled after that, OnStart/Stop will just
         860                 :    * get called with error code as usual.  So just setup mListener and make the
         861                 :    * channel reflect AsyncOpen'ed state.
         862                 :    */
         863                 :
         864               0 :   mIsPending = true;
         865               0 :   mWasOpened = true;
         866               0 :   mListener = listener;
         867               0 :   mListenerContext = aContext;
         868                 :
         869                 :   // add ourselves to the load group.
         870               0 :   if (mLoadGroup)
         871               0 :     mLoadGroup->AddRequest(this, nsnull);
         872                 :
         873                 :   // We already have an open IPDL connection to the parent. If on-modify-request
         874                 :   // listeners or load group observers canceled us, let the parent handle it
         875                 :   // and send it back to us naturally.
         876               0 :   return NS_OK;
         877                 : }
         878                 :
         879                 : //-----------------------------------------------------------------------------
         880                 : // HttpChannelChild::nsIAsyncVerifyRedirectCallback
         881                 : //-----------------------------------------------------------------------------
         882                 :
         883                 : NS_IMETHODIMP
         884               0 : HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
         885                 : {
         886                 :   nsCOMPtr<nsIHttpChannel> newHttpChannel =
         887               0 :       do_QueryInterface(mRedirectChannelChild);
         888                 :
         889               0 :   if (newHttpChannel) {
         890                 :     // Must not be called until after redirect observers called.
         891               0 :     newHttpChannel->SetOriginalURI(mOriginalURI);
         892                 :   }
         893                 :
         894               0 :   RequestHeaderTuples emptyHeaders;
         895               0 :   RequestHeaderTuples* headerTuples = &emptyHeaders;
         896                 :
         897                 :   nsCOMPtr<nsIHttpChannelChild> newHttpChannelChild =
         898               0 :       do_QueryInterface(mRedirectChannelChild);
         899               0 :   if (newHttpChannelChild && NS_SUCCEEDED(result)) {
         900               0 :     newHttpChannelChild->AddCookiesToRequest();
         901               0 :     newHttpChannelChild->GetClientSetRequestHeaders(&headerTuples);
         902                 :   }
         903                 :
         904                 :   // After we verify redirect, nsHttpChannel may hit the network: must give
         905                 :   // "http-on-modify-request" observers the chance to cancel before that.
         906               0 :   if (NS_SUCCEEDED(result))
         907               0 :     gHttpHandler->OnModifyRequest(newHttpChannel);
         908                 :
         909               0 :   if (mIPCOpen)
         910               0 :     SendRedirect2Verify(result, *headerTuples);
         911                 :
         912               0 :   return NS_OK;
         913                 : }
         914                 :
         915                 : //-----------------------------------------------------------------------------
         916                 : // HttpChannelChild::nsIRequest
         917                 : //-----------------------------------------------------------------------------
         918                 :
         919                 : NS_IMETHODIMP
         920               0 : HttpChannelChild::Cancel(nsresult status)
         921                 : {
         922               0 :   if (!mCanceled) {
         923                 :     // If this cancel occurs before nsHttpChannel has been set up, AsyncOpen
         924                 :     // is responsible for cleaning up.
         925               0 :     mCanceled = true;
         926               0 :     mStatus = status;
         927               0 :     if (RemoteChannelExists())
         928               0 :       SendCancel(status);
         929                 :   }
         930               0 :   return NS_OK;
         931                 : }
         932                 :
         933                 : NS_IMETHODIMP
         934               0 : HttpChannelChild::Suspend()
         935                 : {
         936               0 :   NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
         937               0 :   if (!mSuspendCount++) {
         938               0 :     SendSuspend();
         939               0 :     mEventQ.Suspend();
         940                 :   }
         941               0 :   return NS_OK;
         942                 : }
         943                 :
         944                 : void
         945               0 : HttpChannelChild::CompleteResume()
         946                 : {
         947               0 :   if (mCallOnResume) {
         948               0 :     (this->*mCallOnResume)();
         949               0 :     mCallOnResume = 0;
         950                 :   }
         951                 :
         952                 :   // Don't resume event queue until now, else queued events could get
         953                 :   // flushed/called before mCallOnResume, which needs to run first.
         954               0 :   mEventQ.Resume();
         955               0 : }
         956                 :
         957                 : NS_IMETHODIMP
         958               0 : HttpChannelChild::Resume()
         959                 : {
         960               0 :   NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
         961               0 :   NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
         962                 :
         963               0 :   nsresult rv = NS_OK;
         964                 :
         965               0 :   if (!--mSuspendCount) {
         966               0 :     SendResume();
         967               0 :     rv = AsyncCall(&HttpChannelChild::CompleteResume);
         968                 :   }
         969               0 :   return rv;
         970                 : }
         971                 :
         972                 : //-----------------------------------------------------------------------------
         973                 : // HttpChannelChild::nsIChannel
         974                 : //-----------------------------------------------------------------------------
         975                 :
         976                 : NS_IMETHODIMP
         977               0 : HttpChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
         978                 : {
         979               0 :   NS_ENSURE_ARG_POINTER(aSecurityInfo);
         980               0 :   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
         981               0 :   return NS_OK;
         982                 : }
         983                 :
         984                 : NS_IMETHODIMP
         985               0 : HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
         986                 : {
         987               0 :   LOG(("HttpChannelChild::AsyncOpen [this=%x uri=%s]\n", this, mSpec.get()));
         988                 :
         989               0 :   if (mCanceled)
         990               0 :     return mStatus;
         991                 :
         992               0 :   NS_ENSURE_TRUE(gNeckoChild != nsnull, NS_ERROR_FAILURE);
         993               0 :   NS_ENSURE_ARG_POINTER(listener);
         994               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
         995               0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
         996                 :
         997                 :   // Port checked in parent, but duplicate here so we can return with error
         998                 :   // immediately
         999                 :   nsresult rv;
        1000               0 :   rv = NS_CheckPortSafety(mURI);
        1001               0 :   if (NS_FAILED(rv))
        1002               0 :     return rv;
        1003                 :
        1004               0 :   const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie);
        1005               0 :   if (cookieHeader) {
        1006               0 :     mUserSetCookieHeader = cookieHeader;
        1007                 :   }
        1008                 :
        1009               0 :   AddCookiesToRequest();
        1010                 :
        1011                 :   //
        1012                 :   // NOTE: From now on we must return NS_OK; all errors must be handled via
        1013                 :   // OnStart/OnStopRequest
        1014                 :   //
        1015                 :
        1016                 :   // notify "http-on-modify-request" observers
        1017               0 :   gHttpHandler->OnModifyRequest(this);
        1018                 :
        1019               0 :   mIsPending = true;
        1020               0 :   mWasOpened = true;
        1021               0 :   mListener = listener;
        1022               0 :   mListenerContext = aContext;
        1023                 :
        1024                 :   // add ourselves to the load group.
        1025               0 :   if (mLoadGroup)
        1026               0 :     mLoadGroup->AddRequest(this, nsnull);
        1027                 :
        1028               0 :   if (mCanceled) {
        1029                 :     // We may have been canceled already, either by on-modify-request
        1030                 :     // listeners or by load group observers; in that case, don't create IPDL
        1031                 :     // connection. See nsHttpChannel::AsyncOpen().
        1032               0 :     AsyncAbort(mStatus);
        1033               0 :     return NS_OK;
        1034                 :   }
        1035                 :
        1036               0 :   nsCString appCacheClientId;
        1037               0 :   if (mInheritApplicationCache) {
        1038                 :     // Pick up an application cache from the notification
        1039                 :     // callbacks if available
        1040               0 :     nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer;
        1041               0 :     GetCallback(appCacheContainer);
        1042                 :
        1043               0 :     if (appCacheContainer) {
        1044               0 :       nsCOMPtr<nsIApplicationCache> appCache;
        1045               0 :       rv = appCacheContainer->GetApplicationCache(getter_AddRefs(appCache));
        1046               0 :       if (NS_SUCCEEDED(rv) && appCache) {
        1047               0 :         appCache->GetClientID(appCacheClientId);
        1048                 :       }
        1049                 :     }
        1050                 :   }
        1051                 :
        1052                 :   //
        1053                 :   // Send request to the chrome process...
        1054                 :   //
        1055                 :
        1056                 :   // FIXME: bug 558623: Combine constructor and SendAsyncOpen into one IPC msg
        1057                 :
        1058               0 :   mozilla::dom::TabChild* tabChild = nsnull;
        1059               0 :   nsCOMPtr<nsITabChild> iTabChild;
        1060               0 :   GetCallback(iTabChild);
        1061               0 :   if (iTabChild) {
        1062               0 :     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
        1063                 :   }
        1064                 :
        1065                 :   // The socket transport in the chrome process now holds a logical ref to us
        1066                 :   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
        1067               0 :   AddIPDLReference();
        1068                 :
        1069               0 :   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
        1070                 :
        1071               0 :   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
        1072               0 :                 IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
        1073               0 :                 mClientSetRequestHeaders, mRequestHead.Method(),
        1074               0 :                 IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
        1075                 :                 mPriority, mRedirectionLimit, mAllowPipelining,
        1076                 :                 mForceAllowThirdPartyCookie, mSendResumeAt,
        1077                 :                 mStartPos, mEntityID, mChooseApplicationCache,
        1078               0 :                 appCacheClientId, mAllowSpdy);
        1079                 :
        1080               0 :   return NS_OK;
        1081                 : }
        1082                 :
        1083                 : //-----------------------------------------------------------------------------
        1084                 : // HttpChannelChild::nsIHttpChannel
        1085                 : //-----------------------------------------------------------------------------
        1086                 :
        1087                 : NS_IMETHODIMP
        1088               0 : HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
        1089                 :                                    const nsACString& aValue,
        1090                 :                                    bool aMerge)
        1091                 : {
        1092               0 :   nsresult rv = HttpBaseChannel::SetRequestHeader(aHeader, aValue, aMerge);
        1093               0 :   if (NS_FAILED(rv))
        1094               0 :     return rv;
        1095                 :
        1096               0 :   RequestHeaderTuple* tuple = mClientSetRequestHeaders.AppendElement();
        1097               0 :   if (!tuple)
        1098               0 :     return NS_ERROR_OUT_OF_MEMORY;
        1099                 :
        1100               0 :   tuple->mHeader = aHeader;
        1101               0 :   tuple->mValue = aValue;
        1102               0 :   tuple->mMerge = aMerge;
        1103               0 :   return NS_OK;
        1104                 : }
        1105                 :
        1106                 : //-----------------------------------------------------------------------------
        1107                 : // HttpChannelChild::nsIHttpChannelInternal
        1108                 : //-----------------------------------------------------------------------------
        1109                 :
        1110                 : NS_IMETHODIMP
        1111               0 : HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
        1112                 : {
        1113               0 :   DROP_DEAD();
        1114                 : }
        1115                 :
        1116                 : // The next four _should_ be implemented, but we need to figure out how
        1117                 : // to transfer the data from the chrome process first.
        1118                 :
        1119                 : NS_IMETHODIMP
        1120               0 : HttpChannelChild::GetRemoteAddress(nsACString & _result)
        1121                 : {
        1122               0 :   return NS_ERROR_NOT_AVAILABLE;
        1123                 : }
        1124                 :
        1125                 : NS_IMETHODIMP
        1126               0 : HttpChannelChild::GetRemotePort(PRInt32 * _result)
        1127                 : {
        1128               0 :   NS_ENSURE_ARG_POINTER(_result);
        1129               0 :   return NS_ERROR_NOT_AVAILABLE;
        1130                 : }
        1131                 :
        1132                 : NS_IMETHODIMP
        1133               0 : HttpChannelChild::GetLocalAddress(nsACString & _result)
        1134                 : {
        1135               0 :   return NS_ERROR_NOT_AVAILABLE;
        1136                 : }
        1137                 :
        1138                 : NS_IMETHODIMP
        1139               0 : HttpChannelChild::GetLocalPort(PRInt32 * _result)
        1140                 : {
        1141               0 :   NS_ENSURE_ARG_POINTER(_result);
        1142               0 :   return NS_ERROR_NOT_AVAILABLE;
        1143                 : }
        1144                 :
        1145                 :
        1146                 : //-----------------------------------------------------------------------------
        1147                 : // HttpChannelChild::nsICacheInfoChannel
        1148                 : //-----------------------------------------------------------------------------
        1149                 :
        1150                 : NS_IMETHODIMP
        1151               0 : HttpChannelChild::GetCacheTokenExpirationTime(PRUint32 *_retval)
        1152                 : {
        1153               0 :   NS_ENSURE_ARG_POINTER(_retval);
        1154               0 :   if (!mCacheEntryAvailable)
        1155               0 :     return NS_ERROR_NOT_AVAILABLE;
        1156                 :
        1157               0 :   *_retval = mCacheExpirationTime;
        1158               0 :   return NS_OK;
        1159                 : }
        1160                 :
        1161                 : NS_IMETHODIMP
        1162               0 : HttpChannelChild::GetCacheTokenCachedCharset(nsACString &_retval)
        1163                 : {
        1164               0 :   if (!mCacheEntryAvailable)
        1165               0 :     return NS_ERROR_NOT_AVAILABLE;
        1166                 :
        1167               0 :   _retval = mCachedCharset;
        1168               0 :   return NS_OK;
        1169                 : }
        1170                 : NS_IMETHODIMP
        1171               0 : HttpChannelChild::SetCacheTokenCachedCharset(const nsACString &aCharset)
        1172                 : {
        1173               0 :   if (!mCacheEntryAvailable || !RemoteChannelExists())
        1174               0 :     return NS_ERROR_NOT_AVAILABLE;
        1175                 :
        1176               0 :   mCachedCharset = aCharset;
        1177               0 :   if (!SendSetCacheTokenCachedCharset(PromiseFlatCString(aCharset))) {
        1178               0 :     return NS_ERROR_FAILURE;
        1179                 :   }
        1180               0 :   return NS_OK;
        1181                 : }
        1182                 :
        1183                 : NS_IMETHODIMP
        1184               0 : HttpChannelChild::IsFromCache(bool *value)
        1185                 : {
        1186               0 :   if (!mIsPending)
        1187               0 :     return NS_ERROR_NOT_AVAILABLE;
        1188                 :
        1189               0 :   *value = mIsFromCache;
        1190               0 :   return NS_OK;
        1191                 : }
        1192                 :
        1193                 : //-----------------------------------------------------------------------------
        1194                 : // HttpChannelChild::nsIResumableChannel
        1195                 : //-----------------------------------------------------------------------------
        1196                 :
        1197                 : NS_IMETHODIMP
        1198               0 : HttpChannelChild::ResumeAt(PRUint64 startPos, const nsACString& entityID)
        1199                 : {
        1200               0 :   ENSURE_CALLED_BEFORE_ASYNC_OPEN();
        1201               0 :   mStartPos = startPos;
        1202               0 :   mEntityID = entityID;
        1203               0 :   mSendResumeAt = true;
        1204               0 :   return NS_OK;
        1205                 : }
        1206                 :
        1207                 : // GetEntityID is shared in HttpBaseChannel
        1208                 :
        1209                 : //-----------------------------------------------------------------------------
        1210                 : // HttpChannelChild::nsISupportsPriority
        1211                 : //-----------------------------------------------------------------------------
        1212                 :
        1213                 : NS_IMETHODIMP
        1214               0 : HttpChannelChild::SetPriority(PRInt32 aPriority)
        1215                 : {
        1216               0 :   PRInt16 newValue = clamped(aPriority, PR_INT16_MIN, PR_INT16_MAX);
        1217               0 :   if (mPriority == newValue)
        1218               0 :     return NS_OK;
        1219               0 :   mPriority = newValue;
        1220               0 :   if (RemoteChannelExists())
        1221               0 :     SendSetPriority(mPriority);
        1222               0 :   return NS_OK;
        1223                 : }
        1224                 :
        1225                 : //-----------------------------------------------------------------------------
        1226                 : // HttpChannelChild::nsIProxiedChannel
        1227                 : //-----------------------------------------------------------------------------
        1228                 :
        1229                 : NS_IMETHODIMP
        1230               0 : HttpChannelChild::GetProxyInfo(nsIProxyInfo **aProxyInfo)
        1231                 : {
        1232               0 :   DROP_DEAD();
        1233                 : }
        1234                 :
        1235                 : //-----------------------------------------------------------------------------
        1236                 : // HttpChannelChild::nsIApplicationCacheContainer
        1237                 : //-----------------------------------------------------------------------------
        1238                 :
        1239                 : NS_IMETHODIMP
        1240               0 : HttpChannelChild::GetApplicationCache(nsIApplicationCache **aApplicationCache)
        1241                 : {
        1242               0 :   NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
        1243               0 :   return NS_OK;
        1244                 : }
        1245                 : NS_IMETHODIMP
        1246               0 : HttpChannelChild::SetApplicationCache(nsIApplicationCache *aApplicationCache)
        1247                 : {
        1248               0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
        1249                 :
        1250               0 :   mApplicationCache = aApplicationCache;
        1251               0 :   return NS_OK;
        1252                 : }
        1253                 :
        1254                 : //-----------------------------------------------------------------------------
        1255                 : // HttpChannelChild::nsIApplicationCacheChannel
        1256                 : //-----------------------------------------------------------------------------
        1257                 :
        1258                 : NS_IMETHODIMP
        1259               0 : HttpChannelChild::GetLoadedFromApplicationCache(bool *aLoadedFromApplicationCache)
        1260                 : {
        1261               0 :   *aLoadedFromApplicationCache = mLoadedFromApplicationCache;
        1262               0 :   return NS_OK;
        1263                 : }
        1264                 :
        1265                 : NS_IMETHODIMP
        1266               0 : HttpChannelChild::GetInheritApplicationCache(bool *aInherit)
        1267                 : {
        1268               0 :   *aInherit = mInheritApplicationCache;
        1269               0 :   return NS_OK;
        1270                 : }
        1271                 : NS_IMETHODIMP
        1272               0 : HttpChannelChild::SetInheritApplicationCache(bool aInherit)
        1273                 : {
        1274               0 :   mInheritApplicationCache = aInherit;
        1275               0 :   return NS_OK;
        1276                 : }
        1277                 :
        1278                 : NS_IMETHODIMP
        1279               0 : HttpChannelChild::GetChooseApplicationCache(bool *aChoose)
        1280                 : {
        1281               0 :   *aChoose = mChooseApplicationCache;
        1282               0 :   return NS_OK;
        1283                 : }
        1284                 :
        1285                 : NS_IMETHODIMP
        1286               0 : HttpChannelChild::SetChooseApplicationCache(bool aChoose)
        1287                 : {
        1288               0 :   mChooseApplicationCache = aChoose;
        1289               0 :   return NS_OK;
        1290                 : }
        1291                 :
        1292                 : NS_IMETHODIMP
        1293               0 : HttpChannelChild::MarkOfflineCacheEntryAsForeign()
        1294                 : {
        1295               0 :   SendMarkOfflineCacheEntryAsForeign();
        1296               0 :   return NS_OK;
        1297                 : }
        1298                 :
        1299                 : //-----------------------------------------------------------------------------
        1300                 : // HttpChannelChild::nsIAssociatedContentSecurity
        1301                 : //-----------------------------------------------------------------------------
        1302                 :
        1303                 : bool
        1304               0 : HttpChannelChild::GetAssociatedContentSecurity(
        1305                 :                     nsIAssociatedContentSecurity** _result)
        1306                 : {
        1307               0 :   if (!mSecurityInfo)
        1308               0 :     return false;
        1309                 :
        1310                 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc =
        1311               0 :       do_QueryInterface(mSecurityInfo);
        1312               0 :   if (!assoc)
        1313               0 :     return false;
        1314                 :
        1315               0 :   if (_result)
        1316               0 :     assoc.forget(_result);
        1317               0 :   return true;
        1318                 : }
        1319                 :
        1320                 : /* attribute unsigned long countSubRequestsHighSecurity; */
        1321                 : NS_IMETHODIMP
        1322               0 : HttpChannelChild::GetCountSubRequestsHighSecurity(
        1323                 :                     PRInt32 *aSubRequestsHighSecurity)
        1324                 : {
        1325               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1326               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1327               0 :     return NS_OK;
        1328                 :
        1329               0 :   return assoc->GetCountSubRequestsHighSecurity(aSubRequestsHighSecurity);
        1330                 : }
        1331                 : NS_IMETHODIMP
        1332               0 : HttpChannelChild::SetCountSubRequestsHighSecurity(
        1333                 :                     PRInt32 aSubRequestsHighSecurity)
        1334                 : {
        1335               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1336               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1337               0 :     return NS_OK;
        1338                 :
        1339               0 :   return assoc->SetCountSubRequestsHighSecurity(aSubRequestsHighSecurity);
        1340                 : }
        1341                 :
        1342                 : /* attribute unsigned long countSubRequestsLowSecurity; */
        1343                 : NS_IMETHODIMP
        1344               0 : HttpChannelChild::GetCountSubRequestsLowSecurity(
        1345                 :                     PRInt32 *aSubRequestsLowSecurity)
        1346                 : {
        1347               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1348               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1349               0 :     return NS_OK;
        1350                 :
        1351               0 :   return assoc->GetCountSubRequestsLowSecurity(aSubRequestsLowSecurity);
        1352                 : }
        1353                 : NS_IMETHODIMP
        1354               0 : HttpChannelChild::SetCountSubRequestsLowSecurity(
        1355                 :                     PRInt32 aSubRequestsLowSecurity)
        1356                 : {
        1357               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1358               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1359               0 :     return NS_OK;
        1360                 :
        1361               0 :   return assoc->SetCountSubRequestsLowSecurity(aSubRequestsLowSecurity);
        1362                 : }
        1363                 :
        1364                 : /* attribute unsigned long countSubRequestsBrokenSecurity; */
        1365                 : NS_IMETHODIMP
        1366               0 : HttpChannelChild::GetCountSubRequestsBrokenSecurity(
        1367                 :                     PRInt32 *aSubRequestsBrokenSecurity)
        1368                 : {
        1369               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1370               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1371               0 :     return NS_OK;
        1372                 :
        1373               0 :   return assoc->GetCountSubRequestsBrokenSecurity(aSubRequestsBrokenSecurity);
        1374                 : }
        1375                 : NS_IMETHODIMP
        1376               0 : HttpChannelChild::SetCountSubRequestsBrokenSecurity(
        1377                 :                     PRInt32 aSubRequestsBrokenSecurity)
        1378                 : {
        1379               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1380               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1381               0 :     return NS_OK;
        1382                 :
        1383               0 :   return assoc->SetCountSubRequestsBrokenSecurity(aSubRequestsBrokenSecurity);
        1384                 : }
        1385                 :
        1386                 : /* attribute unsigned long countSubRequestsNoSecurity; */
        1387                 : NS_IMETHODIMP
        1388               0 : HttpChannelChild::GetCountSubRequestsNoSecurity(PRInt32 *aSubRequestsNoSecurity)
        1389                 : {
        1390               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1391               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1392               0 :     return NS_OK;
        1393                 :
        1394               0 :   return assoc->GetCountSubRequestsNoSecurity(aSubRequestsNoSecurity);
        1395                 : }
        1396                 : NS_IMETHODIMP
        1397               0 : HttpChannelChild::SetCountSubRequestsNoSecurity(PRInt32 aSubRequestsNoSecurity)
        1398                 : {
        1399               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1400               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1401               0 :     return NS_OK;
        1402                 :
        1403               0 :   return assoc->SetCountSubRequestsNoSecurity(aSubRequestsNoSecurity);
        1404                 : }
        1405                 :
        1406                 : NS_IMETHODIMP
        1407               0 : HttpChannelChild::Flush()
        1408                 : {
        1409               0 :   nsCOMPtr<nsIAssociatedContentSecurity> assoc;
        1410               0 :   if (!GetAssociatedContentSecurity(getter_AddRefs(assoc)))
        1411               0 :     return NS_OK;
        1412                 :
        1413                 :   nsresult rv;
        1414                 :   PRInt32 hi, low, broken, no;
        1415                 :
        1416               0 :   rv = assoc->GetCountSubRequestsHighSecurity(&hi);
        1417               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1418               0 :   rv = assoc->GetCountSubRequestsLowSecurity(&low);
        1419               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1420               0 :   rv = assoc->GetCountSubRequestsBrokenSecurity(&broken);
        1421               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1422               0 :   rv = assoc->GetCountSubRequestsNoSecurity(&no);
        1423               0 :   NS_ENSURE_SUCCESS(rv, rv);
        1424                 :
        1425               0 :   if (mIPCOpen)
        1426               0 :     SendUpdateAssociatedContentSecurity(hi, low, broken, no);
        1427                 :
        1428               0 :   return NS_OK;
        1429                 : }
        1430                 :
        1431                 : //-----------------------------------------------------------------------------
        1432                 : // HttpChannelChild::nsIHttpChannelChild
        1433                 : //-----------------------------------------------------------------------------
        1434                 :
        1435               0 : NS_IMETHODIMP HttpChannelChild::AddCookiesToRequest()
        1436                 : {
        1437               0 :   HttpBaseChannel::AddCookiesToRequest();
        1438               0 :   return NS_OK;
        1439                 : }
        1440                 :
        1441               0 : NS_IMETHODIMP HttpChannelChild::GetClientSetRequestHeaders(RequestHeaderTuples **aRequestHeaders)
        1442                 : {
        1443               0 :   *aRequestHeaders = &mClientSetRequestHeaders;
        1444               0 :   return NS_OK;
        1445                 : }
        1446                 :
        1447                 : //------------------------------------------------------------------------------
        1448                 :
        1449                 : }} // mozilla::net

Generated by: LCOV version 1.7