aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/DlnaServerController.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Controllers/DlnaServerController.cs')
-rw-r--r--Jellyfin.Api/Controllers/DlnaServerController.cs83
1 files changed, 59 insertions, 24 deletions
diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs
index 0100d642b..4e6455eaa 100644
--- a/Jellyfin.Api/Controllers/DlnaServerController.cs
+++ b/Jellyfin.Api/Controllers/DlnaServerController.cs
@@ -1,6 +1,8 @@
using System;
+using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+using System.Net.Mime;
using System.Threading.Tasks;
using Emby.Dlna;
using Emby.Dlna.Main;
@@ -17,8 +19,6 @@ namespace Jellyfin.Api.Controllers
[Route("Dlna")]
public class DlnaServerController : BaseJellyfinApiController
{
- private const string XMLContentType = "text/xml; charset=UTF-8";
-
private readonly IDlnaManager _dlnaManager;
private readonly IContentDirectory _contentDirectory;
private readonly IConnectionManager _connectionManager;
@@ -44,9 +44,10 @@ namespace Jellyfin.Api.Controllers
/// <returns>An <see cref="OkResult"/> containing the description xml.</returns>
[HttpGet("{serverId}/description")]
[HttpGet("{serverId}/description.xml", Name = "GetDescriptionXml_2")]
- [Produces(XMLContentType)]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult GetDescriptionXml([FromRoute] string serverId)
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
+ public ActionResult GetDescriptionXml([FromRoute, Required] string serverId)
{
var url = GetAbsoluteUri();
var serverAddress = url.Substring(0, url.IndexOf("/dlna/", StringComparison.OrdinalIgnoreCase));
@@ -61,11 +62,13 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Dlna content directory returned.</response>
/// <returns>An <see cref="OkResult"/> containing the dlna content directory xml.</returns>
[HttpGet("{serverId}/ContentDirectory")]
- [HttpGet("{serverId}/ContentDirectory.xml", Name = "GetContentDirectory_2")]
- [Produces(XMLContentType)]
+ [HttpGet("{serverId}/ContentDirectory/ContentDirectory", Name = "GetContentDirectory_2")]
+ [HttpGet("{serverId}/ContentDirectory/ContentDirectory.xml", Name = "GetContentDirectory_3")]
[ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetContentDirectory([FromRoute] string serverId)
+ public ActionResult GetContentDirectory([FromRoute, Required] string serverId)
{
return Ok(_contentDirectory.GetServiceXml());
}
@@ -74,13 +77,16 @@ namespace Jellyfin.Api.Controllers
/// Gets Dlna media receiver registrar xml.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Dlna media receiver registrar xml returned.</response>
/// <returns>Dlna media receiver registrar xml.</returns>
[HttpGet("{serverId}/MediaReceiverRegistrar")]
- [HttpGet("{serverId}/MediaReceiverRegistrar.xml", Name = "GetMediaReceiverRegistrar_2")]
- [Produces(XMLContentType)]
+ [HttpGet("{serverId}/MediaReceiverRegistrar/MediaReceiverRegistrar", Name = "GetMediaReceiverRegistrar_2")]
+ [HttpGet("{serverId}/MediaReceiverRegistrar/MediaReceiverRegistrar.xml", Name = "GetMediaReceiverRegistrar_3")]
[ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetMediaReceiverRegistrar([FromRoute] string serverId)
+ public ActionResult GetMediaReceiverRegistrar([FromRoute, Required] string serverId)
{
return Ok(_mediaReceiverRegistrar.GetServiceXml());
}
@@ -89,13 +95,16 @@ namespace Jellyfin.Api.Controllers
/// Gets Dlna media receiver registrar xml.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Dlna media receiver registrar xml returned.</response>
/// <returns>Dlna media receiver registrar xml.</returns>
[HttpGet("{serverId}/ConnectionManager")]
- [HttpGet("{serverId}/ConnectionManager.xml", Name = "GetConnectionManager_2")]
- [Produces(XMLContentType)]
+ [HttpGet("{serverId}/ConnectionManager/ConnectionManager", Name = "GetConnectionManager_2")]
+ [HttpGet("{serverId}/ConnectionManager/ConnectionManager.xml", Name = "GetConnectionManager_3")]
[ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetConnectionManager([FromRoute] string serverId)
+ public ActionResult GetConnectionManager([FromRoute, Required] string serverId)
{
return Ok(_connectionManager.GetServiceXml());
}
@@ -104,9 +113,13 @@ namespace Jellyfin.Api.Controllers
/// Process a content directory control request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Control response.</returns>
[HttpPost("{serverId}/ContentDirectory/Control")]
- public async Task<ActionResult<ControlResponse>> ProcessContentDirectoryControlRequest([FromRoute] string serverId)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
+ public async Task<ActionResult<ControlResponse>> ProcessContentDirectoryControlRequest([FromRoute, Required] string serverId)
{
return await ProcessControlRequestInternalAsync(serverId, Request.Body, _contentDirectory).ConfigureAwait(false);
}
@@ -115,9 +128,13 @@ namespace Jellyfin.Api.Controllers
/// Process a connection manager control request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Control response.</returns>
[HttpPost("{serverId}/ConnectionManager/Control")]
- public async Task<ActionResult<ControlResponse>> ProcessConnectionManagerControlRequest([FromRoute] string serverId)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
+ public async Task<ActionResult<ControlResponse>> ProcessConnectionManagerControlRequest([FromRoute, Required] string serverId)
{
return await ProcessControlRequestInternalAsync(serverId, Request.Body, _connectionManager).ConfigureAwait(false);
}
@@ -126,9 +143,13 @@ namespace Jellyfin.Api.Controllers
/// Process a media receiver registrar control request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Control response.</returns>
[HttpPost("{serverId}/MediaReceiverRegistrar/Control")]
- public async Task<ActionResult<ControlResponse>> ProcessMediaReceiverRegistrarControlRequest([FromRoute] string serverId)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
+ public async Task<ActionResult<ControlResponse>> ProcessMediaReceiverRegistrarControlRequest([FromRoute, Required] string serverId)
{
return await ProcessControlRequestInternalAsync(serverId, Request.Body, _mediaReceiverRegistrar).ConfigureAwait(false);
}
@@ -137,11 +158,15 @@ namespace Jellyfin.Api.Controllers
/// Processes an event subscription request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Event subscription response.</returns>
[HttpSubscribe("{serverId}/MediaReceiverRegistrar/Events")]
[HttpUnsubscribe("{serverId}/MediaReceiverRegistrar/Events")]
[ApiExplorerSettings(IgnoreApi = true)] // Ignore in openapi docs
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
public ActionResult<EventSubscriptionResponse> ProcessMediaReceiverRegistrarEventRequest(string serverId)
{
return ProcessEventRequest(_mediaReceiverRegistrar);
@@ -151,11 +176,15 @@ namespace Jellyfin.Api.Controllers
/// Processes an event subscription request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Event subscription response.</returns>
[HttpSubscribe("{serverId}/ContentDirectory/Events")]
[HttpUnsubscribe("{serverId}/ContentDirectory/Events")]
[ApiExplorerSettings(IgnoreApi = true)] // Ignore in openapi docs
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
public ActionResult<EventSubscriptionResponse> ProcessContentDirectoryEventRequest(string serverId)
{
return ProcessEventRequest(_contentDirectory);
@@ -165,11 +194,15 @@ namespace Jellyfin.Api.Controllers
/// Processes an event subscription request.
/// </summary>
/// <param name="serverId">Server UUID.</param>
+ /// <response code="200">Request processed.</response>
/// <returns>Event subscription response.</returns>
[HttpSubscribe("{serverId}/ConnectionManager/Events")]
[HttpUnsubscribe("{serverId}/ConnectionManager/Events")]
[ApiExplorerSettings(IgnoreApi = true)] // Ignore in openapi docs
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [Produces(MediaTypeNames.Text.Xml)]
+ [ProducesFile(MediaTypeNames.Text.Xml)]
public ActionResult<EventSubscriptionResponse> ProcessConnectionManagerEventRequest(string serverId)
{
return ProcessEventRequest(_connectionManager);
@@ -183,7 +216,9 @@ namespace Jellyfin.Api.Controllers
/// <returns>Icon stream.</returns>
[HttpGet("{serverId}/icons/{fileName}")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetIconId([FromRoute] string serverId, [FromRoute] string fileName)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesImageFile]
+ public ActionResult GetIconId([FromRoute, Required] string serverId, [FromRoute, Required] string fileName)
{
return GetIconInternal(fileName);
}
@@ -194,7 +229,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="fileName">The icon filename.</param>
/// <returns>Icon stream.</returns>
[HttpGet("icons/{fileName}")]
- public ActionResult GetIcon([FromRoute] string fileName)
+ [ProducesImageFile]
+ public ActionResult GetIcon([FromRoute, Required] string fileName)
{
return GetIconInternal(fileName);
}
@@ -221,16 +257,15 @@ namespace Jellyfin.Api.Controllers
private Task<ControlResponse> ProcessControlRequestInternalAsync(string id, Stream requestStream, IUpnpService service)
{
- return service.ProcessControlRequestAsync(new ControlRequest
+ return service.ProcessControlRequestAsync(new ControlRequest(Request.Headers)
{
- Headers = Request.Headers,
InputXml = requestStream,
TargetServerUuId = id,
RequestedUrl = GetAbsoluteUri()
});
}
- private EventSubscriptionResponse ProcessEventRequest(IEventManager eventManager)
+ private EventSubscriptionResponse ProcessEventRequest(IDlnaEventManager dlnaEventManager)
{
var subscriptionId = Request.Headers["SID"];
if (string.Equals(Request.Method, "subscribe", StringComparison.OrdinalIgnoreCase))
@@ -241,17 +276,17 @@ namespace Jellyfin.Api.Controllers
if (string.IsNullOrEmpty(notificationType))
{
- return eventManager.RenewEventSubscription(
+ return dlnaEventManager.RenewEventSubscription(
subscriptionId,
notificationType,
timeoutString,
callback);
}
- return eventManager.CreateEventSubscription(notificationType, timeoutString, callback);
+ return dlnaEventManager.CreateEventSubscription(notificationType, timeoutString, callback);
}
- return eventManager.CancelEventSubscription(subscriptionId);
+ return dlnaEventManager.CancelEventSubscription(subscriptionId);
}
}
}