예제 #1
0
        public async Task <IActionResult> GetAssetContent(DomainId id, AssetContentQueryDto request)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindGlobalAsync(requestContext, id, HttpContext.RequestAborted);

            return(await DeliverAssetAsync(requestContext, asset, request));
        }
예제 #2
0
        public async Task <IActionResult> GetAssetContent(DomainId id, [FromQuery] AssetContentQueryDto queries)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindGlobalAsync(requestContext, id);

            return(await DeliverAssetAsync(requestContext, asset, queries));
        }
예제 #3
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, string more, [FromQuery] AssetContentQueryDto query)
        {
            IAssetEntity?asset;

            if (Guid.TryParse(idOrSlug, out var guid))
            {
                asset = await assetRepository.FindAssetAsync(guid);
            }
            else
            {
                asset = await assetRepository.FindAssetBySlugAsync(App.Id, idOrSlug);
            }

            return(await DeliverAssetAsync(asset, query));
        }
예제 #4
0
        private async Task <IActionResult> DeliverAssetAsync(IAssetEntity?asset, AssetContentQueryDto query)
        {
            query ??= new AssetContentQueryDto();

            if (asset == null)
            {
                return(NotFound());
            }

            if (asset.IsProtected && !Resources.CanReadEvents)
            {
                return(StatusCode(403));
            }

            if (query.Version > EtagVersion.Any && asset.Version != query.Version)
            {
                asset = await assetLoader.GetAsync(asset.Id, query.Version);
            }

            var resizeOptions = query.ToResizeOptions(asset);

            FileCallback callback;

            Response.Headers[HeaderNames.ETag] = asset.FileVersion.ToString();

            if (query.CacheDuration > 0)
            {
                Response.Headers[HeaderNames.CacheControl] = $"public,max-age={query.CacheDuration}";
            }

            var contentLength = (long?)null;

            if (asset.Type == AssetType.Image && resizeOptions.IsValid)
            {
                callback = new FileCallback(async(bodyStream, range, ct) =>
                {
                    var resizedAsset = $"{asset.Id}_{asset.FileVersion}_{resizeOptions}";

                    if (query.ForceResize)
                    {
                        await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, true, ct);
                    }
                    else
                    {
                        try
                        {
                            await assetStore.DownloadAsync(resizedAsset, bodyStream);
                        }
                        catch (AssetNotFoundException)
                        {
                            await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, false, ct);
                        }
                    }
                });
            }
            else
            {
                contentLength = asset.FileSize;

                callback = new FileCallback(async(bodyStream, range, ct) =>
                {
                    await assetFileStore.DownloadAsync(asset.Id, asset.FileVersion, bodyStream, range, ct);
                });
            }

            return(new FileCallbackResult(asset.MimeType, callback)
            {
                EnableRangeProcessing = contentLength > 0,
                ErrorAs404 = true,
                FileDownloadName = asset.FileName,
                FileSize = contentLength,
                LastModified = asset.LastModified.ToDateTimeOffset(),
                SendInline = query.Download != 1
            });
        }
예제 #5
0
        public async Task <IActionResult> GetAssetContent(Guid id, [FromQuery] AssetContentQueryDto query)
        {
            var asset = await assetRepository.FindAssetAsync(id);

            return(await DeliverAssetAsync(asset, query));
        }
예제 #6
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string?more = null)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindAsync(requestContext, DomainId.Create(idOrSlug));

            if (asset == null)
            {
                asset = await assetQuery.FindBySlugAsync(requestContext, idOrSlug);
            }

            return(await DeliverAssetAsync(requestContext, asset, queries));
        }
예제 #7
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, AssetContentQueryDto request, string?more = null)
        {
            var requestContext = Context.Clone(b => b.WithoutAssetEnrichment());

            var asset = await assetQuery.FindAsync(requestContext, DomainId.Create(idOrSlug), ct : HttpContext.RequestAborted);

            if (asset == null)
            {
                asset = await assetQuery.FindBySlugAsync(requestContext, idOrSlug, HttpContext.RequestAborted);
            }

            return(await DeliverAssetAsync(requestContext, asset, request));
        }
