LCOV - code coverage report
Current view: directory - netwerk/base/src - nsBaseChannel.h (source / functions) Found Hit Coverage
Test: app.info Lines: 50 33 66.0 %
Date: 2012-06-02 Functions: 24 12 50.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Google Inc.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *  Darin Fisher <darin@meer.net>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef nsBaseChannel_h__
      39                 : #define nsBaseChannel_h__
      40                 : 
      41                 : #include "nsString.h"
      42                 : #include "nsAutoPtr.h"
      43                 : #include "nsCOMPtr.h"
      44                 : #include "nsHashPropertyBag.h"
      45                 : #include "nsInputStreamPump.h"
      46                 : 
      47                 : #include "nsIChannel.h"
      48                 : #include "nsIInputStream.h"
      49                 : #include "nsIURI.h"
      50                 : #include "nsILoadGroup.h"
      51                 : #include "nsIStreamListener.h"
      52                 : #include "nsIInterfaceRequestor.h"
      53                 : #include "nsIProgressEventSink.h"
      54                 : #include "nsITransport.h"
      55                 : #include "nsIAsyncVerifyRedirectCallback.h"
      56                 : #include "nsThreadUtils.h"
      57                 : 
      58                 : //-----------------------------------------------------------------------------
      59                 : // nsBaseChannel is designed to be subclassed.  The subclass is responsible for
      60                 : // implementing the OpenContentStream method, which will be called by the
      61                 : // nsIChannel::AsyncOpen and nsIChannel::Open implementations.
      62                 : //
      63                 : // nsBaseChannel implements nsIInterfaceRequestor to provide a convenient way
      64                 : // for subclasses to query both the nsIChannel::notificationCallbacks and
      65                 : // nsILoadGroup::notificationCallbacks for supported interfaces.
      66                 : //
      67                 : // nsBaseChannel implements nsITransportEventSink to support progress & status
      68                 : // notifications generated by the transport layer.
      69                 : 
      70                 : class nsBaseChannel : public nsHashPropertyBag
      71                 :                     , public nsIChannel
      72                 :                     , public nsIInterfaceRequestor
      73                 :                     , public nsITransportEventSink
      74                 :                     , public nsIAsyncVerifyRedirectCallback
      75                 :                     , private nsIStreamListener
      76                 : {
      77                 : public:
      78                 :   NS_DECL_ISUPPORTS_INHERITED
      79                 :   NS_DECL_NSIREQUEST
      80                 :   NS_DECL_NSICHANNEL
      81                 :   NS_DECL_NSIINTERFACEREQUESTOR
      82                 :   NS_DECL_NSITRANSPORTEVENTSINK
      83                 :   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
      84                 : 
      85                 :   nsBaseChannel(); 
      86                 : 
      87                 :   // This method must be called to initialize the basechannel instance.
      88           53433 :   nsresult Init() {
      89           53433 :     return nsHashPropertyBag::Init();
      90                 :   }
      91                 : 
      92                 : protected:
      93                 :   // -----------------------------------------------
      94                 :   // Methods to be implemented by the derived class:
      95                 : 
      96          106862 :   virtual ~nsBaseChannel() {}
      97                 : 
      98                 : private:
      99                 :   // Implemented by subclass to supply data stream.  The parameter, async, is
     100                 :   // true when called from nsIChannel::AsyncOpen and false otherwise.  When
     101                 :   // async is true, the resulting stream will be used with a nsIInputStreamPump
     102                 :   // instance.  This means that if it is a non-blocking stream that supports
     103                 :   // nsIAsyncInputStream that it will be read entirely on the main application
     104                 :   // thread, and its AsyncWait method will be called whenever ReadSegments
     105                 :   // returns NS_BASE_STREAM_WOULD_BLOCK.  Otherwise, if the stream is blocking,
     106                 :   // then it will be read on one of the background I/O threads, and it does not
     107                 :   // need to implement ReadSegments.  If async is false, this method may return
     108                 :   // NS_ERROR_NOT_IMPLEMENTED to cause the basechannel to implement Open in
     109                 :   // terms of AsyncOpen (see NS_ImplementChannelOpen).
     110                 :   // A callee is allowed to return an nsIChannel instead of an nsIInputStream.
     111                 :   // That case will be treated as a redirect to the new channel.  By default
     112                 :   // *channel will be set to null by the caller, so callees who don't want to
     113                 :   // return one an just not touch it.
     114                 :   virtual nsresult OpenContentStream(bool async, nsIInputStream **stream,
     115                 :                                      nsIChannel** channel) = 0;
     116                 : 
     117                 :   // The basechannel calls this method from its OnTransportStatus method to
     118                 :   // determine whether to call nsIProgressEventSink::OnStatus in addition to
     119                 :   // nsIProgressEventSink::OnProgress.  This method may be overriden by the
     120                 :   // subclass to enable nsIProgressEventSink::OnStatus events.  If this method
     121                 :   // returns true, then the statusArg out param specifies the "statusArg" value
     122                 :   // to pass to the OnStatus method.  By default, OnStatus messages are
     123                 :   // suppressed.  The status parameter passed to this method is the status value
     124                 :   // from the OnTransportStatus method.
     125               0 :   virtual bool GetStatusArg(nsresult status, nsString &statusArg) {
     126               0 :     return false;
     127                 :   }
     128                 : 
     129                 :   // Called when the callbacks available to this channel may have changed.
     130             329 :   virtual void OnCallbacksChanged() {
     131             329 :   }
     132                 : 
     133                 : public:
     134                 :   // ----------------------------------------------
     135                 :   // Methods provided for use by the derived class:
     136                 : 
     137                 :   // Redirect to another channel.  This method takes care of notifying
     138                 :   // observers of this redirect as well as of opening the new channel, if asked
     139                 :   // to do so.  It also cancels |this| with the status code
     140                 :   // NS_BINDING_REDIRECTED.  A failure return from this method means that the
     141                 :   // redirect could not be performed (no channel was opened; this channel
     142                 :   // wasn't canceled.)  The redirectFlags parameter consists of the flag values
     143                 :   // defined on nsIChannelEventSink.
     144                 :   nsresult Redirect(nsIChannel *newChannel, PRUint32 redirectFlags,
     145                 :                     bool openNewChannel);
     146                 : 
     147                 :   // Tests whether a type hint was set. Subclasses can use this to decide
     148                 :   // whether to call SetContentType.
     149                 :   // NOTE: This is only reliable if the subclass didn't itself call
     150                 :   // SetContentType, and should also not be called after OpenContentStream.
     151                 :   bool HasContentTypeHint() const;
     152                 : 
     153                 :   // The URI member should be initialized before the channel is used, and then
     154                 :   // it should never be changed again until the channel is destroyed.
     155            8850 :   nsIURI *URI() {
     156            8850 :     return mURI;
     157                 :   }
     158           53433 :   void SetURI(nsIURI *uri) {
     159           53433 :     NS_ASSERTION(uri, "must specify a non-null URI");
     160           53433 :     NS_ASSERTION(!mURI, "must not modify URI");
     161           53433 :     NS_ASSERTION(!mOriginalURI, "how did that get set so early?");
     162           53433 :     mURI = uri;
     163           53433 :     mOriginalURI = uri;
     164           53433 :   }
     165              11 :   nsIURI *OriginalURI() {
     166              11 :     return mOriginalURI;
     167                 :   }
     168                 : 
     169                 :   // The security info is a property of the transport-layer, which should be
     170                 :   // assigned by the subclass.
     171                 :   nsISupports *SecurityInfo() {
     172                 :     return mSecurityInfo; 
     173                 :   }
     174                 :   void SetSecurityInfo(nsISupports *info) {
     175                 :     mSecurityInfo = info;
     176                 :   }
     177                 : 
     178                 :   // Test the load flags
     179             177 :   bool HasLoadFlag(PRUint32 flag) {
     180             177 :     return (mLoadFlags & flag) != 0;
     181                 :   }
     182                 : 
     183                 :   // This is a short-cut to calling nsIRequest::IsPending()
     184            2888 :   bool IsPending() const {
     185            2888 :     return mPump || mWaitingOnAsyncRedirect;
     186                 :   }
     187                 : 
     188                 :   // Set the content length that should be reported for this channel.  Pass -1
     189                 :   // to indicate an unspecified content length.
     190                 :   void SetContentLength64(PRInt64 len);
     191                 :   PRInt64 ContentLength64();
     192                 : 
     193                 :   // Helper function for querying the channel's notification callbacks.
     194              29 :   template <class T> void GetCallback(nsCOMPtr<T> &result) {
     195              29 :     GetInterface(NS_GET_TEMPLATE_IID(T), getter_AddRefs(result));
     196              29 :   }
     197                 : 
     198                 :   // Helper function for calling QueryInterface on this.
     199               0 :   nsQueryInterface do_QueryInterface() {
     200               0 :     return nsQueryInterface(static_cast<nsIChannel *>(this));
     201                 :   }
     202                 :   // MSVC needs this:
     203           54669 :   nsQueryInterface do_QueryInterface(nsISupports *obj) {
     204           54669 :     return nsQueryInterface(obj);
     205                 :   }
     206                 : 
     207                 :   // If a subclass does not want to feed transport-layer progress events to the
     208                 :   // base channel via nsITransportEventSink, then it may set this flag to cause
     209                 :   // the base channel to synthesize progress events when it receives data from
     210                 :   // the content stream.  By default, progress events are not synthesized.
     211            2866 :   void EnableSynthesizedProgressEvents(bool enable) {
     212            2866 :     mSynthProgressEvents = enable;
     213            2866 :   }
     214                 : 
     215                 :   // Some subclasses may wish to manually insert a stream listener between this
     216                 :   // and the channel's listener.  The following methods make that possible.
     217               0 :   void SetStreamListener(nsIStreamListener *listener) {
     218               0 :     mListener = listener;
     219               0 :   }
     220               0 :   nsIStreamListener *StreamListener() {
     221               0 :     return mListener;
     222                 :   }
     223                 : 
     224                 :   // Pushes a new stream converter in front of the channel's stream listener.
     225                 :   // The fromType and toType values are passed to nsIStreamConverterService's
     226                 :   // AsyncConvertData method.  If invalidatesContentLength is true, then the
     227                 :   // channel's content-length property will be assigned a value of -1.  This is
     228                 :   // necessary when the converter changes the length of the resulting data
     229                 :   // stream, which is almost always the case for a "stream converter" ;-)
     230                 :   // This function optionally returns a reference to the new converter.
     231                 :   nsresult PushStreamConverter(const char *fromType, const char *toType,
     232                 :                                bool invalidatesContentLength = true,
     233                 :                                nsIStreamListener **converter = nsnull);
     234                 : 
     235                 : private:
     236                 :   NS_DECL_NSISTREAMLISTENER
     237                 :   NS_DECL_NSIREQUESTOBSERVER
     238                 : 
     239                 :   // Called to setup mPump and call AsyncRead on it.
     240                 :   nsresult BeginPumpingData();
     241                 : 
     242                 :   // Called when the callbacks available to this channel may have changed.
     243             346 :   void CallbacksChanged() {
     244             346 :     mProgressSink = nsnull;
     245             346 :     mQueriedProgressSink = false;
     246             346 :     OnCallbacksChanged();
     247             346 :   }
     248                 : 
     249                 :   // Handle an async redirect callback.  This will only be called if we
     250                 :   // returned success from AsyncOpen while posting a redirect runnable.
     251                 :   void HandleAsyncRedirect(nsIChannel* newChannel);
     252                 :   void ContinueHandleAsyncRedirect(nsresult result);
     253                 :   nsresult ContinueRedirect();
     254                 : 
     255                 :   // start URI classifier if requested
     256                 :   void ClassifyURI();
     257                 : 
     258                 :   class RedirectRunnable : public nsRunnable
     259               0 :   {
     260                 :   public:
     261               0 :     RedirectRunnable(nsBaseChannel* chan, nsIChannel* newChannel)
     262               0 :       : mChannel(chan), mNewChannel(newChannel)
     263                 :     {
     264               0 :       NS_PRECONDITION(newChannel, "Must have channel to redirect to");
     265               0 :     }
     266                 :     
     267               0 :     NS_IMETHOD Run()
     268                 :     {
     269               0 :       mChannel->HandleAsyncRedirect(mNewChannel);
     270               0 :       return NS_OK;
     271                 :     }
     272                 : 
     273                 :   private:
     274                 :     nsRefPtr<nsBaseChannel> mChannel;
     275                 :     nsCOMPtr<nsIChannel> mNewChannel;
     276                 :   };
     277                 :   friend class RedirectRunnable;
     278                 : 
     279                 :   nsRefPtr<nsInputStreamPump>         mPump;
     280                 :   nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
     281                 :   nsCOMPtr<nsIProgressEventSink>      mProgressSink;
     282                 :   nsCOMPtr<nsIURI>                    mOriginalURI;
     283                 :   nsCOMPtr<nsIURI>                    mURI;
     284                 :   nsCOMPtr<nsISupports>               mOwner;
     285                 :   nsCOMPtr<nsISupports>               mSecurityInfo;
     286                 :   nsCOMPtr<nsIChannel>                mRedirectChannel;
     287                 :   nsCString                           mContentType;
     288                 :   nsCString                           mContentCharset;
     289                 :   PRUint32                            mLoadFlags;
     290                 :   bool                                mQueriedProgressSink;
     291                 :   bool                                mSynthProgressEvents;
     292                 :   bool                                mWasOpened;
     293                 :   bool                                mWaitingOnAsyncRedirect;
     294                 :   bool                                mOpenRedirectChannel;
     295                 :   PRUint32                            mRedirectFlags;
     296                 : 
     297                 : protected:
     298                 :   nsCOMPtr<nsILoadGroup>              mLoadGroup;
     299                 :   nsCOMPtr<nsIStreamListener>         mListener;
     300                 :   nsCOMPtr<nsISupports>               mListenerContext;
     301                 :   nsresult                            mStatus;
     302                 : };
     303                 : 
     304                 : #endif // !nsBaseChannel_h__

Generated by: LCOV version 1.7