public void GetLength()
    {
        var segments = new List <byte[]>();
        var body     = new CachedResponseBody(segments, 42);

        Assert.Equal(42, body.Length);
    }
    public void GetSegments()
    {
        var segments = new List <byte[]>();
        var body     = new CachedResponseBody(segments, 0);

        Assert.Same(segments, body.Segments);
    }
    public async Task TryServeFromCacheAsync_CachedResponseFound_Serves304IfPossible()
    {
        var cache      = new TestOutputCache();
        var sink       = new TestSink();
        var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider("BaseKey"));
        var context    = TestUtils.CreateTestContext(cache: cache);

        context.HttpContext.Request.Headers.IfNoneMatch = "*";
        middleware.TryGetRequestPolicies(context.HttpContext, out var policies);

        await OutputCacheEntryFormatter.StoreAsync("BaseKey",
                                                   new OutputCacheEntry()
        {
            Body    = new CachedResponseBody(new List <byte[]>(0), 0),
            Headers = new()
        },
    public async Task Copy_DoNothingWhenNoSegments()
    {
        var segments         = new List <byte[]>();
        var receivedSegments = new List <byte[]>();
        var body             = new CachedResponseBody(segments, 0);

        var pipe = new Pipe();

        using var cts = new CancellationTokenSource(_timeout);

        var receiverTask = ReceiveDataAsync(pipe.Reader, receivedSegments, cts.Token);
        var copyTask     = body.CopyToAsync(pipe.Writer, cts.Token).ContinueWith(_ => pipe.Writer.CompleteAsync());

        await Task.WhenAll(receiverTask, copyTask);

        Assert.Empty(receivedSegments);
    }
    public async Task Copy_SingleSegment()
    {
        var segments = new List <byte[]>
        {
            new byte[] { 1 }
        };
        var receivedSegments = new List <byte[]>();
        var body             = new CachedResponseBody(segments, 0);

        var pipe = new Pipe();

        using var cts = new CancellationTokenSource(_timeout);

        var receiverTask = ReceiveDataAsync(pipe.Reader, receivedSegments, cts.Token);
        var copyTask     = CopyDataAsync(body, pipe.Writer, cts.Token);

        await Task.WhenAll(receiverTask, copyTask);

        Assert.Equal(segments, receivedSegments);
    }
    public async Task Copy_MultipleSegments()
    {
        var segments = new List <byte[]>
        {
            new byte[] { 1 },
            new byte[] { 2, 3 }
        };
        var receivedSegments = new List <byte[]>();
        var body             = new CachedResponseBody(segments, 0);

        var pipe = new Pipe();

        using var cts = new CancellationTokenSource(_timeout);

        var receiverTask = ReceiveDataAsync(pipe.Reader, receivedSegments, cts.Token);
        var copyTask     = CopyDataAsync(body, pipe.Writer, cts.Token);

        await Task.WhenAll(receiverTask, copyTask);

        Assert.Equal(new byte[] { 1, 2, 3 }, receivedSegments.SelectMany(x => x).ToArray());
    }
    public static async ValueTask <OutputCacheEntry?> GetAsync(string key, IOutputCacheStore store, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(key);

        var content = await store.GetAsync(key, cancellationToken);

        if (content == null)
        {
            return(null);
        }

        var formatter = JsonSerializer.Deserialize(content, FormatterEntrySerializerContext.Default.FormatterEntry);

        if (formatter == null)
        {
            return(null);
        }

        var outputCacheEntry = new OutputCacheEntry
        {
            StatusCode = formatter.StatusCode,
            Created    = formatter.Created,
            Tags       = formatter.Tags,
            Headers    = new(),
            Body       = new CachedResponseBody(formatter.Body, formatter.Body.Sum(x => x.Length))
        };

        if (formatter.Headers != null)
        {
            foreach (var header in formatter.Headers)
            {
                outputCacheEntry.Headers.TryAdd(header.Key, header.Value);
            }
        }

        return(outputCacheEntry);
    }
    static async Task CopyDataAsync(CachedResponseBody body, PipeWriter writer, CancellationToken cancellationToken)
    {
        await body.CopyToAsync(writer, cancellationToken);

        await writer.CompleteAsync();
    }