update portable projects

This commit is contained in:
Luke Pulverenti 2016-11-08 13:44:23 -05:00
parent 05a5ce58a9
commit a8b340cbb2
84 changed files with 1055 additions and 921 deletions

View File

@ -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;
//

View File

@ -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;

View File

@ -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}",

View File

@ -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)

View File

@ -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())
{

View File

@ -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)
{

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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)
{
if (String.IsNullOrEmpty(localIP))
_LocalIP = IPAddress.Any;
else
_LocalIP = IPAddress.Parse(localIP);
_logger = logger;
_LocalIP = IPAddress.Any;
}
public ISocket CreateSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode)
{
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
{

View File

@ -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)

View File

@ -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();
}
}
}

View File

@ -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)

View File

@ -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
{

View File

@ -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()

View File

@ -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;

View File

@ -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 + "]";
}

View File

@ -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>

View File

@ -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
{

View File

@ -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; }
}
}

View File

@ -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;
//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 (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)
{

View File

@ -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];
}
}
}

View File

@ -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)

View File

@ -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;
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, string certificatePath, IMemoryStreamProvider memoryStreamProvider)
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);
}
}
_logger.ErrorException("Error processing request", ex);
private Task ProcessRequestAsync(HttpListenerContext context)
{
var request = context.Request;
if (request.IsWebSocketRequest)
{
LoggerUtils.LogRequest(_logger, request);
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
}
}
}
}

View File

@ -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; }

View File

@ -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>

View File

@ -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;

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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 &&

View File

@ -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.

View File

@ -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>

View File

@ -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);

View File

@ -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)

View File

@ -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>
@ -40,15 +40,6 @@ namespace MediaBrowser.Controller.Net
AuthService.Authenticate(serviceRequest, this);
}
/// <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.
/// &lt;0 Executed before global request filters
@ -60,7 +51,6 @@ namespace MediaBrowser.Controller.Net
get { return 0; }
}
public IEnumerable<string> GetRoles()
{
return (Roles ?? string.Empty).Split(',')

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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" />

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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; }
}
}

View File

@ -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; }

View File

@ -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();

View File

@ -0,0 +1,10 @@
using System.Text;
namespace MediaBrowser.Model.Text
{
public interface ITextEncoding
{
Encoding GetASCIIEncoding();
Encoding GetFileEncoding(string path);
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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" };
}
}

View File

@ -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;

View File

@ -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
}
}
}

View File

@ -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 (!ValidateHost(url))
{
httpRes.StatusCode = 400;
httpRes.ContentType = "text/plain";
httpRes.Write("Invalid host");
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";
httpRes.Close();
}
var operationName = httpReq.OperationName;
var localPath = url.LocalPath;
var urlString = url.OriginalString;
var enableLog = EnableLogging(urlString, localPath);
var urlToLog = urlString;
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))
{
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(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
if (_disposed)
{
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.Close();
httpRes.StatusCode = 503;
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(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
if (!ValidateHost(url))
{
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.Close();
httpRes.StatusCode = 400;
httpRes.ContentType = "text/plain";
httpRes.Write("Invalid host");
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;
}
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(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase))
{
httpRes.RedirectToUrl("web/pin.html");
return;
var operationName = httpReq.OperationName;
var localPath = url.LocalPath;
var urlString = url.OriginalString;
enableLog = EnableLogging(urlString, localPath);
urlToLog = urlString;
if (enableLog)
{
urlToLog = GetUrlToLog(urlString);
remoteIp = httpReq.RemoteIp;
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, "/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 (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(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(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(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase))
{
RedirectToUrl(httpRes, "web/pin.html");
return;
}
if (!string.IsNullOrWhiteSpace(GlobalResponse))
{
httpRes.StatusCode = 503;
httpRes.ContentType = "text/html";
httpRes.Write(GlobalResponse);
return;
}
var handler = HttpHandlerFactory.GetHandler(httpReq);
if (handler != null)
{
await handler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false);
}
}
if (!string.IsNullOrWhiteSpace(GlobalResponse))
catch (Exception ex)
{
ErrorHandler(ex, httpReq);
}
finally
{
httpRes.StatusCode = 503;
httpRes.ContentType = "text/html";
httpRes.Write(GlobalResponse);
httpRes.Close();
return;
}
var handler = HttpHandlerFactory.GetHandler(httpReq);
var remoteIp = httpReq.RemoteIp;
var serviceStackHandler = handler as IServiceStackHandler;
if (serviceStackHandler != null)
{
var restHandler = serviceStackHandler as RestHandler;
if (restHandler != null)
if (enableLog)
{
httpReq.OperationName = operationName = restHandler.RestPath.RequestType.GetOperationName();
}
try
{
await serviceStackHandler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false);
}
finally
{
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; }
}
}

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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" />

View File

@ -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)
{

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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>

View File

@ -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)
public string GetLocalApiUrl(IpAddressInfo ipAddress)
{
return GetLocalApiUrl(ipAddress.ToString(), ipAddress.AddressFamily == AddressFamily.InterNetworkV6);
}
public string GetLocalApiUrl(string ipAddress, bool isIpv6)
{
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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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>