mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 19:37:55 +02:00
commit
82c46a84e4
85 changed files with 1201 additions and 952 deletions
|
@ -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;
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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}",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
85
Emby.Common.Implementations/Net/NetSocket.cs
Normal file
85
Emby.Common.Implementations/Net/NetSocket.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
111
Emby.Common.Implementations/Net/SocketAcceptor.cs
Normal file
111
Emby.Common.Implementations/Net/SocketAcceptor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 + "]";
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
{
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -1,37 +1,51 @@
|
|||
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;
|
||||
private readonly bool _enableDualMode;
|
||||
|
||||
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, bool enableDualMode, Func<HttpListenerContext, IHttpRequest> httpRequestFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_certificatePath = certificatePath;
|
||||
_certificate = certificate;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
_textEncoding = textEncoding;
|
||||
_networkManager = networkManager;
|
||||
_socketFactory = socketFactory;
|
||||
_cryptoProvider = cryptoProvider;
|
||||
_streamFactory = streamFactory;
|
||||
_enableDualMode = enableDualMode;
|
||||
_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 +55,14 @@ 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);
|
||||
|
||||
_listener.EnableDualMode = _enableDualMode;
|
||||
|
||||
if (_certificate != null)
|
||||
{
|
||||
_listener.LoadCert(_certificate);
|
||||
}
|
||||
|
||||
foreach (var prefix in urlPrefixes)
|
||||
{
|
||||
|
@ -59,41 +80,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 +115,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 +139,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,22 +162,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);
|
||||
req.RequestAttributes = req.GetAttributes();
|
||||
|
||||
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()
|
||||
|
@ -214,4 +203,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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; }
|
|
@ -2496,10 +2496,12 @@ namespace Emby.Server.Implementations.Library
|
|||
}).OrderBy(i => i.Path).ToList();
|
||||
}
|
||||
|
||||
private static readonly string[] ExtrasSubfolderNames = new[] { "extras", "specials", "shorts", "scenes", "featurettes", "behind the scenes", "deleted scenes" };
|
||||
|
||||
public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
||||
{
|
||||
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
||||
.Where(i => string.Equals(i.Name, "extras", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "specials", StringComparison.OrdinalIgnoreCase))
|
||||
.Where(i => ExtrasSubfolderNames.Contains(i.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
.SelectMany(i => _fileSystem.GetFiles(i.FullName, false))
|
||||
.ToList();
|
||||
|
||||
|
@ -2788,7 +2790,7 @@ namespace Emby.Server.Implementations.Library
|
|||
{
|
||||
var path = Path.Combine(virtualFolderPath, collectionType + ".collection");
|
||||
|
||||
_fileSystem.WriteAllBytes(path, new byte[] {});
|
||||
_fileSystem.WriteAllBytes(path, new byte[] { });
|
||||
}
|
||||
|
||||
CollectionFolder.SaveLibraryOptions(virtualFolderPath, options);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
/// <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(',')
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
13
MediaBrowser.Model/Cryptography/ICryptoProvider.cs
Normal file
13
MediaBrowser.Model/Cryptography/ICryptoProvider.cs
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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" />
|
||||
|
|
16
MediaBrowser.Model/Net/ISocket.cs
Normal file
16
MediaBrowser.Model/Net/ISocket.cs
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("::1", 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
47
MediaBrowser.Model/Services/IHttpResult.cs
Normal file
47
MediaBrowser.Model/Services/IHttpResult.cs
Normal 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; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
10
MediaBrowser.Model/Text/ITextEncoding.cs
Normal file
10
MediaBrowser.Model/Text/ITextEncoding.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Model.Text
|
||||
{
|
||||
public interface ITextEncoding
|
||||
{
|
||||
Encoding GetASCIIEncoding();
|
||||
Encoding GetFileEncoding(string path);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
{
|
||||
|
@ -93,33 +106,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
{typeof (NotSupportedException), 500}
|
||||
};
|
||||
|
||||
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"));
|
||||
|
||||
//Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
|
||||
// new SessionAuthProvider(_containerAdapter.Resolve<ISessionContext>()),
|
||||
//}));
|
||||
|
||||
//PreRequestFilters.Add((httpReq, httpRes) =>
|
||||
//{
|
||||
// //Handles Request and closes Responses after emitting global HTTP Headers
|
||||
// if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// httpRes.EndRequest(); //add a 'using ServiceStack;'
|
||||
// }
|
||||
//});
|
||||
Container.Adapter = _containerAdapter;
|
||||
|
||||
var requestFilters = _appHost.GetExports<IRequestFilter>().ToList();
|
||||
foreach (var filter in requestFilters)
|
||||
|
@ -130,11 +121,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse);
|
||||
}
|
||||
|
||||
public override void OnAfterInit()
|
||||
protected override ILogger Logger
|
||||
{
|
||||
SetAppDomainData();
|
||||
|
||||
base.OnAfterInit();
|
||||
get
|
||||
{
|
||||
return _logger;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnConfigLoad()
|
||||
|
@ -153,23 +145,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
return new ServiceController(this, () => types);
|
||||
}
|
||||
|
||||
public virtual void SetAppDomainData()
|
||||
{
|
||||
//Required for Mono to resolve VirtualPathUtility and Url.Content urls
|
||||
var domain = Thread.GetDomain(); // or AppDomain.Current
|
||||
domain.SetData(".appDomain", "1");
|
||||
domain.SetData(".appVPath", "/");
|
||||
domain.SetData(".appPath", domain.BaseDirectory);
|
||||
if (string.IsNullOrEmpty(domain.GetData(".appId") as string))
|
||||
{
|
||||
domain.SetData(".appId", "1");
|
||||
}
|
||||
if (string.IsNullOrEmpty(domain.GetData(".domainId") as string))
|
||||
{
|
||||
domain.SetData(".domainId", "1");
|
||||
}
|
||||
}
|
||||
|
||||
public override ServiceStackHost Start(string listeningAtUrlBase)
|
||||
{
|
||||
StartListener();
|
||||
|
@ -207,7 +182,35 @@ 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;
|
||||
|
||||
var enableDualMode = Environment.OSVersion.Platform == PlatformID.Win32NT;
|
||||
|
||||
return new WebSocketSharpListener(_logger, cert, _memoryStreamProvider, _textEncoding, _networkManager, _socketFactory, _cryptoProvider, new StreamFactory(), enableDualMode, 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 +262,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 +414,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 +655,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 +689,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; }
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,12 +22,11 @@ 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;
|
||||
this.RequestAttributes = requestAttributes;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
this.request = httpContext.Request;
|
||||
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
|
||||
|
@ -56,38 +52,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
get { return response; }
|
||||
}
|
||||
|
||||
public RequestAttributes RequestAttributes { get; set; }
|
||||
|
||||
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; }
|
||||
|
@ -107,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"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,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"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,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"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,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"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +230,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
get
|
||||
{
|
||||
return responseContentType
|
||||
?? (responseContentType = this.GetResponseContentType());
|
||||
?? (responseContentType = GetResponseContentType(this));
|
||||
}
|
||||
set
|
||||
{
|
||||
|
@ -271,6 +239,98 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
}
|
||||
}
|
||||
|
||||
private static string GetResponseContentType(IRequest httpReq)
|
||||
{
|
||||
var specifiedContentType = GetQueryStringContentType(httpReq);
|
||||
if (!string.IsNullOrEmpty(specifiedContentType)) return specifiedContentType;
|
||||
|
||||
var acceptContentTypes = httpReq.AcceptTypes;
|
||||
var defaultContentType = httpReq.ContentType;
|
||||
if (httpReq.HasAnyOfContentTypes(MimeTypes.FormUrlEncoded, MimeTypes.MultiPartFormData))
|
||||
{
|
||||
defaultContentType = HostContext.Config.DefaultContentType;
|
||||
}
|
||||
|
||||
var customContentTypes = ContentTypes.Instance.ContentTypeFormats.Values;
|
||||
var preferredContentTypes = new string[] {};
|
||||
|
||||
var acceptsAnything = false;
|
||||
var hasDefaultContentType = !string.IsNullOrEmpty(defaultContentType);
|
||||
if (acceptContentTypes != null)
|
||||
{
|
||||
var hasPreferredContentTypes = new bool[preferredContentTypes.Length];
|
||||
foreach (var acceptsType in acceptContentTypes)
|
||||
{
|
||||
var contentType = ContentFormat.GetRealContentType(acceptsType);
|
||||
acceptsAnything = acceptsAnything || contentType == "*/*";
|
||||
|
||||
for (var i = 0; i < preferredContentTypes.Length; i++)
|
||||
{
|
||||
if (hasPreferredContentTypes[i]) continue;
|
||||
var preferredContentType = preferredContentTypes[i];
|
||||
hasPreferredContentTypes[i] = contentType.StartsWith(preferredContentType);
|
||||
|
||||
//Prefer Request.ContentType if it is also a preferredContentType
|
||||
if (hasPreferredContentTypes[i] && preferredContentType == defaultContentType)
|
||||
return preferredContentType;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < preferredContentTypes.Length; i++)
|
||||
{
|
||||
if (hasPreferredContentTypes[i]) return preferredContentTypes[i];
|
||||
}
|
||||
|
||||
if (acceptsAnything)
|
||||
{
|
||||
if (hasDefaultContentType)
|
||||
return defaultContentType;
|
||||
if (HostContext.Config.DefaultContentType != null)
|
||||
return HostContext.Config.DefaultContentType;
|
||||
}
|
||||
|
||||
foreach (var contentType in acceptContentTypes)
|
||||
{
|
||||
foreach (var customContentType in customContentTypes)
|
||||
{
|
||||
if (contentType.StartsWith(customContentType, StringComparison.OrdinalIgnoreCase))
|
||||
return customContentType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (acceptContentTypes == null && httpReq.ContentType == MimeTypes.Soap11)
|
||||
{
|
||||
return MimeTypes.Soap11;
|
||||
}
|
||||
|
||||
//We could also send a '406 Not Acceptable', but this is allowed also
|
||||
return HostContext.Config.DefaultContentType;
|
||||
}
|
||||
|
||||
private static string GetQueryStringContentType(IRequest httpReq)
|
||||
{
|
||||
var format = httpReq.QueryString["format"];
|
||||
if (format == null)
|
||||
{
|
||||
const int formatMaxLength = 4;
|
||||
var pi = httpReq.PathInfo;
|
||||
if (pi == null || pi.Length <= formatMaxLength) return null;
|
||||
if (pi[0] == '/') pi = pi.Substring(1);
|
||||
format = pi.LeftPart('/');
|
||||
if (format.Length > formatMaxLength) return null;
|
||||
}
|
||||
|
||||
format = format.LeftPart('.').ToLower();
|
||||
if (format.Contains("json")) return "application/json";
|
||||
if (format.Contains("xml")) return MimeTypes.Xml;
|
||||
|
||||
string contentType;
|
||||
ContentTypes.Instance.ContentTypeFormats.TryGetValue(format, out contentType);
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public bool HasExplicitResponseContentType { get; private set; }
|
||||
|
||||
private string pathInfo;
|
||||
|
@ -286,7 +346,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
if (pos != -1)
|
||||
{
|
||||
var path = request.RawUrl.Substring(0, pos);
|
||||
this.pathInfo = HttpRequestExtensions.GetPathInfo(
|
||||
this.pathInfo = GetPathInfo(
|
||||
path,
|
||||
mode,
|
||||
mode ?? "");
|
||||
|
@ -303,6 +363,55 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
|||
}
|
||||
}
|
||||
|
||||
private static string GetPathInfo(string fullPath, string mode, string appPath)
|
||||
{
|
||||
var pathInfo = ResolvePathInfoFromMappedPath(fullPath, mode);
|
||||
if (!string.IsNullOrEmpty(pathInfo)) return pathInfo;
|
||||
|
||||
//Wildcard mode relies on this to work out the handlerPath
|
||||
pathInfo = ResolvePathInfoFromMappedPath(fullPath, appPath);
|
||||
if (!string.IsNullOrEmpty(pathInfo)) return pathInfo;
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static string ResolvePathInfoFromMappedPath(string fullPath, string mappedPathRoot)
|
||||
{
|
||||
if (mappedPathRoot == null) return null;
|
||||
|
||||
var sbPathInfo = new StringBuilder();
|
||||
var fullPathParts = fullPath.Split('/');
|
||||
var mappedPathRootParts = mappedPathRoot.Split('/');
|
||||
var fullPathIndexOffset = mappedPathRootParts.Length - 1;
|
||||
var pathRootFound = false;
|
||||
|
||||
for (var fullPathIndex = 0; fullPathIndex < fullPathParts.Length; fullPathIndex++)
|
||||
{
|
||||
if (pathRootFound)
|
||||
{
|
||||
sbPathInfo.Append("/" + fullPathParts[fullPathIndex]);
|
||||
}
|
||||
else if (fullPathIndex - fullPathIndexOffset >= 0)
|
||||
{
|
||||
pathRootFound = true;
|
||||
for (var mappedPathRootIndex = 0; mappedPathRootIndex < mappedPathRootParts.Length; mappedPathRootIndex++)
|
||||
{
|
||||
if (!string.Equals(fullPathParts[fullPathIndex - fullPathIndexOffset + mappedPathRootIndex], mappedPathRootParts[mappedPathRootIndex], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
pathRootFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pathRootFound) return null;
|
||||
|
||||
var path = sbPathInfo.ToString();
|
||||
return path.Length > 1 ? path.TrimEnd('/') : "/";
|
||||
}
|
||||
|
||||
private Dictionary<string, System.Net.Cookie> cookies;
|
||||
public IDictionary<string, System.Net.Cookie> Cookies
|
||||
{
|
||||
|
@ -327,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;
|
||||
|
@ -345,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; }
|
||||
|
@ -416,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
|
||||
|
@ -466,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)
|
||||
{
|
||||
|
@ -507,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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue