LCOV - code coverage report
Current view: top level - dom/cache - AutoUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 249 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 16 0.0 %
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/AutoUtils.h"
       8             : 
       9             : #include "mozilla/Unused.h"
      10             : #include "mozilla/dom/InternalHeaders.h"
      11             : #include "mozilla/dom/InternalRequest.h"
      12             : #include "mozilla/dom/cache/CacheParent.h"
      13             : #include "mozilla/dom/cache/CacheStreamControlParent.h"
      14             : #include "mozilla/dom/cache/ReadStream.h"
      15             : #include "mozilla/dom/cache/SavedTypes.h"
      16             : #include "mozilla/dom/cache/StreamList.h"
      17             : #include "mozilla/dom/cache/TypeUtils.h"
      18             : #include "mozilla/ipc/IPCStreamUtils.h"
      19             : #include "mozilla/ipc/PBackgroundParent.h"
      20             : #include "nsCRT.h"
      21             : #include "nsHttp.h"
      22             : 
      23             : using mozilla::Unused;
      24             : using mozilla::dom::cache::CacheReadStream;
      25             : using mozilla::dom::cache::CacheReadStreamOrVoid;
      26             : using mozilla::ipc::AutoIPCStream;
      27             : using mozilla::ipc::PBackgroundParent;
      28             : 
      29             : namespace {
      30             : 
      31             : enum CleanupAction
      32             : {
      33             :   Forget,
      34             :   Delete
      35             : };
      36             : 
      37             : void
      38           0 : CleanupChild(CacheReadStream& aReadStream, CleanupAction aAction)
      39             : {
      40             :   // fds cleaned up by mStreamCleanupList
      41             :   // PChildToParentStream actors cleaned up by mStreamCleanupList
      42           0 : }
      43             : 
      44             : void
      45           0 : CleanupChild(CacheReadStreamOrVoid& aReadStreamOrVoid, CleanupAction aAction)
      46             : {
      47           0 :   if (aReadStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) {
      48           0 :     return;
      49             :   }
      50             : 
      51           0 :   CleanupChild(aReadStreamOrVoid.get_CacheReadStream(), aAction);
      52             : }
      53             : 
      54             : } // namespace
      55             : 
      56             : namespace mozilla {
      57             : namespace dom {
      58             : namespace cache {
      59             : 
      60             : // --------------------------------------------
      61             : 
      62           0 : AutoChildOpArgs::AutoChildOpArgs(TypeUtils* aTypeUtils,
      63             :                                  const CacheOpArgs& aOpArgs,
      64           0 :                                  uint32_t aEntryCount)
      65             :   : mTypeUtils(aTypeUtils)
      66             :   , mOpArgs(aOpArgs)
      67           0 :   , mSent(false)
      68             : {
      69           0 :   MOZ_DIAGNOSTIC_ASSERT(mTypeUtils);
      70           0 :   MOZ_RELEASE_ASSERT(aEntryCount != 0);
      71             :   // We are using AutoIPCStream objects to cleanup target IPCStream
      72             :   // structures embedded in our CacheOpArgs.  These IPCStream structs
      73             :   // must not move once we attach our AutoIPCStream to them.  Therefore,
      74             :   // its important that any arrays containing streams are pre-sized for
      75             :   // the number of entries we have in order to avoid realloc moving
      76             :   // things around on us.
      77           0 :   if (mOpArgs.type() == CacheOpArgs::TCachePutAllArgs) {
      78           0 :     CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
      79           0 :     args.requestResponseList().SetCapacity(aEntryCount);
      80             :   } else {
      81           0 :     MOZ_DIAGNOSTIC_ASSERT(aEntryCount == 1);
      82             :   }
      83           0 : }
      84             : 
      85           0 : AutoChildOpArgs::~AutoChildOpArgs()
      86             : {
      87           0 :   CleanupAction action = mSent ? Forget : Delete;
      88             : 
      89           0 :   switch(mOpArgs.type()) {
      90             :     case CacheOpArgs::TCacheMatchArgs:
      91             :     {
      92           0 :       CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
      93           0 :       CleanupChild(args.request().body(), action);
      94           0 :       break;
      95             :     }
      96             :     case CacheOpArgs::TCacheMatchAllArgs:
      97             :     {
      98           0 :       CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
      99           0 :       if (args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t) {
     100           0 :         break;
     101             :       }
     102           0 :       CleanupChild(args.requestOrVoid().get_CacheRequest().body(), action);
     103           0 :       break;
     104             :     }
     105             :     case CacheOpArgs::TCachePutAllArgs:
     106             :     {
     107           0 :       CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
     108           0 :       auto& list = args.requestResponseList();
     109           0 :       for (uint32_t i = 0; i < list.Length(); ++i) {
     110           0 :         CleanupChild(list[i].request().body(), action);
     111           0 :         CleanupChild(list[i].response().body(), action);
     112             :       }
     113           0 :       break;
     114             :     }
     115             :     case CacheOpArgs::TCacheDeleteArgs:
     116             :     {
     117           0 :       CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
     118           0 :       CleanupChild(args.request().body(), action);
     119           0 :       break;
     120             :     }
     121             :     case CacheOpArgs::TCacheKeysArgs:
     122             :     {
     123           0 :       CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
     124           0 :       if (args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t) {
     125           0 :         break;
     126             :       }
     127           0 :       CleanupChild(args.requestOrVoid().get_CacheRequest().body(), action);
     128           0 :       break;
     129             :     }
     130             :     case CacheOpArgs::TStorageMatchArgs:
     131             :     {
     132           0 :       StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
     133           0 :       CleanupChild(args.request().body(), action);
     134           0 :       break;
     135             :     }
     136             :     default:
     137             :       // Other types do not need cleanup
     138           0 :       break;
     139             :   }
     140             : 
     141           0 :   mStreamCleanupList.Clear();
     142           0 : }
     143             : 
     144             : void
     145           0 : AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
     146             :                      SchemeAction aSchemeAction, ErrorResult& aRv)
     147             : {
     148           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     149             : 
     150           0 :   switch(mOpArgs.type()) {
     151             :     case CacheOpArgs::TCacheMatchArgs:
     152             :     {
     153           0 :       CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
     154           0 :       mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
     155           0 :                                  aSchemeAction, mStreamCleanupList, aRv);
     156           0 :       break;
     157             :     }
     158             :     case CacheOpArgs::TCacheMatchAllArgs:
     159             :     {
     160           0 :       CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
     161           0 :       MOZ_DIAGNOSTIC_ASSERT(args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t);
     162           0 :       args.requestOrVoid() = CacheRequest();
     163           0 :       mTypeUtils->ToCacheRequest(args.requestOrVoid().get_CacheRequest(),
     164             :                                  aRequest, aBodyAction, aSchemeAction,
     165           0 :                                  mStreamCleanupList, aRv);
     166           0 :       break;
     167             :     }
     168             :     case CacheOpArgs::TCacheDeleteArgs:
     169             :     {
     170           0 :       CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
     171           0 :       mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
     172           0 :                                  aSchemeAction, mStreamCleanupList, aRv);
     173           0 :       break;
     174             :     }
     175             :     case CacheOpArgs::TCacheKeysArgs:
     176             :     {
     177           0 :       CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
     178           0 :       MOZ_DIAGNOSTIC_ASSERT(args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t);
     179           0 :       args.requestOrVoid() = CacheRequest();
     180           0 :       mTypeUtils->ToCacheRequest(args.requestOrVoid().get_CacheRequest(),
     181             :                                   aRequest, aBodyAction, aSchemeAction,
     182           0 :                                   mStreamCleanupList, aRv);
     183           0 :       break;
     184             :     }
     185             :     case CacheOpArgs::TStorageMatchArgs:
     186             :     {
     187           0 :       StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
     188           0 :       mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
     189           0 :                                  aSchemeAction, mStreamCleanupList, aRv);
     190           0 :       break;
     191             :     }
     192             :     default:
     193           0 :       MOZ_CRASH("Cache args type cannot send a Request!");
     194             :   }
     195           0 : }
     196             : 
     197             : namespace {
     198             : 
     199             : bool
     200           0 : MatchInPutList(InternalRequest* aRequest,
     201             :                const nsTArray<CacheRequestResponse>& aPutList)
     202             : {
     203           0 :   MOZ_DIAGNOSTIC_ASSERT(aRequest);
     204             : 
     205             :   // This method implements the SW spec QueryCache algorithm against an
     206             :   // in memory array of Request/Response objects.  This essentially the
     207             :   // same algorithm that is implemented in DBSchema.cpp.  Unfortunately
     208             :   // we cannot unify them because when operating against the real database
     209             :   // we don't want to load all request/response objects into memory.
     210             : 
     211             :   // Note, we can skip the check for a invalid request method because
     212             :   // Cache should only call into here with a GET or HEAD.
     213             : #ifdef DEBUG
     214           0 :   nsAutoCString method;
     215           0 :   aRequest->GetMethod(method);
     216           0 :   MOZ_ASSERT(method.LowerCaseEqualsLiteral("get") ||
     217             :              method.LowerCaseEqualsLiteral("head"));
     218             : #endif
     219             : 
     220           0 :   RefPtr<InternalHeaders> requestHeaders = aRequest->Headers();
     221             : 
     222           0 :   for (uint32_t i = 0; i < aPutList.Length(); ++i) {
     223           0 :     const CacheRequest& cachedRequest = aPutList[i].request();
     224           0 :     const CacheResponse& cachedResponse = aPutList[i].response();
     225             : 
     226           0 :     nsAutoCString url;
     227           0 :     aRequest->GetURL(url);
     228             : 
     229           0 :     nsAutoCString requestUrl(cachedRequest.urlWithoutQuery());
     230           0 :     requestUrl.Append(cachedRequest.urlQuery());
     231             : 
     232             :     // If the URLs don't match, then just skip to the next entry.
     233           0 :     if (url != requestUrl) {
     234           0 :       continue;
     235             :     }
     236             : 
     237             :     RefPtr<InternalHeaders> cachedRequestHeaders =
     238           0 :       TypeUtils::ToInternalHeaders(cachedRequest.headers());
     239             : 
     240             :     RefPtr<InternalHeaders> cachedResponseHeaders =
     241           0 :       TypeUtils::ToInternalHeaders(cachedResponse.headers());
     242             : 
     243           0 :     nsCString varyHeaders;
     244           0 :     ErrorResult rv;
     245           0 :     cachedResponseHeaders->Get(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
     246           0 :     MOZ_ALWAYS_TRUE(!rv.Failed());
     247             : 
     248             :     // Assume the vary headers match until we find a conflict
     249           0 :     bool varyHeadersMatch = true;
     250             : 
     251           0 :     char* rawBuffer = varyHeaders.BeginWriting();
     252           0 :     char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
     253           0 :     for (; token;
     254           0 :          token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
     255           0 :       nsDependentCString header(token);
     256           0 :       MOZ_DIAGNOSTIC_ASSERT(!header.EqualsLiteral("*"),
     257             :                             "We should have already caught this in "
     258             :                             "TypeUtils::ToPCacheResponseWithoutBody()");
     259             : 
     260           0 :       ErrorResult headerRv;
     261           0 :       nsAutoCString value;
     262           0 :       requestHeaders->Get(header, value, headerRv);
     263           0 :       if (NS_WARN_IF(headerRv.Failed())) {
     264           0 :         headerRv.SuppressException();
     265           0 :         MOZ_DIAGNOSTIC_ASSERT(value.IsEmpty());
     266             :       }
     267             : 
     268           0 :       nsAutoCString cachedValue;
     269           0 :       cachedRequestHeaders->Get(header, cachedValue, headerRv);
     270           0 :       if (NS_WARN_IF(headerRv.Failed())) {
     271           0 :         headerRv.SuppressException();
     272           0 :         MOZ_DIAGNOSTIC_ASSERT(cachedValue.IsEmpty());
     273             :       }
     274             : 
     275           0 :       if (value != cachedValue) {
     276           0 :         varyHeadersMatch = false;
     277           0 :         break;
     278             :       }
     279             :     }
     280             : 
     281             :     // URL was equal and all vary headers match!
     282           0 :     if (varyHeadersMatch) {
     283           0 :       return true;
     284             :     }
     285             :   }
     286             : 
     287           0 :   return false;
     288             : }
     289             : 
     290             : } // namespace
     291             : 
     292             : void
     293           0 : AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
     294             :                      SchemeAction aSchemeAction, Response& aResponse,
     295             :                      ErrorResult& aRv)
     296             : {
     297           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     298             : 
     299           0 :   switch(mOpArgs.type()) {
     300             :     case CacheOpArgs::TCachePutAllArgs:
     301             :     {
     302           0 :       CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
     303             : 
     304             :       // Throw an error if a request/response pair would mask another
     305             :       // request/response pair in the same PutAll operation.  This is
     306             :       // step 2.3.2.3 from the "Batch Cache Operations" spec algorithm.
     307           0 :       if (MatchInPutList(aRequest, args.requestResponseList())) {
     308           0 :         aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     309           0 :         return;
     310             :       }
     311             : 
     312             :       // Ensure that we don't realloc the array since this can result
     313             :       // in our AutoIPCStream objects to reference the wrong memory
     314             :       // location.  This should never happen and is a UAF if it does.
     315             :       // Therefore make this a release assertion.
     316           0 :       MOZ_RELEASE_ASSERT(args.requestResponseList().Length() <
     317             :                          args.requestResponseList().Capacity());
     318             : 
     319             :       // The FileDescriptorSetChild asserts in its destructor that all fds have
     320             :       // been removed.  The copy constructor, however, simply duplicates the
     321             :       // fds without removing any.  This means each temporary and copy must be
     322             :       // explicitly cleaned up.
     323             :       //
     324             :       // Avoid a lot of this hassle by making sure we only create one here.  On
     325             :       // error we remove it.
     326           0 :       CacheRequestResponse& pair = *args.requestResponseList().AppendElement();
     327           0 :       pair.request().body() = void_t();
     328           0 :       pair.response().body() = void_t();
     329             : 
     330           0 :       mTypeUtils->ToCacheRequest(pair.request(), aRequest, aBodyAction,
     331           0 :                                  aSchemeAction, mStreamCleanupList, aRv);
     332           0 :       if (!aRv.Failed()) {
     333           0 :         mTypeUtils->ToCacheResponse(pair.response(), aResponse,
     334           0 :                                     mStreamCleanupList, aRv);
     335             :       }
     336             : 
     337           0 :       if (aRv.Failed()) {
     338           0 :         CleanupChild(pair.request().body(), Delete);
     339           0 :         args.requestResponseList().RemoveElementAt(
     340           0 :           args.requestResponseList().Length() - 1);
     341             :       }
     342             : 
     343           0 :       break;
     344             :     }
     345             :     default:
     346           0 :       MOZ_CRASH("Cache args type cannot send a Request/Response pair!");
     347             :   }
     348             : }
     349             : 
     350             : const CacheOpArgs&
     351           0 : AutoChildOpArgs::SendAsOpArgs()
     352             : {
     353           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     354           0 :   mSent = true;
     355           0 :   for (UniquePtr<AutoIPCStream>& autoStream : mStreamCleanupList) {
     356           0 :     autoStream->TakeValue();
     357             :   }
     358           0 :   return mOpArgs;
     359             : }
     360             : 
     361             : // --------------------------------------------
     362             : 
     363           0 : AutoParentOpResult::AutoParentOpResult(mozilla::ipc::PBackgroundParent* aManager,
     364             :                                        const CacheOpResult& aOpResult,
     365           0 :                                        uint32_t aEntryCount)
     366             :   : mManager(aManager)
     367             :   , mOpResult(aOpResult)
     368             :   , mStreamControl(nullptr)
     369           0 :   , mSent(false)
     370             : {
     371           0 :   MOZ_DIAGNOSTIC_ASSERT(mManager);
     372           0 :   MOZ_RELEASE_ASSERT(aEntryCount != 0);
     373             :   // We are using AutoIPCStream objects to cleanup target IPCStream
     374             :   // structures embedded in our CacheOpArgs.  These IPCStream structs
     375             :   // must not move once we attach our AutoIPCStream to them.  Therefore,
     376             :   // its important that any arrays containing streams are pre-sized for
     377             :   // the number of entries we have in order to avoid realloc moving
     378             :   // things around on us.
     379           0 :   if (mOpResult.type() == CacheOpResult::TCacheMatchAllResult) {
     380           0 :     CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
     381           0 :     result.responseList().SetCapacity(aEntryCount);
     382           0 :   } else if (mOpResult.type() == CacheOpResult::TCacheKeysResult) {
     383           0 :     CacheKeysResult& result = mOpResult.get_CacheKeysResult();
     384           0 :     result.requestList().SetCapacity(aEntryCount);
     385             :   } else {
     386           0 :     MOZ_DIAGNOSTIC_ASSERT(aEntryCount == 1);
     387             :   }
     388           0 : }
     389             : 
     390           0 : AutoParentOpResult::~AutoParentOpResult()
     391             : {
     392           0 :   CleanupAction action = mSent ? Forget : Delete;
     393             : 
     394           0 :   switch (mOpResult.type()) {
     395             :     case CacheOpResult::TStorageOpenResult:
     396             :     {
     397           0 :       StorageOpenResult& result = mOpResult.get_StorageOpenResult();
     398           0 :       if (action == Forget || result.actorParent() == nullptr) {
     399           0 :         break;
     400             :       }
     401           0 :       Unused << PCacheParent::Send__delete__(result.actorParent());
     402           0 :       break;
     403             :     }
     404             :     default:
     405             :       // other types do not need additional clean up
     406           0 :       break;
     407             :   }
     408             : 
     409           0 :   if (action == Delete && mStreamControl) {
     410           0 :     Unused << PCacheStreamControlParent::Send__delete__(mStreamControl);
     411             :   }
     412             : 
     413           0 :   mStreamCleanupList.Clear();
     414           0 : }
     415             : 
     416             : void
     417           0 : AutoParentOpResult::Add(CacheId aOpenedCacheId, Manager* aManager)
     418             : {
     419           0 :   MOZ_DIAGNOSTIC_ASSERT(mOpResult.type() == CacheOpResult::TStorageOpenResult);
     420           0 :   MOZ_DIAGNOSTIC_ASSERT(mOpResult.get_StorageOpenResult().actorParent() == nullptr);
     421           0 :   mOpResult.get_StorageOpenResult().actorParent() =
     422           0 :     mManager->SendPCacheConstructor(new CacheParent(aManager, aOpenedCacheId));
     423           0 : }
     424             : 
     425             : void
     426           0 : AutoParentOpResult::Add(const SavedResponse& aSavedResponse,
     427             :                         StreamList* aStreamList)
     428             : {
     429           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     430             : 
     431           0 :   switch (mOpResult.type()) {
     432             :     case CacheOpResult::TCacheMatchResult:
     433             :     {
     434           0 :       CacheMatchResult& result = mOpResult.get_CacheMatchResult();
     435           0 :       MOZ_DIAGNOSTIC_ASSERT(result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t);
     436           0 :       result.responseOrVoid() = aSavedResponse.mValue;
     437             :       SerializeResponseBody(aSavedResponse, aStreamList,
     438           0 :                             &result.responseOrVoid().get_CacheResponse());
     439           0 :       break;
     440             :     }
     441             :     case CacheOpResult::TCacheMatchAllResult:
     442             :     {
     443           0 :       CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
     444             :       // Ensure that we don't realloc the array since this can result
     445             :       // in our AutoIPCStream objects to reference the wrong memory
     446             :       // location.  This should never happen and is a UAF if it does.
     447             :       // Therefore make this a release assertion.
     448           0 :       MOZ_RELEASE_ASSERT(result.responseList().Length() <
     449             :                          result.responseList().Capacity());
     450           0 :       result.responseList().AppendElement(aSavedResponse.mValue);
     451             :       SerializeResponseBody(aSavedResponse, aStreamList,
     452           0 :                             &result.responseList().LastElement());
     453           0 :       break;
     454             :     }
     455             :     case CacheOpResult::TStorageMatchResult:
     456             :     {
     457           0 :       StorageMatchResult& result = mOpResult.get_StorageMatchResult();
     458           0 :       MOZ_DIAGNOSTIC_ASSERT(result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t);
     459           0 :       result.responseOrVoid() = aSavedResponse.mValue;
     460             :       SerializeResponseBody(aSavedResponse, aStreamList,
     461           0 :                             &result.responseOrVoid().get_CacheResponse());
     462           0 :       break;
     463             :     }
     464             :     default:
     465           0 :       MOZ_CRASH("Cache result type cannot handle returning a Response!");
     466             :   }
     467           0 : }
     468             : 
     469             : void
     470           0 : AutoParentOpResult::Add(const SavedRequest& aSavedRequest,
     471             :                         StreamList* aStreamList)
     472             : {
     473           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     474             : 
     475           0 :   switch (mOpResult.type()) {
     476             :     case CacheOpResult::TCacheKeysResult:
     477             :     {
     478           0 :       CacheKeysResult& result = mOpResult.get_CacheKeysResult();
     479             :       // Ensure that we don't realloc the array since this can result
     480             :       // in our AutoIPCStream objects to reference the wrong memory
     481             :       // location.  This should never happen and is a UAF if it does.
     482             :       // Therefore make this a release assertion.
     483           0 :       MOZ_RELEASE_ASSERT(result.requestList().Length() <
     484             :                          result.requestList().Capacity());
     485           0 :       result.requestList().AppendElement(aSavedRequest.mValue);
     486           0 :       CacheRequest& request = result.requestList().LastElement();
     487             : 
     488           0 :       if (!aSavedRequest.mHasBodyId) {
     489           0 :         request.body() = void_t();
     490           0 :         break;
     491             :       }
     492             : 
     493           0 :       request.body() = CacheReadStream();
     494           0 :       SerializeReadStream(aSavedRequest.mBodyId, aStreamList,
     495           0 :                           &request.body().get_CacheReadStream());
     496           0 :       break;
     497             :     }
     498             :     default:
     499           0 :       MOZ_CRASH("Cache result type cannot handle returning a Request!");
     500             :   }
     501           0 : }
     502             : 
     503             : const CacheOpResult&
     504           0 : AutoParentOpResult::SendAsOpResult()
     505             : {
     506           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     507           0 :   mSent = true;
     508           0 :   for (UniquePtr<AutoIPCStream>& autoStream : mStreamCleanupList) {
     509           0 :     autoStream->TakeValue();
     510             :   }
     511           0 :   return mOpResult;
     512             : }
     513             : 
     514             : void
     515           0 : AutoParentOpResult::SerializeResponseBody(const SavedResponse& aSavedResponse,
     516             :                                           StreamList* aStreamList,
     517             :                                           CacheResponse* aResponseOut)
     518             : {
     519           0 :   MOZ_DIAGNOSTIC_ASSERT(aResponseOut);
     520             : 
     521           0 :   if (!aSavedResponse.mHasBodyId) {
     522           0 :     aResponseOut->body() = void_t();
     523           0 :     return;
     524             :   }
     525             : 
     526           0 :   aResponseOut->body() = CacheReadStream();
     527           0 :   SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
     528           0 :                       &aResponseOut->body().get_CacheReadStream());
     529             : }
     530             : 
     531             : void
     532           0 : AutoParentOpResult::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
     533             :                                         CacheReadStream* aReadStreamOut)
     534             : {
     535           0 :   MOZ_DIAGNOSTIC_ASSERT(aStreamList);
     536           0 :   MOZ_DIAGNOSTIC_ASSERT(aReadStreamOut);
     537           0 :   MOZ_DIAGNOSTIC_ASSERT(!mSent);
     538             : 
     539           0 :   nsCOMPtr<nsIInputStream> stream = aStreamList->Extract(aId);
     540           0 :   MOZ_DIAGNOSTIC_ASSERT(stream);
     541             : 
     542           0 :   if (!mStreamControl) {
     543           0 :     mStreamControl = static_cast<CacheStreamControlParent*>(
     544           0 :       mManager->SendPCacheStreamControlConstructor(new CacheStreamControlParent()));
     545             : 
     546             :     // If this failed, then the child process is gone.  Warn and allow actor
     547             :     // cleanup to proceed as normal.
     548           0 :     if (!mStreamControl) {
     549           0 :       NS_WARNING("Cache failed to create stream control actor.");
     550           0 :       return;
     551             :     }
     552             :   }
     553             : 
     554           0 :   aStreamList->SetStreamControl(mStreamControl);
     555             : 
     556           0 :   RefPtr<ReadStream> readStream = ReadStream::Create(mStreamControl,
     557           0 :                                                      aId, stream);
     558           0 :   ErrorResult rv;
     559           0 :   readStream->Serialize(aReadStreamOut, mStreamCleanupList, rv);
     560           0 :   MOZ_DIAGNOSTIC_ASSERT(!rv.Failed());
     561             : }
     562             : 
     563             : } // namespace cache
     564             : } // namespace dom
     565             : } // namespace mozilla

Generated by: LCOV version 1.13