using System; using System.IO; using System.Threading.Tasks; using Jellyfin.Extensions; namespace MediaBrowser.Controller.ClientEvent { /// public class ClientEventLogger : IClientEventLogger { private readonly IServerApplicationPaths _applicationPaths; /// /// Initializes a new instance of the class. /// /// Instance of the interface. public ClientEventLogger(IServerApplicationPaths applicationPaths) { _applicationPaths = applicationPaths; } /// public async Task WriteDocumentAsync(string clientName, string clientVersion, Stream fileContents) { var safeClientName = PathHelper.GetSafeLeafFileName(clientName) ?? "unknown-client"; var safeClientVersion = PathHelper.GetSafeLeafFileName(clientVersion) ?? "unknown-version"; var fileName = $"upload_{safeClientName}_{safeClientVersion}_{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid():N}.log"; var logFilePath = Path.Combine(_applicationPaths.LogDirectoryPath, fileName); if (!PathHelper.IsContainedIn(_applicationPaths.LogDirectoryPath, logFilePath)) { throw new ArgumentException("Path resolved to filename not in log directory"); } var fileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None); await using (fileStream.ConfigureAwait(false)) { await fileContents.CopyToAsync(fileStream).ConfigureAwait(false); return fileName; } } } }