diff options
84 files changed, 1044 insertions, 910 deletions
diff --git a/BDInfo/BDROM.cs b/BDInfo/BDROM.cs index 2a23645b1..97dbfbf3b 100644 --- a/BDInfo/BDROM.cs +++ b/BDInfo/BDROM.cs @@ -22,7 +22,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using MediaBrowser.Model.IO; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace BDInfo { @@ -75,7 +75,7 @@ namespace BDInfo public event OnPlaylistFileScanError PlaylistFileScanError; public BDROM( - string path, IFileSystem fileSystem, IEncoding textEncoding) + string path, IFileSystem fileSystem, ITextEncoding textEncoding) { _fileSystem = fileSystem; // diff --git a/BDInfo/TSPlaylistFile.cs b/BDInfo/TSPlaylistFile.cs index 2826b3c80..46d66f513 100644 --- a/BDInfo/TSPlaylistFile.cs +++ b/BDInfo/TSPlaylistFile.cs @@ -23,14 +23,14 @@ using System.Collections.Generic; using System.IO; using System.Text; using MediaBrowser.Model.IO; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace BDInfo { public class TSPlaylistFile { private readonly IFileSystem _fileSystem; - private readonly IEncoding _textEncoding; + private readonly ITextEncoding _textEncoding; private FileSystemMetadata FileInfo = null; public string FileType = null; public bool IsInitialized = false; @@ -67,7 +67,7 @@ namespace BDInfo public TSPlaylistFile( BDROM bdrom, - FileSystemMetadata fileInfo, IFileSystem fileSystem, IEncoding textEncoding) + FileSystemMetadata fileInfo, IFileSystem fileSystem, ITextEncoding textEncoding) { BDROM = bdrom; FileInfo = fileInfo; @@ -79,7 +79,7 @@ namespace BDInfo public TSPlaylistFile( BDROM bdrom, string name, - List<TSStreamClip> clips, IFileSystem fileSystem, IEncoding textEncoding) + List<TSStreamClip> clips, IFileSystem fileSystem, ITextEncoding textEncoding) { BDROM = bdrom; Name = name; @@ -1247,7 +1247,7 @@ namespace BDInfo ref int pos) { string val = - _textEncoding.GetASCIIString(data, pos, count); + _textEncoding.GetASCIIEncoding().GetString(data, pos, count); pos += count; diff --git a/BDInfo/TSStreamClipFile.cs b/BDInfo/TSStreamClipFile.cs index 118e3b5fc..f2accb88d 100644 --- a/BDInfo/TSStreamClipFile.cs +++ b/BDInfo/TSStreamClipFile.cs @@ -23,14 +23,14 @@ using System.Collections.Generic; using System.IO; using System.Text; using MediaBrowser.Model.IO; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace BDInfo { public class TSStreamClipFile { private readonly IFileSystem _fileSystem; - private readonly IEncoding _textEncoding; + private readonly ITextEncoding _textEncoding; public FileSystemMetadata FileInfo = null; public string FileType = null; public bool IsValid = false; @@ -40,7 +40,7 @@ namespace BDInfo new Dictionary<ushort,TSStream>(); public TSStreamClipFile( - FileSystemMetadata fileInfo, IFileSystem fileSystem, IEncoding textEncoding) + FileSystemMetadata fileInfo, IFileSystem fileSystem, ITextEncoding textEncoding) { FileInfo = fileInfo; _fileSystem = fileSystem; @@ -70,7 +70,7 @@ namespace BDInfo byte[] fileType = new byte[8]; Array.Copy(data, 0, fileType, 0, fileType.Length); - FileType = _textEncoding.GetASCIIString(fileType, 0, fileType.Length); + FileType = _textEncoding.GetASCIIEncoding().GetString(fileType, 0, fileType.Length); if (FileType != "HDMV0100" && FileType != "HDMV0200") { @@ -167,7 +167,7 @@ namespace BDInfo Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = - _textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length); + _textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length); TSChannelLayout channelLayout = (TSChannelLayout) (clipData[streamOffset + 2] >> 4); @@ -198,7 +198,7 @@ namespace BDInfo Array.Copy(clipData, streamOffset + 2, languageBytes, 0, languageBytes.Length); string languageCode = - _textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length); + _textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length); stream = new TSGraphicsStream(); stream.LanguageCode = languageCode; @@ -218,7 +218,7 @@ namespace BDInfo Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = - _textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length); + _textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length); #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs index 9585abb2a..0cf11e825 100644 --- a/Emby.Common.Implementations/BaseApplicationHost.cs +++ b/Emby.Common.Implementations/BaseApplicationHost.cs @@ -170,7 +170,7 @@ namespace Emby.Common.Implementations /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value> public abstract bool IsRunningAsService { get; } - protected ICryptographyProvider CryptographyProvider = new CryptographyProvider(); + protected ICryptoProvider CryptographyProvider = new CryptographyProvider(); protected IEnvironmentInfo EnvironmentInfo = new Emby.Common.Implementations.EnvironmentInfo.EnvironmentInfo(); @@ -183,7 +183,7 @@ namespace Emby.Common.Implementations { _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); } - + return _deviceId.Value; } } @@ -193,7 +193,7 @@ namespace Emby.Common.Implementations get { return EnvironmentInfo.OperatingSystemName; } } - public IMemoryStreamProvider MemoryStreamProvider { get; set; } + public IMemoryStreamFactory MemoryStreamProvider { get; set; } /// <summary> /// The container @@ -209,7 +209,7 @@ namespace Emby.Common.Implementations { // hack alert, until common can target .net core BaseExtensions.CryptographyProvider = CryptographyProvider; - + XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer")); FailedAssemblies = new List<string>(); @@ -267,7 +267,7 @@ namespace Emby.Common.Implementations progress.Report(100); } - protected abstract IMemoryStreamProvider CreateMemoryStreamProvider(); + protected abstract IMemoryStreamFactory CreateMemoryStreamProvider(); protected abstract ISystemEvents CreateSystemEvents(); protected virtual void OnLoggerLoaded(bool isFirstLoad) diff --git a/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs index 7b8d95b96..01a31bcc0 100644 --- a/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs @@ -6,21 +6,14 @@ using MediaBrowser.Model.Cryptography; namespace Emby.Common.Implementations.Cryptography { - public class CryptographyProvider : ICryptographyProvider + public class CryptographyProvider : ICryptoProvider { public Guid GetMD5(string str) { - return new Guid(GetMD5Bytes(str)); - } - public byte[] GetMD5Bytes(string str) - { - using (var provider = MD5.Create()) - { - return provider.ComputeHash(Encoding.Unicode.GetBytes(str)); - } + return new Guid(ComputeMD5(Encoding.Unicode.GetBytes(str))); } - public byte[] GetSHA1Bytes(byte[] bytes) + public byte[] ComputeSHA1(byte[] bytes) { using (var provider = SHA1.Create()) { @@ -28,7 +21,7 @@ namespace Emby.Common.Implementations.Cryptography } } - public byte[] GetMD5Bytes(Stream str) + public byte[] ComputeMD5(Stream str) { using (var provider = MD5.Create()) { @@ -36,7 +29,7 @@ namespace Emby.Common.Implementations.Cryptography } } - public byte[] GetMD5Bytes(byte[] bytes) + public byte[] ComputeMD5(byte[] bytes) { using (var provider = MD5.Create()) { diff --git a/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs index 85fcb556f..06af5af53 100644 --- a/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -42,7 +42,7 @@ namespace Emby.Common.Implementations.HttpClientManager private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; /// <summary> /// Initializes a new instance of the <see cref="HttpClientManager" /> class. @@ -53,7 +53,7 @@ namespace Emby.Common.Implementations.HttpClientManager /// <exception cref="System.ArgumentNullException">appPaths /// or /// logger</exception> - public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider) + public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamFactory memoryStreamProvider) { if (appPaths == null) { diff --git a/Emby.Common.Implementations/Net/NetSocket.cs b/Emby.Common.Implementations/Net/NetSocket.cs new file mode 100644 index 000000000..72faa41a9 --- /dev/null +++ b/Emby.Common.Implementations/Net/NetSocket.cs @@ -0,0 +1,85 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using Emby.Common.Implementations.Networking; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Logging; + +namespace Emby.Common.Implementations.Net +{ + public class NetSocket : ISocket + { + public Socket Socket { get; private set; } + private readonly ILogger _logger; + + public NetSocket(Socket socket, ILogger logger) + { + Socket = socket; + _logger = logger; + } + + public IpEndPointInfo LocalEndPoint + { + get + { + return BaseNetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.LocalEndPoint); + } + } + + public IpEndPointInfo RemoteEndPoint + { + get + { + return BaseNetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.RemoteEndPoint); + } + } + + public void Close() + { +#if NET46 + Socket.Close(); +#else + Socket.Dispose(); +#endif + } + + public void Shutdown(bool both) + { + if (both) + { + Socket.Shutdown(SocketShutdown.Both); + } + else + { + // Change interface if ever needed + throw new NotImplementedException(); + } + } + + public void Listen(int backlog) + { + Socket.Listen(backlog); + } + + public void Bind(IpEndPointInfo endpoint) + { + var nativeEndpoint = BaseNetworkManager.ToIPEndPoint(endpoint); + + Socket.Bind(nativeEndpoint); + } + + private SocketAcceptor _acceptor; + public void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed) + { + _acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed); + + _acceptor.StartAccept(); + } + + public void Dispose() + { + Socket.Dispose(); + } + } +} diff --git a/Emby.Common.Implementations/Net/SocketAcceptor.cs b/Emby.Common.Implementations/Net/SocketAcceptor.cs new file mode 100644 index 000000000..fd65e9fbc --- /dev/null +++ b/Emby.Common.Implementations/Net/SocketAcceptor.cs @@ -0,0 +1,111 @@ +using System; +using System.Net.Sockets; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; + +namespace Emby.Common.Implementations.Net +{ + public class SocketAcceptor + { + private readonly ILogger _logger; + private readonly Socket _originalSocket; + private readonly Func<bool> _isClosed; + private readonly Action<ISocket> _onAccept; + + public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed) + { + _logger = logger; + _originalSocket = originalSocket; + _isClosed = isClosed; + _onAccept = onAccept; + } + + public void StartAccept() + { + Socket dummy = null; + StartAccept(null, ref dummy); + } + + public void StartAccept(SocketAsyncEventArgs acceptEventArg, ref Socket accepted) + { + if (acceptEventArg == null) + { + acceptEventArg = new SocketAsyncEventArgs(); + acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed); + } + else + { + // socket must be cleared since the context object is being reused + acceptEventArg.AcceptSocket = null; + } + + try + { + bool willRaiseEvent = _originalSocket.AcceptAsync(acceptEventArg); + + if (!willRaiseEvent) + { + ProcessAccept(acceptEventArg); + } + } + catch (Exception ex) + { + if (accepted != null) + { + try + { +#if NET46 + accepted.Close(); +#else + accepted.Dispose(); +#endif + } + catch + { + } + accepted = null; + } + } + } + + // This method is the callback method associated with Socket.AcceptAsync + // operations and is invoked when an accept operation is complete + // + void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) + { + ProcessAccept(e); + } + + private void ProcessAccept(SocketAsyncEventArgs e) + { + if (_isClosed()) + { + return; + } + + // http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync%28v=vs.110%29.aspx + // Under certain conditions ConnectionReset can occur + // Need to attept to re-accept + if (e.SocketError == SocketError.ConnectionReset) + { + _logger.Error("SocketError.ConnectionReset reported. Attempting to re-accept."); + Socket dummy = null; + StartAccept(e, ref dummy); + return; + } + + var acceptSocket = e.AcceptSocket; + if (acceptSocket != null) + { + //ProcessAccept(acceptSocket); + _onAccept(new NetSocket(acceptSocket, _logger)); + } + + if (_originalSocket != null) + { + // Accept the next connection request + StartAccept(e, ref acceptSocket); + } + } + } +} diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs index bb38c72da..922b0f3cc 100644 --- a/Emby.Common.Implementations/Net/SocketFactory.cs +++ b/Emby.Common.Implementations/Net/SocketFactory.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; namespace Emby.Common.Implementations.Net @@ -22,16 +23,28 @@ namespace Emby.Common.Implementations.Net /// </summary> private IPAddress _LocalIP; - /// <summary> - /// Default constructor. - /// </summary> - /// <param name="localIP">A string containing the IP address of the local network adapter to bind sockets to. Null or empty string will use <see cref="IPAddress.Any"/>.</param> - public SocketFactory(string localIP) + private ILogger _logger; + + public SocketFactory(ILogger logger) + { + _logger = logger; + _LocalIP = IPAddress.Any; + } + + public ISocket CreateSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode) { - if (String.IsNullOrEmpty(localIP)) - _LocalIP = IPAddress.Any; - else - _LocalIP = IPAddress.Parse(localIP); + var addressFamily = family == IpAddressFamily.InterNetwork + ? AddressFamily.InterNetwork + : AddressFamily.InterNetworkV6; + + var socket = new Socket(addressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); + + if (dualMode) + { + socket.DualMode = true; + } + + return new NetSocket(socket, _logger); } #region ISocketFactory Members @@ -44,7 +57,7 @@ namespace Emby.Common.Implementations.Net { if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); - var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); @@ -68,7 +81,7 @@ namespace Emby.Common.Implementations.Net { if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); - var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); @@ -99,7 +112,7 @@ namespace Emby.Common.Implementations.Net if (multicastTimeToLive <= 0) throw new ArgumentException("multicastTimeToLive cannot be zero or less.", "multicastTimeToLive"); if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); - var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs index d999d3fe8..244b37bb4 100644 --- a/Emby.Common.Implementations/Net/UdpSocket.cs +++ b/Emby.Common.Implementations/Net/UdpSocket.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Sockets; using System.Security; using System.Threading.Tasks; +using Emby.Common.Implementations.Networking; using MediaBrowser.Model.Net; namespace Emby.Common.Implementations.Net @@ -174,16 +175,7 @@ namespace Emby.Common.Implementations.Net return null; } - return new IpEndPointInfo - { - IpAddress = new IpAddressInfo - { - Address = endpoint.Address.ToString(), - IsIpv6 = endpoint.AddressFamily == AddressFamily.InterNetworkV6 - }, - - Port = endpoint.Port - }; + return BaseNetworkManager.ToIpEndPointInfo(endpoint); } private void ProcessResponse(IAsyncResult asyncResult) diff --git a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs index 10d0db968..f1ac8413b 100644 --- a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs @@ -22,14 +22,10 @@ namespace Emby.Common.Implementations.Networking Logger = logger; } - private List<IPAddress> _localIpAddresses; + private List<IpAddressInfo> _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); - /// <summary> - /// Gets the machine's local ip address - /// </summary> - /// <returns>IPAddress.</returns> - public IEnumerable<IPAddress> GetLocalIpAddresses() + public IEnumerable<IpAddressInfo> GetLocalIpAddresses() { const int cacheMinutes = 5; @@ -39,7 +35,7 @@ namespace Emby.Common.Implementations.Networking if (_localIpAddresses == null || forceRefresh) { - var addresses = GetLocalIpAddressesInternal().ToList(); + var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList(); _localIpAddresses = addresses; _lastRefresh = DateTime.UtcNow; @@ -405,18 +401,85 @@ namespace Emby.Common.Implementations.Networking IPAddress address; if (IPAddress.TryParse(ipAddress, out address)) { - - ipAddressInfo = new IpAddressInfo - { - Address = address.ToString(), - IsIpv6 = address.AddressFamily == AddressFamily.InterNetworkV6 - }; - + ipAddressInfo = ToIpAddressInfo(address); return true; } ipAddressInfo = null; return false; } + + public static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) + { + if (endpoint == null) + { + return null; + } + + return new IpEndPointInfo(ToIpAddressInfo(endpoint.Address), endpoint.Port); + } + + public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint) + { + if (endpoint == null) + { + return null; + } + + return new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port); + } + + public static IPAddress ToIPAddress(IpAddressInfo address) + { + if (address.Equals(IpAddressInfo.Any)) + { + return IPAddress.Any; + } + if (address.Equals(IpAddressInfo.IPv6Any)) + { + return IPAddress.IPv6Any; + } + if (address.Equals(IpAddressInfo.Loopback)) + { + return IPAddress.Loopback; + } + if (address.Equals(IpAddressInfo.IPv6Loopback)) + { + return IPAddress.IPv6Loopback; + } + + return IPAddress.Parse(address.Address); + } + + public static IpAddressInfo ToIpAddressInfo(IPAddress address) + { + if (address.Equals(IPAddress.Any)) + { + return IpAddressInfo.Any; + } + if (address.Equals(IPAddress.IPv6Any)) + { + return IpAddressInfo.IPv6Any; + } + if (address.Equals(IPAddress.Loopback)) + { + return IpAddressInfo.Loopback; + } + if (address.Equals(IPAddress.IPv6Loopback)) + { + return IpAddressInfo.IPv6Loopback; + } + return new IpAddressInfo + { + Address = address.ToString(), + AddressFamily = address.AddressFamily == AddressFamily.InterNetworkV6 ? IpAddressFamily.InterNetworkV6 : IpAddressFamily.InterNetwork + }; + } + + public async Task<IpAddressInfo[]> GetHostAddressesAsync(string host) + { + var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); + return addresses.Select(ToIpAddressInfo).ToArray(); + } } } diff --git a/Emby.Common.Implementations/TextEncoding/TextEncoding.cs b/Emby.Common.Implementations/TextEncoding/TextEncoding.cs index 35b869e43..254d35222 100644 --- a/Emby.Common.Implementations/TextEncoding/TextEncoding.cs +++ b/Emby.Common.Implementations/TextEncoding/TextEncoding.cs @@ -1,10 +1,10 @@ using System.Text; using MediaBrowser.Model.IO; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace Emby.Common.Implementations.TextEncoding { - public class TextEncoding : IEncoding + public class TextEncoding : ITextEncoding { private readonly IFileSystem _fileSystem; @@ -13,14 +13,9 @@ namespace Emby.Common.Implementations.TextEncoding _fileSystem = fileSystem; } - public byte[] GetASCIIBytes(string text) + public Encoding GetASCIIEncoding() { - return Encoding.ASCII.GetBytes(text); - } - - public string GetASCIIString(byte[] bytes, int startIndex, int length) - { - return Encoding.ASCII.GetString(bytes, 0, bytes.Length); + return Encoding.ASCII; } public Encoding GetFileEncoding(string srcFile) diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 142b9f96e..ef27c029d 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -250,14 +250,12 @@ namespace Emby.Dlna.Main // continue; //} - var addressString = address.ToString(); - var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; - _logger.Info("Registering publisher for {0} on {1}", fullService, addressString); + _logger.Info("Registering publisher for {0} on {1}", fullService, address.ToString()); var descriptorUri = "/dlna/" + udn + "/description.xml"; - var uri = new Uri(_appHost.GetLocalApiUrl(addressString, address.IsIpv6) + descriptorUri); + var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri); var device = new SsdpRootDevice { diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index b714f4ac0..a93f7da14 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -16,6 +16,7 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; namespace Emby.Dlna.PlayTo @@ -131,11 +132,11 @@ namespace Emby.Dlna.PlayTo string serverAddress; if (info.LocalIpAddress == null) { - serverAddress = await GetServerAddress(null, false).ConfigureAwait(false); + serverAddress = await GetServerAddress(null).ConfigureAwait(false); } else { - serverAddress = await GetServerAddress(info.LocalIpAddress.Address, info.LocalIpAddress.IsIpv6).ConfigureAwait(false); + serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false); } string accessToken = null; @@ -189,14 +190,14 @@ namespace Emby.Dlna.PlayTo } } - private Task<string> GetServerAddress(string ipAddress, bool isIpv6) + private Task<string> GetServerAddress(IpAddressInfo address) { - if (string.IsNullOrWhiteSpace(ipAddress)) + if (address == null) { return _appHost.GetLocalApiUrl(); } - return Task.FromResult(_appHost.GetLocalApiUrl(ipAddress, isIpv6)); + return Task.FromResult(_appHost.GetLocalApiUrl(address)); } public void Dispose() diff --git a/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs index d7574d466..170ef07f3 100644 --- a/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Connect validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false); // Try to find the ipv4 address, if present - if (!validIpAddress.IsIpv6) + if (validIpAddress.AddressFamily != IpAddressFamily.InterNetworkV6) { break; } @@ -77,9 +77,9 @@ namespace Emby.Server.Implementations.Connect _logger.ErrorException("Error getting connection info", ex); } } - + // If this produced an ipv6 address, try again - if (validIpAddress != null && validIpAddress.IsIpv6) + if (validIpAddress != null && validIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { foreach (var ipLookupUrl in _ipLookups) { @@ -88,7 +88,7 @@ namespace Emby.Server.Implementations.Connect var newAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false); // Try to find the ipv4 address, if present - if (!newAddress.IsIpv6) + if (newAddress.AddressFamily != IpAddressFamily.InterNetworkV6) { validIpAddress = newAddress; break; diff --git a/Emby.Server.Implementations/Connect/ConnectManager.cs b/Emby.Server.Implementations/Connect/ConnectManager.cs index 6c2ac40c3..079bfe868 100644 --- a/Emby.Server.Implementations/Connect/ConnectManager.cs +++ b/Emby.Server.Implementations/Connect/ConnectManager.cs @@ -74,7 +74,7 @@ namespace Emby.Server.Implementations.Connect if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null) { - if (DiscoveredWanIpAddress.IsIpv6) + if (DiscoveredWanIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { address = "[" + DiscoveredWanIpAddress + "]"; } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 894ba334d..806702dfd 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -68,11 +68,18 @@ <Compile Include="FileOrganization\OrganizerScheduledTask.cs" /> <Compile Include="FileOrganization\TvFolderOrganizer.cs" /> <Compile Include="HttpServer\GetSwaggerResource.cs" /> + <Compile Include="HttpServer\LoggerUtils.cs" /> + <Compile Include="HttpServer\RangeRequestWriter.cs" /> + <Compile Include="HttpServer\ResponseFilter.cs" /> + <Compile Include="HttpServer\SocketSharp\Extensions.cs" /> <Compile Include="HttpServer\SocketSharp\HttpUtility.cs" /> <Compile Include="HttpServer\IHttpListener.cs" /> <Compile Include="HttpServer\Security\AuthorizationContext.cs" /> <Compile Include="HttpServer\Security\AuthService.cs" /> <Compile Include="HttpServer\Security\SessionContext.cs" /> + <Compile Include="HttpServer\SocketSharp\SharpWebSocket.cs" /> + <Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" /> + <Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" /> <Compile Include="HttpServer\StreamWriter.cs" /> <Compile Include="HttpServer\SwaggerService.cs" /> <Compile Include="Images\BaseDynamicImageProvider.cs" /> @@ -254,6 +261,9 @@ <Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project> <Name>MediaBrowser.Providers</Name> </ProjectReference> + <Reference Include="SocketHttpListener.Portable"> + <HintPath>..\ThirdParty\emby\SocketHttpListener.Portable.dll</HintPath> + </Reference> <Reference Include="UniversalDetector, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath> <Private>True</Private> diff --git a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs index bfbb228ed..8fc92a09a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs @@ -3,7 +3,7 @@ using System; using System.Globalization; using SocketHttpListener.Net; -namespace MediaBrowser.Server.Implementations.HttpServer +namespace Emby.Server.Implementations.HttpServer { public static class LoggerUtils { diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs index 7d4cd3b4d..e88994bec 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -1,5 +1,4 @@ using MediaBrowser.Model.Logging; -using ServiceStack.Web; using System; using System.Collections.Generic; using System.Globalization; @@ -9,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Services; -namespace MediaBrowser.Server.Implementations.HttpServer +namespace Emby.Server.Implementations.HttpServer { public class RangeRequestWriter : IAsyncStreamWriter, IHttpResult { @@ -41,7 +40,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// </summary> private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public Func<IDisposable> ResultScope { get; set; } public List<Cookie> Cookies { get; private set; } /// <summary> @@ -213,8 +211,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer public object Response { get; set; } - public IContentTypeWriter ResponseFilter { get; set; } - public int Status { get; set; } public HttpStatusCode StatusCode @@ -224,7 +220,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer } public string StatusDescription { get; set; } - - public int PaddingLength { get; set; } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs index 6247e4c17..6d9d7d921 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs @@ -1,12 +1,11 @@ using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.HttpServer.SocketSharp; using System; using System.Globalization; -using System.Net; using System.Text; +using Emby.Server.Implementations.HttpServer.SocketSharp; using MediaBrowser.Model.Services; -namespace MediaBrowser.Server.Implementations.HttpServer +namespace Emby.Server.Implementations.HttpServer { public class ResponseFilter { @@ -28,6 +27,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer { // Try to prevent compatibility view res.AddHeader("X-UA-Compatible", "IE=Edge"); + res.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); + res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); + res.AddHeader("Access-Control-Allow-Origin", "*"); var exception = dto as Exception; @@ -68,15 +70,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer { res.SetContentLength(length); - var listenerResponse = res.OriginalResponse as HttpListenerResponse; - - if (listenerResponse != null) - { - // Disable chunked encoding. Technically this is only needed when using Content-Range, but - // anytime we know the content length there's no need for it - listenerResponse.SendChunked = false; - return; - } + //var listenerResponse = res.OriginalResponse as HttpListenerResponse; + + //if (listenerResponse != null) + //{ + // // Disable chunked encoding. Technically this is only needed when using Content-Range, but + // // anytime we know the content length there's no need for it + // listenerResponse.SendChunked = false; + // return; + //} if (sharpResponse != null) { diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/Extensions.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/Extensions.cs new file mode 100644 index 000000000..07a338f19 --- /dev/null +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/Extensions.cs @@ -0,0 +1,12 @@ +using SocketHttpListener.Net; + +namespace Emby.Server.Implementations.HttpServer.SocketSharp +{ + public static class Extensions + { + public static string GetOperationName(this HttpListenerRequest request) + { + return request.Url.Segments[request.Url.Segments.Length - 1]; + } + } +} diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index d363c4de6..0a312f7b9 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -6,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using WebSocketState = MediaBrowser.Model.Net.WebSocketState; -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +namespace Emby.Server.Implementations.HttpServer.SocketSharp { public class SharpWebSocket : IWebSocket { @@ -25,12 +25,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - /// <summary> - /// Initializes a new instance of the <see cref="NativeWebSocket" /> class. - /// </summary> - /// <param name="socket">The socket.</param> - /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">socket</exception> public SharpWebSocket(SocketHttpListener.WebSocket socket, ILogger logger) { if (socket == null) diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 56f8ab429..0cb4d428b 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -1,37 +1,49 @@ -using System.Collections.Specialized; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using SocketHttpListener.Net; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.Logging; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; -using ServiceStack; +using MediaBrowser.Model.Text; +using SocketHttpListener.Primitives; -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +namespace Emby.Server.Implementations.HttpServer.SocketSharp { public class WebSocketSharpListener : IHttpListener { private HttpListener _listener; private readonly ILogger _logger; - private readonly string _certificatePath; - private readonly IMemoryStreamProvider _memoryStreamProvider; - - public WebSocketSharpListener(ILogger logger, string certificatePath, IMemoryStreamProvider memoryStreamProvider) + private readonly ICertificate _certificate; + private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly ITextEncoding _textEncoding; + private readonly INetworkManager _networkManager; + private readonly ISocketFactory _socketFactory; + private readonly ICryptoProvider _cryptoProvider; + private readonly IStreamFactory _streamFactory; + private readonly Func<HttpListenerContext, IHttpRequest> _httpRequestFactory; + + public WebSocketSharpListener(ILogger logger, ICertificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, Func<HttpListenerContext, IHttpRequest> httpRequestFactory) { _logger = logger; - _certificatePath = certificatePath; + _certificate = certificate; _memoryStreamProvider = memoryStreamProvider; + _textEncoding = textEncoding; + _networkManager = networkManager; + _socketFactory = socketFactory; + _cryptoProvider = cryptoProvider; + _streamFactory = streamFactory; + _httpRequestFactory = httpRequestFactory; } public Action<Exception, IRequest> ErrorHandler { get; set; } - public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; } public Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; } @@ -41,7 +53,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public void Start(IEnumerable<string> urlPrefixes) { if (_listener == null) - _listener = new HttpListener(new PatternsLogger(_logger), _certificatePath); + _listener = new HttpListener(new PatternsLogger(_logger), _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider); + + if (_certificate != null) + { + _listener.LoadCert(_certificate); + } foreach (var prefix in urlPrefixes) { @@ -59,41 +76,32 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp Task.Factory.StartNew(() => InitTask(context)); } - private void InitTask(HttpListenerContext context) + private Task InitTask(HttpListenerContext context) { + IHttpRequest httpReq = null; + var request = context.Request; + try { - var task = this.ProcessRequestAsync(context); - task.ContinueWith(x => HandleError(x.Exception, context), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent); + if (request.IsWebSocketRequest) + { + LoggerUtils.LogRequest(_logger, request); - //if (task.Status == TaskStatus.Created) - //{ - // task.RunSynchronously(); - //} + ProcessWebSocketRequest(context); + return Task.FromResult(true); + } + + httpReq = GetRequest(context); } catch (Exception ex) { - HandleError(ex, context); - } - } - - private Task ProcessRequestAsync(HttpListenerContext context) - { - var request = context.Request; - - if (request.IsWebSocketRequest) - { - LoggerUtils.LogRequest(_logger, request); + _logger.ErrorException("Error processing request", ex); - ProcessWebSocketRequest(context); + httpReq = httpReq ?? GetRequest(context); + ErrorHandler(ex, httpReq); return Task.FromResult(true); } - if (string.IsNullOrEmpty(context.Request.RawUrl)) - return ((object)null).AsTaskResult(); - - var httpReq = GetRequest(context); - return RequestHandler(httpReq, request.Url); } @@ -103,19 +111,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { var endpoint = ctx.Request.RemoteEndPoint.ToString(); var url = ctx.Request.RawUrl; - var queryString = ctx.Request.QueryString ?? new NameValueCollection(); - - var queryParamCollection = new QueryParamCollection(); - - foreach (var key in queryString.AllKeys) - { - queryParamCollection[key] = queryString[key]; - } var connectingArgs = new WebSocketConnectingEventArgs { Url = url, - QueryString = queryParamCollection, + QueryString = ctx.Request.QueryString, Endpoint = endpoint }; @@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp WebSocketConnected(new WebSocketConnectEventArgs { Url = url, - QueryString = queryParamCollection, + QueryString = ctx.Request.QueryString, WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger), Endpoint = endpoint }); @@ -158,21 +158,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private IHttpRequest GetRequest(HttpListenerContext httpContext) { - var operationName = httpContext.Request.GetOperationName(); - - var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger, _memoryStreamProvider); - - return req; - } - - private void HandleError(Exception ex, HttpListenerContext context) - { - var httpReq = GetRequest(context); - - if (ErrorHandler != null) - { - ErrorHandler(ex, httpReq); - } + return _httpRequestFactory(httpContext); } public void Stop() @@ -213,4 +199,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } } } + }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs index 3aae6c9ca..de0b33fe3 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs @@ -2,14 +2,13 @@ using System.Collections.Generic; using System.IO; using System.Net; +using System.Text; using MediaBrowser.Model.Logging; -using ServiceStack; -using ServiceStack.Host; using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse; using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse; using IRequest = MediaBrowser.Model.Services.IRequest; -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +namespace Emby.Server.Implementations.HttpServer.SocketSharp { public class WebSocketSharpResponse : IHttpResponse { @@ -98,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp try { - this._response.CloseOutputStream(_logger); + CloseOutputStream(this._response); } catch (Exception ex) { @@ -107,6 +106,20 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } } + public void CloseOutputStream(HttpListenerResponse response) + { + try + { + response.OutputStream.Flush(); + response.OutputStream.Dispose(); + response.Close(); + } + catch (Exception ex) + { + _logger.ErrorException("Error in HttpListenerResponseWrapper: " + ex.Message, ex); + } + } + public void End() { Close(); @@ -133,10 +146,49 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public void SetCookie(Cookie cookie) { - var cookieStr = cookie.AsHeaderValue(); - _response.Headers.Add(HttpHeaders.SetCookie, cookieStr); + var cookieStr = AsHeaderValue(cookie); + _response.Headers.Add("Set-Cookie", cookieStr); + } + + public static string AsHeaderValue(Cookie cookie) + { + var defaultExpires = DateTime.MinValue; + + var path = cookie.Expires == defaultExpires + ? "/" + : cookie.Path ?? "/"; + + var sb = new StringBuilder(); + + sb.Append($"{cookie.Name}={cookie.Value};path={path}"); + + if (cookie.Expires != defaultExpires) + { + sb.Append($";expires={cookie.Expires:R}"); + } + + if (!string.IsNullOrEmpty(cookie.Domain)) + { + sb.Append($";domain={cookie.Domain}"); + } + //else if (restrictAllCookiesToDomain != null) + //{ + // sb.Append($";domain={restrictAllCookiesToDomain}"); + //} + + if (cookie.Secure) + { + sb.Append(";Secure"); + } + if (cookie.HttpOnly) + { + sb.Append(";HttpOnly"); + } + + return sb.ToString(); } + public bool SendChunked { get { return _response.SendChunked; } diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 9c1d7fdf1..2a5706b3b 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -70,10 +70,10 @@ namespace Emby.Server.Implementations.Library private readonly Func<IConnectManager> _connectFactory; private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; private readonly string _defaultUserName; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider, string defaultUserName) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string defaultUserName) { _logger = logger; UserRepository = userRepository; @@ -334,7 +334,7 @@ namespace Emby.Server.Implementations.Library /// <returns>System.String.</returns> private string GetSha1String(string str) { - return BitConverter.ToString(_cryptographyProvider.GetSHA1Bytes(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty); + return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty); } /// <summary> diff --git a/Emby.Server.Implementations/Security/MBLicenseFile.cs b/Emby.Server.Implementations/Security/MBLicenseFile.cs index 7cb6165a5..4b6a82b6c 100644 --- a/Emby.Server.Implementations/Security/MBLicenseFile.cs +++ b/Emby.Server.Implementations/Security/MBLicenseFile.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Security { private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; public string RegKey { @@ -43,7 +43,7 @@ namespace Emby.Server.Implementations.Security private readonly object _fileLock = new object(); private string _regKey; - public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider) + public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) { _appPaths = appPaths; _fileSystem = fileSystem; @@ -59,7 +59,7 @@ namespace Emby.Server.Implementations.Security public void AddRegCheck(string featureId) { - var key = new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))); + var key = new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId))); var value = DateTime.UtcNow; SetUpdateRecord(key, value); @@ -68,7 +68,7 @@ namespace Emby.Server.Implementations.Security public void RemoveRegCheck(string featureId) { - var key = new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))); + var key = new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId))); DateTime val; _updateRecords.TryRemove(key, out val); @@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.Security public DateTime LastChecked(string featureId) { DateTime last; - _updateRecords.TryGetValue(new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))), out last); + _updateRecords.TryGetValue(new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId))), out last); // guard agains people just putting a large number in the file return last < DateTime.UtcNow ? last : DateTime.MinValue; diff --git a/Emby.Server.Implementations/Security/PluginSecurityManager.cs b/Emby.Server.Implementations/Security/PluginSecurityManager.cs index c3a7e9450..61d4f5252 100644 --- a/Emby.Server.Implementations/Security/PluginSecurityManager.cs +++ b/Emby.Server.Implementations/Security/PluginSecurityManager.cs @@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Security private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; private IEnumerable<IRequiresRegistration> _registeredEntities; protected IEnumerable<IRequiresRegistration> RegisteredEntities @@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.Security /// Initializes a new instance of the <see cref="PluginSecurityManager" /> class. /// </summary> public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, - IApplicationPaths appPaths, ILogManager logManager, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider) + IApplicationPaths appPaths, ILogManager logManager, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) { if (httpClient == null) { diff --git a/Emby.Server.Implementations/ServerManager/ServerManager.cs b/Emby.Server.Implementations/ServerManager/ServerManager.cs index 83ce0b6a3..f660d01ec 100644 --- a/Emby.Server.Implementations/ServerManager/ServerManager.cs +++ b/Emby.Server.Implementations/ServerManager/ServerManager.cs @@ -15,7 +15,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace Emby.Server.Implementations.ServerManager { @@ -75,8 +75,8 @@ namespace Emby.Server.Implementations.ServerManager private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>(); private bool _disposed; - private readonly IMemoryStreamProvider _memoryStreamProvider; - private readonly IEncoding _textEncoding; + private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly ITextEncoding _textEncoding; /// <summary> /// Initializes a new instance of the <see cref="ServerManager" /> class. @@ -86,7 +86,7 @@ namespace Emby.Server.Implementations.ServerManager /// <param name="logger">The logger.</param> /// <param name="configurationManager">The configuration manager.</param> /// <exception cref="System.ArgumentNullException">applicationHost</exception> - public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, IMemoryStreamProvider memoryStreamProvider, IEncoding textEncoding) + public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding) { if (applicationHost == null) { diff --git a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs index dd17edea5..4608a13e6 100644 --- a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; using UniversalDetector; namespace Emby.Server.Implementations.ServerManager @@ -77,8 +77,8 @@ namespace Emby.Server.Implementations.ServerManager /// </summary> /// <value>The query string.</value> public QueryParamCollection QueryString { get; set; } - private readonly IMemoryStreamProvider _memoryStreamProvider; - private readonly IEncoding _textEncoding; + private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly ITextEncoding _textEncoding; /// <summary> /// Initializes a new instance of the <see cref="WebSocketConnection" /> class. @@ -88,7 +88,7 @@ namespace Emby.Server.Implementations.ServerManager /// <param name="jsonSerializer">The json serializer.</param> /// <param name="logger">The logger.</param> /// <exception cref="System.ArgumentNullException">socket</exception> - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamProvider memoryStreamProvider, IEncoding textEncoding) + public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding) { if (socket == null) { @@ -145,7 +145,7 @@ namespace Emby.Server.Implementations.ServerManager } else { - OnReceiveInternal(_textEncoding.GetASCIIString(bytes, 0, bytes.Length)); + OnReceiveInternal(_textEncoding.GetASCIIEncoding().GetString(bytes, 0, bytes.Length)); } } private string DetectCharset(byte[] bytes) diff --git a/Emby.Server.Implementations/Sync/MediaSync.cs b/Emby.Server.Implementations/Sync/MediaSync.cs index b420a3df4..fa8388b6c 100644 --- a/Emby.Server.Implementations/Sync/MediaSync.cs +++ b/Emby.Server.Implementations/Sync/MediaSync.cs @@ -29,12 +29,12 @@ namespace Emby.Server.Implementations.Sync private readonly ILogger _logger; private readonly IFileSystem _fileSystem; private readonly IConfigurationManager _config; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; public const string PathSeparatorString = "/"; public const char PathSeparatorChar = '/'; - public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config, ICryptographyProvider cryptographyProvider) + public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config, ICryptoProvider cryptographyProvider) { _logger = logger; _syncManager = syncManager; @@ -370,7 +370,7 @@ namespace Emby.Server.Implementations.Sync private byte[] CreateMd5(byte[] value) { - return _cryptographyProvider.GetMD5Bytes(value); + return _cryptographyProvider.ComputeMD5(value); } public LocalItem CreateLocalItem(IServerSyncProvider provider, SyncedItem syncedItem, SyncJob job, SyncTarget target, BaseItemDto libraryItem, string serverId, string serverName, string originalFileName) diff --git a/Emby.Server.Implementations/Sync/MultiProviderSync.cs b/Emby.Server.Implementations/Sync/MultiProviderSync.cs index db6cfcbd6..8189b8550 100644 --- a/Emby.Server.Implementations/Sync/MultiProviderSync.cs +++ b/Emby.Server.Implementations/Sync/MultiProviderSync.cs @@ -23,9 +23,9 @@ namespace Emby.Server.Implementations.Sync private readonly ILogger _logger; private readonly IFileSystem _fileSystem; private readonly IConfigurationManager _config; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; - public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem, IConfigurationManager config, ICryptographyProvider cryptographyProvider) + public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem, IConfigurationManager config, ICryptoProvider cryptographyProvider) { _syncManager = syncManager; _appHost = appHost; diff --git a/Emby.Server.Implementations/Sync/ServerSyncScheduledTask.cs b/Emby.Server.Implementations/Sync/ServerSyncScheduledTask.cs index 17171633e..09a0bfde4 100644 --- a/Emby.Server.Implementations/Sync/ServerSyncScheduledTask.cs +++ b/Emby.Server.Implementations/Sync/ServerSyncScheduledTask.cs @@ -20,9 +20,9 @@ namespace Emby.Server.Implementations.Sync private readonly IFileSystem _fileSystem; private readonly IServerApplicationHost _appHost; private readonly IConfigurationManager _config; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; - public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost, IConfigurationManager config, ICryptographyProvider cryptographyProvider) + public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost, IConfigurationManager config, ICryptoProvider cryptographyProvider) { _syncManager = syncManager; _logger = logger; diff --git a/Emby.Server.Implementations/Sync/SyncManager.cs b/Emby.Server.Implementations/Sync/SyncManager.cs index d06ed49fd..13f60f5ee 100644 --- a/Emby.Server.Implementations/Sync/SyncManager.cs +++ b/Emby.Server.Implementations/Sync/SyncManager.cs @@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Sync private readonly Func<IMediaSourceManager> _mediaSourceManager; private readonly IJsonSerializer _json; private readonly ITaskManager _taskManager; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; private ISyncProvider[] _providers = { }; @@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.Sync public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated; public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated; - public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager, IMemoryStreamProvider memoryStreamProvider) + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager, IMemoryStreamFactory memoryStreamProvider) { _libraryManager = libraryManager; _repo = repo; diff --git a/Emby.Server.Implementations/Sync/TargetDataProvider.cs b/Emby.Server.Implementations/Sync/TargetDataProvider.cs index a0e0f4313..fbd82aa7a 100644 --- a/Emby.Server.Implementations/Sync/TargetDataProvider.cs +++ b/Emby.Server.Implementations/Sync/TargetDataProvider.cs @@ -26,9 +26,9 @@ namespace Emby.Server.Implementations.Sync private readonly IFileSystem _fileSystem; private readonly IApplicationPaths _appPaths; private readonly IServerApplicationHost _appHost; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths, IMemoryStreamProvider memoryStreamProvider) + public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths, IMemoryStreamFactory memoryStreamProvider) { _logger = logger; _json = json; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 3c7a8242c..52bf09284 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -119,9 +119,9 @@ namespace Emby.Server.Implementations.Updates /// <value>The application host.</value> private readonly IApplicationHost _applicationHost; - private readonly ICryptographyProvider _cryptographyProvider; + private readonly ICryptoProvider _cryptographyProvider; - public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider) + public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) { if (logger == null) { @@ -606,7 +606,7 @@ namespace Emby.Server.Implementations.Updates { using (var stream = _fileSystem.OpenRead(tempFile)) { - var check = Guid.Parse(BitConverter.ToString(_cryptographyProvider.GetMD5Bytes(stream)).Replace("-", String.Empty)); + var check = Guid.Parse(BitConverter.ToString(_cryptographyProvider.ComputeMD5(stream)).Replace("-", String.Empty)); if (check != packageChecksum) { throw new Exception(string.Format("Download validation failed for {0}. Probably corrupted during transfer.", package.name)); diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs index 93d0b3d55..8125951b5 100644 --- a/MediaBrowser.Api/Dlna/DlnaServerService.cs +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -111,9 +111,9 @@ namespace MediaBrowser.Api.Dlna private readonly IMediaReceiverRegistrar _mediaReceiverRegistrar; private const string XMLContentType = "text/xml; charset=UTF-8"; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar, IMemoryStreamProvider memoryStreamProvider) + public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar, IMemoryStreamFactory memoryStreamProvider) { _dlnaManager = dlnaManager; _contentDirectory = contentDirectory; diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index c62889214..4fa663b19 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1263,6 +1263,7 @@ namespace MediaBrowser.Api.Playback private bool EnableThrottling(StreamState state) { + return false; // do not use throttling with hardware encoders return state.InputProtocol == MediaProtocol.File && state.RunTimeTicks.HasValue && diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs index 09f6e8706..d7f4424fa 100644 --- a/MediaBrowser.Common/Extensions/BaseExtensions.cs +++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Common.Extensions /// </summary> public static class BaseExtensions { - public static ICryptographyProvider CryptographyProvider { get; set; } + public static ICryptoProvider CryptographyProvider { get; set; } /// <summary> /// Strips the HTML. diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index fe60c7ebf..779db0a82 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using System.Collections.Generic; using System.Net; +using System.Threading.Tasks; namespace MediaBrowser.Common.Net { @@ -46,10 +47,14 @@ namespace MediaBrowser.Common.Net /// <returns><c>true</c> if [is in local network] [the specified endpoint]; otherwise, <c>false</c>.</returns> bool IsInLocalNetwork(string endpoint); + IEnumerable<IpAddressInfo> GetLocalIpAddresses(); + IpAddressInfo ParseIpAddress(string ipAddress); bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo); + Task<IpAddressInfo[]> GetHostAddressesAsync(string host); + /// <summary> /// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>. /// </summary> diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 2fd96577a..d2cf23f43 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -85,7 +85,7 @@ namespace MediaBrowser.Controller /// <summary> /// Gets the local API URL. /// </summary> - string GetLocalApiUrl(string ipAddress, bool isIpv6); + string GetLocalApiUrl(IpAddressInfo address); void LaunchUrl(string url); diff --git a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs index 52199c5a2..8169cc7d9 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs @@ -69,7 +69,8 @@ namespace MediaBrowser.Controller.MediaEncoding // if the audio language is not understood by the user, load their preferred subs, if there are any if (!ContainsOrdinal(preferredLanguages, audioTrackLanguage)) { - stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)); + stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)) ?? + streams.FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)); } } else if (mode == SubtitlePlaybackMode.Always) diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs index d45416f53..b025011d7 100644 --- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -7,7 +7,7 @@ namespace MediaBrowser.Controller.Net { public class AuthenticatedAttribute : Attribute, IHasRequestFilter, IAuthenticationAttributes { - public IAuthService AuthService { get; set; } + public static IAuthService AuthService { get; set; } /// <summary> /// Gets or sets the roles. @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Net /// </summary> /// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value> public bool AllowBeforeStartupWizard { get; set; } - + /// <summary> /// The request filter is executed before the service. /// </summary> @@ -41,15 +41,6 @@ namespace MediaBrowser.Controller.Net } /// <summary> - /// A new shallow copy of this filter is used on every request. - /// </summary> - /// <returns>IHasRequestFilter.</returns> - public IHasRequestFilter Copy() - { - return this; - } - - /// <summary> /// Order in which Request Filters are executed. /// <0 Executed before global request filters /// >0 Executed after global request filters @@ -60,7 +51,6 @@ namespace MediaBrowser.Controller.Net get { return 0; } } - public IEnumerable<string> GetRoles() { return (Roles ?? string.Empty).Split(',') diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs index ee7cb9dda..bf7343f3d 100644 --- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs +++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Model.IO; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace MediaBrowser.MediaEncoding.BdInfo { @@ -15,9 +15,9 @@ namespace MediaBrowser.MediaEncoding.BdInfo public class BdInfoExaminer : IBlurayExaminer { private readonly IFileSystem _fileSystem; - private readonly IEncoding _textEncoding; + private readonly ITextEncoding _textEncoding; - public BdInfoExaminer(IFileSystem fileSystem, IEncoding textEncoding) + public BdInfoExaminer(IFileSystem fileSystem, ITextEncoding textEncoding) { _fileSystem = fileSystem; _textEncoding = textEncoding; diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 098cd14db..0d7a7912a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IHttpClient _httpClient; private readonly IZipClient _zipClient; private readonly IProcessFactory _processFactory; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>(); private readonly bool _hasExternalEncoder; @@ -88,7 +88,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly int DefaultImageExtractionTimeoutMs; private readonly bool EnableEncoderFontFile; - public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamProvider memoryStreamProvider, IProcessFactory processFactory, + public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IMemoryStreamFactory memoryStreamProvider, IProcessFactory processFactory, int defaultImageExtractionTimeoutMs, bool enableEncoderFontFile) { diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index f0c4c465d..6a1583094 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -23,9 +23,9 @@ namespace MediaBrowser.MediaEncoding.Probing private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly ILogger _logger; private readonly IFileSystem _fileSystem; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider) + public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem, IMemoryStreamFactory memoryStreamProvider) { _logger = logger; _fileSystem = fileSystem; diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 0baee67ea..5d065f528 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -19,7 +19,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; using MediaBrowser.Model.Diagnostics; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; using UniversalDetector; namespace MediaBrowser.MediaEncoding.Subtitles @@ -34,11 +34,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles private readonly IJsonSerializer _json; private readonly IHttpClient _httpClient; private readonly IMediaSourceManager _mediaSourceManager; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IProcessFactory _processFactory; - private readonly IEncoding _textEncoding; + private readonly ITextEncoding _textEncoding; - public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager, IMemoryStreamProvider memoryStreamProvider, IProcessFactory processFactory, IEncoding textEncoding) + public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager, IMemoryStreamFactory memoryStreamProvider, IProcessFactory processFactory, ITextEncoding textEncoding) { _libraryManager = libraryManager; _logger = logger; diff --git a/MediaBrowser.Model/Cryptography/ICryptoProvider.cs b/MediaBrowser.Model/Cryptography/ICryptoProvider.cs new file mode 100644 index 000000000..7a82dee52 --- /dev/null +++ b/MediaBrowser.Model/Cryptography/ICryptoProvider.cs @@ -0,0 +1,13 @@ +using System; +using System.IO; + +namespace MediaBrowser.Model.Cryptography +{ + public interface ICryptoProvider + { + Guid GetMD5(string str); + byte[] ComputeMD5(Stream str); + byte[] ComputeMD5(byte[] bytes); + byte[] ComputeSHA1(byte[] bytes); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Cryptography/ICryptographyProvider.cs b/MediaBrowser.Model/Cryptography/ICryptographyProvider.cs deleted file mode 100644 index a3f86f9e2..000000000 --- a/MediaBrowser.Model/Cryptography/ICryptographyProvider.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.IO; - -namespace MediaBrowser.Model.Cryptography -{ - public interface ICryptographyProvider - { - Guid GetMD5(string str); - byte[] GetMD5Bytes(string str); - byte[] GetSHA1Bytes(byte[] bytes); - byte[] GetMD5Bytes(Stream str); - byte[] GetMD5Bytes(byte[] bytes); - } -}
\ No newline at end of file diff --git a/MediaBrowser.Model/IO/IMemoryStreamProvider.cs b/MediaBrowser.Model/IO/IMemoryStreamFactory.cs index 82a758d9a..f4f174643 100644 --- a/MediaBrowser.Model/IO/IMemoryStreamProvider.cs +++ b/MediaBrowser.Model/IO/IMemoryStreamFactory.cs @@ -2,10 +2,11 @@ namespace MediaBrowser.Model.IO { - public interface IMemoryStreamProvider + public interface IMemoryStreamFactory { MemoryStream CreateNew(); MemoryStream CreateNew(int capacity); MemoryStream CreateNew(byte[] buffer); + bool TryGetBuffer(MemoryStream stream, out byte[] buffer); } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 52e477b1a..ee7582619 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -100,7 +100,7 @@ <Compile Include="Connect\PinExchangeResult.cs" /> <Compile Include="Connect\PinStatusResult.cs" /> <Compile Include="Connect\UserLinkType.cs" /> - <Compile Include="Cryptography\ICryptographyProvider.cs" /> + <Compile Include="Cryptography\ICryptoProvider.cs" /> <Compile Include="Devices\DeviceOptions.cs" /> <Compile Include="Devices\DeviceQuery.cs" /> <Compile Include="Devices\LocalFileInfo.cs" /> @@ -138,17 +138,19 @@ <Compile Include="Dto\NameIdPair.cs" /> <Compile Include="Dto\NameValuePair.cs" /> <Compile Include="Net\IpEndPointInfo.cs" /> + <Compile Include="Net\ISocket.cs" /> <Compile Include="Net\ISocketFactory.cs" /> <Compile Include="Net\IUdpSocket.cs" /> <Compile Include="Net\SocketReceiveResult.cs" /> + <Compile Include="Services\IHttpResult.cs" /> <Compile Include="System\IEnvironmentInfo.cs" /> - <Compile Include="TextEncoding\IEncoding.cs" /> + <Compile Include="Text\ITextEncoding.cs" /> <Compile Include="Extensions\LinqExtensions.cs" /> <Compile Include="FileOrganization\SmartMatchInfo.cs" /> <Compile Include="Health\IHealthMonitor.cs" /> <Compile Include="IO\FileSystemMetadata.cs" /> <Compile Include="IO\IFileSystem.cs" /> - <Compile Include="IO\IMemoryStreamProvider.cs" /> + <Compile Include="IO\IMemoryStreamFactory.cs" /> <Compile Include="IO\IShortcutHandler.cs" /> <Compile Include="IO\StreamDefaults.cs" /> <Compile Include="Globalization\ILocalizationManager.cs" /> diff --git a/MediaBrowser.Model/Net/ISocket.cs b/MediaBrowser.Model/Net/ISocket.cs new file mode 100644 index 000000000..371fbc567 --- /dev/null +++ b/MediaBrowser.Model/Net/ISocket.cs @@ -0,0 +1,16 @@ +using System; + +namespace MediaBrowser.Model.Net +{ + public interface ISocket : IDisposable + { + IpEndPointInfo LocalEndPoint { get; } + IpEndPointInfo RemoteEndPoint { get; } + void Close(); + void Shutdown(bool both); + void Listen(int backlog); + void Bind(IpEndPointInfo endpoint); + + void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed); + } +} diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 3f1ddf84f..599292ddf 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -27,5 +27,17 @@ namespace MediaBrowser.Model.Net /// <param name="localPort">The local port to bind to.</param> /// <returns>A <see cref="IUdpSocket"/> implementation.</returns> IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); - } + + ISocket CreateSocket(IpAddressFamily family, SocketType socketType, ProtocolType protocolType, bool dualMode); + } + + public enum SocketType + { + Stream + } + + public enum ProtocolType + { + Tcp + } } diff --git a/MediaBrowser.Model/Net/IpAddressInfo.cs b/MediaBrowser.Model/Net/IpAddressInfo.cs index b48347d1d..47ffe5118 100644 --- a/MediaBrowser.Model/Net/IpAddressInfo.cs +++ b/MediaBrowser.Model/Net/IpAddressInfo.cs @@ -4,12 +4,39 @@ namespace MediaBrowser.Model.Net { public class IpAddressInfo { + public static IpAddressInfo Any = new IpAddressInfo("0.0.0.0", IpAddressFamily.InterNetwork); + public static IpAddressInfo IPv6Any = new IpAddressInfo("00000000000000000000", IpAddressFamily.InterNetworkV6); + public static IpAddressInfo Loopback = new IpAddressInfo("127.0.0.1", IpAddressFamily.InterNetwork); + public static IpAddressInfo IPv6Loopback = new IpAddressInfo("IPv6Loopback", IpAddressFamily.InterNetworkV6); + public string Address { get; set; } - public bool IsIpv6 { get; set; } + public IpAddressFamily AddressFamily { get; set; } + + public IpAddressInfo() + { + + } + + public IpAddressInfo(string address, IpAddressFamily addressFamily) + { + Address = address; + AddressFamily = addressFamily; + } + + public bool Equals(IpAddressInfo address) + { + return string.Equals(address.Address, Address, StringComparison.OrdinalIgnoreCase); + } public override String ToString() { return Address; } } + + public enum IpAddressFamily + { + InterNetwork, + InterNetworkV6 + } } diff --git a/MediaBrowser.Model/Net/IpEndPointInfo.cs b/MediaBrowser.Model/Net/IpEndPointInfo.cs index 5fd331a16..b5cadc429 100644 --- a/MediaBrowser.Model/Net/IpEndPointInfo.cs +++ b/MediaBrowser.Model/Net/IpEndPointInfo.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; namespace MediaBrowser.Model.Net { @@ -8,11 +9,22 @@ namespace MediaBrowser.Model.Net public int Port { get; set; } + public IpEndPointInfo() + { + + } + + public IpEndPointInfo(IpAddressInfo address, int port) + { + IpAddress = address; + Port = port; + } + public override string ToString() { var ipAddresString = IpAddress == null ? string.Empty : IpAddress.ToString(); - return ipAddresString + ":" + this.Port.ToString(); + return ipAddresString + ":" + Port.ToString(CultureInfo.InvariantCulture); } } } diff --git a/MediaBrowser.Model/Services/IHasRequestFilter.cs b/MediaBrowser.Model/Services/IHasRequestFilter.cs index c5c6ccf59..2164179d5 100644 --- a/MediaBrowser.Model/Services/IHasRequestFilter.cs +++ b/MediaBrowser.Model/Services/IHasRequestFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - + namespace MediaBrowser.Model.Services { public interface IHasRequestFilter @@ -22,11 +17,5 @@ namespace MediaBrowser.Model.Services /// <param name="res">The http response wrapper</param> /// <param name="requestDto">The request DTO</param> void RequestFilter(IRequest req, IResponse res, object requestDto); - - /// <summary> - /// A new shallow copy of this filter is used on every request. - /// </summary> - /// <returns></returns> - IHasRequestFilter Copy(); } } diff --git a/MediaBrowser.Model/Services/IHttpResult.cs b/MediaBrowser.Model/Services/IHttpResult.cs new file mode 100644 index 000000000..36ffeb284 --- /dev/null +++ b/MediaBrowser.Model/Services/IHttpResult.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Model.Services +{ + public interface IHttpResult : IHasHeaders + { + /// <summary> + /// The HTTP Response Status + /// </summary> + int Status { get; set; } + + /// <summary> + /// The HTTP Response Status Code + /// </summary> + HttpStatusCode StatusCode { get; set; } + + /// <summary> + /// The HTTP Status Description + /// </summary> + string StatusDescription { get; set; } + + /// <summary> + /// The HTTP Response ContentType + /// </summary> + string ContentType { get; set; } + + /// <summary> + /// Additional HTTP Cookies + /// </summary> + List<Cookie> Cookies { get; } + + /// <summary> + /// Response DTO + /// </summary> + object Response { get; set; } + + /// <summary> + /// Holds the request call context + /// </summary> + IRequest RequestContext { get; set; } + } +} diff --git a/MediaBrowser.Model/Services/IRequest.cs b/MediaBrowser.Model/Services/IRequest.cs index 45dc97b76..5dc995b06 100644 --- a/MediaBrowser.Model/Services/IRequest.cs +++ b/MediaBrowser.Model/Services/IRequest.cs @@ -60,16 +60,6 @@ namespace MediaBrowser.Model.Services QueryParamCollection QueryString { get; } QueryParamCollection FormData { get; } - /// <summary> - /// Buffer the Request InputStream so it can be re-read - /// </summary> - bool UseBufferedStream { get; set; } - - /// <summary> - /// The entire string contents of Request.InputStream - /// </summary> - /// <returns></returns> - string GetRawBody(); string RawUrl { get; } diff --git a/MediaBrowser.Model/Services/QueryParamCollection.cs b/MediaBrowser.Model/Services/QueryParamCollection.cs index 1ab3f0bfb..dfea62821 100644 --- a/MediaBrowser.Model/Services/QueryParamCollection.cs +++ b/MediaBrowser.Model/Services/QueryParamCollection.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Model.Services { public QueryParamCollection() { - + } public QueryParamCollection(IDictionary<string, string> headers) @@ -30,15 +30,30 @@ namespace MediaBrowser.Model.Services return StringComparer.OrdinalIgnoreCase; } + public string GetKey(int index) + { + return this[index].Name; + } + + public string Get(int index) + { + return this[index].Value; + } + + public virtual string[] GetValues(int index) + { + return new[] { Get(index) }; + } + /// <summary> /// Adds a new query parameter. /// </summary> - public void Add(string key, string value) + public virtual void Add(string key, string value) { Add(new NameValuePair(key, value)); } - public void Set(string key, string value) + public virtual void Set(string key, string value) { if (string.IsNullOrWhiteSpace(value)) { @@ -81,17 +96,21 @@ namespace MediaBrowser.Model.Services /// </summary> /// <returns>The number of parameters that were removed</returns> /// <exception cref="ArgumentNullException"><paramref name="name" /> is null.</exception> - public int Remove(string name) + public virtual int Remove(string name) { return RemoveAll(p => p.Name == name); } public string Get(string name) { - return GetValues(name).FirstOrDefault(); + var stringComparison = GetStringComparison(); + + return this.Where(p => string.Equals(p.Name, name, stringComparison)) + .Select(p => p.Value) + .FirstOrDefault(); } - public string[] GetValues(string name) + public virtual string[] GetValues(string name) { var stringComparison = GetStringComparison(); diff --git a/MediaBrowser.Model/Text/ITextEncoding.cs b/MediaBrowser.Model/Text/ITextEncoding.cs new file mode 100644 index 000000000..6901f1f94 --- /dev/null +++ b/MediaBrowser.Model/Text/ITextEncoding.cs @@ -0,0 +1,10 @@ +using System.Text; + +namespace MediaBrowser.Model.Text +{ + public interface ITextEncoding + { + Encoding GetASCIIEncoding(); + Encoding GetFileEncoding(string path); + } +} diff --git a/MediaBrowser.Model/TextEncoding/IEncoding.cs b/MediaBrowser.Model/TextEncoding/IEncoding.cs deleted file mode 100644 index 3d884c9d2..000000000 --- a/MediaBrowser.Model/TextEncoding/IEncoding.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text; - -namespace MediaBrowser.Model.TextEncoding -{ - public interface IEncoding - { - byte[] GetASCIIBytes(string text); - string GetASCIIString(byte[] bytes, int startIndex, int length); - - Encoding GetFileEncoding(string path); - } -} diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index d4bfad174..59d67740d 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.Providers.Manager private readonly ILibraryMonitor _libraryMonitor; private readonly IFileSystem _fileSystem; private readonly ILogger _logger; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; /// <summary> /// Initializes a new instance of the <see cref="ImageSaver" /> class. @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Manager /// <param name="libraryMonitor">The directory watchers.</param> /// <param name="fileSystem">The file system.</param> /// <param name="logger">The logger.</param> - public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger, IMemoryStreamProvider memoryStreamProvider) + public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger, IMemoryStreamFactory memoryStreamProvider) { _config = config; _libraryMonitor = libraryMonitor; diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 67ad21dbb..5e00b356a 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.Manager private IExternalId[] _externalIds; private readonly Func<ILibraryManager> _libraryManagerFactory; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; /// <summary> /// Initializes a new instance of the <see cref="ProviderManager" /> class. @@ -76,7 +76,7 @@ namespace MediaBrowser.Providers.Manager /// <param name="libraryMonitor">The directory watchers.</param> /// <param name="logManager">The log manager.</param> /// <param name="fileSystem">The file system.</param> - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json, IMemoryStreamProvider memoryStreamProvider) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json, IMemoryStreamFactory memoryStreamProvider) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs index e4becec56..313feda52 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs @@ -45,6 +45,11 @@ namespace MediaBrowser.Providers.MediaInfo var codec = Path.GetExtension(fullName).ToLower().TrimStart('.'); + if (string.Equals(codec, "txt", StringComparison.OrdinalIgnoreCase)) + { + codec = "srt"; + } + // If the subtitle file matches the video file name if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) { @@ -74,9 +79,9 @@ namespace MediaBrowser.Providers.MediaInfo // Try to translate to three character code // Be flexible and check against both the full and three character versions var culture = _localization.GetCultures() - .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || - string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || - string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || + .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || + string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || + string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase)); if (culture != null) @@ -119,7 +124,7 @@ namespace MediaBrowser.Providers.MediaInfo { get { - return new[] { ".srt", ".ssa", ".ass", ".sub", ".smi", ".sami" }; + return new[] { ".srt", ".ssa", ".ass", ".sub", ".smi", ".sami", ".txt" }; } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index 66adf6c8a..5147e9d10 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -40,10 +40,10 @@ namespace MediaBrowser.Providers.TV private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly ILocalizationManager _localizationManager; - public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamProvider memoryStreamProvider, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager) + public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamFactory memoryStreamProvider, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager) { _zipClient = zipClient; _httpClient = httpClient; diff --git a/MediaBrowser.Server.Implementations/HttpServer/ContainerAdapter.cs b/MediaBrowser.Server.Implementations/HttpServer/ContainerAdapter.cs index 93d224b8d..235b62f69 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ContainerAdapter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ContainerAdapter.cs @@ -6,7 +6,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// <summary> /// Class ContainerAdapter /// </summary> - class ContainerAdapter : IContainerAdapter, IRelease + class ContainerAdapter : IContainerAdapter { /// <summary> /// The _app host @@ -40,14 +40,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer { return _appHost.TryResolve<T>(); } - - /// <summary> - /// Releases the specified instance. - /// </summary> - /// <param name="instance">The instance.</param> - public void Release(object instance) - { - // Leave this empty so SS doesn't try to dispose our objects - } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 805cb0353..ebb282503 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -8,24 +8,31 @@ using MediaBrowser.Server.Implementations.HttpServer.SocketSharp; using ServiceStack; using ServiceStack.Host; using ServiceStack.Host.Handlers; -using ServiceStack.Logging; using ServiceStack.Web; using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Security; +using System.Net.Sockets; using System.Reflection; +using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +using Emby.Common.Implementations.Net; using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer.SocketSharp; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; using MediaBrowser.Controller; +using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; -using ServiceStack.Api.Swagger; +using MediaBrowser.Model.Text; +using SocketHttpListener.Net; +using SocketHttpListener.Primitives; namespace MediaBrowser.Server.Implementations.HttpServer { @@ -49,21 +56,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IServerApplicationHost _appHost; + private readonly ITextEncoding _textEncoding; + private readonly ISocketFactory _socketFactory; + private readonly ICryptoProvider _cryptoProvider; + public HttpListenerHost(IServerApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, string serviceName, - string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamProvider memoryStreamProvider, params Assembly[] assembliesWithServices) - : base(serviceName, assembliesWithServices) + string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider) + : base(serviceName, new Assembly[] { }) { _appHost = applicationHost; DefaultRedirectPath = defaultRedirectPath; _networkManager = networkManager; _memoryStreamProvider = memoryStreamProvider; + _textEncoding = textEncoding; + _socketFactory = socketFactory; + _cryptoProvider = cryptoProvider; _config = config; _logger = logManager.GetLogger("HttpServer"); @@ -73,10 +87,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer public string GlobalResponse { get; set; } - public override void Configure(Container container) + public override void Configure() { HostConfig.Instance.DefaultRedirectPath = DefaultRedirectPath; - HostConfig.Instance.LogUnobservedTaskExceptions = false; HostConfig.Instance.MapExceptionToStatusCode = new Dictionary<Type, int> { @@ -94,19 +107,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer }; HostConfig.Instance.GlobalResponseHeaders = new Dictionary<string, string>(); - HostConfig.Instance.DebugMode = false; - - HostConfig.Instance.LogFactory = LogManager.LogFactory; - HostConfig.Instance.AllowJsonpRequests = false; // The Markdown feature causes slow startup times (5 mins+) on cold boots for some users // Custom format allows images HostConfig.Instance.EnableFeatures = Feature.Html | Feature.Json | Feature.Xml | Feature.CustomFormat; - container.Adapter = _containerAdapter; - - Plugins.Add(new SwaggerFeature()); - Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization")); + Container.Adapter = _containerAdapter; //Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] { // new SessionAuthProvider(_containerAdapter.Resolve<ISessionContext>()), @@ -130,6 +136,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse); } + protected override ILogger Logger + { + get + { + return _logger; + } + } + public override void OnAfterInit() { SetAppDomainData(); @@ -207,7 +221,33 @@ namespace MediaBrowser.Server.Implementations.HttpServer private IHttpListener GetListener() { - return new WebSocketSharpListener(_logger, CertificatePath, _memoryStreamProvider); + var cert = !string.IsNullOrWhiteSpace(CertificatePath) && File.Exists(CertificatePath) + ? GetCert(CertificatePath) : + null; + + return new WebSocketSharpListener(_logger, cert, _memoryStreamProvider, _textEncoding, _networkManager, _socketFactory, _cryptoProvider, new StreamFactory(), GetRequest); + } + + public static ICertificate GetCert(string certificateLocation) + { + X509Certificate2 localCert = new X509Certificate2(certificateLocation); + //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA; + if (localCert.PrivateKey == null) + { + //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation); + return null; + } + + return new Certificate(localCert); + } + + private IHttpRequest GetRequest(HttpListenerContext httpContext) + { + var operationName = httpContext.Request.GetOperationName(); + + var req = new WebSocketSharpRequest(httpContext, operationName, _logger, _memoryStreamProvider); + + return req; } private void OnWebSocketConnecting(WebSocketConnectingEventArgs args) @@ -259,11 +299,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer var contentType = httpReq.ResponseContentType; - var serializer = HostContext.ContentTypes.GetResponseSerializer(contentType); + var serializer = ContentTypes.Instance.GetResponseSerializer(contentType); if (serializer == null) { contentType = HostContext.Config.DefaultContentType; - serializer = HostContext.ContentTypes.GetResponseSerializer(contentType); + serializer = ContentTypes.Instance.GetResponseSerializer(contentType); } var httpError = ex as IHttpError; @@ -411,171 +451,170 @@ namespace MediaBrowser.Server.Implementations.HttpServer protected async Task RequestHandler(IHttpRequest httpReq, Uri url) { var date = DateTime.Now; - var httpRes = httpReq.Response; + bool enableLog = false; + string urlToLog = null; + string remoteIp = null; - if (_disposed) + try { - httpRes.StatusCode = 503; - httpRes.Close(); - return ; - } + if (_disposed) + { + httpRes.StatusCode = 503; + return; + } - if (!ValidateHost(url)) - { - httpRes.StatusCode = 400; - httpRes.ContentType = "text/plain"; - httpRes.Write("Invalid host"); + if (!ValidateHost(url)) + { + httpRes.StatusCode = 400; + httpRes.ContentType = "text/plain"; + httpRes.Write("Invalid host"); + return; + } - httpRes.Close(); - return; - } + if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase)) + { + httpRes.StatusCode = 200; + httpRes.AddHeader("Access-Control-Allow-Origin", "*"); + httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); + httpRes.AddHeader("Access-Control-Allow-Headers", + "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); + httpRes.ContentType = "text/html"; + return; + } - if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase)) - { - httpRes.StatusCode = 200; - httpRes.AddHeader("Access-Control-Allow-Origin", "*"); - httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - httpRes.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); - httpRes.ContentType = "text/html"; + var operationName = httpReq.OperationName; + var localPath = url.LocalPath; - httpRes.Close(); - } + var urlString = url.OriginalString; + enableLog = EnableLogging(urlString, localPath); + urlToLog = urlString; - var operationName = httpReq.OperationName; - var localPath = url.LocalPath; + if (enableLog) + { + urlToLog = GetUrlToLog(urlString); + remoteIp = httpReq.RemoteIp; - var urlString = url.OriginalString; - var enableLog = EnableLogging(urlString, localPath); - var urlToLog = urlString; + LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent); + } - if (enableLog) - { - urlToLog = GetUrlToLog(urlString); - LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent); - } + if (string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase) || + string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase)) + { + RedirectToUrl(httpRes, DefaultRedirectPath); + return; + } + if (string.Equals(localPath, "/emby", StringComparison.OrdinalIgnoreCase) || + string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase)) + { + RedirectToUrl(httpRes, "emby/" + DefaultRedirectPath); + return; + } - if (string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase) || - string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl(DefaultRedirectPath); - return; - } - if (string.Equals(localPath, "/emby", StringComparison.OrdinalIgnoreCase) || - string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl("emby/" + DefaultRedirectPath); - return; - } + if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || + string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) || + localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1) + { + httpRes.StatusCode = 200; + httpRes.ContentType = "text/html"; + var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) + .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); - if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || - string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) || - localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1) - { - httpRes.StatusCode = 200; - httpRes.ContentType = "text/html"; - var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) - .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); + if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + { + httpRes.Write( + "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + + newUrl + "\">" + newUrl + "</a></body></html>"); + return; + } + } - if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 && + localPath.IndexOf("web/dashboard", StringComparison.OrdinalIgnoreCase) == -1) { - httpRes.Write("<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + newUrl + "\">" + newUrl + "</a></body></html>"); + httpRes.StatusCode = 200; + httpRes.ContentType = "text/html"; + var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) + .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); - httpRes.Close(); - return; + if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + { + httpRes.Write( + "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + + newUrl + "\">" + newUrl + "</a></body></html>"); + return; + } } - } - if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 && - localPath.IndexOf("web/dashboard", StringComparison.OrdinalIgnoreCase) == -1) - { - httpRes.StatusCode = 200; - httpRes.ContentType = "text/html"; - var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) - .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); + if (string.Equals(localPath, "/web", StringComparison.OrdinalIgnoreCase)) + { + RedirectToUrl(httpRes, DefaultRedirectPath); + return; + } + if (string.Equals(localPath, "/web/", StringComparison.OrdinalIgnoreCase)) + { + RedirectToUrl(httpRes, "../" + DefaultRedirectPath); + return; + } + if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase)) + { + RedirectToUrl(httpRes, DefaultRedirectPath); + return; + } + if (string.IsNullOrEmpty(localPath)) + { + RedirectToUrl(httpRes, "/" + DefaultRedirectPath); + return; + } - if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase)) { - httpRes.Write("<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + newUrl + "\">" + newUrl + "</a></body></html>"); + RedirectToUrl(httpRes, "web/pin.html"); + return; + } - httpRes.Close(); + if (!string.IsNullOrWhiteSpace(GlobalResponse)) + { + httpRes.StatusCode = 503; + httpRes.ContentType = "text/html"; + httpRes.Write(GlobalResponse); return; } - } - if (string.Equals(localPath, "/web", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl(DefaultRedirectPath); - return; - } - if (string.Equals(localPath, "/web/", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl("../" + DefaultRedirectPath); - return; - } - if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl(DefaultRedirectPath); - return; - } - if (string.IsNullOrEmpty(localPath)) - { - httpRes.RedirectToUrl("/" + DefaultRedirectPath); - return; - } + var handler = HttpHandlerFactory.GetHandler(httpReq); - if (string.Equals(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase)) - { - httpRes.RedirectToUrl("web/pin.html"); - return; + if (handler != null) + { + await handler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false); + } } - - if (!string.IsNullOrWhiteSpace(GlobalResponse)) + catch (Exception ex) { - httpRes.StatusCode = 503; - httpRes.ContentType = "text/html"; - httpRes.Write(GlobalResponse); - - httpRes.Close(); - return; + ErrorHandler(ex, httpReq); } - - var handler = HttpHandlerFactory.GetHandler(httpReq); - - var remoteIp = httpReq.RemoteIp; - - var serviceStackHandler = handler as IServiceStackHandler; - if (serviceStackHandler != null) + finally { - var restHandler = serviceStackHandler as RestHandler; - if (restHandler != null) - { - httpReq.OperationName = operationName = restHandler.RestPath.RequestType.GetOperationName(); - } + httpRes.Close(); - try - { - await serviceStackHandler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false); - } - finally + if (enableLog) { - httpRes.Close(); var statusCode = httpRes.StatusCode; var duration = DateTime.Now - date; - if (enableLog) - { - LoggerUtils.LogResponse(_logger, statusCode, urlToLog, remoteIp, duration); - } + LoggerUtils.LogResponse(_logger, statusCode, urlToLog, remoteIp, duration); } } - else - { - httpRes.Close(); - } } + public static void RedirectToUrl(IResponse httpRes, string url) + { + httpRes.StatusCode = 302; + httpRes.AddHeader(HttpHeaders.Location, url); + httpRes.EndRequest(); + } + + /// <summary> /// Adds the rest handlers. /// </summary> @@ -653,15 +692,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer return "mediabrowser/" + path; } - /// <summary> - /// Releases the specified instance. - /// </summary> - /// <param name="instance">The instance.</param> - public override void Release(object instance) - { - // Leave this empty so SS doesn't try to dispose our objects - } - private bool _disposed; private readonly object _disposeLock = new object(); protected virtual void Dispose(bool disposing) @@ -696,4 +726,37 @@ namespace MediaBrowser.Server.Implementations.HttpServer Start(UrlPrefixes.First()); } } + + public class StreamFactory : IStreamFactory + { + public Stream CreateNetworkStream(ISocket socket, bool ownsSocket) + { + var netSocket = (NetSocket)socket; + + return new NetworkStream(netSocket.Socket, ownsSocket); + } + + public Task AuthenticateSslStreamAsServer(Stream stream, ICertificate certificate) + { + var sslStream = (SslStream)stream; + var cert = (Certificate)certificate; + + return sslStream.AuthenticateAsServerAsync(cert.X509Certificate); + } + + public Stream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen) + { + return new SslStream(innerStream, leaveInnerStreamOpen); + } + } + + public class Certificate : ICertificate + { + public Certificate(X509Certificate x509Certificate) + { + X509Certificate = x509Certificate; + } + + public X509Certificate X509Certificate { get; private set; } + } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index 95e1a35e6..4c251ba24 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -9,6 +9,7 @@ using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; +using Emby.Server.Implementations.HttpServer; using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; using ServiceStack; diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs index 4dff2d5a3..5da515900 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs @@ -2,9 +2,11 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; +using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; -using ServiceStack.Logging; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Text; namespace MediaBrowser.Server.Implementations.HttpServer { @@ -21,13 +23,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer ILogManager logManager, IServerConfigurationManager config, INetworkManager networkmanager, - IMemoryStreamProvider streamProvider, + IMemoryStreamFactory streamProvider, string serverName, - string defaultRedirectpath) + string defaultRedirectpath, + ITextEncoding textEncoding, + ISocketFactory socketFactory, + ICryptoProvider cryptoProvider) { - LogManager.LogFactory = new ServerLogFactory(logManager); - - return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, networkmanager, streamProvider); + return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, networkmanager, streamProvider, textEncoding, socketFactory, cryptoProvider); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerLogFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerLogFactory.cs deleted file mode 100644 index 40af3f3b0..000000000 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerLogFactory.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using MediaBrowser.Model.Logging; -using ServiceStack.Logging; - -namespace MediaBrowser.Server.Implementations.HttpServer -{ - /// <summary> - /// Class ServerLogFactory - /// </summary> - public class ServerLogFactory : ILogFactory - { - /// <summary> - /// The _log manager - /// </summary> - private readonly ILogManager _logManager; - - /// <summary> - /// Initializes a new instance of the <see cref="ServerLogFactory"/> class. - /// </summary> - /// <param name="logManager">The log manager.</param> - public ServerLogFactory(ILogManager logManager) - { - _logManager = logManager; - } - - /// <summary> - /// Gets the logger. - /// </summary> - /// <param name="typeName">Name of the type.</param> - /// <returns>ILog.</returns> - public ILog GetLogger(string typeName) - { - return new ServerLogger(_logManager.GetLogger(typeName)); - } - - /// <summary> - /// Gets the logger. - /// </summary> - /// <param name="type">The type.</param> - /// <returns>ILog.</returns> - public ILog GetLogger(Type type) - { - return GetLogger(type.Name); - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerLogger.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerLogger.cs deleted file mode 100644 index bf7924784..000000000 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerLogger.cs +++ /dev/null @@ -1,194 +0,0 @@ -using MediaBrowser.Model.Logging; -using ServiceStack.Logging; -using System; - -namespace MediaBrowser.Server.Implementations.HttpServer -{ - /// <summary> - /// Class ServerLogger - /// </summary> - public class ServerLogger : ILog - { - /// <summary> - /// The _logger - /// </summary> - private readonly ILogger _logger; - - /// <summary> - /// Initializes a new instance of the <see cref="ServerLogger"/> class. - /// </summary> - /// <param name="logger">The logger.</param> - public ServerLogger(ILogger logger) - { - _logger = logger; - } - - /// <summary> - /// Logs a Debug message and exception. - /// </summary> - /// <param name="message">The message.</param> - /// <param name="exception">The exception.</param> - public void Debug(object message, Exception exception) - { - _logger.ErrorException(GetMesssage(message), exception); - } - - /// <summary> - /// Logs a Debug message. - /// </summary> - /// <param name="message">The message.</param> - public void Debug(object message) - { - // Way too verbose. Can always make this configurable if needed again. - //_logger.Debug(GetMesssage(message)); - } - - /// <summary> - /// Logs a Debug format message. - /// </summary> - /// <param name="format">The format.</param> - /// <param name="args">The args.</param> - public void DebugFormat(string format, params object[] args) - { - // Way too verbose. Can always make this configurable if needed again. - //_logger.Debug(format, args); - } - - /// <summary> - /// Logs a Error message and exception. - /// </summary> - /// <param name="message">The message.</param> - /// <param name="exception">The exception.</param> - public void Error(object message, Exception exception) - { - _logger.ErrorException(GetMesssage(message), exception); - } - - /// <summary> - /// Logs a Error message. - /// </summary> - /// <param name="message">The message.</param> - public void Error(object message) - { - _logger.Error(GetMesssage(message)); - } - - /// <summary> - /// Logs a Error format message. - /// </summary> - /// <param name="format">The format.</param> - /// <param name="args">The args.</param> - public void ErrorFormat(string format, params object[] args) - { - _logger.Error(format, args); - } - - /// <summary> - /// Logs a Fatal message and exception. - /// </summary> - /// <param name="message">The message.</param> - /// <param name="exception">The exception.</param> - public void Fatal(object message, Exception exception) - { - _logger.FatalException(GetMesssage(message), exception); - } - - /// <summary> - /// Logs a Fatal message. - /// </summary> - /// <param name="message">The message.</param> - public void Fatal(object message) - { - _logger.Fatal(GetMesssage(message)); - } - - /// <summary> - /// Logs a Error format message. - /// </summary> - /// <param name="format">The format.</param> - /// <param name="args">The args.</param> - public void FatalFormat(string format, params object[] args) - { - _logger.Fatal(format, args); - } - - /// <summary> - /// Logs an Info message and exception. - /// </summary> - /// <param name="message">The message.</param> - /// <param name="exception">The exception.</param> - public void Info(object message, Exception exception) - { - _logger.ErrorException(GetMesssage(message), exception); - } - - /// <summary> - /// Logs an Info message and exception. - /// </summary> - /// <param name="message">The message.</param> - public void Info(object message) - { - _logger.Info(GetMesssage(message)); - } - - /// <summary> - /// Logs an Info format message. - /// </summary> - /// <param name="format">The format.</param> - /// <param name="args">The args.</param> - public void InfoFormat(string format, params object[] args) - { - _logger.Info(format, args); - } - - /// <summary> - /// Gets or sets a value indicating whether this instance is debug enabled. - /// </summary> - /// <value><c>true</c> if this instance is debug enabled; otherwise, <c>false</c>.</value> - public bool IsDebugEnabled - { - get { return true; } - } - - /// <summary> - /// Logs a Warning message and exception. - /// </summary> - /// <param name="message">The message.</param> - /// <param name="exception">The exception.</param> - public void Warn(object message, Exception exception) - { - _logger.ErrorException(GetMesssage(message), exception); - } - - /// <summary> - /// Logs a Warning message. - /// </summary> - /// <param name="message">The message.</param> - public void Warn(object message) - { - // Hide StringMapTypeDeserializer messages - // _logger.Warn(GetMesssage(message)); - } - - /// <summary> - /// Logs a Warning format message. - /// </summary> - /// <param name="format">The format.</param> - /// <param name="args">The args.</param> - public void WarnFormat(string format, params object[] args) - { - // Hide StringMapTypeDeserializer messages - // _logger.Warn(format, args); - } - - /// <summary> - /// Gets the messsage. - /// </summary> - /// <param name="o">The o.</param> - /// <returns>System.String.</returns> - private string GetMesssage(object o) - { - return o == null ? string.Empty : o.ToString(); - } - } -} diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/Extensions.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/Extensions.cs deleted file mode 100644 index 154313fb9..000000000 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/Extensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using MediaBrowser.Model.Logging; -using SocketHttpListener.Net; -using System; - -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp -{ - public static class Extensions - { - public static string GetOperationName(this HttpListenerRequest request) - { - return request.Url.Segments[request.Url.Segments.Length - 1]; - } - - public static void CloseOutputStream(this HttpListenerResponse response, ILogger logger) - { - try - { - response.OutputStream.Flush(); - response.OutputStream.Close(); - response.Close(); - } - catch (Exception ex) - { - logger.ErrorException("Error in HttpListenerResponseWrapper: " + ex.Message, ex); - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs index 13ae48cff..543eb4afe 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs @@ -2,11 +2,10 @@ using System.Collections.Specialized; using System.Globalization; using System.IO; +using System.Net; using System.Text; using System.Threading.Tasks; -using System.Web; using MediaBrowser.Model.Services; -using ServiceStack; namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { @@ -128,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return string.IsNullOrEmpty(request.Headers[HttpHeaders.Accept]) ? null : request.Headers[HttpHeaders.Accept]; + return string.IsNullOrEmpty(request.Headers["Accept"]) ? null : request.Headers["Accept"]; } } @@ -136,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return string.IsNullOrEmpty(request.Headers[HttpHeaders.Authorization]) ? null : request.Headers[HttpHeaders.Authorization]; + return string.IsNullOrEmpty(request.Headers["Authorization"]) ? null : request.Headers["Authorization"]; } } @@ -152,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp string msg = String.Format("A potentially dangerous Request.{0} value was " + "detected from the client ({1}={2}).", name, key, v); - throw new HttpRequestValidationException(msg); + throw new Exception(msg); } static void ValidateNameValueCollection(string name, QueryParamCollection coll) @@ -278,9 +277,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp void AddRawKeyValue(StringBuilder key, StringBuilder value) { - string decodedKey = HttpUtility.UrlDecode(key.ToString(), ContentEncoding); + string decodedKey = WebUtility.UrlDecode(key.ToString()); form.Add(decodedKey, - HttpUtility.UrlDecode(value.ToString(), ContentEncoding)); + WebUtility.UrlDecode(value.ToString())); key.Length = 0; value.Length = 0; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 72047609d..6f44fcce7 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -1,17 +1,14 @@ using System; using System.Collections.Generic; -using System.Collections.Specialized; using System.IO; using System.Text; using Emby.Server.Implementations.HttpServer.SocketSharp; using Funq; -using MediaBrowser.Common.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Services; using ServiceStack; using ServiceStack.Host; -using ServiceStack.Web; using SocketHttpListener.Net; using IHttpFile = MediaBrowser.Model.Services.IHttpFile; using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest; @@ -25,9 +22,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public Container Container { get; set; } private readonly HttpListenerRequest request; private readonly IHttpResponse response; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider) + public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, ILogger logger, IMemoryStreamFactory memoryStreamProvider) { this.OperationName = operationName; _memoryStreamProvider = memoryStreamProvider; @@ -55,36 +52,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp get { return response; } } - public T TryResolve<T>() - { - if (typeof(T) == typeof(IHttpRequest)) - throw new Exception("You don't need to use IHttpRequest.TryResolve<IHttpRequest> to resolve itself"); - - if (typeof(T) == typeof(IHttpResponse)) - throw new Exception("Resolve IHttpResponse with 'Response' property instead of IHttpRequest.TryResolve<IHttpResponse>"); - - return Container == null - ? HostContext.TryResolve<T>() - : Container.TryResolve<T>(); - } - public string OperationName { get; set; } public object Dto { get; set; } - public string GetRawBody() - { - if (bufferedStream != null) - { - return bufferedStream.ToArray().FromUtf8Bytes(); - } - - using (var reader = new StreamReader(InputStream)) - { - return reader.ReadToEnd(); - } - } - public string RawUrl { get { return request.RawUrl; } @@ -104,7 +75,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return String.IsNullOrEmpty(request.Headers[HttpHeaders.XForwardedFor]) ? null : request.Headers[HttpHeaders.XForwardedFor]; + return String.IsNullOrEmpty(request.Headers["X-Forwarded-For"]) ? null : request.Headers["X-Forwarded-For"]; } } @@ -112,7 +83,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return string.IsNullOrEmpty(request.Headers[HttpHeaders.XForwardedPort]) ? (int?)null : int.Parse(request.Headers[HttpHeaders.XForwardedPort]); + return string.IsNullOrEmpty(request.Headers["X-Forwarded-Port"]) ? (int?)null : int.Parse(request.Headers["X-Forwarded-Port"]); } } @@ -120,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return string.IsNullOrEmpty(request.Headers[HttpHeaders.XForwardedProtocol]) ? null : request.Headers[HttpHeaders.XForwardedProtocol]; + return string.IsNullOrEmpty(request.Headers["X-Forwarded-Proto"]) ? null : request.Headers["X-Forwarded-Proto"]; } } @@ -128,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return String.IsNullOrEmpty(request.Headers[HttpHeaders.XRealIp]) ? null : request.Headers[HttpHeaders.XRealIp]; + return String.IsNullOrEmpty(request.Headers["X-Real-IP"]) ? null : request.Headers["X-Real-IP"]; } } @@ -140,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return remoteIp ?? (remoteIp = (CheckBadChars(XForwardedFor)) ?? (NormalizeIp(CheckBadChars(XRealIp)) ?? - (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null))); + (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.IpAddress.ToString()) : null))); } } @@ -280,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp defaultContentType = HostContext.Config.DefaultContentType; } - var customContentTypes = HostContext.ContentTypes.ContentTypeFormats.Values; + var customContentTypes = ContentTypes.Instance.ContentTypeFormats.Values; var preferredContentTypes = new string[] {}; var acceptsAnything = false; @@ -328,11 +299,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } } - if (httpReq.ContentType.MatchesContentType(MimeTypes.Soap12)) - { - return MimeTypes.Soap12; - } - if (acceptContentTypes == null && httpReq.ContentType == MimeTypes.Soap11) { return MimeTypes.Soap11; @@ -344,10 +310,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private static string GetQueryStringContentType(IRequest httpReq) { - var callback = httpReq.QueryString[Keywords.Callback]; - if (!string.IsNullOrEmpty(callback)) return MimeTypes.Json; - - var format = httpReq.QueryString[Keywords.Format]; + var format = httpReq.QueryString["format"]; if (format == null) { const int formatMaxLength = 4; @@ -359,12 +322,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } format = format.LeftPart('.').ToLower(); - if (format.Contains("json")) return MimeTypes.Json; + if (format.Contains("json")) return "application/json"; if (format.Contains("xml")) return MimeTypes.Xml; - if (format.Contains("jsv")) return MimeTypes.Jsv; string contentType; - HostContext.ContentTypes.ContentTypeFormats.TryGetValue(format, out contentType); + ContentTypes.Instance.ContentTypeFormats.TryGetValue(format, out contentType); return contentType; } @@ -474,10 +436,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp get { return request.UserAgent; } } - private QueryParamCollection headers; public QueryParamCollection Headers { - get { return headers ?? (headers = ToQueryParams(request.Headers)); } + get { return request.Headers; } } private QueryParamCollection queryString; @@ -492,18 +453,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp get { return formData ?? (formData = this.Form); } } - private QueryParamCollection ToQueryParams(NameValueCollection collection) - { - var result = new QueryParamCollection(); - - foreach (var key in collection.AllKeys) - { - result[key] = collection[key]; - } - - return result; - } - public bool IsLocal { get { return request.IsLocal; } @@ -563,21 +512,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } } - public bool UseBufferedStream - { - get { return bufferedStream != null; } - set - { - bufferedStream = value - ? bufferedStream ?? _memoryStreamProvider.CreateNew(request.InputStream.ReadFully()) - : null; - } - } - - private MemoryStream bufferedStream; public Stream InputStream { - get { return bufferedStream ?? request.InputStream; } + get { return request.InputStream; } } public long ContentLength @@ -613,7 +550,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } } - static Stream GetSubStream(Stream stream, IMemoryStreamProvider streamProvider) + static Stream GetSubStream(Stream stream, IMemoryStreamFactory streamProvider) { if (stream is MemoryStream) { @@ -654,4 +591,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return pathInfo; } } + + public class HttpFile : IHttpFile + { + public string Name { get; set; } + public string FileName { get; set; } + public long ContentLength { get; set; } + public string ContentType { get; set; } + public Stream InputStream { get; set; } + } } diff --git a/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs b/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs index 0a0a04d5d..cb62ffa98 100644 --- a/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs +++ b/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs @@ -4,7 +4,7 @@ using Microsoft.IO; namespace MediaBrowser.Server.Implementations.IO { - public class RecyclableMemoryStreamProvider : IMemoryStreamProvider + public class RecyclableMemoryStreamProvider : IMemoryStreamFactory { readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager(); @@ -22,9 +22,15 @@ namespace MediaBrowser.Server.Implementations.IO { return _manager.GetStream("RecyclableMemoryStream", buffer, 0, buffer.Length); } + + public bool TryGetBuffer(MemoryStream stream, out byte[] buffer) + { + buffer = stream.GetBuffer(); + return true; + } } - public class MemoryStreamProvider : IMemoryStreamProvider + public class MemoryStreamProvider : IMemoryStreamFactory { public MemoryStream CreateNew() { @@ -40,5 +46,11 @@ namespace MediaBrowser.Server.Implementations.IO { return new MemoryStream(buffer); } + + public bool TryGetBuffer(MemoryStream stream, out byte[] buffer) + { + buffer = stream.GetBuffer(); + return true; + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 42e2e0d7b..4096d71dc 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -69,16 +69,12 @@ <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath> <Private>True</Private> </Reference> - <Reference Include="ServiceStack.Api.Swagger"> - <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath> - </Reference> <Reference Include="SharpCompress, Version=0.10.3.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath> </Reference> - <Reference Include="SocketHttpListener, Version=1.0.6154.22657, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\SocketHttpListener.1.0.0.44\lib\net45\SocketHttpListener.dll</HintPath> - <Private>True</Private> + <Reference Include="SocketHttpListener.Portable"> + <HintPath>..\ThirdParty\emby\SocketHttpListener.Portable.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> @@ -88,7 +84,6 @@ <Reference Include="System.Net" /> <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Security" /> - <Reference Include="System.Web" /> <Reference Include="System.Xml" /> <Reference Include="ServiceStack"> <HintPath>..\ThirdParty\ServiceStack\ServiceStack.dll</HintPath> @@ -119,18 +114,9 @@ <Compile Include="HttpServer\ContainerAdapter.cs" /> <Compile Include="HttpServer\HttpListenerHost.cs" /> <Compile Include="HttpServer\HttpResultFactory.cs" /> - <Compile Include="HttpServer\LoggerUtils.cs" /> - <Compile Include="HttpServer\RangeRequestWriter.cs" /> - <Compile Include="HttpServer\ResponseFilter.cs" /> <Compile Include="HttpServer\ServerFactory.cs" /> - <Compile Include="HttpServer\ServerLogFactory.cs" /> - <Compile Include="HttpServer\ServerLogger.cs" /> - <Compile Include="HttpServer\SocketSharp\SharpWebSocket.cs" /> - <Compile Include="HttpServer\SocketSharp\Extensions.cs" /> <Compile Include="HttpServer\SocketSharp\RequestMono.cs" /> - <Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" /> <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" /> - <Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" /> <Compile Include="IO\LibraryMonitor.cs" /> <Compile Include="IO\MemoryStreamProvider.cs" /> <Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" /> diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs index 86ecbd24d..179101ca2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// </summary> /// <returns>Stream.</returns> /// <exception cref="System.ArgumentNullException">reader</exception> - public static Stream GetMemoryStream(this IDataReader reader, int ordinal, IMemoryStreamProvider streamProvider) + public static Stream GetMemoryStream(this IDataReader reader, int ordinal, IMemoryStreamFactory streamProvider) { if (reader == null) { @@ -134,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// </summary> /// <returns>System.Byte[][].</returns> /// <exception cref="System.ArgumentNullException">obj</exception> - public static byte[] SerializeToBytes(this IJsonSerializer json, object obj, IMemoryStreamProvider streamProvider) + public static byte[] SerializeToBytes(this IJsonSerializer json, object obj, IMemoryStreamFactory streamProvider) { if (obj == null) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 3d20cad36..c97ba8792 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -20,9 +20,9 @@ namespace MediaBrowser.Server.Implementations.Persistence /// </summary> public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository { - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider) + public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector, IMemoryStreamFactory memoryStreamProvider) : base(logManager, dbConnector) { _jsonSerializer = jsonSerializer; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 5fcd38f87..3577d1883 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -99,12 +99,12 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedTagsCommand; public const int LatestSchemaVersion = 109; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. /// </summary> - public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector, IMemoryStreamProvider memoryStreamProvider) + public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector, IMemoryStreamFactory memoryStreamProvider) : base(logManager, connector) { if (config == null) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index c3cf4acc4..0c1367e0a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -20,9 +20,9 @@ namespace MediaBrowser.Server.Implementations.Persistence public class SqliteUserRepository : BaseSqliteRepository, IUserRepository { private readonly IJsonSerializer _jsonSerializer; - private readonly IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamFactory _memoryStreamProvider; - public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider) : base(logManager, dbConnector) + public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector, IMemoryStreamFactory memoryStreamProvider) : base(logManager, dbConnector) { _jsonSerializer = jsonSerializer; _memoryStreamProvider = memoryStreamProvider; diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 909246f68..84a5d5a1d 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -5,6 +5,5 @@ <package id="MediaBrowser.Naming" version="1.0.0.59" targetFramework="net46" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net46" />
<package id="Patterns.Logging" version="1.0.0.6" targetFramework="net46" />
- <package id="SocketHttpListener" version="1.0.0.44" targetFramework="net46" />
<package id="UniversalDetector" version="1.0.1" targetFramework="net46" />
</packages>
\ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index fd84940dd..c0f184bef 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -126,7 +126,7 @@ using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using MediaBrowser.Model.Social; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; using MediaBrowser.Model.Xml; using MediaBrowser.Server.Implementations.Archiving; using MediaBrowser.Server.Implementations.Serialization; @@ -252,6 +252,8 @@ namespace MediaBrowser.Server.Startup.Common /// <value>The zip client.</value> protected IZipClient ZipClient { get; private set; } + protected IAuthService AuthService { get; private set; } + private readonly StartupOptions _startupOptions; private readonly string _releaseAssetFilename; @@ -410,7 +412,7 @@ namespace MediaBrowser.Server.Startup.Common LogManager.RemoveConsoleOutput(); } - protected override IMemoryStreamProvider CreateMemoryStreamProvider() + protected override IMemoryStreamFactory CreateMemoryStreamProvider() { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { @@ -555,7 +557,7 @@ namespace MediaBrowser.Server.Startup.Common StringExtensions.LocalizationManager = LocalizationManager; RegisterSingleInstance(LocalizationManager); - IEncoding textEncoding = new TextEncoding(FileSystemManager); + ITextEncoding textEncoding = new TextEncoding(FileSystemManager); RegisterSingleInstance(textEncoding); Utilities.EncodingHelper = textEncoding; RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding)); @@ -601,7 +603,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager)); - HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamProvider, "Emby", "web/index.html"); + HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamProvider, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider); HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); RegisterSingleInstance(HttpServer, false); progress.Report(10); @@ -702,7 +704,9 @@ namespace MediaBrowser.Server.Startup.Common var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager); RegisterSingleInstance<IAuthorizationContext>(authContext); RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager)); - RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager)); + + AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager); + RegisterSingleInstance<IAuthService>(AuthService); SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider, ProcessFactory, textEncoding); RegisterSingleInstance(SubtitleEncoder); @@ -900,6 +904,7 @@ namespace MediaBrowser.Server.Startup.Common BaseStreamingService.AppHost = this; BaseStreamingService.HttpClient = HttpClient; Utilities.CryptographyProvider = CryptographyProvider; + AuthenticatedAttribute.AuthService = AuthService; } /// <summary> @@ -1291,7 +1296,7 @@ namespace MediaBrowser.Server.Startup.Common try { // Return the first matched address, if found, or the first known local address - var address = (await GetLocalIpAddressesInternal().ConfigureAwait(false)).FirstOrDefault(i => !IPAddress.IsLoopback(i)); + var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); if (address != null) { @@ -1308,19 +1313,14 @@ namespace MediaBrowser.Server.Startup.Common return null; } - public string GetLocalApiUrl(IPAddress ipAddress) - { - return GetLocalApiUrl(ipAddress.ToString(), ipAddress.AddressFamily == AddressFamily.InterNetworkV6); - } - - public string GetLocalApiUrl(string ipAddress, bool isIpv6) + public string GetLocalApiUrl(IpAddressInfo ipAddress) { - if (isIpv6) + if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { - return GetLocalApiUrl("[" + ipAddress + "]"); + return GetLocalApiUrl("[" + ipAddress.Address + "]"); } - return GetLocalApiUrl(ipAddress); + return GetLocalApiUrl(ipAddress.Address); } public string GetLocalApiUrl(string host) @@ -1332,23 +1332,8 @@ namespace MediaBrowser.Server.Startup.Common public async Task<List<IpAddressInfo>> GetLocalIpAddresses() { - var list = await GetLocalIpAddressesInternal().ConfigureAwait(false); - - return list.Select(i => new IpAddressInfo - { - Address = i.ToString(), - IsIpv6 = i.AddressFamily == AddressFamily.InterNetworkV6 - - }).ToList(); - } - - private async Task<List<IPAddress>> GetLocalIpAddressesInternal() - { - // Need to do this until Common will compile with this method - var nativeNetworkManager = (BaseNetworkManager)NetworkManager; - - var addresses = nativeNetworkManager.GetLocalIpAddresses().ToList(); - var list = new List<IPAddress>(); + var addresses = NetworkManager.GetLocalIpAddresses().ToList(); + var list = new List<IpAddressInfo>(); foreach (var address in addresses) { @@ -1364,9 +1349,10 @@ namespace MediaBrowser.Server.Startup.Common private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); private DateTime _lastAddressCacheClear; - private async Task<bool> IsIpAddressValidAsync(IPAddress address) + private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address) { - if (IPAddress.IsLoopback(address)) + if (address.Equals(IpAddressInfo.Loopback) || + address.Equals(IpAddressInfo.IPv6Loopback)) { return true; } diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index e813c0a0a..7b949fcb1 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.684</version> + <version>3.0.688</version> <title>Emby.Common</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 9b0c10cbb..96986de9b 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.684</version> + <version>3.0.688</version> <title>Emby.Server.Core</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Emby Server.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.684" /> + <dependency id="MediaBrowser.Common" version="3.0.688" /> </dependencies> </metadata> <files> diff --git a/OpenSubtitlesHandler/Utilities.cs b/OpenSubtitlesHandler/Utilities.cs index b2ad2d0f1..3fe606c78 100644 --- a/OpenSubtitlesHandler/Utilities.cs +++ b/OpenSubtitlesHandler/Utilities.cs @@ -24,7 +24,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.TextEncoding; +using MediaBrowser.Model.Text; namespace OpenSubtitlesHandler { @@ -33,9 +33,9 @@ namespace OpenSubtitlesHandler /// </summary> public sealed class Utilities { - public static ICryptographyProvider CryptographyProvider { get; set; } + public static ICryptoProvider CryptographyProvider { get; set; } public static IHttpClient HttpClient { get; set; } - public static IEncoding EncodingHelper { get; set; } + public static ITextEncoding EncodingHelper { get; set; } private const string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc"; @@ -124,13 +124,13 @@ namespace OpenSubtitlesHandler data.Add((byte)r); } var bytes = data.ToArray(); - return EncodingHelper.GetASCIIString(bytes, 0, bytes.Length); + return EncodingHelper.GetASCIIEncoding().GetString(bytes, 0, bytes.Length); } } public static byte[] GetASCIIBytes(string text) { - return EncodingHelper.GetASCIIBytes(text); + return EncodingHelper.GetASCIIEncoding().GetBytes(text); } /// <summary> |
