commit
82c46a84e4
|
@ -22,7 +22,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace BDInfo
|
namespace BDInfo
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ namespace BDInfo
|
||||||
public event OnPlaylistFileScanError PlaylistFileScanError;
|
public event OnPlaylistFileScanError PlaylistFileScanError;
|
||||||
|
|
||||||
public BDROM(
|
public BDROM(
|
||||||
string path, IFileSystem fileSystem, IEncoding textEncoding)
|
string path, IFileSystem fileSystem, ITextEncoding textEncoding)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,14 +23,14 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace BDInfo
|
namespace BDInfo
|
||||||
{
|
{
|
||||||
public class TSPlaylistFile
|
public class TSPlaylistFile
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IEncoding _textEncoding;
|
private readonly ITextEncoding _textEncoding;
|
||||||
private FileSystemMetadata FileInfo = null;
|
private FileSystemMetadata FileInfo = null;
|
||||||
public string FileType = null;
|
public string FileType = null;
|
||||||
public bool IsInitialized = false;
|
public bool IsInitialized = false;
|
||||||
|
@ -67,7 +67,7 @@ namespace BDInfo
|
||||||
|
|
||||||
public TSPlaylistFile(
|
public TSPlaylistFile(
|
||||||
BDROM bdrom,
|
BDROM bdrom,
|
||||||
FileSystemMetadata fileInfo, IFileSystem fileSystem, IEncoding textEncoding)
|
FileSystemMetadata fileInfo, IFileSystem fileSystem, ITextEncoding textEncoding)
|
||||||
{
|
{
|
||||||
BDROM = bdrom;
|
BDROM = bdrom;
|
||||||
FileInfo = fileInfo;
|
FileInfo = fileInfo;
|
||||||
|
@ -79,7 +79,7 @@ namespace BDInfo
|
||||||
public TSPlaylistFile(
|
public TSPlaylistFile(
|
||||||
BDROM bdrom,
|
BDROM bdrom,
|
||||||
string name,
|
string name,
|
||||||
List<TSStreamClip> clips, IFileSystem fileSystem, IEncoding textEncoding)
|
List<TSStreamClip> clips, IFileSystem fileSystem, ITextEncoding textEncoding)
|
||||||
{
|
{
|
||||||
BDROM = bdrom;
|
BDROM = bdrom;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
@ -1247,7 +1247,7 @@ namespace BDInfo
|
||||||
ref int pos)
|
ref int pos)
|
||||||
{
|
{
|
||||||
string val =
|
string val =
|
||||||
_textEncoding.GetASCIIString(data, pos, count);
|
_textEncoding.GetASCIIEncoding().GetString(data, pos, count);
|
||||||
|
|
||||||
pos += count;
|
pos += count;
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,14 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace BDInfo
|
namespace BDInfo
|
||||||
{
|
{
|
||||||
public class TSStreamClipFile
|
public class TSStreamClipFile
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IEncoding _textEncoding;
|
private readonly ITextEncoding _textEncoding;
|
||||||
public FileSystemMetadata FileInfo = null;
|
public FileSystemMetadata FileInfo = null;
|
||||||
public string FileType = null;
|
public string FileType = null;
|
||||||
public bool IsValid = false;
|
public bool IsValid = false;
|
||||||
|
@ -40,7 +40,7 @@ namespace BDInfo
|
||||||
new Dictionary<ushort,TSStream>();
|
new Dictionary<ushort,TSStream>();
|
||||||
|
|
||||||
public TSStreamClipFile(
|
public TSStreamClipFile(
|
||||||
FileSystemMetadata fileInfo, IFileSystem fileSystem, IEncoding textEncoding)
|
FileSystemMetadata fileInfo, IFileSystem fileSystem, ITextEncoding textEncoding)
|
||||||
{
|
{
|
||||||
FileInfo = fileInfo;
|
FileInfo = fileInfo;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
@ -70,7 +70,7 @@ namespace BDInfo
|
||||||
byte[] fileType = new byte[8];
|
byte[] fileType = new byte[8];
|
||||||
Array.Copy(data, 0, fileType, 0, fileType.Length);
|
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" &&
|
if (FileType != "HDMV0100" &&
|
||||||
FileType != "HDMV0200")
|
FileType != "HDMV0200")
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,7 @@ namespace BDInfo
|
||||||
Array.Copy(clipData, streamOffset + 3,
|
Array.Copy(clipData, streamOffset + 3,
|
||||||
languageBytes, 0, languageBytes.Length);
|
languageBytes, 0, languageBytes.Length);
|
||||||
string languageCode =
|
string languageCode =
|
||||||
_textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length);
|
_textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length);
|
||||||
|
|
||||||
TSChannelLayout channelLayout = (TSChannelLayout)
|
TSChannelLayout channelLayout = (TSChannelLayout)
|
||||||
(clipData[streamOffset + 2] >> 4);
|
(clipData[streamOffset + 2] >> 4);
|
||||||
|
@ -198,7 +198,7 @@ namespace BDInfo
|
||||||
Array.Copy(clipData, streamOffset + 2,
|
Array.Copy(clipData, streamOffset + 2,
|
||||||
languageBytes, 0, languageBytes.Length);
|
languageBytes, 0, languageBytes.Length);
|
||||||
string languageCode =
|
string languageCode =
|
||||||
_textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length);
|
_textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length);
|
||||||
|
|
||||||
stream = new TSGraphicsStream();
|
stream = new TSGraphicsStream();
|
||||||
stream.LanguageCode = languageCode;
|
stream.LanguageCode = languageCode;
|
||||||
|
@ -218,7 +218,7 @@ namespace BDInfo
|
||||||
Array.Copy(clipData, streamOffset + 3,
|
Array.Copy(clipData, streamOffset + 3,
|
||||||
languageBytes, 0, languageBytes.Length);
|
languageBytes, 0, languageBytes.Length);
|
||||||
string languageCode =
|
string languageCode =
|
||||||
_textEncoding.GetASCIIString(languageBytes, 0, languageBytes.Length);
|
_textEncoding.GetASCIIEncoding().GetString(languageBytes, 0, languageBytes.Length);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Debug.WriteLine(string.Format(
|
Debug.WriteLine(string.Format(
|
||||||
"\t{0} {1} {2}",
|
"\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>
|
/// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
|
||||||
public abstract bool IsRunningAsService { get; }
|
public abstract bool IsRunningAsService { get; }
|
||||||
|
|
||||||
protected ICryptographyProvider CryptographyProvider = new CryptographyProvider();
|
protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
|
||||||
|
|
||||||
protected IEnvironmentInfo EnvironmentInfo = new Emby.Common.Implementations.EnvironmentInfo.EnvironmentInfo();
|
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);
|
_deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _deviceId.Value;
|
return _deviceId.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ namespace Emby.Common.Implementations
|
||||||
get { return EnvironmentInfo.OperatingSystemName; }
|
get { return EnvironmentInfo.OperatingSystemName; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMemoryStreamProvider MemoryStreamProvider { get; set; }
|
public IMemoryStreamFactory MemoryStreamProvider { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The container
|
/// The container
|
||||||
|
@ -209,7 +209,7 @@ namespace Emby.Common.Implementations
|
||||||
{
|
{
|
||||||
// hack alert, until common can target .net core
|
// hack alert, until common can target .net core
|
||||||
BaseExtensions.CryptographyProvider = CryptographyProvider;
|
BaseExtensions.CryptographyProvider = CryptographyProvider;
|
||||||
|
|
||||||
XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer"));
|
XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer"));
|
||||||
FailedAssemblies = new List<string>();
|
FailedAssemblies = new List<string>();
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ namespace Emby.Common.Implementations
|
||||||
progress.Report(100);
|
progress.Report(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IMemoryStreamProvider CreateMemoryStreamProvider();
|
protected abstract IMemoryStreamFactory CreateMemoryStreamProvider();
|
||||||
protected abstract ISystemEvents CreateSystemEvents();
|
protected abstract ISystemEvents CreateSystemEvents();
|
||||||
|
|
||||||
protected virtual void OnLoggerLoaded(bool isFirstLoad)
|
protected virtual void OnLoggerLoaded(bool isFirstLoad)
|
||||||
|
|
|
@ -6,21 +6,14 @@ using MediaBrowser.Model.Cryptography;
|
||||||
|
|
||||||
namespace Emby.Common.Implementations.Cryptography
|
namespace Emby.Common.Implementations.Cryptography
|
||||||
{
|
{
|
||||||
public class CryptographyProvider : ICryptographyProvider
|
public class CryptographyProvider : ICryptoProvider
|
||||||
{
|
{
|
||||||
public Guid GetMD5(string str)
|
public Guid GetMD5(string str)
|
||||||
{
|
{
|
||||||
return new Guid(GetMD5Bytes(str));
|
return new Guid(ComputeMD5(Encoding.Unicode.GetBytes(str)));
|
||||||
}
|
|
||||||
public byte[] GetMD5Bytes(string str)
|
|
||||||
{
|
|
||||||
using (var provider = MD5.Create())
|
|
||||||
{
|
|
||||||
return provider.ComputeHash(Encoding.Unicode.GetBytes(str));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetSHA1Bytes(byte[] bytes)
|
public byte[] ComputeSHA1(byte[] bytes)
|
||||||
{
|
{
|
||||||
using (var provider = SHA1.Create())
|
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())
|
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())
|
using (var provider = MD5.Create())
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Emby.Common.Implementations.HttpClientManager
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="HttpClientManager" /> class.
|
/// Initializes a new instance of the <see cref="HttpClientManager" /> class.
|
||||||
|
@ -53,7 +53,7 @@ namespace Emby.Common.Implementations.HttpClientManager
|
||||||
/// <exception cref="System.ArgumentNullException">appPaths
|
/// <exception cref="System.ArgumentNullException">appPaths
|
||||||
/// or
|
/// or
|
||||||
/// logger</exception>
|
/// 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)
|
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;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
|
||||||
namespace Emby.Common.Implementations.Net
|
namespace Emby.Common.Implementations.Net
|
||||||
|
@ -22,16 +23,28 @@ namespace Emby.Common.Implementations.Net
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IPAddress _LocalIP;
|
private IPAddress _LocalIP;
|
||||||
|
|
||||||
/// <summary>
|
private ILogger _logger;
|
||||||
/// Default constructor.
|
|
||||||
/// </summary>
|
public SocketFactory(ILogger logger)
|
||||||
/// <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)
|
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(localIP))
|
_logger = logger;
|
||||||
_LocalIP = IPAddress.Any;
|
_LocalIP = IPAddress.Any;
|
||||||
else
|
}
|
||||||
_LocalIP = IPAddress.Parse(localIP);
|
|
||||||
|
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
|
#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");
|
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
|
try
|
||||||
{
|
{
|
||||||
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
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");
|
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
|
try
|
||||||
{
|
{
|
||||||
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
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 (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");
|
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
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Emby.Common.Implementations.Networking;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
|
||||||
namespace Emby.Common.Implementations.Net
|
namespace Emby.Common.Implementations.Net
|
||||||
|
@ -174,16 +175,7 @@ namespace Emby.Common.Implementations.Net
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IpEndPointInfo
|
return BaseNetworkManager.ToIpEndPointInfo(endpoint);
|
||||||
{
|
|
||||||
IpAddress = new IpAddressInfo
|
|
||||||
{
|
|
||||||
Address = endpoint.Address.ToString(),
|
|
||||||
IsIpv6 = endpoint.AddressFamily == AddressFamily.InterNetworkV6
|
|
||||||
},
|
|
||||||
|
|
||||||
Port = endpoint.Port
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessResponse(IAsyncResult asyncResult)
|
private void ProcessResponse(IAsyncResult asyncResult)
|
||||||
|
|
|
@ -22,14 +22,10 @@ namespace Emby.Common.Implementations.Networking
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IPAddress> _localIpAddresses;
|
private List<IpAddressInfo> _localIpAddresses;
|
||||||
private readonly object _localIpAddressSyncLock = new object();
|
private readonly object _localIpAddressSyncLock = new object();
|
||||||
|
|
||||||
/// <summary>
|
public IEnumerable<IpAddressInfo> GetLocalIpAddresses()
|
||||||
/// Gets the machine's local ip address
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>IPAddress.</returns>
|
|
||||||
public IEnumerable<IPAddress> GetLocalIpAddresses()
|
|
||||||
{
|
{
|
||||||
const int cacheMinutes = 5;
|
const int cacheMinutes = 5;
|
||||||
|
|
||||||
|
@ -39,7 +35,7 @@ namespace Emby.Common.Implementations.Networking
|
||||||
|
|
||||||
if (_localIpAddresses == null || forceRefresh)
|
if (_localIpAddresses == null || forceRefresh)
|
||||||
{
|
{
|
||||||
var addresses = GetLocalIpAddressesInternal().ToList();
|
var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList();
|
||||||
|
|
||||||
_localIpAddresses = addresses;
|
_localIpAddresses = addresses;
|
||||||
_lastRefresh = DateTime.UtcNow;
|
_lastRefresh = DateTime.UtcNow;
|
||||||
|
@ -405,18 +401,85 @@ namespace Emby.Common.Implementations.Networking
|
||||||
IPAddress address;
|
IPAddress address;
|
||||||
if (IPAddress.TryParse(ipAddress, out address))
|
if (IPAddress.TryParse(ipAddress, out address))
|
||||||
{
|
{
|
||||||
|
ipAddressInfo = ToIpAddressInfo(address);
|
||||||
ipAddressInfo = new IpAddressInfo
|
|
||||||
{
|
|
||||||
Address = address.ToString(),
|
|
||||||
IsIpv6 = address.AddressFamily == AddressFamily.InterNetworkV6
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipAddressInfo = null;
|
ipAddressInfo = null;
|
||||||
return false;
|
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 System.Text;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace Emby.Common.Implementations.TextEncoding
|
namespace Emby.Common.Implementations.TextEncoding
|
||||||
{
|
{
|
||||||
public class TextEncoding : IEncoding
|
public class TextEncoding : ITextEncoding
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
|
@ -13,14 +13,9 @@ namespace Emby.Common.Implementations.TextEncoding
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetASCIIBytes(string text)
|
public Encoding GetASCIIEncoding()
|
||||||
{
|
{
|
||||||
return Encoding.ASCII.GetBytes(text);
|
return Encoding.ASCII;
|
||||||
}
|
|
||||||
|
|
||||||
public string GetASCIIString(byte[] bytes, int startIndex, int length)
|
|
||||||
{
|
|
||||||
return Encoding.ASCII.GetString(bytes, 0, bytes.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Encoding GetFileEncoding(string srcFile)
|
public Encoding GetFileEncoding(string srcFile)
|
||||||
|
|
|
@ -250,14 +250,12 @@ namespace Emby.Dlna.Main
|
||||||
// continue;
|
// continue;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
var addressString = address.ToString();
|
|
||||||
|
|
||||||
var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
|
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 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
|
var device = new SsdpRootDevice
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Threading;
|
using MediaBrowser.Model.Threading;
|
||||||
|
|
||||||
namespace Emby.Dlna.PlayTo
|
namespace Emby.Dlna.PlayTo
|
||||||
|
@ -131,11 +132,11 @@ namespace Emby.Dlna.PlayTo
|
||||||
string serverAddress;
|
string serverAddress;
|
||||||
if (info.LocalIpAddress == null)
|
if (info.LocalIpAddress == null)
|
||||||
{
|
{
|
||||||
serverAddress = await GetServerAddress(null, false).ConfigureAwait(false);
|
serverAddress = await GetServerAddress(null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serverAddress = await GetServerAddress(info.LocalIpAddress.Address, info.LocalIpAddress.IsIpv6).ConfigureAwait(false);
|
serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
string accessToken = null;
|
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 _appHost.GetLocalApiUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(_appHost.GetLocalApiUrl(ipAddress, isIpv6));
|
return Task.FromResult(_appHost.GetLocalApiUrl(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Connect
|
||||||
validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false);
|
validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false);
|
||||||
|
|
||||||
// Try to find the ipv4 address, if present
|
// Try to find the ipv4 address, if present
|
||||||
if (!validIpAddress.IsIpv6)
|
if (validIpAddress.AddressFamily != IpAddressFamily.InterNetworkV6)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,9 @@ namespace Emby.Server.Implementations.Connect
|
||||||
_logger.ErrorException("Error getting connection info", ex);
|
_logger.ErrorException("Error getting connection info", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this produced an ipv6 address, try again
|
// 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)
|
foreach (var ipLookupUrl in _ipLookups)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ namespace Emby.Server.Implementations.Connect
|
||||||
var newAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false);
|
var newAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false);
|
||||||
|
|
||||||
// Try to find the ipv4 address, if present
|
// Try to find the ipv4 address, if present
|
||||||
if (!newAddress.IsIpv6)
|
if (newAddress.AddressFamily != IpAddressFamily.InterNetworkV6)
|
||||||
{
|
{
|
||||||
validIpAddress = newAddress;
|
validIpAddress = newAddress;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace Emby.Server.Implementations.Connect
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null)
|
if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null)
|
||||||
{
|
{
|
||||||
if (DiscoveredWanIpAddress.IsIpv6)
|
if (DiscoveredWanIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
|
||||||
{
|
{
|
||||||
address = "[" + DiscoveredWanIpAddress + "]";
|
address = "[" + DiscoveredWanIpAddress + "]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,11 +68,18 @@
|
||||||
<Compile Include="FileOrganization\OrganizerScheduledTask.cs" />
|
<Compile Include="FileOrganization\OrganizerScheduledTask.cs" />
|
||||||
<Compile Include="FileOrganization\TvFolderOrganizer.cs" />
|
<Compile Include="FileOrganization\TvFolderOrganizer.cs" />
|
||||||
<Compile Include="HttpServer\GetSwaggerResource.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\SocketSharp\HttpUtility.cs" />
|
||||||
<Compile Include="HttpServer\IHttpListener.cs" />
|
<Compile Include="HttpServer\IHttpListener.cs" />
|
||||||
<Compile Include="HttpServer\Security\AuthorizationContext.cs" />
|
<Compile Include="HttpServer\Security\AuthorizationContext.cs" />
|
||||||
<Compile Include="HttpServer\Security\AuthService.cs" />
|
<Compile Include="HttpServer\Security\AuthService.cs" />
|
||||||
<Compile Include="HttpServer\Security\SessionContext.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\StreamWriter.cs" />
|
||||||
<Compile Include="HttpServer\SwaggerService.cs" />
|
<Compile Include="HttpServer\SwaggerService.cs" />
|
||||||
<Compile Include="Images\BaseDynamicImageProvider.cs" />
|
<Compile Include="Images\BaseDynamicImageProvider.cs" />
|
||||||
|
@ -254,6 +261,9 @@
|
||||||
<Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
|
<Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
|
||||||
<Name>MediaBrowser.Providers</Name>
|
<Name>MediaBrowser.Providers</Name>
|
||||||
</ProjectReference>
|
</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">
|
<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>
|
<HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using SocketHttpListener.Net;
|
using SocketHttpListener.Net;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
public static class LoggerUtils
|
public static class LoggerUtils
|
||||||
{
|
{
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using ServiceStack.Web;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -9,7 +8,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
public class RangeRequestWriter : IAsyncStreamWriter, IHttpResult
|
public class RangeRequestWriter : IAsyncStreamWriter, IHttpResult
|
||||||
{
|
{
|
||||||
|
@ -41,7 +40,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
public Func<IDisposable> ResultScope { get; set; }
|
|
||||||
public List<Cookie> Cookies { get; private set; }
|
public List<Cookie> Cookies { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -213,8 +211,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
public object Response { get; set; }
|
public object Response { get; set; }
|
||||||
|
|
||||||
public IContentTypeWriter ResponseFilter { get; set; }
|
|
||||||
|
|
||||||
public int Status { get; set; }
|
public int Status { get; set; }
|
||||||
|
|
||||||
public HttpStatusCode StatusCode
|
public HttpStatusCode StatusCode
|
||||||
|
@ -224,7 +220,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
|
|
||||||
public string StatusDescription { get; set; }
|
public string StatusDescription { get; set; }
|
||||||
|
|
||||||
public int PaddingLength { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Server.Implementations.HttpServer.SocketSharp;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Net;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Emby.Server.Implementations.HttpServer.SocketSharp;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
public class ResponseFilter
|
public class ResponseFilter
|
||||||
{
|
{
|
||||||
|
@ -28,6 +27,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
// Try to prevent compatibility view
|
// Try to prevent compatibility view
|
||||||
res.AddHeader("X-UA-Compatible", "IE=Edge");
|
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;
|
var exception = dto as Exception;
|
||||||
|
|
||||||
|
@ -68,15 +70,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
res.SetContentLength(length);
|
res.SetContentLength(length);
|
||||||
|
|
||||||
var listenerResponse = res.OriginalResponse as HttpListenerResponse;
|
//var listenerResponse = res.OriginalResponse as HttpListenerResponse;
|
||||||
|
|
||||||
if (listenerResponse != null)
|
//if (listenerResponse != null)
|
||||||
{
|
//{
|
||||||
// Disable chunked encoding. Technically this is only needed when using Content-Range, but
|
// // 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
|
// // anytime we know the content length there's no need for it
|
||||||
listenerResponse.SendChunked = false;
|
// listenerResponse.SendChunked = false;
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (sharpResponse != null)
|
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 System.Threading.Tasks;
|
||||||
using WebSocketState = MediaBrowser.Model.Net.WebSocketState;
|
using WebSocketState = MediaBrowser.Model.Net.WebSocketState;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
namespace Emby.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
public class SharpWebSocket : IWebSocket
|
public class SharpWebSocket : IWebSocket
|
||||||
{
|
{
|
||||||
|
@ -25,12 +25,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
|
|
||||||
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
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)
|
public SharpWebSocket(SocketHttpListener.WebSocket socket, ILogger logger)
|
||||||
{
|
{
|
||||||
if (socket == null)
|
if (socket == null)
|
|
@ -1,37 +1,51 @@
|
||||||
using System.Collections.Specialized;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using SocketHttpListener.Net;
|
using SocketHttpListener.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.HttpServer;
|
|
||||||
using Emby.Server.Implementations.Logging;
|
using Emby.Server.Implementations.Logging;
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.Net;
|
||||||
|
using MediaBrowser.Model.Cryptography;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Services;
|
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
|
public class WebSocketSharpListener : IHttpListener
|
||||||
{
|
{
|
||||||
private HttpListener _listener;
|
private HttpListener _listener;
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly string _certificatePath;
|
private readonly ICertificate _certificate;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
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;
|
_logger = logger;
|
||||||
_certificatePath = certificatePath;
|
_certificate = certificate;
|
||||||
_memoryStreamProvider = memoryStreamProvider;
|
_memoryStreamProvider = memoryStreamProvider;
|
||||||
|
_textEncoding = textEncoding;
|
||||||
|
_networkManager = networkManager;
|
||||||
|
_socketFactory = socketFactory;
|
||||||
|
_cryptoProvider = cryptoProvider;
|
||||||
|
_streamFactory = streamFactory;
|
||||||
|
_enableDualMode = enableDualMode;
|
||||||
|
_httpRequestFactory = httpRequestFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action<Exception, IRequest> ErrorHandler { get; set; }
|
public Action<Exception, IRequest> ErrorHandler { get; set; }
|
||||||
|
|
||||||
public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
|
public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
|
||||||
|
|
||||||
public Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; }
|
public Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; }
|
||||||
|
@ -41,7 +55,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
public void Start(IEnumerable<string> urlPrefixes)
|
public void Start(IEnumerable<string> urlPrefixes)
|
||||||
{
|
{
|
||||||
if (_listener == null)
|
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)
|
foreach (var prefix in urlPrefixes)
|
||||||
{
|
{
|
||||||
|
@ -59,41 +80,32 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
Task.Factory.StartNew(() => InitTask(context));
|
Task.Factory.StartNew(() => InitTask(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitTask(HttpListenerContext context)
|
private Task InitTask(HttpListenerContext context)
|
||||||
{
|
{
|
||||||
|
IHttpRequest httpReq = null;
|
||||||
|
var request = context.Request;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var task = this.ProcessRequestAsync(context);
|
if (request.IsWebSocketRequest)
|
||||||
task.ContinueWith(x => HandleError(x.Exception, context), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
|
{
|
||||||
|
LoggerUtils.LogRequest(_logger, request);
|
||||||
|
|
||||||
//if (task.Status == TaskStatus.Created)
|
ProcessWebSocketRequest(context);
|
||||||
//{
|
return Task.FromResult(true);
|
||||||
// task.RunSynchronously();
|
}
|
||||||
//}
|
|
||||||
|
httpReq = GetRequest(context);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HandleError(ex, context);
|
_logger.ErrorException("Error processing request", ex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task ProcessRequestAsync(HttpListenerContext context)
|
httpReq = httpReq ?? GetRequest(context);
|
||||||
{
|
ErrorHandler(ex, httpReq);
|
||||||
var request = context.Request;
|
|
||||||
|
|
||||||
if (request.IsWebSocketRequest)
|
|
||||||
{
|
|
||||||
LoggerUtils.LogRequest(_logger, request);
|
|
||||||
|
|
||||||
ProcessWebSocketRequest(context);
|
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(context.Request.RawUrl))
|
|
||||||
return ((object)null).AsTaskResult();
|
|
||||||
|
|
||||||
var httpReq = GetRequest(context);
|
|
||||||
|
|
||||||
return RequestHandler(httpReq, request.Url);
|
return RequestHandler(httpReq, request.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,19 +115,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
var endpoint = ctx.Request.RemoteEndPoint.ToString();
|
var endpoint = ctx.Request.RemoteEndPoint.ToString();
|
||||||
var url = ctx.Request.RawUrl;
|
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
|
var connectingArgs = new WebSocketConnectingEventArgs
|
||||||
{
|
{
|
||||||
Url = url,
|
Url = url,
|
||||||
QueryString = queryParamCollection,
|
QueryString = ctx.Request.QueryString,
|
||||||
Endpoint = endpoint
|
Endpoint = endpoint
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,7 +139,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
WebSocketConnected(new WebSocketConnectEventArgs
|
WebSocketConnected(new WebSocketConnectEventArgs
|
||||||
{
|
{
|
||||||
Url = url,
|
Url = url,
|
||||||
QueryString = queryParamCollection,
|
QueryString = ctx.Request.QueryString,
|
||||||
WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
|
WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
|
||||||
Endpoint = endpoint
|
Endpoint = endpoint
|
||||||
});
|
});
|
||||||
|
@ -158,22 +162,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
|
|
||||||
private IHttpRequest GetRequest(HttpListenerContext httpContext)
|
private IHttpRequest GetRequest(HttpListenerContext httpContext)
|
||||||
{
|
{
|
||||||
var operationName = httpContext.Request.GetOperationName();
|
return _httpRequestFactory(httpContext);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
|
@ -214,4 +203,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,14 +2,13 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using ServiceStack;
|
|
||||||
using ServiceStack.Host;
|
|
||||||
using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
|
using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
|
||||||
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
|
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
|
||||||
using IRequest = MediaBrowser.Model.Services.IRequest;
|
using IRequest = MediaBrowser.Model.Services.IRequest;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
namespace Emby.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
public class WebSocketSharpResponse : IHttpResponse
|
public class WebSocketSharpResponse : IHttpResponse
|
||||||
{
|
{
|
||||||
|
@ -98,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this._response.CloseOutputStream(_logger);
|
CloseOutputStream(this._response);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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()
|
public void End()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
@ -133,10 +146,49 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
|
|
||||||
public void SetCookie(Cookie cookie)
|
public void SetCookie(Cookie cookie)
|
||||||
{
|
{
|
||||||
var cookieStr = cookie.AsHeaderValue();
|
var cookieStr = AsHeaderValue(cookie);
|
||||||
_response.Headers.Add(HttpHeaders.SetCookie, cookieStr);
|
_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
|
public bool SendChunked
|
||||||
{
|
{
|
||||||
get { return _response.SendChunked; }
|
get { return _response.SendChunked; }
|
|
@ -2496,10 +2496,12 @@ namespace Emby.Server.Implementations.Library
|
||||||
}).OrderBy(i => i.Path).ToList();
|
}).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)
|
public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
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))
|
.SelectMany(i => _fileSystem.GetFiles(i.FullName, false))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
@ -2788,7 +2790,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
var path = Path.Combine(virtualFolderPath, collectionType + ".collection");
|
var path = Path.Combine(virtualFolderPath, collectionType + ".collection");
|
||||||
|
|
||||||
_fileSystem.WriteAllBytes(path, new byte[] {});
|
_fileSystem.WriteAllBytes(path, new byte[] { });
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionFolder.SaveLibraryOptions(virtualFolderPath, options);
|
CollectionFolder.SaveLibraryOptions(virtualFolderPath, options);
|
||||||
|
|
|
@ -70,10 +70,10 @@ namespace Emby.Server.Implementations.Library
|
||||||
private readonly Func<IConnectManager> _connectFactory;
|
private readonly Func<IConnectManager> _connectFactory;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ICryptographyProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
private readonly string _defaultUserName;
|
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;
|
_logger = logger;
|
||||||
UserRepository = userRepository;
|
UserRepository = userRepository;
|
||||||
|
@ -334,7 +334,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private string GetSha1String(string str)
|
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>
|
/// <summary>
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
{
|
{
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ICryptographyProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
|
|
||||||
public string RegKey
|
public string RegKey
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
private readonly object _fileLock = new object();
|
private readonly object _fileLock = new object();
|
||||||
private string _regKey;
|
private string _regKey;
|
||||||
|
|
||||||
public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider)
|
public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptoProvider cryptographyProvider)
|
||||||
{
|
{
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
@ -59,7 +59,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
|
|
||||||
public void AddRegCheck(string featureId)
|
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;
|
var value = DateTime.UtcNow;
|
||||||
|
|
||||||
SetUpdateRecord(key, value);
|
SetUpdateRecord(key, value);
|
||||||
|
@ -68,7 +68,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
|
|
||||||
public void RemoveRegCheck(string featureId)
|
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;
|
DateTime val;
|
||||||
|
|
||||||
_updateRecords.TryRemove(key, out val);
|
_updateRecords.TryRemove(key, out val);
|
||||||
|
@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
public DateTime LastChecked(string featureId)
|
public DateTime LastChecked(string featureId)
|
||||||
{
|
{
|
||||||
DateTime last;
|
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
|
// guard agains people just putting a large number in the file
|
||||||
return last < DateTime.UtcNow ? last : DateTime.MinValue;
|
return last < DateTime.UtcNow ? last : DateTime.MinValue;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Security
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ICryptographyProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
|
|
||||||
private IEnumerable<IRequiresRegistration> _registeredEntities;
|
private IEnumerable<IRequiresRegistration> _registeredEntities;
|
||||||
protected 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.
|
/// Initializes a new instance of the <see cref="PluginSecurityManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer,
|
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)
|
if (httpClient == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.ServerManager
|
namespace Emby.Server.Implementations.ServerManager
|
||||||
{
|
{
|
||||||
|
@ -75,8 +75,8 @@ namespace Emby.Server.Implementations.ServerManager
|
||||||
private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>();
|
private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>();
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
private readonly IEncoding _textEncoding;
|
private readonly ITextEncoding _textEncoding;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerManager" /> class.
|
/// 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="logger">The logger.</param>
|
||||||
/// <param name="configurationManager">The configuration manager.</param>
|
/// <param name="configurationManager">The configuration manager.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">applicationHost</exception>
|
/// <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)
|
if (applicationHost == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
using UniversalDetector;
|
using UniversalDetector;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.ServerManager
|
namespace Emby.Server.Implementations.ServerManager
|
||||||
|
@ -77,8 +77,8 @@ namespace Emby.Server.Implementations.ServerManager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The query string.</value>
|
/// <value>The query string.</value>
|
||||||
public QueryParamCollection QueryString { get; set; }
|
public QueryParamCollection QueryString { get; set; }
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
private readonly IEncoding _textEncoding;
|
private readonly ITextEncoding _textEncoding;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
|
/// 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="jsonSerializer">The json serializer.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">socket</exception>
|
/// <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)
|
if (socket == null)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +145,7 @@ namespace Emby.Server.Implementations.ServerManager
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnReceiveInternal(_textEncoding.GetASCIIString(bytes, 0, bytes.Length));
|
OnReceiveInternal(_textEncoding.GetASCIIEncoding().GetString(bytes, 0, bytes.Length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string DetectCharset(byte[] bytes)
|
private string DetectCharset(byte[] bytes)
|
||||||
|
|
|
@ -29,12 +29,12 @@ namespace Emby.Server.Implementations.Sync
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IConfigurationManager _config;
|
private readonly IConfigurationManager _config;
|
||||||
private readonly ICryptographyProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
|
|
||||||
public const string PathSeparatorString = "/";
|
public const string PathSeparatorString = "/";
|
||||||
public const char PathSeparatorChar = '/';
|
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;
|
_logger = logger;
|
||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
|
@ -370,7 +370,7 @@ namespace Emby.Server.Implementations.Sync
|
||||||
|
|
||||||
private byte[] CreateMd5(byte[] value)
|
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)
|
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 ILogger _logger;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IConfigurationManager _config;
|
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;
|
_syncManager = syncManager;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace Emby.Server.Implementations.Sync
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly IConfigurationManager _config;
|
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;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Sync
|
||||||
private readonly Func<IMediaSourceManager> _mediaSourceManager;
|
private readonly Func<IMediaSourceManager> _mediaSourceManager;
|
||||||
private readonly IJsonSerializer _json;
|
private readonly IJsonSerializer _json;
|
||||||
private readonly ITaskManager _taskManager;
|
private readonly ITaskManager _taskManager;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
private ISyncProvider[] _providers = { };
|
private ISyncProvider[] _providers = { };
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.Sync
|
||||||
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
|
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
|
||||||
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
|
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;
|
_libraryManager = libraryManager;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace Emby.Server.Implementations.Sync
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IServerApplicationHost _appHost;
|
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;
|
_logger = logger;
|
||||||
_json = json;
|
_json = json;
|
||||||
|
|
|
@ -119,9 +119,9 @@ namespace Emby.Server.Implementations.Updates
|
||||||
/// <value>The application host.</value>
|
/// <value>The application host.</value>
|
||||||
private readonly IApplicationHost _applicationHost;
|
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)
|
if (logger == null)
|
||||||
{
|
{
|
||||||
|
@ -606,7 +606,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
{
|
{
|
||||||
using (var stream = _fileSystem.OpenRead(tempFile))
|
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)
|
if (check != packageChecksum)
|
||||||
{
|
{
|
||||||
throw new Exception(string.Format("Download validation failed for {0}. Probably corrupted during transfer.", package.name));
|
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 readonly IMediaReceiverRegistrar _mediaReceiverRegistrar;
|
||||||
|
|
||||||
private const string XMLContentType = "text/xml; charset=UTF-8";
|
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;
|
_dlnaManager = dlnaManager;
|
||||||
_contentDirectory = contentDirectory;
|
_contentDirectory = contentDirectory;
|
||||||
|
|
|
@ -1263,6 +1263,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
private bool EnableThrottling(StreamState state)
|
private bool EnableThrottling(StreamState state)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
// do not use throttling with hardware encoders
|
// do not use throttling with hardware encoders
|
||||||
return state.InputProtocol == MediaProtocol.File &&
|
return state.InputProtocol == MediaProtocol.File &&
|
||||||
state.RunTimeTicks.HasValue &&
|
state.RunTimeTicks.HasValue &&
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace MediaBrowser.Common.Extensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class BaseExtensions
|
public static class BaseExtensions
|
||||||
{
|
{
|
||||||
public static ICryptographyProvider CryptographyProvider { get; set; }
|
public static ICryptoProvider CryptographyProvider { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Strips the HTML.
|
/// Strips the HTML.
|
||||||
|
|
|
@ -2,6 +2,7 @@ using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net
|
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>
|
/// <returns><c>true</c> if [is in local network] [the specified endpoint]; otherwise, <c>false</c>.</returns>
|
||||||
bool IsInLocalNetwork(string endpoint);
|
bool IsInLocalNetwork(string endpoint);
|
||||||
|
|
||||||
|
IEnumerable<IpAddressInfo> GetLocalIpAddresses();
|
||||||
|
|
||||||
IpAddressInfo ParseIpAddress(string ipAddress);
|
IpAddressInfo ParseIpAddress(string ipAddress);
|
||||||
|
|
||||||
bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
|
bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
|
||||||
|
|
||||||
|
Task<IpAddressInfo[]> GetHostAddressesAsync(string host);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
|
/// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace MediaBrowser.Controller
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the local API URL.
|
/// Gets the local API URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string GetLocalApiUrl(string ipAddress, bool isIpv6);
|
string GetLocalApiUrl(IpAddressInfo address);
|
||||||
|
|
||||||
void LaunchUrl(string url);
|
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 the audio language is not understood by the user, load their preferred subs, if there are any
|
||||||
if (!ContainsOrdinal(preferredLanguages, audioTrackLanguage))
|
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)
|
else if (mode == SubtitlePlaybackMode.Always)
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace MediaBrowser.Controller.Net
|
||||||
{
|
{
|
||||||
public class AuthenticatedAttribute : Attribute, IHasRequestFilter, IAuthenticationAttributes
|
public class AuthenticatedAttribute : Attribute, IHasRequestFilter, IAuthenticationAttributes
|
||||||
{
|
{
|
||||||
public IAuthService AuthService { get; set; }
|
public static IAuthService AuthService { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the roles.
|
/// Gets or sets the roles.
|
||||||
|
@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Net
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value>
|
||||||
public bool AllowBeforeStartupWizard { get; set; }
|
public bool AllowBeforeStartupWizard { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The request filter is executed before the service.
|
/// The request filter is executed before the service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -40,15 +40,6 @@ namespace MediaBrowser.Controller.Net
|
||||||
AuthService.Authenticate(serviceRequest, this);
|
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>
|
/// <summary>
|
||||||
/// Order in which Request Filters are executed.
|
/// Order in which Request Filters are executed.
|
||||||
/// <0 Executed before global request filters
|
/// <0 Executed before global request filters
|
||||||
|
@ -60,7 +51,6 @@ namespace MediaBrowser.Controller.Net
|
||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IEnumerable<string> GetRoles()
|
public IEnumerable<string> GetRoles()
|
||||||
{
|
{
|
||||||
return (Roles ?? string.Empty).Split(',')
|
return (Roles ?? string.Empty).Split(',')
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace MediaBrowser.MediaEncoding.BdInfo
|
namespace MediaBrowser.MediaEncoding.BdInfo
|
||||||
{
|
{
|
||||||
|
@ -15,9 +15,9 @@ namespace MediaBrowser.MediaEncoding.BdInfo
|
||||||
public class BdInfoExaminer : IBlurayExaminer
|
public class BdInfoExaminer : IBlurayExaminer
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
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;
|
_fileSystem = fileSystem;
|
||||||
_textEncoding = textEncoding;
|
_textEncoding = textEncoding;
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IZipClient _zipClient;
|
private readonly IZipClient _zipClient;
|
||||||
private readonly IProcessFactory _processFactory;
|
private readonly IProcessFactory _processFactory;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
|
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
|
||||||
private readonly bool _hasExternalEncoder;
|
private readonly bool _hasExternalEncoder;
|
||||||
|
@ -88,7 +88,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
private readonly int DefaultImageExtractionTimeoutMs;
|
private readonly int DefaultImageExtractionTimeoutMs;
|
||||||
private readonly bool EnableEncoderFontFile;
|
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,
|
int defaultImageExtractionTimeoutMs,
|
||||||
bool enableEncoderFontFile)
|
bool enableEncoderFontFile)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,9 +23,9 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IFileSystem _fileSystem;
|
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;
|
_logger = logger;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
|
|
@ -19,7 +19,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Diagnostics;
|
using MediaBrowser.Model.Diagnostics;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
using UniversalDetector;
|
using UniversalDetector;
|
||||||
|
|
||||||
namespace MediaBrowser.MediaEncoding.Subtitles
|
namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
@ -34,11 +34,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
private readonly IJsonSerializer _json;
|
private readonly IJsonSerializer _json;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
private readonly IProcessFactory _processFactory;
|
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;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_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
|
namespace MediaBrowser.Model.IO
|
||||||
{
|
{
|
||||||
public interface IMemoryStreamProvider
|
public interface IMemoryStreamFactory
|
||||||
{
|
{
|
||||||
MemoryStream CreateNew();
|
MemoryStream CreateNew();
|
||||||
MemoryStream CreateNew(int capacity);
|
MemoryStream CreateNew(int capacity);
|
||||||
MemoryStream CreateNew(byte[] buffer);
|
MemoryStream CreateNew(byte[] buffer);
|
||||||
|
bool TryGetBuffer(MemoryStream stream, out byte[] buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -100,7 +100,7 @@
|
||||||
<Compile Include="Connect\PinExchangeResult.cs" />
|
<Compile Include="Connect\PinExchangeResult.cs" />
|
||||||
<Compile Include="Connect\PinStatusResult.cs" />
|
<Compile Include="Connect\PinStatusResult.cs" />
|
||||||
<Compile Include="Connect\UserLinkType.cs" />
|
<Compile Include="Connect\UserLinkType.cs" />
|
||||||
<Compile Include="Cryptography\ICryptographyProvider.cs" />
|
<Compile Include="Cryptography\ICryptoProvider.cs" />
|
||||||
<Compile Include="Devices\DeviceOptions.cs" />
|
<Compile Include="Devices\DeviceOptions.cs" />
|
||||||
<Compile Include="Devices\DeviceQuery.cs" />
|
<Compile Include="Devices\DeviceQuery.cs" />
|
||||||
<Compile Include="Devices\LocalFileInfo.cs" />
|
<Compile Include="Devices\LocalFileInfo.cs" />
|
||||||
|
@ -138,17 +138,19 @@
|
||||||
<Compile Include="Dto\NameIdPair.cs" />
|
<Compile Include="Dto\NameIdPair.cs" />
|
||||||
<Compile Include="Dto\NameValuePair.cs" />
|
<Compile Include="Dto\NameValuePair.cs" />
|
||||||
<Compile Include="Net\IpEndPointInfo.cs" />
|
<Compile Include="Net\IpEndPointInfo.cs" />
|
||||||
|
<Compile Include="Net\ISocket.cs" />
|
||||||
<Compile Include="Net\ISocketFactory.cs" />
|
<Compile Include="Net\ISocketFactory.cs" />
|
||||||
<Compile Include="Net\IUdpSocket.cs" />
|
<Compile Include="Net\IUdpSocket.cs" />
|
||||||
<Compile Include="Net\SocketReceiveResult.cs" />
|
<Compile Include="Net\SocketReceiveResult.cs" />
|
||||||
|
<Compile Include="Services\IHttpResult.cs" />
|
||||||
<Compile Include="System\IEnvironmentInfo.cs" />
|
<Compile Include="System\IEnvironmentInfo.cs" />
|
||||||
<Compile Include="TextEncoding\IEncoding.cs" />
|
<Compile Include="Text\ITextEncoding.cs" />
|
||||||
<Compile Include="Extensions\LinqExtensions.cs" />
|
<Compile Include="Extensions\LinqExtensions.cs" />
|
||||||
<Compile Include="FileOrganization\SmartMatchInfo.cs" />
|
<Compile Include="FileOrganization\SmartMatchInfo.cs" />
|
||||||
<Compile Include="Health\IHealthMonitor.cs" />
|
<Compile Include="Health\IHealthMonitor.cs" />
|
||||||
<Compile Include="IO\FileSystemMetadata.cs" />
|
<Compile Include="IO\FileSystemMetadata.cs" />
|
||||||
<Compile Include="IO\IFileSystem.cs" />
|
<Compile Include="IO\IFileSystem.cs" />
|
||||||
<Compile Include="IO\IMemoryStreamProvider.cs" />
|
<Compile Include="IO\IMemoryStreamFactory.cs" />
|
||||||
<Compile Include="IO\IShortcutHandler.cs" />
|
<Compile Include="IO\IShortcutHandler.cs" />
|
||||||
<Compile Include="IO\StreamDefaults.cs" />
|
<Compile Include="IO\StreamDefaults.cs" />
|
||||||
<Compile Include="Globalization\ILocalizationManager.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>
|
/// <param name="localPort">The local port to bind to.</param>
|
||||||
/// <returns>A <see cref="IUdpSocket"/> implementation.</returns>
|
/// <returns>A <see cref="IUdpSocket"/> implementation.</returns>
|
||||||
IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
|
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 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 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()
|
public override String ToString()
|
||||||
{
|
{
|
||||||
return Address;
|
return Address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum IpAddressFamily
|
||||||
|
{
|
||||||
|
InterNetwork,
|
||||||
|
InterNetworkV6
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Net
|
namespace MediaBrowser.Model.Net
|
||||||
{
|
{
|
||||||
|
@ -8,11 +9,22 @@ namespace MediaBrowser.Model.Net
|
||||||
|
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
public IpEndPointInfo()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IpEndPointInfo(IpAddressInfo address, int port)
|
||||||
|
{
|
||||||
|
IpAddress = address;
|
||||||
|
Port = port;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
var ipAddresString = IpAddress == null ? string.Empty : IpAddress.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
|
namespace MediaBrowser.Model.Services
|
||||||
{
|
{
|
||||||
public interface IHasRequestFilter
|
public interface IHasRequestFilter
|
||||||
|
@ -22,11 +17,5 @@ namespace MediaBrowser.Model.Services
|
||||||
/// <param name="res">The http response wrapper</param>
|
/// <param name="res">The http response wrapper</param>
|
||||||
/// <param name="requestDto">The request DTO</param>
|
/// <param name="requestDto">The request DTO</param>
|
||||||
void RequestFilter(IRequest req, IResponse res, object requestDto);
|
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 QueryString { get; }
|
||||||
|
|
||||||
QueryParamCollection FormData { 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; }
|
string RawUrl { get; }
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace MediaBrowser.Model.Services
|
||||||
{
|
{
|
||||||
public QueryParamCollection()
|
public QueryParamCollection()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryParamCollection(IDictionary<string, string> headers)
|
public QueryParamCollection(IDictionary<string, string> headers)
|
||||||
|
@ -30,15 +30,30 @@ namespace MediaBrowser.Model.Services
|
||||||
return StringComparer.OrdinalIgnoreCase;
|
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>
|
/// <summary>
|
||||||
/// Adds a new query parameter.
|
/// Adds a new query parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Add(string key, string value)
|
public virtual void Add(string key, string value)
|
||||||
{
|
{
|
||||||
Add(new NameValuePair(key, 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))
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
{
|
{
|
||||||
|
@ -81,17 +96,21 @@ namespace MediaBrowser.Model.Services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The number of parameters that were removed</returns>
|
/// <returns>The number of parameters that were removed</returns>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="name" /> is null.</exception>
|
/// <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);
|
return RemoveAll(p => p.Name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Get(string 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();
|
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 ILibraryMonitor _libraryMonitor;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ImageSaver" /> class.
|
/// 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="libraryMonitor">The directory watchers.</param>
|
||||||
/// <param name="fileSystem">The file system.</param>
|
/// <param name="fileSystem">The file system.</param>
|
||||||
/// <param name="logger">The logger.</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;
|
_config = config;
|
||||||
_libraryMonitor = libraryMonitor;
|
_libraryMonitor = libraryMonitor;
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
private IExternalId[] _externalIds;
|
private IExternalId[] _externalIds;
|
||||||
|
|
||||||
private readonly Func<ILibraryManager> _libraryManagerFactory;
|
private readonly Func<ILibraryManager> _libraryManagerFactory;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
|
/// 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="libraryMonitor">The directory watchers.</param>
|
||||||
/// <param name="logManager">The log manager.</param>
|
/// <param name="logManager">The log manager.</param>
|
||||||
/// <param name="fileSystem">The file system.</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");
|
_logger = logManager.GetLogger("ProviderManager");
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
|
|
@ -45,6 +45,11 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
|
|
||||||
var codec = Path.GetExtension(fullName).ToLower().TrimStart('.');
|
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 the subtitle file matches the video file name
|
||||||
if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -74,9 +79,9 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
// Try to translate to three character code
|
// Try to translate to three character code
|
||||||
// Be flexible and check against both the full and three character versions
|
// Be flexible and check against both the full and three character versions
|
||||||
var culture = _localization.GetCultures()
|
var culture = _localization.GetCultures()
|
||||||
.FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) ||
|
.FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
|
string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (culture != null)
|
if (culture != null)
|
||||||
|
@ -119,7 +124,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
{
|
{
|
||||||
get
|
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 CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
private readonly ILocalizationManager _localizationManager;
|
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;
|
_zipClient = zipClient;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class ContainerAdapter
|
/// Class ContainerAdapter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class ContainerAdapter : IContainerAdapter, IRelease
|
class ContainerAdapter : IContainerAdapter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _app host
|
/// The _app host
|
||||||
|
@ -40,14 +40,5 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
return _appHost.TryResolve<T>();
|
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;
|
||||||
using ServiceStack.Host;
|
using ServiceStack.Host;
|
||||||
using ServiceStack.Host.Handlers;
|
using ServiceStack.Host.Handlers;
|
||||||
using ServiceStack.Logging;
|
|
||||||
using ServiceStack.Web;
|
using ServiceStack.Web;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Net.Sockets;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Emby.Common.Implementations.Net;
|
||||||
using Emby.Server.Implementations.HttpServer;
|
using Emby.Server.Implementations.HttpServer;
|
||||||
using Emby.Server.Implementations.HttpServer.SocketSharp;
|
using Emby.Server.Implementations.HttpServer.SocketSharp;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Common.Security;
|
using MediaBrowser.Common.Security;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Model.Cryptography;
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using ServiceStack.Api.Swagger;
|
using MediaBrowser.Model.Text;
|
||||||
|
using SocketHttpListener.Net;
|
||||||
|
using SocketHttpListener.Primitives;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
|
@ -49,21 +56,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly INetworkManager _networkManager;
|
private readonly INetworkManager _networkManager;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
|
private readonly ITextEncoding _textEncoding;
|
||||||
|
private readonly ISocketFactory _socketFactory;
|
||||||
|
private readonly ICryptoProvider _cryptoProvider;
|
||||||
|
|
||||||
public HttpListenerHost(IServerApplicationHost applicationHost,
|
public HttpListenerHost(IServerApplicationHost applicationHost,
|
||||||
ILogManager logManager,
|
ILogManager logManager,
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
string serviceName,
|
string serviceName,
|
||||||
string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamProvider memoryStreamProvider, params Assembly[] assembliesWithServices)
|
string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider)
|
||||||
: base(serviceName, assembliesWithServices)
|
: base(serviceName, new Assembly[] { })
|
||||||
{
|
{
|
||||||
_appHost = applicationHost;
|
_appHost = applicationHost;
|
||||||
DefaultRedirectPath = defaultRedirectPath;
|
DefaultRedirectPath = defaultRedirectPath;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
_memoryStreamProvider = memoryStreamProvider;
|
_memoryStreamProvider = memoryStreamProvider;
|
||||||
|
_textEncoding = textEncoding;
|
||||||
|
_socketFactory = socketFactory;
|
||||||
|
_cryptoProvider = cryptoProvider;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
_logger = logManager.GetLogger("HttpServer");
|
_logger = logManager.GetLogger("HttpServer");
|
||||||
|
@ -73,10 +87,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
public string GlobalResponse { get; set; }
|
public string GlobalResponse { get; set; }
|
||||||
|
|
||||||
public override void Configure(Container container)
|
public override void Configure()
|
||||||
{
|
{
|
||||||
HostConfig.Instance.DefaultRedirectPath = DefaultRedirectPath;
|
HostConfig.Instance.DefaultRedirectPath = DefaultRedirectPath;
|
||||||
HostConfig.Instance.LogUnobservedTaskExceptions = false;
|
|
||||||
|
|
||||||
HostConfig.Instance.MapExceptionToStatusCode = new Dictionary<Type, int>
|
HostConfig.Instance.MapExceptionToStatusCode = new Dictionary<Type, int>
|
||||||
{
|
{
|
||||||
|
@ -93,33 +106,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{typeof (NotSupportedException), 500}
|
{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
|
// The Markdown feature causes slow startup times (5 mins+) on cold boots for some users
|
||||||
// Custom format allows images
|
// Custom format allows images
|
||||||
HostConfig.Instance.EnableFeatures = Feature.Html | Feature.Json | Feature.Xml | Feature.CustomFormat;
|
HostConfig.Instance.EnableFeatures = Feature.Html | Feature.Json | Feature.Xml | Feature.CustomFormat;
|
||||||
|
|
||||||
container.Adapter = _containerAdapter;
|
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;'
|
|
||||||
// }
|
|
||||||
//});
|
|
||||||
|
|
||||||
var requestFilters = _appHost.GetExports<IRequestFilter>().ToList();
|
var requestFilters = _appHost.GetExports<IRequestFilter>().ToList();
|
||||||
foreach (var filter in requestFilters)
|
foreach (var filter in requestFilters)
|
||||||
|
@ -130,11 +121,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse);
|
HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAfterInit()
|
protected override ILogger Logger
|
||||||
{
|
{
|
||||||
SetAppDomainData();
|
get
|
||||||
|
{
|
||||||
base.OnAfterInit();
|
return _logger;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnConfigLoad()
|
public override void OnConfigLoad()
|
||||||
|
@ -153,23 +145,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
return new ServiceController(this, () => types);
|
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)
|
public override ServiceStackHost Start(string listeningAtUrlBase)
|
||||||
{
|
{
|
||||||
StartListener();
|
StartListener();
|
||||||
|
@ -207,7 +182,35 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
private IHttpListener GetListener()
|
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)
|
private void OnWebSocketConnecting(WebSocketConnectingEventArgs args)
|
||||||
|
@ -259,11 +262,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
|
|
||||||
var contentType = httpReq.ResponseContentType;
|
var contentType = httpReq.ResponseContentType;
|
||||||
|
|
||||||
var serializer = HostContext.ContentTypes.GetResponseSerializer(contentType);
|
var serializer = ContentTypes.Instance.GetResponseSerializer(contentType);
|
||||||
if (serializer == null)
|
if (serializer == null)
|
||||||
{
|
{
|
||||||
contentType = HostContext.Config.DefaultContentType;
|
contentType = HostContext.Config.DefaultContentType;
|
||||||
serializer = HostContext.ContentTypes.GetResponseSerializer(contentType);
|
serializer = ContentTypes.Instance.GetResponseSerializer(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpError = ex as IHttpError;
|
var httpError = ex as IHttpError;
|
||||||
|
@ -411,171 +414,170 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
protected async Task RequestHandler(IHttpRequest httpReq, Uri url)
|
protected async Task RequestHandler(IHttpRequest httpReq, Uri url)
|
||||||
{
|
{
|
||||||
var date = DateTime.Now;
|
var date = DateTime.Now;
|
||||||
|
|
||||||
var httpRes = httpReq.Response;
|
var httpRes = httpReq.Response;
|
||||||
|
bool enableLog = false;
|
||||||
|
string urlToLog = null;
|
||||||
|
string remoteIp = null;
|
||||||
|
|
||||||
if (_disposed)
|
try
|
||||||
{
|
{
|
||||||
httpRes.StatusCode = 503;
|
if (_disposed)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
httpRes.Write("<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + newUrl + "\">" + newUrl + "</a></body></html>");
|
httpRes.StatusCode = 503;
|
||||||
|
|
||||||
httpRes.Close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 &&
|
if (!ValidateHost(url))
|
||||||
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>");
|
httpRes.StatusCode = 400;
|
||||||
|
httpRes.ContentType = "text/plain";
|
||||||
httpRes.Close();
|
httpRes.Write("Invalid host");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(localPath, "/web", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
httpRes.RedirectToUrl(DefaultRedirectPath);
|
httpRes.StatusCode = 200;
|
||||||
return;
|
httpRes.AddHeader("Access-Control-Allow-Origin", "*");
|
||||||
}
|
httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
||||||
if (string.Equals(localPath, "/web/", StringComparison.OrdinalIgnoreCase))
|
httpRes.AddHeader("Access-Control-Allow-Headers",
|
||||||
{
|
"Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization");
|
||||||
httpRes.RedirectToUrl("../" + DefaultRedirectPath);
|
httpRes.ContentType = "text/html";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
httpRes.RedirectToUrl(DefaultRedirectPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(localPath))
|
|
||||||
{
|
|
||||||
httpRes.RedirectToUrl("/" + DefaultRedirectPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase))
|
var operationName = httpReq.OperationName;
|
||||||
{
|
var localPath = url.LocalPath;
|
||||||
httpRes.RedirectToUrl("web/pin.html");
|
|
||||||
return;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
if (!string.IsNullOrWhiteSpace(GlobalResponse))
|
{
|
||||||
|
ErrorHandler(ex, httpReq);
|
||||||
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
httpRes.StatusCode = 503;
|
|
||||||
httpRes.ContentType = "text/html";
|
|
||||||
httpRes.Write(GlobalResponse);
|
|
||||||
|
|
||||||
httpRes.Close();
|
httpRes.Close();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var handler = HttpHandlerFactory.GetHandler(httpReq);
|
if (enableLog)
|
||||||
|
|
||||||
var remoteIp = httpReq.RemoteIp;
|
|
||||||
|
|
||||||
var serviceStackHandler = handler as IServiceStackHandler;
|
|
||||||
if (serviceStackHandler != null)
|
|
||||||
{
|
|
||||||
var restHandler = serviceStackHandler as RestHandler;
|
|
||||||
if (restHandler != null)
|
|
||||||
{
|
{
|
||||||
httpReq.OperationName = operationName = restHandler.RestPath.RequestType.GetOperationName();
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await serviceStackHandler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
httpRes.Close();
|
|
||||||
var statusCode = httpRes.StatusCode;
|
var statusCode = httpRes.StatusCode;
|
||||||
|
|
||||||
var duration = DateTime.Now - date;
|
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>
|
/// <summary>
|
||||||
/// Adds the rest handlers.
|
/// Adds the rest handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -653,15 +655,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
return "mediabrowser/" + path;
|
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 bool _disposed;
|
||||||
private readonly object _disposeLock = new object();
|
private readonly object _disposeLock = new object();
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
|
@ -696,4 +689,37 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
Start(UrlPrefixes.First());
|
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.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Emby.Server.Implementations.HttpServer;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
|
using MediaBrowser.Model.Cryptography;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using ServiceStack.Logging;
|
using MediaBrowser.Model.Net;
|
||||||
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
|
@ -21,13 +23,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||||
ILogManager logManager,
|
ILogManager logManager,
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
INetworkManager networkmanager,
|
INetworkManager networkmanager,
|
||||||
IMemoryStreamProvider streamProvider,
|
IMemoryStreamFactory streamProvider,
|
||||||
string serverName,
|
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, textEncoding, socketFactory, cryptoProvider);
|
||||||
|
|
||||||
return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, networkmanager, streamProvider);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.Collections.Specialized;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using ServiceStack;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
|
@ -128,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
get
|
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
|
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 " +
|
string msg = String.Format("A potentially dangerous Request.{0} value was " +
|
||||||
"detected from the client ({1}={2}).", name, key, v);
|
"detected from the client ({1}={2}).", name, key, v);
|
||||||
|
|
||||||
throw new HttpRequestValidationException(msg);
|
throw new Exception(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ValidateNameValueCollection(string name, QueryParamCollection coll)
|
static void ValidateNameValueCollection(string name, QueryParamCollection coll)
|
||||||
|
@ -278,9 +277,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
|
|
||||||
void AddRawKeyValue(StringBuilder key, StringBuilder value)
|
void AddRawKeyValue(StringBuilder key, StringBuilder value)
|
||||||
{
|
{
|
||||||
string decodedKey = HttpUtility.UrlDecode(key.ToString(), ContentEncoding);
|
string decodedKey = WebUtility.UrlDecode(key.ToString());
|
||||||
form.Add(decodedKey,
|
form.Add(decodedKey,
|
||||||
HttpUtility.UrlDecode(value.ToString(), ContentEncoding));
|
WebUtility.UrlDecode(value.ToString()));
|
||||||
|
|
||||||
key.Length = 0;
|
key.Length = 0;
|
||||||
value.Length = 0;
|
value.Length = 0;
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Emby.Server.Implementations.HttpServer.SocketSharp;
|
using Emby.Server.Implementations.HttpServer.SocketSharp;
|
||||||
using Funq;
|
using Funq;
|
||||||
using MediaBrowser.Common.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using ServiceStack.Host;
|
using ServiceStack.Host;
|
||||||
using ServiceStack.Web;
|
|
||||||
using SocketHttpListener.Net;
|
using SocketHttpListener.Net;
|
||||||
using IHttpFile = MediaBrowser.Model.Services.IHttpFile;
|
using IHttpFile = MediaBrowser.Model.Services.IHttpFile;
|
||||||
using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
|
using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
|
||||||
|
@ -25,12 +22,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
public Container Container { get; set; }
|
public Container Container { get; set; }
|
||||||
private readonly HttpListenerRequest request;
|
private readonly HttpListenerRequest request;
|
||||||
private readonly IHttpResponse response;
|
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.OperationName = operationName;
|
||||||
this.RequestAttributes = requestAttributes;
|
|
||||||
_memoryStreamProvider = memoryStreamProvider;
|
_memoryStreamProvider = memoryStreamProvider;
|
||||||
this.request = httpContext.Request;
|
this.request = httpContext.Request;
|
||||||
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
|
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
|
||||||
|
@ -56,38 +52,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
get { return response; }
|
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 string OperationName { get; set; }
|
||||||
|
|
||||||
public object Dto { 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
|
public string RawUrl
|
||||||
{
|
{
|
||||||
get { return request.RawUrl; }
|
get { return request.RawUrl; }
|
||||||
|
@ -107,7 +75,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
{
|
{
|
||||||
get
|
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
|
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
|
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
|
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 ??
|
return remoteIp ??
|
||||||
(remoteIp = (CheckBadChars(XForwardedFor)) ??
|
(remoteIp = (CheckBadChars(XForwardedFor)) ??
|
||||||
(NormalizeIp(CheckBadChars(XRealIp)) ??
|
(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
|
get
|
||||||
{
|
{
|
||||||
return responseContentType
|
return responseContentType
|
||||||
?? (responseContentType = this.GetResponseContentType());
|
?? (responseContentType = GetResponseContentType(this));
|
||||||
}
|
}
|
||||||
set
|
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; }
|
public bool HasExplicitResponseContentType { get; private set; }
|
||||||
|
|
||||||
private string pathInfo;
|
private string pathInfo;
|
||||||
|
@ -286,7 +346,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
if (pos != -1)
|
if (pos != -1)
|
||||||
{
|
{
|
||||||
var path = request.RawUrl.Substring(0, pos);
|
var path = request.RawUrl.Substring(0, pos);
|
||||||
this.pathInfo = HttpRequestExtensions.GetPathInfo(
|
this.pathInfo = GetPathInfo(
|
||||||
path,
|
path,
|
||||||
mode,
|
mode,
|
||||||
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;
|
private Dictionary<string, System.Net.Cookie> cookies;
|
||||||
public IDictionary<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; }
|
get { return request.UserAgent; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryParamCollection headers;
|
|
||||||
public QueryParamCollection Headers
|
public QueryParamCollection Headers
|
||||||
{
|
{
|
||||||
get { return headers ?? (headers = ToQueryParams(request.Headers)); }
|
get { return request.Headers; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryParamCollection queryString;
|
private QueryParamCollection queryString;
|
||||||
|
@ -345,18 +453,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
get { return formData ?? (formData = this.Form); }
|
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
|
public bool IsLocal
|
||||||
{
|
{
|
||||||
get { return request.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
|
public Stream InputStream
|
||||||
{
|
{
|
||||||
get { return bufferedStream ?? request.InputStream; }
|
get { return request.InputStream; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public long ContentLength
|
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)
|
if (stream is MemoryStream)
|
||||||
{
|
{
|
||||||
|
@ -507,4 +591,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
return pathInfo;
|
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
|
namespace MediaBrowser.Server.Implementations.IO
|
||||||
{
|
{
|
||||||
public class RecyclableMemoryStreamProvider : IMemoryStreamProvider
|
public class RecyclableMemoryStreamProvider : IMemoryStreamFactory
|
||||||
{
|
{
|
||||||
readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager();
|
readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager();
|
||||||
|
|
||||||
|
@ -22,9 +22,15 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||||
{
|
{
|
||||||
return _manager.GetStream("RecyclableMemoryStream", buffer, 0, buffer.Length);
|
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()
|
public MemoryStream CreateNew()
|
||||||
{
|
{
|
||||||
|
@ -40,5 +46,11 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||||
{
|
{
|
||||||
return new MemoryStream(buffer);
|
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>
|
<HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</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">
|
<Reference Include="SharpCompress, Version=0.10.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
|
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="SocketHttpListener, Version=1.0.6154.22657, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="SocketHttpListener.Portable">
|
||||||
<HintPath>..\packages\SocketHttpListener.1.0.0.44\lib\net45\SocketHttpListener.dll</HintPath>
|
<HintPath>..\ThirdParty\emby\SocketHttpListener.Portable.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
@ -88,7 +84,6 @@
|
||||||
<Reference Include="System.Net" />
|
<Reference Include="System.Net" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
<Reference Include="System.Security" />
|
<Reference Include="System.Security" />
|
||||||
<Reference Include="System.Web" />
|
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="ServiceStack">
|
<Reference Include="ServiceStack">
|
||||||
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.dll</HintPath>
|
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.dll</HintPath>
|
||||||
|
@ -119,18 +114,9 @@
|
||||||
<Compile Include="HttpServer\ContainerAdapter.cs" />
|
<Compile Include="HttpServer\ContainerAdapter.cs" />
|
||||||
<Compile Include="HttpServer\HttpListenerHost.cs" />
|
<Compile Include="HttpServer\HttpListenerHost.cs" />
|
||||||
<Compile Include="HttpServer\HttpResultFactory.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\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\RequestMono.cs" />
|
||||||
<Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
|
|
||||||
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
|
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
|
||||||
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
|
|
||||||
<Compile Include="IO\LibraryMonitor.cs" />
|
<Compile Include="IO\LibraryMonitor.cs" />
|
||||||
<Compile Include="IO\MemoryStreamProvider.cs" />
|
<Compile Include="IO\MemoryStreamProvider.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
|
<Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Stream.</returns>
|
/// <returns>Stream.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">reader</exception>
|
/// <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)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>System.Byte[][].</returns>
|
/// <returns>System.Byte[][].</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">obj</exception>
|
/// <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)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
|
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)
|
: base(logManager, dbConnector)
|
||||||
{
|
{
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
|
|
|
@ -99,12 +99,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
private IDbCommand _updateInheritedTagsCommand;
|
private IDbCommand _updateInheritedTagsCommand;
|
||||||
|
|
||||||
public const int LatestSchemaVersion = 109;
|
public const int LatestSchemaVersion = 109;
|
||||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamFactory _memoryStreamProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||||
/// </summary>
|
/// </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)
|
: base(logManager, connector)
|
||||||
{
|
{
|
||||||
if (config == null)
|
if (config == null)
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
|
public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
|
||||||
{
|
{
|
||||||
private readonly IJsonSerializer _jsonSerializer;
|
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;
|
_jsonSerializer = jsonSerializer;
|
||||||
_memoryStreamProvider = memoryStreamProvider;
|
_memoryStreamProvider = memoryStreamProvider;
|
||||||
|
|
|
@ -5,6 +5,5 @@
|
||||||
<package id="MediaBrowser.Naming" version="1.0.0.59" targetFramework="net46" />
|
<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="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net46" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.6" 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" />
|
<package id="UniversalDetector" version="1.0.1" targetFramework="net46" />
|
||||||
</packages>
|
</packages>
|
|
@ -126,7 +126,7 @@ using MediaBrowser.Model.Reflection;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using MediaBrowser.Model.Social;
|
using MediaBrowser.Model.Social;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
using MediaBrowser.Model.Xml;
|
using MediaBrowser.Model.Xml;
|
||||||
using MediaBrowser.Server.Implementations.Archiving;
|
using MediaBrowser.Server.Implementations.Archiving;
|
||||||
using MediaBrowser.Server.Implementations.Serialization;
|
using MediaBrowser.Server.Implementations.Serialization;
|
||||||
|
@ -252,6 +252,8 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
/// <value>The zip client.</value>
|
/// <value>The zip client.</value>
|
||||||
protected IZipClient ZipClient { get; private set; }
|
protected IZipClient ZipClient { get; private set; }
|
||||||
|
|
||||||
|
protected IAuthService AuthService { get; private set; }
|
||||||
|
|
||||||
private readonly StartupOptions _startupOptions;
|
private readonly StartupOptions _startupOptions;
|
||||||
private readonly string _releaseAssetFilename;
|
private readonly string _releaseAssetFilename;
|
||||||
|
|
||||||
|
@ -410,7 +412,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
LogManager.RemoveConsoleOutput();
|
LogManager.RemoveConsoleOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IMemoryStreamProvider CreateMemoryStreamProvider()
|
protected override IMemoryStreamFactory CreateMemoryStreamProvider()
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||||
{
|
{
|
||||||
|
@ -555,7 +557,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
StringExtensions.LocalizationManager = LocalizationManager;
|
StringExtensions.LocalizationManager = LocalizationManager;
|
||||||
RegisterSingleInstance(LocalizationManager);
|
RegisterSingleInstance(LocalizationManager);
|
||||||
|
|
||||||
IEncoding textEncoding = new TextEncoding(FileSystemManager);
|
ITextEncoding textEncoding = new TextEncoding(FileSystemManager);
|
||||||
RegisterSingleInstance(textEncoding);
|
RegisterSingleInstance(textEncoding);
|
||||||
Utilities.EncodingHelper = textEncoding;
|
Utilities.EncodingHelper = textEncoding;
|
||||||
RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding));
|
RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding));
|
||||||
|
@ -601,7 +603,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
|
|
||||||
RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
|
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");
|
HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
|
||||||
RegisterSingleInstance(HttpServer, false);
|
RegisterSingleInstance(HttpServer, false);
|
||||||
progress.Report(10);
|
progress.Report(10);
|
||||||
|
@ -702,7 +704,9 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager);
|
var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager);
|
||||||
RegisterSingleInstance<IAuthorizationContext>(authContext);
|
RegisterSingleInstance<IAuthorizationContext>(authContext);
|
||||||
RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
|
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);
|
SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider, ProcessFactory, textEncoding);
|
||||||
RegisterSingleInstance(SubtitleEncoder);
|
RegisterSingleInstance(SubtitleEncoder);
|
||||||
|
@ -900,6 +904,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
BaseStreamingService.AppHost = this;
|
BaseStreamingService.AppHost = this;
|
||||||
BaseStreamingService.HttpClient = HttpClient;
|
BaseStreamingService.HttpClient = HttpClient;
|
||||||
Utilities.CryptographyProvider = CryptographyProvider;
|
Utilities.CryptographyProvider = CryptographyProvider;
|
||||||
|
AuthenticatedAttribute.AuthService = AuthService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1291,7 +1296,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Return the first matched address, if found, or the first known local address
|
// 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)
|
if (address != null)
|
||||||
{
|
{
|
||||||
|
@ -1308,19 +1313,14 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLocalApiUrl(IPAddress ipAddress)
|
public string GetLocalApiUrl(IpAddressInfo ipAddress)
|
||||||
{
|
{
|
||||||
return GetLocalApiUrl(ipAddress.ToString(), ipAddress.AddressFamily == AddressFamily.InterNetworkV6);
|
if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
|
||||||
}
|
|
||||||
|
|
||||||
public string GetLocalApiUrl(string ipAddress, bool isIpv6)
|
|
||||||
{
|
|
||||||
if (isIpv6)
|
|
||||||
{
|
{
|
||||||
return GetLocalApiUrl("[" + ipAddress + "]");
|
return GetLocalApiUrl("[" + ipAddress.Address + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetLocalApiUrl(ipAddress);
|
return GetLocalApiUrl(ipAddress.Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLocalApiUrl(string host)
|
public string GetLocalApiUrl(string host)
|
||||||
|
@ -1332,23 +1332,8 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
|
|
||||||
public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
|
public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
|
||||||
{
|
{
|
||||||
var list = await GetLocalIpAddressesInternal().ConfigureAwait(false);
|
var addresses = NetworkManager.GetLocalIpAddresses().ToList();
|
||||||
|
var list = new List<IpAddressInfo>();
|
||||||
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>();
|
|
||||||
|
|
||||||
foreach (var address in addresses)
|
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 readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||||
private DateTime _lastAddressCacheClear;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common</id>
|
<id>MediaBrowser.Common</id>
|
||||||
<version>3.0.684</version>
|
<version>3.0.688</version>
|
||||||
<title>Emby.Common</title>
|
<title>Emby.Common</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Server.Core</id>
|
<id>MediaBrowser.Server.Core</id>
|
||||||
<version>3.0.684</version>
|
<version>3.0.688</version>
|
||||||
<title>Emby.Server.Core</title>
|
<title>Emby.Server.Core</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains core components required to build plugins for Emby Server.</description>
|
<description>Contains core components required to build plugins for Emby Server.</description>
|
||||||
<copyright>Copyright © Emby 2013</copyright>
|
<copyright>Copyright © Emby 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.684" />
|
<dependency id="MediaBrowser.Common" version="3.0.688" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|
|
@ -24,7 +24,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.Cryptography;
|
using MediaBrowser.Model.Cryptography;
|
||||||
using MediaBrowser.Model.TextEncoding;
|
using MediaBrowser.Model.Text;
|
||||||
|
|
||||||
namespace OpenSubtitlesHandler
|
namespace OpenSubtitlesHandler
|
||||||
{
|
{
|
||||||
|
@ -33,9 +33,9 @@ namespace OpenSubtitlesHandler
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class Utilities
|
public sealed class Utilities
|
||||||
{
|
{
|
||||||
public static ICryptographyProvider CryptographyProvider { get; set; }
|
public static ICryptoProvider CryptographyProvider { get; set; }
|
||||||
public static IHttpClient HttpClient { 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";
|
private const string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc";
|
||||||
|
|
||||||
|
@ -124,13 +124,13 @@ namespace OpenSubtitlesHandler
|
||||||
data.Add((byte)r);
|
data.Add((byte)r);
|
||||||
}
|
}
|
||||||
var bytes = data.ToArray();
|
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)
|
public static byte[] GetASCIIBytes(string text)
|
||||||
{
|
{
|
||||||
return EncodingHelper.GetASCIIBytes(text);
|
return EncodingHelper.GetASCIIEncoding().GetBytes(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user