LCOV - code coverage report
Current view: top level - dom/cache - TypeUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 248 0.4 %
Date: 2017-07-14 16:53:18 Functions: 2 18 11.1 %
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             : #include "mozilla/dom/cache/TypeUtils.h"
       8             : 
       9             : #include "mozilla/Unused.h"
      10             : #include "mozilla/dom/CacheBinding.h"
      11             : #include "mozilla/dom/InternalRequest.h"
      12             : #include "mozilla/dom/Request.h"
      13             : #include "mozilla/dom/Response.h"
      14             : #include "mozilla/dom/cache/CacheTypes.h"
      15             : #include "mozilla/dom/cache/ReadStream.h"
      16             : #include "mozilla/ipc/BackgroundChild.h"
      17             : #include "mozilla/ipc/PBackgroundChild.h"
      18             : #include "mozilla/ipc/PFileDescriptorSetChild.h"
      19             : #include "mozilla/ipc/InputStreamUtils.h"
      20             : #include "nsCOMPtr.h"
      21             : #include "nsIAsyncInputStream.h"
      22             : #include "nsIAsyncOutputStream.h"
      23             : #include "nsIIPCSerializableInputStream.h"
      24             : #include "nsQueryObject.h"
      25             : #include "nsPromiseFlatString.h"
      26             : #include "nsStreamUtils.h"
      27             : #include "nsString.h"
      28             : #include "nsURLParsers.h"
      29             : #include "nsCRT.h"
      30             : #include "nsHttp.h"
      31             : 
      32             : namespace mozilla {
      33             : namespace dom {
      34             : namespace cache {
      35             : 
      36             : using mozilla::ipc::AutoIPCStream;
      37             : using mozilla::ipc::BackgroundChild;
      38             : using mozilla::ipc::FileDescriptor;
      39             : using mozilla::ipc::PBackgroundChild;
      40             : using mozilla::ipc::PFileDescriptorSetChild;
      41             : 
      42             : namespace {
      43             : 
      44             : static bool
      45           0 : HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
      46             : {
      47           0 :   nsCString varyHeaders;
      48           0 :   ErrorResult rv;
      49           0 :   aHeaders->Get(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
      50           0 :   MOZ_ALWAYS_TRUE(!rv.Failed());
      51             : 
      52           0 :   char* rawBuffer = varyHeaders.BeginWriting();
      53           0 :   char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
      54           0 :   for (; token;
      55           0 :        token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
      56           0 :     nsDependentCString header(token);
      57           0 :     if (header.EqualsLiteral("*")) {
      58           0 :       return true;
      59             :     }
      60             :   }
      61           0 :   return false;
      62             : }
      63             : 
      64             : void
      65           0 : ToHeadersEntryList(nsTArray<HeadersEntry>& aOut, InternalHeaders* aHeaders)
      66             : {
      67           0 :   MOZ_DIAGNOSTIC_ASSERT(aHeaders);
      68             : 
      69           0 :   AutoTArray<InternalHeaders::Entry, 16> entryList;
      70           0 :   aHeaders->GetEntries(entryList);
      71             : 
      72           0 :   for (uint32_t i = 0; i < entryList.Length(); ++i) {
      73           0 :     InternalHeaders::Entry& entry = entryList[i];
      74           0 :     aOut.AppendElement(HeadersEntry(entry.mName, entry.mValue));
      75             :   }
      76           0 : }
      77             : 
      78             : } // namespace
      79             : 
      80             : already_AddRefed<InternalRequest>
      81           0 : TypeUtils::ToInternalRequest(const RequestOrUSVString& aIn,
      82             :                              BodyAction aBodyAction, ErrorResult& aRv)
      83             : {
      84           0 :   if (aIn.IsRequest()) {
      85           0 :     Request& request = aIn.GetAsRequest();
      86             : 
      87             :     // Check and set bodyUsed flag immediately because its on Request
      88             :     // instead of InternalRequest.
      89           0 :     CheckAndSetBodyUsed(&request, aBodyAction, aRv);
      90           0 :     if (aRv.Failed()) { return nullptr; }
      91             : 
      92           0 :     return request.GetInternalRequest();
      93             :   }
      94             : 
      95           0 :   return ToInternalRequest(aIn.GetAsUSVString(), aRv);
      96             : }
      97             : 
      98             : already_AddRefed<InternalRequest>
      99           0 : TypeUtils::ToInternalRequest(const OwningRequestOrUSVString& aIn,
     100             :                              BodyAction aBodyAction, ErrorResult& aRv)
     101             : {
     102             : 
     103           0 :   if (aIn.IsRequest()) {
     104           0 :     RefPtr<Request> request = aIn.GetAsRequest().get();
     105             : 
     106             :     // Check and set bodyUsed flag immediately because its on Request
     107             :     // instead of InternalRequest.
     108           0 :     CheckAndSetBodyUsed(request, aBodyAction, aRv);
     109           0 :     if (aRv.Failed()) { return nullptr; }
     110             : 
     111           0 :     return request->GetInternalRequest();
     112             :   }
     113             : 
     114           0 :   return ToInternalRequest(aIn.GetAsUSVString(), aRv);
     115             : }
     116             : 
     117             : void
     118           0 : TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
     119             :                           BodyAction aBodyAction, SchemeAction aSchemeAction,
     120             :                           nsTArray<UniquePtr<AutoIPCStream>>& aStreamCleanupList,
     121             :                           ErrorResult& aRv)
     122             : {
     123           0 :   MOZ_DIAGNOSTIC_ASSERT(aIn);
     124           0 :   aIn->GetMethod(aOut.method());
     125           0 :   nsCString url(aIn->GetURLWithoutFragment());
     126             :   bool schemeValid;
     127           0 :   ProcessURL(url, &schemeValid, &aOut.urlWithoutQuery(), &aOut.urlQuery(), aRv);
     128           0 :   if (aRv.Failed()) {
     129           0 :     return;
     130             :   }
     131           0 :   if (!schemeValid) {
     132           0 :     if (aSchemeAction == TypeErrorOnInvalidScheme) {
     133           0 :       NS_ConvertUTF8toUTF16 urlUTF16(url);
     134           0 :       aRv.ThrowTypeError<MSG_INVALID_URL_SCHEME>(NS_LITERAL_STRING("Request"),
     135           0 :                                                  urlUTF16);
     136           0 :       return;
     137             :     }
     138             :   }
     139           0 :   aOut.urlFragment() = aIn->GetFragment();
     140             : 
     141           0 :   aIn->GetReferrer(aOut.referrer());
     142           0 :   aOut.referrerPolicy() = aIn->ReferrerPolicy_();
     143           0 :   RefPtr<InternalHeaders> headers = aIn->Headers();
     144           0 :   MOZ_DIAGNOSTIC_ASSERT(headers);
     145           0 :   ToHeadersEntryList(aOut.headers(), headers);
     146           0 :   aOut.headersGuard() = headers->Guard();
     147           0 :   aOut.mode() = aIn->Mode();
     148           0 :   aOut.credentials() = aIn->GetCredentialsMode();
     149           0 :   aOut.contentPolicyType() = aIn->ContentPolicyType();
     150           0 :   aOut.requestCache() = aIn->GetCacheMode();
     151           0 :   aOut.requestRedirect() = aIn->GetRedirectMode();
     152             : 
     153           0 :   aOut.integrity() = aIn->GetIntegrity();
     154             : 
     155           0 :   if (aBodyAction == IgnoreBody) {
     156           0 :     aOut.body() = void_t();
     157           0 :     return;
     158             :   }
     159             : 
     160             :   // BodyUsed flag is checked and set previously in ToInternalRequest()
     161             : 
     162           0 :   nsCOMPtr<nsIInputStream> stream;
     163           0 :   aIn->GetBody(getter_AddRefs(stream));
     164           0 :   SerializeCacheStream(stream, &aOut.body(), aStreamCleanupList, aRv);
     165           0 :   if (NS_WARN_IF(aRv.Failed())) {
     166           0 :     return;
     167             :   }
     168             : }
     169             : 
     170             : void
     171           0 : TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
     172             :                                       InternalResponse& aIn, ErrorResult& aRv)
     173             : {
     174           0 :   aOut.type() = aIn.Type();
     175             : 
     176           0 :   aIn.GetUnfilteredURLList(aOut.urlList());
     177           0 :   AutoTArray<nsCString, 4> urlList;
     178           0 :   aIn.GetURLList(urlList);
     179             : 
     180           0 :   for (uint32_t i = 0; i < aOut.urlList().Length(); i++) {
     181           0 :     MOZ_DIAGNOSTIC_ASSERT(!aOut.urlList()[i].IsEmpty());
     182             :     // Pass all Response URL schemes through... The spec only requires we take
     183             :     // action on invalid schemes for Request objects.
     184           0 :     ProcessURL(aOut.urlList()[i], nullptr, nullptr, nullptr, aRv);
     185             :   }
     186             : 
     187           0 :   aOut.status() = aIn.GetUnfilteredStatus();
     188           0 :   aOut.statusText() = aIn.GetUnfilteredStatusText();
     189           0 :   RefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
     190           0 :   MOZ_DIAGNOSTIC_ASSERT(headers);
     191           0 :   if (HasVaryStar(headers)) {
     192           0 :     aRv.ThrowTypeError<MSG_RESPONSE_HAS_VARY_STAR>();
     193           0 :     return;
     194             :   }
     195           0 :   ToHeadersEntryList(aOut.headers(), headers);
     196           0 :   aOut.headersGuard() = headers->Guard();
     197           0 :   aOut.channelInfo() = aIn.GetChannelInfo().AsIPCChannelInfo();
     198           0 :   if (aIn.GetPrincipalInfo()) {
     199           0 :     aOut.principalInfo() = *aIn.GetPrincipalInfo();
     200             :   } else {
     201           0 :     aOut.principalInfo() = void_t();
     202             :   }
     203             : }
     204             : 
     205             : void
     206           0 : TypeUtils::ToCacheResponse(CacheResponse& aOut, Response& aIn,
     207             :                            nsTArray<UniquePtr<AutoIPCStream>>& aStreamCleanupList,
     208             :                            ErrorResult& aRv)
     209             : {
     210           0 :   if (aIn.BodyUsed()) {
     211           0 :     aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
     212           0 :     return;
     213             :   }
     214             : 
     215           0 :   RefPtr<InternalResponse> ir = aIn.GetInternalResponse();
     216           0 :   ToCacheResponseWithoutBody(aOut, *ir, aRv);
     217           0 :   if (NS_WARN_IF(aRv.Failed())) {
     218           0 :     return;
     219             :   }
     220             : 
     221           0 :   nsCOMPtr<nsIInputStream> stream;
     222           0 :   ir->GetUnfilteredBody(getter_AddRefs(stream));
     223           0 :   if (stream) {
     224           0 :     aIn.SetBodyUsed();
     225             :   }
     226             : 
     227           0 :   SerializeCacheStream(stream, &aOut.body(), aStreamCleanupList, aRv);
     228           0 :   if (NS_WARN_IF(aRv.Failed())) {
     229           0 :     return;
     230             :   }
     231             : }
     232             : 
     233             : // static
     234             : void
     235           0 : TypeUtils::ToCacheQueryParams(CacheQueryParams& aOut,
     236             :                               const CacheQueryOptions& aIn)
     237             : {
     238           0 :   aOut.ignoreSearch() = aIn.mIgnoreSearch;
     239           0 :   aOut.ignoreMethod() = aIn.mIgnoreMethod;
     240           0 :   aOut.ignoreVary() = aIn.mIgnoreVary;
     241           0 :   aOut.cacheNameSet() = aIn.mCacheName.WasPassed();
     242           0 :   if (aOut.cacheNameSet()) {
     243           0 :     aOut.cacheName() = aIn.mCacheName.Value();
     244             :   } else {
     245           0 :     aOut.cacheName() = NS_LITERAL_STRING("");
     246             :   }
     247           0 : }
     248             : 
     249             : already_AddRefed<Response>
     250           0 : TypeUtils::ToResponse(const CacheResponse& aIn)
     251             : {
     252           0 :   if (aIn.type() == ResponseType::Error) {
     253           0 :     RefPtr<InternalResponse> error = InternalResponse::NetworkError();
     254           0 :     RefPtr<Response> r = new Response(GetGlobalObject(), error);
     255           0 :     return r.forget();
     256             :   }
     257             : 
     258           0 :   RefPtr<InternalResponse> ir = new InternalResponse(aIn.status(),
     259           0 :                                                        aIn.statusText());
     260           0 :   ir->SetURLList(aIn.urlList());
     261             : 
     262             :   RefPtr<InternalHeaders> internalHeaders =
     263           0 :     ToInternalHeaders(aIn.headers(), aIn.headersGuard());
     264           0 :   ErrorResult result;
     265             : 
     266             :   // Be careful to fill the headers before setting the guard in order to
     267             :   // correctly re-create the original headers.
     268           0 :   ir->Headers()->Fill(*internalHeaders, result);
     269           0 :   MOZ_DIAGNOSTIC_ASSERT(!result.Failed());
     270           0 :   ir->Headers()->SetGuard(aIn.headersGuard(), result);
     271           0 :   MOZ_DIAGNOSTIC_ASSERT(!result.Failed());
     272             : 
     273           0 :   ir->InitChannelInfo(aIn.channelInfo());
     274           0 :   if (aIn.principalInfo().type() == mozilla::ipc::OptionalPrincipalInfo::TPrincipalInfo) {
     275           0 :     UniquePtr<mozilla::ipc::PrincipalInfo> info(new mozilla::ipc::PrincipalInfo(aIn.principalInfo().get_PrincipalInfo()));
     276           0 :     ir->SetPrincipalInfo(Move(info));
     277             :   }
     278             : 
     279           0 :   nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
     280           0 :   ir->SetBody(stream, InternalResponse::UNKNOWN_BODY_SIZE);
     281             : 
     282           0 :   switch (aIn.type())
     283             :   {
     284             :     case ResponseType::Basic:
     285           0 :       ir = ir->BasicResponse();
     286           0 :       break;
     287             :     case ResponseType::Cors:
     288           0 :       ir = ir->CORSResponse();
     289           0 :       break;
     290             :     case ResponseType::Default:
     291           0 :       break;
     292             :     case ResponseType::Opaque:
     293           0 :       ir = ir->OpaqueResponse();
     294           0 :       break;
     295             :     case ResponseType::Opaqueredirect:
     296           0 :       ir = ir->OpaqueRedirectResponse();
     297           0 :       break;
     298             :     default:
     299           0 :       MOZ_CRASH("Unexpected ResponseType!");
     300             :   }
     301           0 :   MOZ_DIAGNOSTIC_ASSERT(ir);
     302             : 
     303           0 :   RefPtr<Response> ref = new Response(GetGlobalObject(), ir);
     304           0 :   return ref.forget();
     305             : }
     306             : already_AddRefed<InternalRequest>
     307           0 : TypeUtils::ToInternalRequest(const CacheRequest& aIn)
     308             : {
     309           0 :   nsAutoCString url(aIn.urlWithoutQuery());
     310           0 :   url.Append(aIn.urlQuery());
     311             :   RefPtr<InternalRequest> internalRequest =
     312           0 :     new InternalRequest(url, aIn.urlFragment());
     313           0 :   internalRequest->SetMethod(aIn.method());
     314           0 :   internalRequest->SetReferrer(aIn.referrer());
     315           0 :   internalRequest->SetReferrerPolicy(aIn.referrerPolicy());
     316           0 :   internalRequest->SetMode(aIn.mode());
     317           0 :   internalRequest->SetCredentialsMode(aIn.credentials());
     318           0 :   internalRequest->SetContentPolicyType(aIn.contentPolicyType());
     319           0 :   internalRequest->SetCacheMode(aIn.requestCache());
     320           0 :   internalRequest->SetRedirectMode(aIn.requestRedirect());
     321           0 :   internalRequest->SetIntegrity(aIn.integrity());
     322             : 
     323             :   RefPtr<InternalHeaders> internalHeaders =
     324           0 :     ToInternalHeaders(aIn.headers(), aIn.headersGuard());
     325           0 :   ErrorResult result;
     326             : 
     327             :   // Be careful to fill the headers before setting the guard in order to
     328             :   // correctly re-create the original headers.
     329           0 :   internalRequest->Headers()->Fill(*internalHeaders, result);
     330           0 :   MOZ_DIAGNOSTIC_ASSERT(!result.Failed());
     331             : 
     332           0 :   internalRequest->Headers()->SetGuard(aIn.headersGuard(), result);
     333           0 :   MOZ_DIAGNOSTIC_ASSERT(!result.Failed());
     334             : 
     335           0 :   nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
     336             : 
     337           0 :   internalRequest->SetBody(stream);
     338             : 
     339           0 :   return internalRequest.forget();
     340             : }
     341             : 
     342             : already_AddRefed<Request>
     343           0 : TypeUtils::ToRequest(const CacheRequest& aIn)
     344             : {
     345           0 :   RefPtr<InternalRequest> internalRequest = ToInternalRequest(aIn);
     346           0 :   RefPtr<Request> request = new Request(GetGlobalObject(), internalRequest);
     347           0 :   return request.forget();
     348             : }
     349             : 
     350             : // static
     351             : already_AddRefed<InternalHeaders>
     352           0 : TypeUtils::ToInternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
     353             :                              HeadersGuardEnum aGuard)
     354             : {
     355           0 :   nsTArray<InternalHeaders::Entry> entryList(aHeadersEntryList.Length());
     356             : 
     357           0 :   for (uint32_t i = 0; i < aHeadersEntryList.Length(); ++i) {
     358           0 :     const HeadersEntry& headersEntry = aHeadersEntryList[i];
     359           0 :     entryList.AppendElement(InternalHeaders::Entry(headersEntry.name(),
     360           0 :                                                    headersEntry.value()));
     361             :   }
     362             : 
     363           0 :   RefPtr<InternalHeaders> ref = new InternalHeaders(Move(entryList), aGuard);
     364           0 :   return ref.forget();
     365             : }
     366             : 
     367             : // Utility function to remove the fragment from a URL, check its scheme, and optionally
     368             : // provide a URL without the query.  We're not using nsIURL or URL to do this because
     369             : // they require going to the main thread.
     370             : // static
     371             : void
     372           0 : TypeUtils::ProcessURL(nsACString& aUrl, bool* aSchemeValidOut,
     373             :                       nsACString* aUrlWithoutQueryOut,nsACString* aUrlQueryOut,
     374             :                       ErrorResult& aRv)
     375             : {
     376           0 :   const nsCString& flatURL = PromiseFlatCString(aUrl);
     377           0 :   const char* url = flatURL.get();
     378             : 
     379             :   // off the main thread URL parsing using nsStdURLParser.
     380           0 :   nsCOMPtr<nsIURLParser> urlParser = new nsStdURLParser();
     381             : 
     382             :   uint32_t pathPos;
     383             :   int32_t pathLen;
     384             :   uint32_t schemePos;
     385             :   int32_t schemeLen;
     386           0 :   aRv = urlParser->ParseURL(url, flatURL.Length(), &schemePos, &schemeLen,
     387             :                             nullptr, nullptr,       // ignore authority
     388           0 :                             &pathPos, &pathLen);
     389           0 :   if (NS_WARN_IF(aRv.Failed())) { return; }
     390             : 
     391           0 :   if (aSchemeValidOut) {
     392           0 :     nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
     393           0 :     *aSchemeValidOut = scheme.LowerCaseEqualsLiteral("http") ||
     394           0 :                        scheme.LowerCaseEqualsLiteral("https");
     395             :   }
     396             : 
     397             :   uint32_t queryPos;
     398             :   int32_t queryLen;
     399             : 
     400           0 :   aRv = urlParser->ParsePath(url + pathPos, flatURL.Length() - pathPos,
     401             :                              nullptr, nullptr,               // ignore filepath
     402             :                              &queryPos, &queryLen,
     403           0 :                              nullptr, nullptr);
     404           0 :   if (NS_WARN_IF(aRv.Failed())) {
     405           0 :     return;
     406             :   }
     407             : 
     408           0 :   if (!aUrlWithoutQueryOut) {
     409           0 :     return;
     410             :   }
     411             : 
     412           0 :   MOZ_DIAGNOSTIC_ASSERT(aUrlQueryOut);
     413             : 
     414           0 :   if (queryLen < 0) {
     415           0 :     *aUrlWithoutQueryOut = aUrl;
     416           0 :     *aUrlQueryOut = EmptyCString();
     417           0 :     return;
     418             :   }
     419             : 
     420             :   // ParsePath gives us query position relative to the start of the path
     421           0 :   queryPos += pathPos;
     422             : 
     423           0 :   *aUrlWithoutQueryOut = Substring(aUrl, 0, queryPos - 1);
     424           0 :   *aUrlQueryOut = Substring(aUrl, queryPos - 1, queryLen + 1);
     425             : }
     426             : 
     427             : void
     428           0 : TypeUtils::CheckAndSetBodyUsed(Request* aRequest, BodyAction aBodyAction,
     429             :                                ErrorResult& aRv)
     430             : {
     431           0 :   MOZ_DIAGNOSTIC_ASSERT(aRequest);
     432             : 
     433           0 :   if (aBodyAction == IgnoreBody) {
     434           0 :     return;
     435             :   }
     436             : 
     437           0 :   if (aRequest->BodyUsed()) {
     438           0 :     aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
     439           0 :     return;
     440             :   }
     441             : 
     442           0 :   nsCOMPtr<nsIInputStream> stream;
     443           0 :   aRequest->GetBody(getter_AddRefs(stream));
     444           0 :   if (stream) {
     445           0 :     aRequest->SetBodyUsed();
     446             :   }
     447             : }
     448             : 
     449             : already_AddRefed<InternalRequest>
     450           0 : TypeUtils::ToInternalRequest(const nsAString& aIn, ErrorResult& aRv)
     451             : {
     452           0 :   RequestOrUSVString requestOrString;
     453           0 :   requestOrString.SetAsUSVString().Rebind(aIn.Data(), aIn.Length());
     454             : 
     455             :   // Re-create a GlobalObject stack object so we can use webidl Constructors.
     456           0 :   AutoJSAPI jsapi;
     457           0 :   if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) {
     458           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     459           0 :     return nullptr;
     460             :   }
     461           0 :   JSContext* cx = jsapi.cx();
     462           0 :   GlobalObject global(cx, GetGlobalObject()->GetGlobalJSObject());
     463           0 :   MOZ_DIAGNOSTIC_ASSERT(!global.Failed());
     464             : 
     465           0 :   RefPtr<Request> request = Request::Constructor(global, requestOrString,
     466           0 :                                                    RequestInit(), aRv);
     467           0 :   if (NS_WARN_IF(aRv.Failed())) { return nullptr; }
     468             : 
     469           0 :   return request->GetInternalRequest();
     470             : }
     471             : 
     472             : void
     473           0 : TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
     474             :                                 CacheReadStreamOrVoid* aStreamOut,
     475             :                                 nsTArray<UniquePtr<AutoIPCStream>>& aStreamCleanupList,
     476             :                                 ErrorResult& aRv)
     477             : {
     478           0 :   *aStreamOut = void_t();
     479           0 :   if (!aStream) {
     480           0 :     return;
     481             :   }
     482             : 
     483           0 :   RefPtr<ReadStream> controlled = do_QueryObject(aStream);
     484           0 :   if (controlled) {
     485           0 :     controlled->Serialize(aStreamOut, aStreamCleanupList, aRv);
     486           0 :     return;
     487             :   }
     488             : 
     489           0 :   *aStreamOut = CacheReadStream();
     490           0 :   CacheReadStream& cacheStream = aStreamOut->get_CacheReadStream();
     491             : 
     492           0 :   cacheStream.controlChild() = nullptr;
     493           0 :   cacheStream.controlParent() = nullptr;
     494             : 
     495           0 :   UniquePtr<AutoIPCStream> autoStream(new AutoIPCStream(cacheStream.stream()));
     496           0 :   autoStream->Serialize(aStream, GetIPCManager());
     497             : 
     498           0 :   aStreamCleanupList.AppendElement(Move(autoStream));
     499             : }
     500             : 
     501             : } // namespace cache
     502             : } // namespace dom
     503           9 : } // namespace mozilla

Generated by: LCOV version 1.13