// Kyoo - A portable and vast media library solution. // Copyright (c) Kyoo. // // See AUTHORS.md and LICENSE file in the project root for full license information. // // Kyoo is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // Kyoo is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Attributes; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Core.Controllers { /// /// A for http/https links. /// [FileSystemMetadata(new[] { "http", "https" })] public class HttpFileSystem : IFileSystem { /// /// The http client factory used to create clients. /// private readonly IHttpClientFactory _clientFactory; /// /// Create a using the given client factory. /// /// The http client factory used to create clients. public HttpFileSystem(IHttpClientFactory factory) { _clientFactory = factory; } /// public IActionResult FileResult(string path, bool rangeSupport = false, string type = null) { if (path == null) return new NotFoundResult(); return new HttpForwardResult(new Uri(path), rangeSupport, type); } /// public Task GetReader(string path) { HttpClient client = _clientFactory.CreateClient(); return client.GetStreamAsync(path); } /// public async Task GetReader(string path, AsyncRef mime) { HttpClient client = _clientFactory.CreateClient(); HttpResponseMessage response = await client.GetAsync(path); response.EnsureSuccessStatusCode(); mime.Value = response.Content.Headers.ContentType?.MediaType; return await response.Content.ReadAsStreamAsync(); } /// public Task NewFile(string path) { throw new NotSupportedException("An http filesystem is readonly, a new file can't be created."); } /// public Task CreateDirectory(string path) { throw new NotSupportedException("An http filesystem is readonly, a directory can't be created."); } /// public string Combine(params string[] paths) { return Path.Combine(paths); } /// public Task> ListFiles(string path, SearchOption options = SearchOption.TopDirectoryOnly) { throw new NotSupportedException("Listing files is not supported on an http filesystem."); } /// public Task Exists(string path) { throw new NotSupportedException("Checking if a file exists is not supported on an http filesystem."); } /// public Task GetExtraDirectory(T resource) { throw new NotSupportedException("Extras can not be stored inside an http filesystem."); } /// /// An to proxy an http request. /// // TODO remove this suppress message once the class has been implemented. [SuppressMessage("ReSharper", "NotAccessedField.Local", Justification = "Not Implemented Yet.")] public class HttpForwardResult : IActionResult { /// /// The path of the request to forward. /// private readonly Uri _path; /// /// Should the proxied result support ranges requests? /// private readonly bool _rangeSupport; /// /// If not null, override the content type of the resulting request. /// private readonly string _type; /// /// Create a new . /// /// The path of the request to forward. /// Should the proxied result support ranges requests? /// If not null, override the content type of the resulting request. public HttpForwardResult(Uri path, bool rangeSupport, string type = null) { _path = path; _rangeSupport = rangeSupport; _type = type; } /// public Task ExecuteResultAsync(ActionContext context) { // TODO implement that, example: https://github.com/twitchax/AspNetCore.Proxy/blob/14dd0f212d7abb43ca1bf8c890d5efb95db66acb/src/Core/Extensions/Http.cs#L15 throw new NotImplementedException(); } } } }