예제 #8
0
        private async Task <IActionResult> DeliverAssetAsync(Context context, IAssetEntity?asset, AssetContentQueryDto request)
        {
            request ??= new AssetContentQueryDto();

            if (asset == null)
            {
                return(NotFound());
            }

            if (asset.IsProtected && !Resources.CanReadAssets)
            {
                Response.Headers[HeaderNames.CacheControl] = "public,max-age=0";

                return(StatusCode(403));
            }

            if (asset != null && request.Version > EtagVersion.Any && asset.Version != request.Version)
            {
                if (context.App != null)
                {
                    asset = await assetQuery.FindAsync(context, asset.Id, request.Version, HttpContext.RequestAborted);
                }
                else
                {
                    // Fallback for old endpoint. Does not set the surrogate key.
                    asset = await assetLoader.GetAsync(asset.AppId.Id, asset.Id, request.Version);
                }
            }

            if (asset == null)
            {
                return(NotFound());
            }

            var resizeOptions = request.ToResizeOptions(asset);

            FileCallback callback;

            Response.Headers[HeaderNames.ETag] = asset.FileVersion.ToString();

            if (request.CacheDuration > 0)
            {
                Response.Headers[HeaderNames.CacheControl] = $"public,max-age={request.CacheDuration}";
            }

            var contentLength = (long?)null;

            if (asset.Type == AssetType.Image && resizeOptions.IsValid)
            {
                callback = async(bodyStream, range, ct) =>
                {
                    var resizedAsset = $"{asset.AppId.Id}_{asset.Id}_{asset.FileVersion}_{resizeOptions}";

                    if (request.ForceResize)
                    {
                        await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, true, ct);
                    }
                    else
                    {
                        try
                        {
                            await assetStore.DownloadAsync(resizedAsset, bodyStream, ct : ct);
                        }
                        catch (AssetNotFoundException)
                        {
                            await ResizeAsync(asset, bodyStream, resizedAsset, resizeOptions, false, ct);
                        }
                    }
                };
            }
            else
            {
                contentLength = asset.FileSize;

                callback = async(bodyStream, range, ct) =>
                {
                    await assetFileStore.DownloadAsync(asset.AppId.Id, asset.Id, asset.FileVersion, bodyStream, range, ct);
                };
            }

            return(new FileCallbackResult(asset.MimeType, callback)
            {
                EnableRangeProcessing = contentLength > 0,
                ErrorAs404 = true,
                FileDownloadName = asset.FileName,
                FileSize = contentLength,
                LastModified = asset.LastModified.ToDateTimeOffset(),
                SendInline = request.Download != 1
            });
        }
예제 #9
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string?more = null)
        {
            var asset = await assetRepository.FindAssetAsync(AppId, DomainId.Create(idOrSlug));

            if (asset == null)
            {
                asset = await assetRepository.FindAssetBySlugAsync(AppId, idOrSlug);
            }

            return(await DeliverAssetAsync(asset, queries));
        }
예제 #10
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string?more = null)
        {
            var asset = await assetRepository.FindAssetAsync(AppId, DomainId.Create(idOrSlug));

            if (asset == null)
            {
                asset = await assetRepository.FindAssetBySlugAsync(AppId, idOrSlug);
            }

            if (asset != null && queries.Version > EtagVersion.Any && asset.Version != queries.Version)
            {
                asset = await assetLoader.GetAsync(App.Id, asset.Id, queries.Version);
            }

            return(DeliverAsset(asset, queries));
        }
예제 #11
0
        public async Task <IActionResult> GetAssetContent(DomainId id, [FromQuery] AssetContentQueryDto queries)
        {
            var asset = await assetRepository.FindAssetAsync(id);

            return(DeliverAsset(asset, queries));
        }
예제 #12
0
        private IActionResult DeliverAsset(IAssetEntity?asset, AssetContentQueryDto query)
        {
            query ??= new AssetContentQueryDto();

            if (asset == null || asset.FileVersion < query.Version)
            {
                return(NotFound());
            }

            if (asset.IsProtected && !this.HasPermission(Permissions.AppAssetsRead))
            {
                return(StatusCode(403));
            }

            var fileVersion = query.Version;

            if (fileVersion <= EtagVersion.Any)
            {
                fileVersion = asset.FileVersion;
            }

            Response.Headers[HeaderNames.ETag] = fileVersion.ToString();

            if (query.CacheDuration > 0)
            {
                Response.Headers[HeaderNames.CacheControl] = $"public,max-age={query.CacheDuration}";
            }

            var handler = new Func <Stream, Task>(async bodyStream =>
            {
                var resizeOptions = query.ToResizeOptions(asset);

                if (asset.Type == AssetType.Image && resizeOptions.IsValid)
                {
                    var resizedAsset = $"{asset.Id}_{asset.FileVersion}_{resizeOptions}";

                    if (query.ForceResize)
                    {
                        await ResizeAsync(asset, bodyStream, resizedAsset, fileVersion, resizeOptions, true);
                    }
                    else
                    {
                        try
                        {
                            await assetStore.DownloadAsync(resizedAsset, bodyStream);
                        }
                        catch (AssetNotFoundException)
                        {
                            await ResizeAsync(asset, bodyStream, resizedAsset, fileVersion, resizeOptions, false);
                        }
                    }
                }
                else
                {
                    await assetFileStore.DownloadAsync(asset.Id, fileVersion, bodyStream);
                }
            });

            var inline = query.Download != 1;

            return(new FileCallbackResult(asset.MimeType, asset.FileName, handler)
            {
                LastModified = asset.LastModified.ToDateTimeOffset(),
                Send404 = true,
                SendInline = inline,
            });
        }
예제 #13
0
        public async Task <IActionResult> GetAssetContentBySlug(string app, string idOrSlug, string more, [FromQuery] AssetContentQueryDto query)
        {
            IAssetEntity?asset;

            if (Guid.TryParse(idOrSlug, out var guid))
            {
                asset = await assetRepository.FindAssetAsync(guid);
            }
            else
            {
                asset = await assetRepository.FindAssetBySlugAsync(App.Id, idOrSlug);
            }

            if (Request.Method.Equals("HEAD"))
            {
                Response.ContentLength = asset.FileVersion;
                Response.Headers.Add("Digest", asset.FileHash);
                return(Ok());
            }
            else
            {
                return(await DeliverAssetAsync(asset, query));
            }
        }