LCOV - code coverage report
Current view: top level - dom/fetch - Fetch.h (source / functions) Hit Total Coverage
Test: output.info Lines: 8 18 44.4 %
Date: 2017-07-14 16:53:18 Functions: 5 18 27.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_Fetch_h
       8             : #define mozilla_dom_Fetch_h
       9             : 
      10             : #include "nsAutoPtr.h"
      11             : #include "nsIStreamLoader.h"
      12             : 
      13             : #include "nsCOMPtr.h"
      14             : #include "nsError.h"
      15             : #include "nsProxyRelease.h"
      16             : #include "nsString.h"
      17             : 
      18             : #include "mozilla/DebugOnly.h"
      19             : #include "mozilla/ErrorResult.h"
      20             : #include "mozilla/dom/Promise.h"
      21             : #include "mozilla/dom/RequestBinding.h"
      22             : 
      23             : class nsIGlobalObject;
      24             : class nsIEventTarget;
      25             : 
      26             : namespace mozilla {
      27             : namespace dom {
      28             : 
      29             : class BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString;
      30             : class BlobImpl;
      31             : class InternalRequest;
      32             : class OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString;
      33             : class RequestOrUSVString;
      34             : enum class CallerType : uint32_t;
      35             : 
      36             : namespace workers {
      37             : class WorkerPrivate;
      38             : } // namespace workers
      39             : 
      40             : already_AddRefed<Promise>
      41             : FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
      42             :              const RequestInit& aInit, CallerType aCallerType,
      43             :              ErrorResult& aRv);
      44             : 
      45             : nsresult
      46             : UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest);
      47             : 
      48             : namespace fetch {
      49             : typedef BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString BodyInit;
      50             : typedef OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString OwningBodyInit;
      51             : };
      52             : 
      53             : /*
      54             :  * Creates an nsIInputStream based on the fetch specifications 'extract a byte
      55             :  * stream algorithm' - http://fetch.spec.whatwg.org/#concept-bodyinit-extract.
      56             :  * Stores content type in out param aContentType.
      57             :  */
      58             : nsresult
      59             : ExtractByteStreamFromBody(const fetch::OwningBodyInit& aBodyInit,
      60             :                           nsIInputStream** aStream,
      61             :                           nsCString& aContentType,
      62             :                           uint64_t& aContentLength);
      63             : 
      64             : /*
      65             :  * Non-owning version.
      66             :  */
      67             : nsresult
      68             : ExtractByteStreamFromBody(const fetch::BodyInit& aBodyInit,
      69             :                           nsIInputStream** aStream,
      70             :                           nsCString& aContentType,
      71             :                           uint64_t& aContentLength);
      72             : 
      73             : template <class Derived> class FetchBodyConsumer;
      74             : 
      75             : enum FetchConsumeType
      76             : {
      77             :   CONSUME_ARRAYBUFFER,
      78             :   CONSUME_BLOB,
      79             :   CONSUME_FORMDATA,
      80             :   CONSUME_JSON,
      81             :   CONSUME_TEXT,
      82             : };
      83             : 
      84             : /*
      85             :  * FetchBody's body consumption uses nsIInputStreamPump to read from the
      86             :  * underlying stream to a block of memory, which is then adopted by
      87             :  * ContinueConsumeBody() and converted to the right type based on the JS
      88             :  * function called.
      89             :  *
      90             :  * Use of the nsIInputStreamPump complicates things on the worker thread.
      91             :  * The solution used here is similar to WebSockets.
      92             :  * The difference is that we are only interested in completion and not data
      93             :  * events, and nsIInputStreamPump can only deliver completion on the main thread.
      94             :  *
      95             :  * Before starting the pump on the main thread, we addref the FetchBody to keep
      96             :  * it alive. Then we add a feature, to track the status of the worker.
      97             :  *
      98             :  * ContinueConsumeBody() is the function that cleans things up in both success
      99             :  * and error conditions and so all callers call it with the appropriate status.
     100             :  *
     101             :  * Once the read is initiated on the main thread there are two possibilities.
     102             :  *
     103             :  * 1) Pump finishes before worker has finished Running.
     104             :  *    In this case we adopt the data and dispatch a runnable to the worker,
     105             :  *    which derefs FetchBody and removes the feature and resolves the Promise.
     106             :  *
     107             :  * 2) Pump still working while worker has stopped Running.
     108             :  *    The feature is Notify()ed and ContinueConsumeBody() is called with
     109             :  *    NS_BINDING_ABORTED. We first Cancel() the pump using a sync runnable to
     110             :  *    ensure that mFetchBody remains alive (since mConsumeBodyPump is strongly
     111             :  *    held by it) until pump->Cancel() is called. OnStreamComplete() will not
     112             :  *    do anything if the error code is NS_BINDING_ABORTED, so we don't have to
     113             :  *    worry about keeping anything alive.
     114             :  *
     115             :  * The pump is always released on the main thread.
     116             :  */
     117             : template <class Derived>
     118             : class FetchBody
     119             : {
     120             : public:
     121             :   friend class FetchBodyConsumer<Derived>;
     122             : 
     123             :   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
     124             : 
     125             :   bool
     126           2 :   BodyUsed() const { return mBodyUsed; }
     127             : 
     128             :   already_AddRefed<Promise>
     129           0 :   ArrayBuffer(ErrorResult& aRv)
     130             :   {
     131           0 :     return ConsumeBody(CONSUME_ARRAYBUFFER, aRv);
     132             :   }
     133             : 
     134             :   already_AddRefed<Promise>
     135           0 :   Blob(ErrorResult& aRv)
     136             :   {
     137           0 :     return ConsumeBody(CONSUME_BLOB, aRv);
     138             :   }
     139             : 
     140             :   already_AddRefed<Promise>
     141           0 :   FormData(ErrorResult& aRv)
     142             :   {
     143           0 :     return ConsumeBody(CONSUME_FORMDATA, aRv);
     144             :   }
     145             : 
     146             :   already_AddRefed<Promise>
     147           1 :   Json(ErrorResult& aRv)
     148             :   {
     149           1 :     return ConsumeBody(CONSUME_JSON, aRv);
     150             :   }
     151             : 
     152             :   already_AddRefed<Promise>
     153           0 :   Text(ErrorResult& aRv)
     154             :   {
     155           0 :     return ConsumeBody(CONSUME_TEXT, aRv);
     156             :   }
     157             : 
     158             :   // Utility public methods accessed by various runnables.
     159             : 
     160             :   void
     161           1 :   SetBodyUsed()
     162             :   {
     163           1 :     mBodyUsed = true;
     164           1 :   }
     165             : 
     166             :   const nsCString&
     167           0 :   MimeType() const
     168             :   {
     169           0 :     return mMimeType;
     170             :   }
     171             : 
     172             : protected:
     173             :   nsCOMPtr<nsIGlobalObject> mOwner;
     174             : 
     175             :   // Always set whenever the FetchBody is created on the worker thread.
     176             :   workers::WorkerPrivate* mWorkerPrivate;
     177             : 
     178             :   explicit FetchBody(nsIGlobalObject* aOwner);
     179             : 
     180             :   virtual ~FetchBody();
     181             : 
     182             :   void
     183             :   SetMimeType();
     184             : 
     185             : private:
     186             :   Derived*
     187           9 :   DerivedClass() const
     188             :   {
     189           9 :     return static_cast<Derived*>(const_cast<FetchBody*>(this));
     190             :   }
     191             : 
     192             :   already_AddRefed<Promise>
     193             :   ConsumeBody(FetchConsumeType aType, ErrorResult& aRv);
     194             : 
     195             :   bool
     196             :   IsOnTargetThread()
     197             :   {
     198             :     return NS_IsMainThread() == !mWorkerPrivate;
     199             :   }
     200             : 
     201             :   void
     202             :   AssertIsOnTargetThread()
     203             :   {
     204             :     MOZ_ASSERT(IsOnTargetThread());
     205             :   }
     206             : 
     207             :   // Only ever set once, always on target thread.
     208             :   bool mBodyUsed;
     209             :   nsCString mMimeType;
     210             : 
     211             :   // The main-thread event target for runnable dispatching.
     212             :   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
     213             : };
     214             : 
     215             : } // namespace dom
     216             : } // namespace mozilla
     217             : 
     218             : #endif // mozilla_dom_Fetch_h

Generated by: LCOV version 1.13