LCOV - code coverage report
Current view: directory - netwerk/protocol/websocket - WebSocketChannelChild.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 183 0 0.0 %
Date: 2012-06-02 Functions: 46 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                 : /* ***** 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.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Mozilla Foundation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Josh Matthews <josh@joshmatthews.net>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "WebSocketLog.h"
      41                 : #include "mozilla/dom/TabChild.h"
      42                 : #include "mozilla/net/NeckoChild.h"
      43                 : #include "WebSocketChannelChild.h"
      44                 : #include "nsITabChild.h"
      45                 : 
      46                 : namespace mozilla {
      47                 : namespace net {
      48                 : 
      49               0 : NS_IMPL_ADDREF(WebSocketChannelChild)
      50                 : 
      51               0 : NS_IMETHODIMP_(nsrefcnt) WebSocketChannelChild::Release()
      52                 : {
      53               0 :   NS_PRECONDITION(0 != mRefCnt, "dup release");
      54               0 :   NS_ASSERT_OWNINGTHREAD(WebSocketChannelChild);
      55               0 :   --mRefCnt;
      56               0 :   NS_LOG_RELEASE(this, mRefCnt, "WebSocketChannelChild");
      57                 : 
      58               0 :   if (mRefCnt == 1 && mIPCOpen) {
      59               0 :     SendDeleteSelf();
      60               0 :     return mRefCnt;
      61                 :   }
      62                 : 
      63               0 :   if (mRefCnt == 0) {
      64               0 :     mRefCnt = 1; /* stabilize */
      65               0 :     delete this;
      66               0 :     return 0;
      67                 :   }
      68               0 :   return mRefCnt;
      69                 : }
      70                 : 
      71               0 : NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
      72               0 :   NS_INTERFACE_MAP_ENTRY(nsIWebSocketChannel)
      73               0 :   NS_INTERFACE_MAP_ENTRY(nsIProtocolHandler)
      74               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebSocketChannel)
      75               0 : NS_INTERFACE_MAP_END
      76                 : 
      77               0 : WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
      78                 : : mEventQ(static_cast<nsIWebSocketChannel*>(this))
      79               0 : , mIPCOpen(false)
      80                 : {
      81               0 :   LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
      82               0 :   BaseWebSocketChannel::mEncrypted = aSecure;
      83               0 : }
      84                 : 
      85               0 : WebSocketChannelChild::~WebSocketChannelChild()
      86                 : {
      87               0 :   LOG(("WebSocketChannelChild::~WebSocketChannelChild() %p\n", this));
      88               0 : }
      89                 : 
      90                 : void
      91               0 : WebSocketChannelChild::AddIPDLReference()
      92                 : {
      93               0 :   NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
      94               0 :   mIPCOpen = true;
      95               0 :   AddRef();
      96               0 : }
      97                 : 
      98                 : void
      99               0 : WebSocketChannelChild::ReleaseIPDLReference()
     100                 : {
     101               0 :   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
     102               0 :   mIPCOpen = false;
     103               0 :   Release();
     104               0 : }
     105                 : 
     106                 : class StartEvent : public ChannelEvent
     107               0 : {
     108                 :  public:
     109               0 :   StartEvent(WebSocketChannelChild* aChild,
     110                 :              const nsCString& aProtocol,
     111                 :              const nsCString& aExtensions)
     112                 :   : mChild(aChild)
     113                 :   , mProtocol(aProtocol)
     114               0 :   , mExtensions(aExtensions)
     115               0 :   {}
     116                 : 
     117               0 :   void Run()
     118                 :   {
     119               0 :     mChild->OnStart(mProtocol, mExtensions);
     120               0 :   }
     121                 :  private:
     122                 :   WebSocketChannelChild* mChild;
     123                 :   nsCString mProtocol;
     124                 :   nsCString mExtensions;
     125                 : };
     126                 : 
     127                 : bool
     128               0 : WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
     129                 :                                    const nsCString& aExtensions)
     130                 : {
     131               0 :   if (mEventQ.ShouldEnqueue()) {
     132               0 :     mEventQ.Enqueue(new StartEvent(this, aProtocol, aExtensions));
     133                 :   } else {
     134               0 :     OnStart(aProtocol, aExtensions);
     135                 :   }
     136               0 :   return true;
     137                 : }
     138                 : 
     139                 : void
     140               0 : WebSocketChannelChild::OnStart(const nsCString& aProtocol,
     141                 :                                const nsCString& aExtensions)
     142                 : {
     143               0 :   LOG(("WebSocketChannelChild::RecvOnStart() %p\n", this));
     144               0 :   SetProtocol(aProtocol);
     145               0 :   mNegotiatedExtensions = aExtensions;
     146                 : 
     147               0 :   if (mListener) {
     148               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     149               0 :     mListener->OnStart(mContext);
     150                 :   }
     151               0 : }
     152                 : 
     153                 : class StopEvent : public ChannelEvent
     154               0 : {
     155                 :  public:
     156               0 :   StopEvent(WebSocketChannelChild* aChild,
     157                 :             const nsresult& aStatusCode)
     158                 :   : mChild(aChild)
     159               0 :   , mStatusCode(aStatusCode)
     160               0 :   {}
     161                 : 
     162               0 :   void Run()
     163                 :   {
     164               0 :     mChild->OnStop(mStatusCode);
     165               0 :   }
     166                 :  private:
     167                 :   WebSocketChannelChild* mChild;
     168                 :   nsresult mStatusCode;
     169                 : };
     170                 : 
     171                 : bool
     172               0 : WebSocketChannelChild::RecvOnStop(const nsresult& aStatusCode)
     173                 : {
     174               0 :   if (mEventQ.ShouldEnqueue()) {
     175               0 :     mEventQ.Enqueue(new StopEvent(this, aStatusCode));
     176                 :   } else {
     177               0 :     OnStop(aStatusCode);
     178                 :   }
     179               0 :   return true;
     180                 : }
     181                 : 
     182                 : void
     183               0 : WebSocketChannelChild::OnStop(const nsresult& aStatusCode)
     184                 : {
     185               0 :   LOG(("WebSocketChannelChild::RecvOnStop() %p\n", this));
     186               0 :   if (mListener) {
     187               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     188               0 :     mListener->OnStop(mContext, aStatusCode);
     189                 :   }
     190               0 : }
     191                 : 
     192                 : class MessageEvent : public ChannelEvent
     193               0 : {
     194                 :  public:
     195               0 :   MessageEvent(WebSocketChannelChild* aChild,
     196                 :                const nsCString& aMessage,
     197                 :                bool aBinary)
     198                 :   : mChild(aChild)
     199                 :   , mMessage(aMessage)
     200               0 :   , mBinary(aBinary)
     201               0 :   {}
     202                 : 
     203               0 :   void Run()
     204                 :   {
     205               0 :     if (!mBinary) {
     206               0 :       mChild->OnMessageAvailable(mMessage);
     207                 :     } else {
     208               0 :       mChild->OnBinaryMessageAvailable(mMessage);
     209                 :     }
     210               0 :   }
     211                 :  private:
     212                 :   WebSocketChannelChild* mChild;
     213                 :   nsCString mMessage;
     214                 :   bool mBinary;
     215                 : };
     216                 : 
     217                 : bool
     218               0 : WebSocketChannelChild::RecvOnMessageAvailable(const nsCString& aMsg)
     219                 : {
     220               0 :   if (mEventQ.ShouldEnqueue()) {
     221               0 :     mEventQ.Enqueue(new MessageEvent(this, aMsg, false));
     222                 :   } else {
     223               0 :     OnMessageAvailable(aMsg);
     224                 :   }
     225               0 :   return true;
     226                 : }
     227                 : 
     228                 : void
     229               0 : WebSocketChannelChild::OnMessageAvailable(const nsCString& aMsg)
     230                 : {
     231               0 :   LOG(("WebSocketChannelChild::RecvOnMessageAvailable() %p\n", this));
     232               0 :   if (mListener) {
     233               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     234               0 :     mListener->OnMessageAvailable(mContext, aMsg);
     235                 :   }
     236               0 : }
     237                 : 
     238                 : bool
     239               0 : WebSocketChannelChild::RecvOnBinaryMessageAvailable(const nsCString& aMsg)
     240                 : {
     241               0 :   if (mEventQ.ShouldEnqueue()) {
     242               0 :     mEventQ.Enqueue(new MessageEvent(this, aMsg, true));
     243                 :   } else {
     244               0 :     OnBinaryMessageAvailable(aMsg);
     245                 :   }
     246               0 :   return true;
     247                 : }
     248                 : 
     249                 : void
     250               0 : WebSocketChannelChild::OnBinaryMessageAvailable(const nsCString& aMsg)
     251                 : {
     252               0 :   LOG(("WebSocketChannelChild::RecvOnBinaryMessageAvailable() %p\n", this));
     253               0 :   if (mListener) {
     254               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     255               0 :     mListener->OnBinaryMessageAvailable(mContext, aMsg);
     256                 :   }
     257               0 : }
     258                 : 
     259                 : class AcknowledgeEvent : public ChannelEvent
     260               0 : {
     261                 :  public:
     262               0 :   AcknowledgeEvent(WebSocketChannelChild* aChild,
     263                 :                    const PRUint32& aSize)
     264                 :   : mChild(aChild)
     265               0 :   , mSize(aSize)
     266               0 :   {}
     267                 : 
     268               0 :   void Run()
     269                 :   {
     270               0 :     mChild->OnAcknowledge(mSize);
     271               0 :   }
     272                 :  private:
     273                 :   WebSocketChannelChild* mChild;
     274                 :   PRUint32 mSize;
     275                 : };
     276                 : 
     277                 : bool
     278               0 : WebSocketChannelChild::RecvOnAcknowledge(const PRUint32& aSize)
     279                 : {
     280               0 :   if (mEventQ.ShouldEnqueue()) {
     281               0 :     mEventQ.Enqueue(new AcknowledgeEvent(this, aSize));
     282                 :   } else {
     283               0 :     OnAcknowledge(aSize);
     284                 :   }
     285               0 :   return true;
     286                 : }
     287                 : 
     288                 : void
     289               0 : WebSocketChannelChild::OnAcknowledge(const PRUint32& aSize)
     290                 : {
     291               0 :   LOG(("WebSocketChannelChild::RecvOnAcknowledge() %p\n", this));
     292               0 :   if (mListener) {
     293               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     294               0 :     mListener->OnAcknowledge(mContext, aSize);
     295                 :   }
     296               0 : }
     297                 : 
     298                 : class ServerCloseEvent : public ChannelEvent
     299               0 : {
     300                 :  public:
     301               0 :   ServerCloseEvent(WebSocketChannelChild* aChild,
     302                 :                    const PRUint16 aCode,
     303                 :                    const nsCString &aReason)
     304                 :   : mChild(aChild)
     305                 :   , mCode(aCode)
     306               0 :   , mReason(aReason)
     307               0 :   {}
     308                 : 
     309               0 :   void Run()
     310                 :   {
     311               0 :     mChild->OnServerClose(mCode, mReason);
     312               0 :   }
     313                 :  private:
     314                 :   WebSocketChannelChild* mChild;
     315                 :   PRUint16               mCode;
     316                 :   nsCString              mReason;
     317                 : };
     318                 : 
     319                 : bool
     320               0 : WebSocketChannelChild::RecvOnServerClose(const PRUint16& aCode,
     321                 :                                          const nsCString& aReason)
     322                 : {
     323               0 :   if (mEventQ.ShouldEnqueue()) {
     324               0 :     mEventQ.Enqueue(new ServerCloseEvent(this, aCode, aReason));
     325                 :   } else {
     326               0 :     OnServerClose(aCode, aReason);
     327                 :   }
     328               0 :   return true;
     329                 : }
     330                 : 
     331                 : void
     332               0 : WebSocketChannelChild::OnServerClose(const PRUint16& aCode,
     333                 :                                      const nsCString& aReason)
     334                 : {
     335               0 :   LOG(("WebSocketChannelChild::RecvOnServerClose() %p\n", this));
     336               0 :   if (mListener) {
     337               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
     338               0 :     mListener->OnServerClose(mContext, aCode, aReason);
     339                 :   }
     340               0 : }
     341                 : 
     342                 : NS_IMETHODIMP
     343               0 : WebSocketChannelChild::AsyncOpen(nsIURI *aURI,
     344                 :                                  const nsACString &aOrigin,
     345                 :                                  nsIWebSocketListener *aListener,
     346                 :                                  nsISupports *aContext)
     347                 : {
     348               0 :   LOG(("WebSocketChannelChild::AsyncOpen() %p\n", this));
     349                 : 
     350               0 :   NS_ABORT_IF_FALSE(aURI && aListener && !mListener, 
     351                 :                     "Invalid state for WebSocketChannelChild::AsyncOpen");
     352                 : 
     353               0 :   mozilla::dom::TabChild* tabChild = nsnull;
     354               0 :   nsCOMPtr<nsITabChild> iTabChild;
     355                 :   NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
     356                 :                                 NS_GET_IID(nsITabChild),
     357               0 :                                 getter_AddRefs(iTabChild));
     358               0 :   if (iTabChild) {
     359               0 :     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
     360                 :   }
     361                 : 
     362                 :   // Corresponding release in DeallocPWebSocket
     363               0 :   AddIPDLReference();
     364                 : 
     365               0 :   gNeckoChild->SendPWebSocketConstructor(this, tabChild);
     366               0 :   if (!SendAsyncOpen(aURI, nsCString(aOrigin), mProtocol, mEncrypted))
     367               0 :     return NS_ERROR_UNEXPECTED;
     368                 : 
     369               0 :   mOriginalURI = aURI;
     370               0 :   mURI = mOriginalURI;
     371               0 :   mListener = aListener;
     372               0 :   mContext = aContext;
     373               0 :   mOrigin = aOrigin;
     374                 : 
     375               0 :   return NS_OK;
     376                 : }
     377                 : 
     378                 : NS_IMETHODIMP
     379               0 : WebSocketChannelChild::Close(PRUint16 code, const nsACString & reason)
     380                 : {
     381               0 :   LOG(("WebSocketChannelChild::Close() %p\n", this));
     382                 : 
     383               0 :   if (!mIPCOpen || !SendClose(code, nsCString(reason)))
     384               0 :     return NS_ERROR_UNEXPECTED;
     385               0 :   return NS_OK;
     386                 : }
     387                 : 
     388                 : NS_IMETHODIMP
     389               0 : WebSocketChannelChild::SendMsg(const nsACString &aMsg)
     390                 : {
     391               0 :   LOG(("WebSocketChannelChild::SendMsg() %p\n", this));
     392                 : 
     393               0 :   if (!mIPCOpen || !SendSendMsg(nsCString(aMsg)))
     394               0 :     return NS_ERROR_UNEXPECTED;
     395               0 :   return NS_OK;
     396                 : }
     397                 : 
     398                 : NS_IMETHODIMP
     399               0 : WebSocketChannelChild::SendBinaryMsg(const nsACString &aMsg)
     400                 : {
     401               0 :   LOG(("WebSocketChannelChild::SendBinaryMsg() %p\n", this));
     402                 : 
     403               0 :   if (!mIPCOpen || !SendSendBinaryMsg(nsCString(aMsg)))
     404               0 :     return NS_ERROR_UNEXPECTED;
     405               0 :   return NS_OK;
     406                 : }
     407                 : 
     408                 : NS_IMETHODIMP
     409               0 : WebSocketChannelChild::SendBinaryStream(nsIInputStream *aStream,
     410                 :                                         PRUint32 aLength)
     411                 : {
     412               0 :   LOG(("WebSocketChannelChild::SendBinaryStream() %p\n", this));
     413                 : 
     414               0 :   if (!mIPCOpen || !SendSendBinaryStream(IPC::InputStream(aStream), aLength))
     415               0 :     return NS_ERROR_UNEXPECTED;
     416               0 :   return NS_OK;
     417                 : }
     418                 : 
     419                 : NS_IMETHODIMP
     420               0 : WebSocketChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
     421                 : {
     422               0 :   LOG(("WebSocketChannelChild::GetSecurityInfo() %p\n", this));
     423               0 :   return NS_ERROR_NOT_AVAILABLE;
     424                 : }
     425                 : 
     426                 : } // namespace net
     427                 : } // namespace mozilla

Generated by: LCOV version 1.7