LCOV - code coverage report
Current view: top level - netwerk/base - nsBaseChannel.h (source / functions) Hit Total Coverage
Test: output.info Lines: 43 57 75.4 %
Date: 2017-07-14 16:53:18 Functions: 15 26 57.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13