From e174a7c1efae8cdf0e91197c35ec2cb0eb5d129a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 27 Dec 2015 14:07:16 -0500 Subject: add ipv6, update SocketHttpListener --- .../HttpServer/HttpListenerHost.cs | 13 +- .../HttpServer/ServerFactory.cs | 5 +- .../HttpServer/SocketSharp/HttpUtility.cs | 941 +++++++++++++++++++++ .../SocketSharp/WebSocketSharpRequest.cs | 3 +- 4 files changed, 953 insertions(+), 9 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs (limited to 'MediaBrowser.Server.Implementations/HttpServer') diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 6ade9a8f6..847982976 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -19,6 +19,7 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; namespace MediaBrowser.Server.Implementations.HttpServer @@ -46,6 +47,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer public string CertificatePath { get; private set; } private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; /// /// Gets the local end points. @@ -69,10 +71,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer ILogManager logManager, IServerConfigurationManager config, string serviceName, - string defaultRedirectPath, params Assembly[] assembliesWithServices) + string defaultRedirectPath, INetworkManager networkManager, params Assembly[] assembliesWithServices) : base(serviceName, assembliesWithServices) { DefaultRedirectPath = defaultRedirectPath; + _networkManager = networkManager; _config = config; _logger = logManager.GetLogger("HttpServer"); @@ -175,11 +178,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private void OnRequestReceived(string localEndPoint) { - var ignore = localEndPoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 || - - localEndPoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || - localEndPoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || - localEndPoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase); + var ignore = _networkManager.IsInPrivateAddressSpace(localEndPoint); if (ignore) { @@ -188,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (_localEndpointLock.TryEnterWriteLock(100)) { - var list = _localEndpoints.ToList(); + var list = _localEndpoints; list.Remove(localEndPoint); list.Insert(0, localEndPoint); diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs index 4d81ec157..cc351f6b3 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; @@ -17,18 +18,20 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// The application host. /// The log manager. /// The configuration. + /// The _networkmanager. /// Name of the server. /// The default redirectpath. /// IHttpServer. public static IHttpServer CreateServer(IApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, + INetworkManager _networkmanager, string serverName, string defaultRedirectpath) { LogManager.LogFactory = new ServerLogFactory(logManager); - return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath); + return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs new file mode 100644 index 000000000..3ef48d13a --- /dev/null +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs @@ -0,0 +1,941 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; + +namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +{ + public static class MyHttpUtility + { + sealed class HttpQSCollection : NameValueCollection + { + public override string ToString() + { + int count = Count; + if (count == 0) + return ""; + StringBuilder sb = new StringBuilder(); + string[] keys = AllKeys; + for (int i = 0; i < count; i++) + { + sb.AppendFormat("{0}={1}&", keys[i], this[keys[i]]); + } + if (sb.Length > 0) + sb.Length--; + return sb.ToString(); + } + } + + // Must be sorted + static readonly long[] entities = new long[] { + (long)'A' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'A' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'A' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24, + (long)'A' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24, + (long)'A' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'B' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'C' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'C' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'D' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16, + (long)'D' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'E' << 56 | (long)'T' << 48 | (long)'H' << 40, + (long)'E' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'E' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'E' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'E' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'E' << 56 | (long)'t' << 48 | (long)'a' << 40, + (long)'E' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'G' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'I' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'I' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'I' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'I' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'I' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'K' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24, + (long)'L' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16, + (long)'M' << 56 | (long)'u' << 48, + (long)'N' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'N' << 56 | (long)'u' << 48, + (long)'O' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'O' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'O' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24, + (long)'O' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'O' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16, + (long)'O' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'P' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'P' << 56 | (long)'i' << 48, + (long)'P' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24, + (long)'P' << 56 | (long)'s' << 48 | (long)'i' << 40, + (long)'R' << 56 | (long)'h' << 48 | (long)'o' << 40, + (long)'S' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16, + (long)'S' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'T' << 56 | (long)'H' << 48 | (long)'O' << 40 | (long)'R' << 32 | (long)'N' << 24, + (long)'T' << 56 | (long)'a' << 48 | (long)'u' << 40, + (long)'T' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'U' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'U' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'U' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'U' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'U' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'X' << 56 | (long)'i' << 48, + (long)'Y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'Y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'Z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'a' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'a' << 56 | (long)'c' << 48 | (long)'u' << 40 | (long)'t' << 32 | (long)'e' << 24, + (long)'a' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'a' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'l' << 48 | (long)'e' << 40 | (long)'f' << 32 | (long)'s' << 24 | (long)'y' << 16 | (long)'m' << 8, + (long)'a' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24, + (long)'a' << 56 | (long)'m' << 48 | (long)'p' << 40, + (long)'a' << 56 | (long)'n' << 48 | (long)'d' << 40, + (long)'a' << 56 | (long)'n' << 48 | (long)'g' << 40, + (long)'a' << 56 | (long)'p' << 48 | (long)'o' << 40 | (long)'s' << 32, + (long)'a' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24, + (long)'a' << 56 | (long)'s' << 48 | (long)'y' << 40 | (long)'m' << 32 | (long)'p' << 24, + (long)'a' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'b' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'b' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'b' << 56 | (long)'r' << 48 | (long)'v' << 40 | (long)'b' << 32 | (long)'a' << 24 | (long)'r' << 16, + (long)'b' << 56 | (long)'u' << 48 | (long)'l' << 40 | (long)'l' << 32, + (long)'c' << 56 | (long)'a' << 48 | (long)'p' << 40, + (long)'c' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'c' << 56 | (long)'e' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'c' << 56 | (long)'e' << 48 | (long)'n' << 40 | (long)'t' << 32, + (long)'c' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'c' << 56 | (long)'i' << 48 | (long)'r' << 40 | (long)'c' << 32, + (long)'c' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'b' << 32 | (long)'s' << 24, + (long)'c' << 56 | (long)'o' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'c' << 56 | (long)'o' << 48 | (long)'p' << 40 | (long)'y' << 32, + (long)'c' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'r' << 24, + (long)'c' << 56 | (long)'u' << 48 | (long)'p' << 40, + (long)'c' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'n' << 16, + (long)'d' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'d' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16, + (long)'d' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'d' << 56 | (long)'e' << 48 | (long)'g' << 40, + (long)'d' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'d' << 56 | (long)'i' << 48 | (long)'a' << 40 | (long)'m' << 32 | (long)'s' << 24, + (long)'d' << 56 | (long)'i' << 48 | (long)'v' << 40 | (long)'i' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'e' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'m' << 48 | (long)'p' << 40 | (long)'t' << 32 | (long)'y' << 24, + (long)'e' << 56 | (long)'m' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'e' << 56 | (long)'n' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'e' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'e' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'i' << 32 | (long)'v' << 24, + (long)'e' << 56 | (long)'t' << 48 | (long)'a' << 40, + (long)'e' << 56 | (long)'t' << 48 | (long)'h' << 40, + (long)'e' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'e' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'o' << 32, + (long)'e' << 56 | (long)'x' << 48 | (long)'i' << 40 | (long)'s' << 32 | (long)'t' << 24, + (long)'f' << 56 | (long)'n' << 48 | (long)'o' << 40 | (long)'f' << 32, + (long)'f' << 56 | (long)'o' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'l' << 24 | (long)'l' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'2' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'4' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'3' << 24 | (long)'4' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'l' << 24, + (long)'g' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'g' << 56 | (long)'e' << 48, + (long)'g' << 56 | (long)'t' << 48, + (long)'h' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'h' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'h' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'t' << 24 | (long)'s' << 16, + (long)'h' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'l' << 32 | (long)'i' << 24 | (long)'p' << 16, + (long)'i' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'i' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'i' << 56 | (long)'e' << 48 | (long)'x' << 40 | (long)'c' << 32 | (long)'l' << 24, + (long)'i' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'i' << 56 | (long)'m' << 48 | (long)'a' << 40 | (long)'g' << 32 | (long)'e' << 24, + (long)'i' << 56 | (long)'n' << 48 | (long)'f' << 40 | (long)'i' << 32 | (long)'n' << 24, + (long)'i' << 56 | (long)'n' << 48 | (long)'t' << 40, + (long)'i' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'i' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'e' << 32 | (long)'s' << 24 | (long)'t' << 16, + (long)'i' << 56 | (long)'s' << 48 | (long)'i' << 40 | (long)'n' << 32, + (long)'i' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'k' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24, + (long)'l' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'l' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16, + (long)'l' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'l' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'l' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'l' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'e' << 48, + (long)'l' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16, + (long)'l' << 56 | (long)'o' << 48 | (long)'w' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'t' << 16, + (long)'l' << 56 | (long)'o' << 48 | (long)'z' << 40, + (long)'l' << 56 | (long)'r' << 48 | (long)'m' << 40, + (long)'l' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16, + (long)'l' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'t' << 48, + (long)'m' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'r' << 32, + (long)'m' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24, + (long)'m' << 56 | (long)'i' << 48 | (long)'c' << 40 | (long)'r' << 32 | (long)'o' << 24, + (long)'m' << 56 | (long)'i' << 48 | (long)'d' << 40 | (long)'d' << 32 | (long)'o' << 24 | (long)'t' << 16, + (long)'m' << 56 | (long)'i' << 48 | (long)'n' << 40 | (long)'u' << 32 | (long)'s' << 24, + (long)'m' << 56 | (long)'u' << 48, + (long)'n' << 56 | (long)'a' << 48 | (long)'b' << 40 | (long)'l' << 32 | (long)'a' << 24, + (long)'n' << 56 | (long)'b' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'n' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24, + (long)'n' << 56 | (long)'e' << 48, + (long)'n' << 56 | (long)'i' << 48, + (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40, + (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'i' << 32 | (long)'n' << 24, + (long)'n' << 56 | (long)'s' << 48 | (long)'u' << 40 | (long)'b' << 32, + (long)'n' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'n' << 56 | (long)'u' << 48, + (long)'o' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'o' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'o' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'l' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'e' << 24, + (long)'o' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24, + (long)'o' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'o' << 56 | (long)'p' << 48 | (long)'l' << 40 | (long)'u' << 32 | (long)'s' << 24, + (long)'o' << 56 | (long)'r' << 48, + (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'f' << 32, + (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'m' << 32, + (long)'o' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16, + (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24 | (long)'s' << 16, + (long)'o' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'a' << 32, + (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'t' << 32, + (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'m' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'p' << 32, + (long)'p' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'p' << 56 | (long)'i' << 48, + (long)'p' << 56 | (long)'i' << 48 | (long)'v' << 40, + (long)'p' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'s' << 32 | (long)'m' << 24 | (long)'n' << 16, + (long)'p' << 56 | (long)'o' << 48 | (long)'u' << 40 | (long)'n' << 32 | (long)'d' << 24, + (long)'p' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24, + (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'d' << 32, + (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'p' << 32, + (long)'p' << 56 | (long)'s' << 48 | (long)'i' << 40, + (long)'q' << 56 | (long)'u' << 48 | (long)'o' << 40 | (long)'t' << 32, + (long)'r' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'r' << 56 | (long)'a' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'c' << 24, + (long)'r' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'r' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'r' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'r' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'r' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'r' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'l' << 32, + (long)'r' << 56 | (long)'e' << 48 | (long)'g' << 40, + (long)'r' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16, + (long)'r' << 56 | (long)'h' << 48 | (long)'o' << 40, + (long)'r' << 56 | (long)'l' << 48 | (long)'m' << 40, + (long)'r' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16, + (long)'r' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'s' << 56 | (long)'b' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'s' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16, + (long)'s' << 56 | (long)'d' << 48 | (long)'o' << 40 | (long)'t' << 32, + (long)'s' << 56 | (long)'e' << 48 | (long)'c' << 40 | (long)'t' << 32, + (long)'s' << 56 | (long)'h' << 48 | (long)'y' << 40, + (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24 | (long)'f' << 16, + (long)'s' << 56 | (long)'i' << 48 | (long)'m' << 40, + (long)'s' << 56 | (long)'p' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24 | (long)'s' << 16, + (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40 | (long)'e' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'m' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'1' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'2' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'3' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'e' << 32, + (long)'s' << 56 | (long)'z' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'t' << 56 | (long)'a' << 48 | (long)'u' << 40, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'4' << 16, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24 | (long)'s' << 16 | (long)'y' << 8 | (long)'m' << 0, + (long)'t' << 56 | (long)'h' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'s' << 24 | (long)'p' << 16, + (long)'t' << 56 | (long)'h' << 48 | (long)'o' << 40 | (long)'r' << 32 | (long)'n' << 24, + (long)'t' << 56 | (long)'i' << 48 | (long)'l' << 40 | (long)'d' << 32 | (long)'e' << 24, + (long)'t' << 56 | (long)'i' << 48 | (long)'m' << 40 | (long)'e' << 32 | (long)'s' << 24, + (long)'t' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24, + (long)'u' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'u' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'u' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'u' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'u' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'u' << 56 | (long)'m' << 48 | (long)'l' << 40, + (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'h' << 24, + (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'u' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'w' << 56 | (long)'e' << 48 | (long)'i' << 40 | (long)'e' << 32 | (long)'r' << 24 | (long)'p' << 16, + (long)'x' << 56 | (long)'i' << 48, + (long)'y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'y' << 56 | (long)'e' << 48 | (long)'n' << 40, + (long)'y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'z' << 56 | (long)'w' << 48 | (long)'j' << 40, + (long)'z' << 56 | (long)'w' << 48 | (long)'n' << 40 | (long)'j' << 32 + }; + + static readonly char[] entities_values = new char[] { + '\u00C6', + '\u00C1', + '\u00C2', + '\u00C0', + '\u0391', + '\u00C5', + '\u00C3', + '\u00C4', + '\u0392', + '\u00C7', + '\u03A7', + '\u2021', + '\u0394', + '\u00D0', + '\u00C9', + '\u00CA', + '\u00C8', + '\u0395', + '\u0397', + '\u00CB', + '\u0393', + '\u00CD', + '\u00CE', + '\u00CC', + '\u0399', + '\u00CF', + '\u039A', + '\u039B', + '\u039C', + '\u00D1', + '\u039D', + '\u0152', + '\u00D3', + '\u00D4', + '\u00D2', + '\u03A9', + '\u039F', + '\u00D8', + '\u00D5', + '\u00D6', + '\u03A6', + '\u03A0', + '\u2033', + '\u03A8', + '\u03A1', + '\u0160', + '\u03A3', + '\u00DE', + '\u03A4', + '\u0398', + '\u00DA', + '\u00DB', + '\u00D9', + '\u03A5', + '\u00DC', + '\u039E', + '\u00DD', + '\u0178', + '\u0396', + '\u00E1', + '\u00E2', + '\u00B4', + '\u00E6', + '\u00E0', + '\u2135', + '\u03B1', + '\u0026', + '\u2227', + '\u2220', + '\u0027', + '\u00E5', + '\u2248', + '\u00E3', + '\u00E4', + '\u201E', + '\u03B2', + '\u00A6', + '\u2022', + '\u2229', + '\u00E7', + '\u00B8', + '\u00A2', + '\u03C7', + '\u02C6', + '\u2663', + '\u2245', + '\u00A9', + '\u21B5', + '\u222A', + '\u00A4', + '\u21D3', + '\u2020', + '\u2193', + '\u00B0', + '\u03B4', + '\u2666', + '\u00F7', + '\u00E9', + '\u00EA', + '\u00E8', + '\u2205', + '\u2003', + '\u2002', + '\u03B5', + '\u2261', + '\u03B7', + '\u00F0', + '\u00EB', + '\u20AC', + '\u2203', + '\u0192', + '\u2200', + '\u00BD', + '\u00BC', + '\u00BE', + '\u2044', + '\u03B3', + '\u2265', + '\u003E', + '\u21D4', + '\u2194', + '\u2665', + '\u2026', + '\u00ED', + '\u00EE', + '\u00A1', + '\u00EC', + '\u2111', + '\u221E', + '\u222B', + '\u03B9', + '\u00BF', + '\u2208', + '\u00EF', + '\u03BA', + '\u21D0', + '\u03BB', + '\u2329', + '\u00AB', + '\u2190', + '\u2308', + '\u201C', + '\u2264', + '\u230A', + '\u2217', + '\u25CA', + '\u200E', + '\u2039', + '\u2018', + '\u003C', + '\u00AF', + '\u2014', + '\u00B5', + '\u00B7', + '\u2212', + '\u03BC', + '\u2207', + '\u00A0', + '\u2013', + '\u2260', + '\u220B', + '\u00AC', + '\u2209', + '\u2284', + '\u00F1', + '\u03BD', + '\u00F3', + '\u00F4', + '\u0153', + '\u00F2', + '\u203E', + '\u03C9', + '\u03BF', + '\u2295', + '\u2228', + '\u00AA', + '\u00BA', + '\u00F8', + '\u00F5', + '\u2297', + '\u00F6', + '\u00B6', + '\u2202', + '\u2030', + '\u22A5', + '\u03C6', + '\u03C0', + '\u03D6', + '\u00B1', + '\u00A3', + '\u2032', + '\u220F', + '\u221D', + '\u03C8', + '\u0022', + '\u21D2', + '\u221A', + '\u232A', + '\u00BB', + '\u2192', + '\u2309', + '\u201D', + '\u211C', + '\u00AE', + '\u230B', + '\u03C1', + '\u200F', + '\u203A', + '\u2019', + '\u201A', + '\u0161', + '\u22C5', + '\u00A7', + '\u00AD', + '\u03C3', + '\u03C2', + '\u223C', + '\u2660', + '\u2282', + '\u2286', + '\u2211', + '\u2283', + '\u00B9', + '\u00B2', + '\u00B3', + '\u2287', + '\u00DF', + '\u03C4', + '\u2234', + '\u03B8', + '\u03D1', + '\u2009', + '\u00FE', + '\u02DC', + '\u00D7', + '\u2122', + '\u21D1', + '\u00FA', + '\u2191', + '\u00FB', + '\u00F9', + '\u00A8', + '\u03D2', + '\u03C5', + '\u00FC', + '\u2118', + '\u03BE', + '\u00FD', + '\u00A5', + '\u00FF', + '\u03B6', + '\u200D', + '\u200C' + }; + + #region Methods + + static void WriteCharBytes(IList buf, char ch, Encoding e) + { + if (ch > 255) + { + foreach (byte b in e.GetBytes(new char[] { ch })) + buf.Add(b); + } + else + buf.Add((byte)ch); + } + + public static string UrlDecode(string s, Encoding e) + { + if (null == s) + return null; + + if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1) + return s; + + if (e == null) + e = Encoding.UTF8; + + long len = s.Length; + var bytes = new List(); + int xchar; + char ch; + + for (int i = 0; i < len; i++) + { + ch = s[i]; + if (ch == '%' && i + 2 < len && s[i + 1] != '%') + { + if (s[i + 1] == 'u' && i + 5 < len) + { + // unicode hex sequence + xchar = GetChar(s, i + 2, 4); + if (xchar != -1) + { + WriteCharBytes(bytes, (char)xchar, e); + i += 5; + } + else + WriteCharBytes(bytes, '%', e); + } + else if ((xchar = GetChar(s, i + 1, 2)) != -1) + { + WriteCharBytes(bytes, (char)xchar, e); + i += 2; + } + else + { + WriteCharBytes(bytes, '%', e); + } + continue; + } + + if (ch == '+') + WriteCharBytes(bytes, ' ', e); + else + WriteCharBytes(bytes, ch, e); + } + + byte[] buf = bytes.ToArray(); + bytes = null; + return e.GetString(buf); + + } + + static int GetInt(byte b) + { + char c = (char)b; + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -1; + } + + static int GetChar(string str, int offset, int length) + { + int val = 0; + int end = length + offset; + for (int i = offset; i < end; i++) + { + char c = str[i]; + if (c > 127) + return -1; + + int current = GetInt((byte)c); + if (current == -1) + return -1; + val = (val << 4) + current; + } + + return val; + } + + static bool TryConvertKeyToEntity(string key, out char value) + { + var token = CalculateKeyValue(key); + if (token == 0) + { + value = '\0'; + return false; + } + + var idx = Array.BinarySearch(entities, token); + if (idx < 0) + { + value = '\0'; + return false; + } + + value = entities_values[idx]; + return true; + } + + static long CalculateKeyValue(string s) + { + if (s.Length > 8) + return 0; + + long key = 0; + for (int i = 0; i < s.Length; ++i) + { + long ch = s[i]; + if (ch > 'z' || ch < '0') + return 0; + + key |= ch << ((7 - i) * 8); + } + + return key; + } + + /// + /// Decodes an HTML-encoded string and returns the decoded string. + /// + /// The HTML string to decode. + /// The decoded text. + public static string HtmlDecode(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + if (s.IndexOf('&') == -1) + return s; + + StringBuilder entity = new StringBuilder(); + StringBuilder output = new StringBuilder(); + int len = s.Length; + // 0 -> nothing, + // 1 -> right after '&' + // 2 -> between '&' and ';' but no '#' + // 3 -> '#' found after '&' and getting numbers + int state = 0; + int number = 0; + int digit_start = 0; + bool hex_number = false; + + for (int i = 0; i < len; i++) + { + char c = s[i]; + if (state == 0) + { + if (c == '&') + { + entity.Append(c); + state = 1; + } + else + { + output.Append(c); + } + continue; + } + + if (c == '&') + { + state = 1; + if (digit_start > 0) + { + entity.Append(s, digit_start, i - digit_start); + digit_start = 0; + } + + output.Append(entity.ToString()); + entity.Length = 0; + entity.Append('&'); + continue; + } + + switch (state) + { + case 1: + if (c == ';') + { + state = 0; + output.Append(entity.ToString()); + output.Append(c); + entity.Length = 0; + break; + } + + number = 0; + hex_number = false; + if (c != '#') + { + state = 2; + } + else + { + state = 3; + } + entity.Append(c); + + break; + case 2: + entity.Append(c); + if (c == ';') + { + string key = entity.ToString(); + state = 0; + entity.Length = 0; + + if (key.Length > 1) + { + var skey = key.Substring(1, key.Length - 2); + if (TryConvertKeyToEntity(skey, out c)) + { + output.Append(c); + break; + } + } + + output.Append(key); + } + + break; + case 3: + if (c == ';') + { + if (number < 0x10000) + { + output.Append((char)number); + } + else + { + output.Append((char)(0xd800 + ((number - 0x10000) >> 10))); + output.Append((char)(0xdc00 + ((number - 0x10000) & 0x3ff))); + } + state = 0; + entity.Length = 0; + digit_start = 0; + break; + } + + if (c == 'x' || c == 'X' && !hex_number) + { + digit_start = i; + hex_number = true; + break; + } + + if (Char.IsDigit(c)) + { + if (digit_start == 0) + digit_start = i; + + number = number * (hex_number ? 16 : 10) + ((int)c - '0'); + break; + } + + if (hex_number) + { + if (c >= 'a' && c <= 'f') + { + number = number * 16 + 10 + ((int)c - 'a'); + break; + } + if (c >= 'A' && c <= 'F') + { + number = number * 16 + 10 + ((int)c - 'A'); + break; + } + } + + state = 2; + if (digit_start > 0) + { + entity.Append(s, digit_start, i - digit_start); + digit_start = 0; + } + + entity.Append(c); + break; + } + } + + if (entity.Length > 0) + { + output.Append(entity); + } + else if (digit_start > 0) + { + output.Append(s, digit_start, s.Length - digit_start); + } + return output.ToString(); + } + + public static NameValueCollection ParseQueryString(string query) + { + return ParseQueryString(query, Encoding.UTF8); + } + + public static NameValueCollection ParseQueryString(string query, Encoding encoding) + { + if (query == null) + throw new ArgumentNullException("query"); + if (encoding == null) + throw new ArgumentNullException("encoding"); + if (query.Length == 0 || (query.Length == 1 && query[0] == '?')) + return new NameValueCollection(); + if (query[0] == '?') + query = query.Substring(1); + + NameValueCollection result = new HttpQSCollection(); + ParseQueryString(query, encoding, result); + return result; + } + + internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result) + { + if (query.Length == 0) + return; + + string decoded = HtmlDecode(query); + int decodedLength = decoded.Length; + int namePos = 0; + bool first = true; + while (namePos <= decodedLength) + { + int valuePos = -1, valueEnd = -1; + for (int q = namePos; q < decodedLength; q++) + { + if (valuePos == -1 && decoded[q] == '=') + { + valuePos = q + 1; + } + else if (decoded[q] == '&') + { + valueEnd = q; + break; + } + } + + if (first) + { + first = false; + if (decoded[namePos] == '?') + namePos++; + } + + string name, value; + if (valuePos == -1) + { + name = null; + valuePos = namePos; + } + else + { + name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding); + } + if (valueEnd < 0) + { + namePos = -1; + valueEnd = decoded.Length; + } + else + { + namePos = valueEnd + 1; + } + value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding); + + result.Add(name, value); + if (namePos == -1) + break; + } + } + #endregion // Methods + } +} diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 54c27cf0a..b3fbd2d1d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using System.Web; using Funq; using MediaBrowser.Model.Logging; using ServiceStack; @@ -236,7 +237,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private NameValueCollectionWrapper queryString; public INameValueCollection QueryString { - get { return queryString ?? (queryString = new NameValueCollectionWrapper(HttpUtility.ParseQueryString(request.Url.Query))); } + get { return queryString ?? (queryString = new NameValueCollectionWrapper(MyHttpUtility.ParseQueryString(request.Url.Query))); } } private NameValueCollectionWrapper formData; -- cgit v1.2.3 From 8998f906c6bfcf32e517bbab720c77e25f1d9bd3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 28 Dec 2015 22:39:38 -0500 Subject: update local address detection Conflicts: MediaBrowser.Server.Startup.Common/ApplicationHost.cs --- MediaBrowser.Api/System/SystemService.cs | 11 ++++ .../Networking/BaseNetworkManager.cs | 4 +- MediaBrowser.Controller/IServerApplicationHost.cs | 4 +- MediaBrowser.Controller/Net/IHttpServer.cs | 6 -- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 44 +++++++------ MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 7 ++- .../HttpServer/HttpListenerHost.cs | 38 ------------ .../ApplicationHost.cs | 72 +++++++++++++++------- 8 files changed, 95 insertions(+), 91 deletions(-) (limited to 'MediaBrowser.Server.Implementations/HttpServer') diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index a95fcb542..4faff8780 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -32,6 +32,12 @@ namespace MediaBrowser.Api.System } + [Route("/System/Ping", "POST")] + public class PingSystem : IReturnVoid + { + + } + /// /// Class RestartApplication /// @@ -117,6 +123,11 @@ namespace MediaBrowser.Api.System return ToOptimizedResult(result); } + public void Post(PingSystem request) + { + + } + public object Get(GetServerLogs request) { List files; diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index 789cde5fc..9b278b889 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -69,7 +69,7 @@ namespace MediaBrowser.Common.Implementations.Networking list.AddRange(GetLocalIpAddressesFallback()); } - return list.Where(i => !IPAddress.IsLoopback(i)).Where(FilterIpAddress).DistinctBy(i => i.ToString()); + return list.Where(FilterIpAddress).DistinctBy(i => i.ToString()); } private bool FilterIpAddress(IPAddress address) @@ -232,7 +232,7 @@ namespace MediaBrowser.Common.Implementations.Networking return properties.UnicastAddresses .Select(i => i.Address) - .Where(i => i.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(i)) + .Where(i => i.AddressFamily == AddressFamily.InterNetwork) .ToList(); } catch (Exception ex) diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 1b842a5f6..fb843d191 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -1,6 +1,8 @@ using MediaBrowser.Common; using MediaBrowser.Model.System; using System; +using System.Collections.Generic; +using System.Net; namespace MediaBrowser.Controller { @@ -63,7 +65,7 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// /// The local ip address. - string LocalIpAddress { get; } + List LocalIpAddresses { get; } /// /// Gets the local API URL. diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 91da5fab2..97c5dd31b 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -28,12 +28,6 @@ namespace MediaBrowser.Controller.Net /// the ssl certificate localtion on the file system. void StartServer(IEnumerable urlPrefixes, string certificatePath); - /// - /// Gets the local end points. - /// - /// The local end points. - IEnumerable LocalEndPoints { get; } - /// /// Stops this instance. /// diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 37cca43eb..d79ef9eaf 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -43,19 +43,19 @@ namespace MediaBrowser.Dlna.Main private readonly List _registeredServerIds = new List(); private bool _dlnaServerStarted; - public DlnaEntryPoint(IServerConfigurationManager config, - ILogManager logManager, - IServerApplicationHost appHost, - INetworkManager network, - ISessionManager sessionManager, - IHttpClient httpClient, - ILibraryManager libraryManager, - IUserManager userManager, - IDlnaManager dlnaManager, - IImageProcessor imageProcessor, - IUserDataManager userDataManager, - ILocalizationManager localization, - IMediaSourceManager mediaSourceManager, + public DlnaEntryPoint(IServerConfigurationManager config, + ILogManager logManager, + IServerApplicationHost appHost, + INetworkManager network, + ISessionManager sessionManager, + IHttpClient httpClient, + ILibraryManager libraryManager, + IUserManager userManager, + IDlnaManager dlnaManager, + IImageProcessor imageProcessor, + IUserDataManager userDataManager, + ILocalizationManager localization, + IMediaSourceManager mediaSourceManager, ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery) { _config = config; @@ -148,14 +148,20 @@ namespace MediaBrowser.Dlna.Main private void RegisterServerEndpoints() { - foreach (var address in _network.GetLocalIpAddresses()) + foreach (var address in _appHost.LocalIpAddresses) { - var addressString = address.ToString (); - var guid = addressString.GetMD5(); + //if (IPAddress.IsLoopback(address)) + //{ + // // Should we allow this? + // continue; + //} + + var addressString = address.ToString(); + var guid = addressString.GetMD5(); var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml"; - var uri = new Uri(_appHost.GetLocalApiUrl(addressString) + descriptorURI); + var uri = new Uri(_appHost.GetLocalApiUrl(addressString) + descriptorURI); var services = new List { @@ -166,8 +172,8 @@ namespace MediaBrowser.Dlna.Main "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", "uuid:" + guid.ToString("N") }; - - _ssdpHandler.RegisterNotification(guid, uri, address, services); + + _ssdpHandler.RegisterNotification(guid, uri, address, services); _registeredServerIds.Add(guid.ToString("N")); } diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index 457134913..279979550 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -110,8 +110,11 @@ namespace MediaBrowser.Dlna.Ssdp { if (e.LocalEndPoint == null) { - var ip = _appHost.LocalIpAddress; - e.LocalEndPoint = new IPEndPoint(IPAddress.Parse(ip), 0); + var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i)); + if (ip != null) + { + e.LocalEndPoint = new IPEndPoint(ip, 0); + } } if (e.LocalEndPoint != null) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 847982976..0283c1f7a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -40,33 +40,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer public event EventHandler WebSocketConnected; public event EventHandler WebSocketConnecting; - private readonly List _localEndpoints = new List(); - - private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim(); - public string CertificatePath { get; private set; } private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; - /// - /// Gets the local end points. - /// - /// The local end points. - public IEnumerable LocalEndPoints - { - get - { - _localEndpointLock.EnterReadLock(); - - var list = _localEndpoints.ToList(); - - _localEndpointLock.ExitReadLock(); - - return list; - } - } - public HttpListenerHost(IApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, @@ -178,22 +156,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer private void OnRequestReceived(string localEndPoint) { - var ignore = _networkManager.IsInPrivateAddressSpace(localEndPoint); - - if (ignore) - { - return; - } - - if (_localEndpointLock.TryEnterWriteLock(100)) - { - var list = _localEndpoints; - - list.Remove(localEndPoint); - list.Insert(0, localEndPoint); - - _localEndpointLock.ExitWriteLock(); - } } /// diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index f623fb7bb..b8525388e 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -91,10 +91,12 @@ using MediaBrowser.Server.Startup.Common.Migrations; using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -207,6 +209,7 @@ namespace MediaBrowser.Server.Startup.Common private readonly string _remotePackageName; internal INativeApp NativeApp { get; set; } + private Timer _ipAddressCacheTimer; /// /// Initializes a new instance of the class. @@ -230,6 +233,8 @@ namespace MediaBrowser.Server.Startup.Common NativeApp = nativeApp; SetBaseExceptionMessage(); + + _ipAddressCacheTimer = new Timer(OnCacheClearTimerFired, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3)); } private Version _version; @@ -1108,14 +1113,14 @@ namespace MediaBrowser.Server.Startup.Common try { // Return the first matched address, if found, or the first known local address - var address = LocalIpAddress; + var address = LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i)); - if (!string.IsNullOrWhiteSpace(address)) + if (address != null) { - address = GetLocalApiUrl(address); + return GetLocalApiUrl(address.ToString()); } - return address; + return null; } catch (Exception ex) { @@ -1133,39 +1138,60 @@ namespace MediaBrowser.Server.Startup.Common HttpPort.ToString(CultureInfo.InvariantCulture)); } - public string LocalIpAddress + public List LocalIpAddresses { get { - return HttpServerIpAddresses.FirstOrDefault(); + var localAddresses = NetworkManager.GetLocalIpAddresses() + .Where(IsIpAddressValid) + .ToList(); + + return localAddresses; } } - private IEnumerable HttpServerIpAddresses + private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private bool IsIpAddressValid(IPAddress address) { - get + if (IPAddress.IsLoopback(address)) { - var localAddresses = NetworkManager.GetLocalIpAddresses() - .Select(i => i.ToString()) - .ToList(); + return true; + } - var httpServerAddresses = HttpServer.LocalEndPoints - .Select(i => i.Split(':').FirstOrDefault()) - .Where(i => !string.IsNullOrEmpty(i)) - .ToList(); + var apiUrl = GetLocalApiUrl(address.ToString()); + apiUrl += "/system/ping"; - // Cross-check the local ip addresses with addresses that have been received on with the http server - var matchedAddresses = httpServerAddresses - .Where(i => localAddresses.Contains(i, StringComparer.OrdinalIgnoreCase)) - .ToList(); + bool cachedResult; + if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) + { + return cachedResult; + } - if (matchedAddresses.Count == 0) + try + { + using (var response = HttpClient.SendAsync(new HttpRequestOptions { - return localAddresses; - } + Url = apiUrl, + BufferContent = false, + LogErrorResponseBody = false, + LogErrors = false - return matchedAddresses; + }, "POST").Result) + { + _validAddressResults.AddOrUpdate(apiUrl, true, (k, v) => true); + return true; + } } + catch + { + _validAddressResults.AddOrUpdate(apiUrl, true, (k, v) => false); + return false; + } + } + + private void OnCacheClearTimerFired(object state) + { + _validAddressResults.Clear(); } public string FriendlyName -- cgit v1.2.3 From 7fe2809483a03b431f680629dc9370a852313fab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 16:41:23 -0500 Subject: xbox 360 dlna fixes --- MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 3 +-- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 4 ++-- MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs | 12 ++++++++---- .../HttpServer/ResponseFilter.cs | 5 ++++- 4 files changed, 15 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations/HttpServer') diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 431807aed..64b728721 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "Xbox 360"; // Required according to above - ModelName = "Windows Media Connect"; + ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; @@ -25,7 +25,6 @@ namespace MediaBrowser.Dlna.Profiles ManufacturerUrl = "http://www.microsoft.com"; XDlnaDoc = "DMS-1.50"; ModelDescription = "Emby : UPnP Media Server"; - ModelNumber = "001"; TimelineOffsetSeconds = 40; RequiresPlainFolders = true; diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index bfe1fceea..35799f313 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -11,9 +11,9 @@ ${HostName}: 1 Microsoft Corporation http://www.microsoft.com - Windows Media Connect + Windows Media Player Sharing Emby : UPnP Media Server - 001 + 12.0 http://go.microsoft.com/fwlink/?LinkId=105926 false false diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index 649612e1e..63ea59d53 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -92,10 +92,7 @@ namespace MediaBrowser.Dlna.Server builder.Append(""); AppendDeviceProperties(builder); - if (_profile.EnableDlnaProtocol) - { - AppendIconList(builder); - } + AppendIconList(builder); AppendServiceList(builder); builder.Append(""); } @@ -111,6 +108,13 @@ namespace MediaBrowser.Dlna.Server builder.Append("M-DMS-1.50"); builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); } + else + { + builder.Append("" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + ""); + + builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); + builder.Append("M-DMS-1.50"); + } builder.Append("" + SecurityElement.Escape(GetFriendlyName()) + ""); builder.Append("" + SecurityElement.Escape(_profile.Manufacturer ?? string.Empty) + ""); diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs index 0da34efc6..4ef9d5277 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs @@ -58,7 +58,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (hasOptions != null) { - hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1"; + if (!hasOptions.Options.ContainsKey("Server")) + { + hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50"; + } // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy string contentLength; -- cgit v1.2.3