private async Task SendResponse(HttpResponse response, MediaSegment mediaSegment)
        {
            response.StatusCode = 200;
            var length = mediaSegment.Length;

            if (mediaSegment.Complete)
            {
                response.ContentLength = mediaSegment.Length;
                _logger.LogWarning($"Sending full response for {mediaSegment.Path} length:{mediaSegment.Length} ");
            }
            else
            {
                _logger.LogWarning($"Chunked transfer encoding for {mediaSegment.Path}");
            }
            response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue
            {
                Public  = true,
                NoCache = true,
                NoStore = true
            };

            foreach (var index in mediaSegment.GetBufferIndex())
            {
                var cacheKey = mediaSegment.GetChunkKey(index);
                var buffer   = _cache.Get <MediaBuffer>(cacheKey);
                if (buffer == null)
                {
                    throw new InvalidOperationException($"Missing cache entry for {cacheKey}");
                }
                await response.Body.WriteAsync(buffer.Memory);

                await response.Body.FlushAsync();
            }
        }
        private async Task ReadBodyAsync(HttpRequest request, MediaSegment mediaSegment, bool expire)
        {
            int count = 0;

            while (true)
            {
                var(buffer, endOfStream) = await ReadBufferAsync(request);

                var cacheKey = mediaSegment.GetChunkKey(count++);
                var options  = new MemoryCacheEntryOptions
                {
                    SlidingExpiration = expire ? TimeSpan.FromSeconds(60) : (TimeSpan?)null,
                    Priority          = expire ? CacheItemPriority.Normal : CacheItemPriority.NeverRemove,
                    Size = BUFFER_SIZE
                };
                options.RegisterPostEvictionCallback(RemoveCacheEntry);
                _cache.Set <MediaBuffer>(cacheKey, buffer, options);
                _logger.LogDebug($"Got buffer of size: {buffer.Length} for {cacheKey} ");
                mediaSegment.AddBuffer(buffer.Length, endOfStream);
                if (endOfStream)
                {
                    break;
                }
            }
        }
        private MediaBuffer GetMediaBuffer(MediaSegment mediaSegment, int index)
        {
            var cacheKey = mediaSegment.GetChunkKey(index);
            var buffer   = _cache.Get <MediaBuffer>(cacheKey);

            if (buffer == null)
            {
                throw new InvalidOperationException($"Missing cache entry for {cacheKey}");
            }
            return(buffer);
        }