jellyfin/Emby.Server.Implementations/Session/HttpSessionController.cs
Erwin de Haan ec1f5dc317 Mayor code cleanup
Add Argument*Exceptions now use proper nameof operators.

Added exception messages to quite a few Argument*Exceptions.

Fixed rethorwing to be proper syntax.

Added a ton of null checkes. (This is only a start, there are about 500 places that need proper null handling)

Added some TODOs to log certain exceptions.

Fix sln again.

Fixed all AssemblyInfo's and added proper copyright (where I could find them)

We live in *current year*.

Fixed the use of braces.

Fixed a ton of properties, and made a fair amount of functions static that should be and can be static.

Made more Methods that should be static static.

You can now use static to find bad functions!

Removed unused variable. And added one more proper XML comment.
2019-01-10 20:38:53 +01:00

194 lines
6.7 KiB
C#

using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace Emby.Server.Implementations.Session
{
public class HttpSessionController : ISessionController
{
private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _json;
private readonly ISessionManager _sessionManager;
public SessionInfo Session { get; private set; }
private readonly string _postUrl;
public HttpSessionController(IHttpClient httpClient,
IJsonSerializer json,
SessionInfo session,
string postUrl, ISessionManager sessionManager)
{
_httpClient = httpClient;
_json = json;
Session = session;
_postUrl = postUrl;
_sessionManager = sessionManager;
}
private string PostUrl => string.Format("http://{0}{1}", Session.RemoteEndPoint, _postUrl);
public bool IsSessionActive => (DateTime.UtcNow - Session.LastActivityDate).TotalMinutes <= 5;
public bool SupportsMediaControl => true;
private Task SendMessage(string name, string messageId, CancellationToken cancellationToken)
{
return SendMessage(name, messageId, new Dictionary<string, string>(), cancellationToken);
}
private Task SendMessage(string name, string messageId, Dictionary<string, string> args, CancellationToken cancellationToken)
{
args["messageId"] = messageId;
var url = PostUrl + "/" + name + ToQueryString(args);
return SendRequest(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
BufferContent = false
});
}
private Task SendPlayCommand(PlayRequest command, string messageId, CancellationToken cancellationToken)
{
var dict = new Dictionary<string, string>();
dict["ItemIds"] = string.Join(",", command.ItemIds.Select(i => i.ToString("N")).ToArray());
if (command.StartPositionTicks.HasValue)
{
dict["StartPositionTicks"] = command.StartPositionTicks.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.AudioStreamIndex.HasValue)
{
dict["AudioStreamIndex"] = command.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.SubtitleStreamIndex.HasValue)
{
dict["SubtitleStreamIndex"] = command.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.StartIndex.HasValue)
{
dict["StartIndex"] = command.StartIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(command.MediaSourceId))
{
dict["MediaSourceId"] = command.MediaSourceId;
}
return SendMessage(command.PlayCommand.ToString(), messageId, dict, cancellationToken);
}
private Task SendPlaystateCommand(PlaystateRequest command, string messageId, CancellationToken cancellationToken)
{
var args = new Dictionary<string, string>();
if (command.Command == PlaystateCommand.Seek)
{
if (!command.SeekPositionTicks.HasValue)
{
throw new ArgumentException("SeekPositionTicks cannot be null");
}
args["SeekPositionTicks"] = command.SeekPositionTicks.Value.ToString(CultureInfo.InvariantCulture);
}
return SendMessage(command.Command.ToString(), messageId, args, cancellationToken);
}
private string[] _supportedMessages = new string[] { };
public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken)
{
if (!IsSessionActive)
{
return Task.CompletedTask;
}
if (string.Equals(name, "Play", StringComparison.OrdinalIgnoreCase))
{
return SendPlayCommand(data as PlayRequest, messageId, cancellationToken);
}
if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase))
{
return SendPlaystateCommand(data as PlaystateRequest, messageId, cancellationToken);
}
if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase))
{
var command = data as GeneralCommand;
return SendMessage(command.Name, messageId, command.Arguments, cancellationToken);
}
if (!_supportedMessages.Contains(name, StringComparer.OrdinalIgnoreCase))
{
return Task.CompletedTask;
}
var url = PostUrl + "/" + name;
url += "?messageId=" + messageId;
var options = new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
BufferContent = false
};
if (data != null)
{
if (typeof(T) == typeof(string))
{
var str = data as string;
if (!string.IsNullOrEmpty(str))
{
options.RequestContent = str;
options.RequestContentType = "application/json";
}
}
else
{
options.RequestContent = _json.SerializeToString(data);
options.RequestContentType = "application/json";
}
}
return SendRequest(options);
}
private async Task SendRequest(HttpRequestOptions options)
{
using (var response = await _httpClient.Post(options).ConfigureAwait(false))
{
}
}
private static string ToQueryString(Dictionary<string, string> nvc)
{
var array = (from item in nvc
select string.Format("{0}={1}", WebUtility.UrlEncode(item.Key), WebUtility.UrlEncode(item.Value)))
.ToArray();
var args = string.Join("&", array);
if (string.IsNullOrEmpty(args))
{
return args;
}
return "?" + args;
}
}
}