void
    WriteNetworkBufferToNewCache()
    {
        AssertIsOnMainThread();
        MOZ_ASSERT(mCN);
        MOZ_ASSERT(mCacheStorage);
        MOZ_ASSERT(mNewCacheName.IsEmpty());

        ErrorResult result;
        result = serviceWorkerScriptCache::GenerateCacheName(mNewCacheName);
        if (NS_WARN_IF(result.Failed())) {
            MOZ_ASSERT(!result.IsErrorWithMessage());
            Fail(result.StealNSResult());
            return;
        }

        RefPtr<Promise> cacheOpenPromise = mCacheStorage->Open(mNewCacheName, result);
        if (NS_WARN_IF(result.Failed())) {
            MOZ_ASSERT(!result.IsErrorWithMessage());
            Fail(result.StealNSResult());
            return;
        }

        cacheOpenPromise->AppendNativeHandler(this);
    }
  nsresult
  Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
             const nsAString& aCacheName, nsILoadGroup* aLoadGroup)
  {
    AssertIsOnMainThread();
    MOZ_ASSERT(aPrincipal);

    mURL = aURL;

    // Always create a CacheStorage since we want to write the network entry to
    // the cache even if there isn't an existing one.
    ErrorResult result;
    mCacheStorage = CreateCacheStorage(aPrincipal, result, getter_AddRefs(mSandbox));
    if (NS_WARN_IF(result.Failed())) {
      MOZ_ASSERT(!result.IsErrorWithMessage());
      return result.StealNSResult();
    }

    mCN = new CompareNetwork(this);
    nsresult rv = mCN->Initialize(aPrincipal, aURL, aLoadGroup);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }

    if (!aCacheName.IsEmpty()) {
      mCC = new CompareCache(this);
      rv = mCC->Initialize(aPrincipal, aURL, aCacheName);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        mCN->Abort();
        return rv;
      }
    }

    return NS_OK;
  }
  void
  WriteToCache(Cache* aCache)
  {
    AssertIsOnMainThread();
    MOZ_ASSERT(aCache);
    MOZ_ASSERT(mState == WaitingForOpen);

    ErrorResult result;
    nsCOMPtr<nsIInputStream> body;
    result = NS_NewCStringInputStream(getter_AddRefs(body),
                                      NS_ConvertUTF16toUTF8(mCN->Buffer()));
    if (NS_WARN_IF(result.Failed())) {
      MOZ_ASSERT(!result.IsErrorWithMessage());
      Fail(result.StealNSResult());
      return;
    }

    RefPtr<InternalResponse> ir =
      new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
    ir->SetBody(body, mCN->Buffer().Length());

    ir->InitChannelInfo(mChannelInfo);
    if (mPrincipalInfo) {
      ir->SetPrincipalInfo(Move(mPrincipalInfo));
    }

    RefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir);

    RequestOrUSVString request;
    request.SetAsUSVString().Rebind(URL().Data(), URL().Length());

    // For now we have to wait until the Put Promise is fulfilled before we can
    // continue since Cache does not yet support starting a read that is being
    // written to.
    RefPtr<Promise> cachePromise = aCache->Put(request, *response, result);
    if (NS_WARN_IF(result.Failed())) {
      MOZ_ASSERT(!result.IsErrorWithMessage());
      Fail(result.StealNSResult());
      return;
    }

    mState = WaitingForPut;
    cachePromise->AppendNativeHandler(this);
  }
nsresult
CompareCache::Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
                         const nsAString& aCacheName)
{
    MOZ_ASSERT(aPrincipal);
    AssertIsOnMainThread();

    mURL = aURL;

    ErrorResult rv;

    RefPtr<Promise> promise = mManager->CacheStorage_()->Open(aCacheName, rv);
    if (NS_WARN_IF(rv.Failed())) {
        MOZ_ASSERT(!rv.IsErrorWithMessage());
        return rv.StealNSResult();
    }

    promise->AppendNativeHandler(this);
    return NS_OK;
}