aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Connect
diff options
context:
space:
mode:
authorMichalis Adamidis <gsnerf@gsnerf.de>2014-08-30 02:05:33 +0200
committerMichalis Adamidis <gsnerf@gsnerf.de>2014-08-30 02:05:33 +0200
commit7c5613fc51738cb3af1ce3e7ada9eb19a54b3aed (patch)
treedfd23a717d87e1da776a74f9952a5fae8f215b4a /MediaBrowser.Server.Implementations/Connect
parent5740a4c22d676d0050e875b0bd5455f5a303f5bd (diff)
parent6a9dbf6ae85b4e7abcf06f7f29ef9d8b0b890876 (diff)
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
Diffstat (limited to 'MediaBrowser.Server.Implementations/Connect')
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectData.cs17
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs125
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs204
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ServerRegistrationResponse.cs18
4 files changed, 364 insertions, 0 deletions
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectData.cs b/MediaBrowser.Server.Implementations/Connect/ConnectData.cs
new file mode 100644
index 000000000..1816b103e
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectData.cs
@@ -0,0 +1,17 @@
+
+namespace MediaBrowser.Server.Implementations.Connect
+{
+ public class ConnectData
+ {
+ /// <summary>
+ /// Gets or sets the server identifier.
+ /// </summary>
+ /// <value>The server identifier.</value>
+ public string ServerId { get; set; }
+ /// <summary>
+ /// Gets or sets the access key.
+ /// </summary>
+ /// <value>The access key.</value>
+ public string AccessKey { get; set; }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
new file mode 100644
index 000000000..2ee78ba01
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
@@ -0,0 +1,125 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Connect;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.Logging;
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+
+namespace MediaBrowser.Server.Implementations.Connect
+{
+ public class ConnectEntryPoint : IServerEntryPoint
+ {
+ private Timer _timer;
+ private readonly IHttpClient _httpClient;
+ private readonly IApplicationPaths _appPaths;
+ private readonly ILogger _logger;
+ private readonly IConnectManager _connectManager;
+
+ private readonly INetworkManager _networkManager;
+
+ public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager)
+ {
+ _httpClient = httpClient;
+ _appPaths = appPaths;
+ _logger = logger;
+ _networkManager = networkManager;
+ _connectManager = connectManager;
+ }
+
+ public void Run()
+ {
+ LoadCachedAddress();
+
+ _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(30), TimeSpan.FromHours(24));
+ }
+
+ private async void TimerCallback(object state)
+ {
+ try
+ {
+ using (var stream = await _httpClient.Get(new HttpRequestOptions
+ {
+ Url = "http://bot.whatismyipaddress.com/"
+
+ }).ConfigureAwait(false))
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ var address = await reader.ReadToEndAsync().ConfigureAwait(false);
+
+ if (IsValid(address))
+ {
+ ((ConnectManager) _connectManager).OnWanAddressResolved(address);
+ CacheAddress(address);
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ private string CacheFilePath
+ {
+ get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
+ }
+
+ private void CacheAddress(string address)
+ {
+ var path = CacheFilePath;
+
+ try
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+ File.WriteAllText(path, address, Encoding.UTF8);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error saving data", ex);
+ }
+ }
+
+ private void LoadCachedAddress()
+ {
+ var path = CacheFilePath;
+
+ try
+ {
+ var endpoint = File.ReadAllText(path, Encoding.UTF8);
+
+ if (IsValid(endpoint))
+ {
+ ((ConnectManager)_connectManager).OnWanAddressResolved(endpoint);
+ }
+ }
+ catch (IOException)
+ {
+ // File isn't there. no biggie
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error loading data", ex);
+ }
+ }
+
+ private bool IsValid(string address)
+ {
+ IPAddress ipAddress;
+ return IPAddress.TryParse(address, out ipAddress);
+ }
+
+ public void Dispose()
+ {
+ if (_timer != null)
+ {
+ _timer.Dispose();
+ _timer = null;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
new file mode 100644
index 000000000..504814fe0
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -0,0 +1,204 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Connect;
+using MediaBrowser.Controller.Security;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Connect
+{
+ public class ConnectManager : IConnectManager
+ {
+ private readonly ILogger _logger;
+ private readonly IApplicationPaths _appPaths;
+ private readonly IJsonSerializer _json;
+ private readonly IEncryptionManager _encryption;
+ private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
+ private readonly IServerConfigurationManager _config;
+
+ public string ConnectServerId { get; set; }
+ public string ConnectAccessKey { get; set; }
+
+ public string WanIpAddress { get; private set; }
+
+ public string WanApiAddress
+ {
+ get
+ {
+ var ip = WanIpAddress;
+
+ if (!string.IsNullOrEmpty(ip))
+ {
+ if (!ip.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
+ !ip.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
+ {
+ ip = "http://" + ip;
+ }
+
+ return ip + ":" + _config.Configuration.HttpServerPortNumber.ToString(CultureInfo.InvariantCulture);
+ }
+
+ return null;
+ }
+ }
+
+ public ConnectManager(ILogger logger,
+ IApplicationPaths appPaths,
+ IJsonSerializer json,
+ IEncryptionManager encryption,
+ IHttpClient httpClient,
+ IServerApplicationHost appHost,
+ IServerConfigurationManager config)
+ {
+ _logger = logger;
+ _appPaths = appPaths;
+ _json = json;
+ _encryption = encryption;
+ _httpClient = httpClient;
+ _appHost = appHost;
+ _config = config;
+
+ LoadCachedData();
+ }
+
+ internal void OnWanAddressResolved(string address)
+ {
+ WanIpAddress = address;
+
+ UpdateConnectInfo();
+ }
+
+ private async void UpdateConnectInfo()
+ {
+ var wanApiAddress = WanApiAddress;
+
+ if (string.IsNullOrWhiteSpace(wanApiAddress))
+ {
+ _logger.Warn("Cannot update Media Browser Connect information without a WanApiAddress");
+ return;
+ }
+
+ try
+ {
+ var hasExistingRecord = !string.IsNullOrWhiteSpace(ConnectServerId) &&
+ !string.IsNullOrWhiteSpace(ConnectAccessKey);
+
+ if (hasExistingRecord)
+ {
+ //await UpdateServerRegistration(wanApiAddress).ConfigureAwait(false);
+ }
+ else
+ {
+ //await CreateServerRegistration(wanApiAddress).ConfigureAwait(false);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error registering with Connect", ex);
+ }
+ }
+
+ private async Task CreateServerRegistration(string wanApiAddress)
+ {
+ var url = "Servers";
+ url = GetConnectUrl(url);
+ url += "?Name=" + WebUtility.UrlEncode(_appHost.FriendlyName);
+ url += "&Url=" + WebUtility.UrlEncode(wanApiAddress);
+
+ using (var stream = await _httpClient.Post(url, new Dictionary<string, string>(), CancellationToken.None).ConfigureAwait(false))
+ {
+ var data = _json.DeserializeFromStream<ServerRegistrationResponse>(stream);
+
+ ConnectServerId = data.Id;
+ ConnectAccessKey = data.AccessKey;
+
+ CacheData();
+ }
+ }
+
+ private async Task UpdateServerRegistration(string wanApiAddress)
+ {
+ var url = "Servers/" + ConnectServerId;
+ url = GetConnectUrl(url);
+ url += "?Name=" + WebUtility.UrlEncode(_appHost.FriendlyName);
+ url += "&Url=" + WebUtility.UrlEncode(wanApiAddress);
+
+ // TODO: Add AccessKey http request header
+
+ // No need to examine the response
+ using (var stream = await _httpClient.Post(url, new Dictionary<string, string>(), CancellationToken.None).ConfigureAwait(false))
+ {
+ }
+ }
+
+ private string CacheFilePath
+ {
+ get { return Path.Combine(_appPaths.DataPath, "connect.txt"); }
+ }
+
+ private void CacheData()
+ {
+ var path = CacheFilePath;
+
+ try
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+
+ var json = _json.SerializeToString(new ConnectData
+ {
+ AccessKey = ConnectAccessKey,
+ ServerId = ConnectServerId
+ });
+
+ var encrypted = _encryption.EncryptString(json);
+
+ File.WriteAllText(path, encrypted, Encoding.UTF8);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error saving data", ex);
+ }
+ }
+
+ private void LoadCachedData()
+ {
+ var path = CacheFilePath;
+
+ try
+ {
+ var encrypted = File.ReadAllText(path, Encoding.UTF8);
+
+ var json = _encryption.DecryptString(encrypted);
+
+ var data = _json.DeserializeFromString<ConnectData>(json);
+
+ ConnectAccessKey = data.AccessKey;
+ ConnectServerId = data.ServerId;
+ }
+ catch (IOException)
+ {
+ // File isn't there. no biggie
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error loading data", ex);
+ }
+ }
+
+ private string GetConnectUrl(string handler)
+ {
+ return "http://mb3admin.com/admin/connect/" + handler;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Connect/ServerRegistrationResponse.cs b/MediaBrowser.Server.Implementations/Connect/ServerRegistrationResponse.cs
new file mode 100644
index 000000000..75c55e26e
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Connect/ServerRegistrationResponse.cs
@@ -0,0 +1,18 @@
+
+namespace MediaBrowser.Server.Implementations.Connect
+{
+ public class ServerRegistrationResponse
+ {
+ public string Id { get; set; }
+ public string Url { get; set; }
+ public string Name { get; set; }
+ public string AccessKey { get; set; }
+ }
+
+ public class UpdateServerRegistrationResponse
+ {
+ public string Id { get; set; }
+ public string Url { get; set; }
+ public string Name { get; set; }
+ }
+}