ClientLogController.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System.Net.Mime;
  2. using System.Threading.Tasks;
  3. using Jellyfin.Api.Attributes;
  4. using Jellyfin.Api.Constants;
  5. using Jellyfin.Api.Extensions;
  6. using Jellyfin.Api.Models.ClientLogDtos;
  7. using MediaBrowser.Controller.ClientEvent;
  8. using MediaBrowser.Controller.Configuration;
  9. using Microsoft.AspNetCore.Authorization;
  10. using Microsoft.AspNetCore.Http;
  11. using Microsoft.AspNetCore.Mvc;
  12. namespace Jellyfin.Api.Controllers;
  13. /// <summary>
  14. /// Client log controller.
  15. /// </summary>
  16. [Authorize(Policy = Policies.DefaultAuthorization)]
  17. public class ClientLogController : BaseJellyfinApiController
  18. {
  19. private const int MaxDocumentSize = 1_000_000;
  20. private readonly IClientEventLogger _clientEventLogger;
  21. private readonly IServerConfigurationManager _serverConfigurationManager;
  22. /// <summary>
  23. /// Initializes a new instance of the <see cref="ClientLogController"/> class.
  24. /// </summary>
  25. /// <param name="clientEventLogger">Instance of the <see cref="IClientEventLogger"/> interface.</param>
  26. /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
  27. public ClientLogController(
  28. IClientEventLogger clientEventLogger,
  29. IServerConfigurationManager serverConfigurationManager)
  30. {
  31. _clientEventLogger = clientEventLogger;
  32. _serverConfigurationManager = serverConfigurationManager;
  33. }
  34. /// <summary>
  35. /// Upload a document.
  36. /// </summary>
  37. /// <response code="200">Document saved.</response>
  38. /// <response code="403">Event logging disabled.</response>
  39. /// <response code="413">Upload size too large.</response>
  40. /// <returns>Create response.</returns>
  41. [HttpPost("Document")]
  42. [ProducesResponseType(typeof(ClientLogDocumentResponseDto), StatusCodes.Status200OK)]
  43. [ProducesResponseType(StatusCodes.Status403Forbidden)]
  44. [ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
  45. [AcceptsFile(MediaTypeNames.Text.Plain)]
  46. [RequestSizeLimit(MaxDocumentSize)]
  47. public async Task<ActionResult<ClientLogDocumentResponseDto>> LogFile()
  48. {
  49. if (!_serverConfigurationManager.Configuration.AllowClientLogUpload)
  50. {
  51. return Forbid();
  52. }
  53. if (Request.ContentLength > MaxDocumentSize)
  54. {
  55. // Manually validate to return proper status code.
  56. return StatusCode(StatusCodes.Status413PayloadTooLarge, $"Payload must be less than {MaxDocumentSize:N0} bytes");
  57. }
  58. var (clientName, clientVersion) = GetRequestInformation();
  59. var fileName = await _clientEventLogger.WriteDocumentAsync(clientName, clientVersion, Request.Body)
  60. .ConfigureAwait(false);
  61. return Ok(new ClientLogDocumentResponseDto(fileName));
  62. }
  63. private (string ClientName, string ClientVersion) GetRequestInformation()
  64. {
  65. var clientName = HttpContext.User.GetClient() ?? "unknown-client";
  66. var clientVersion = HttpContext.User.GetIsApiKey()
  67. ? "apikey"
  68. : HttpContext.User.GetVersion() ?? "unknown-version";
  69. return (clientName, clientVersion);
  70. }
  71. }