Luke Pulverenti преди 11 години
родител
ревизия
13563b6047
променени са 21 файла, в които са добавени 383 реда и са изтрити 158 реда
  1. 21 1
      MediaBrowser.Api/UserService.cs
  2. 10 2
      MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
  3. 11 1
      MediaBrowser.Common/Net/HttpRequestOptions.cs
  4. 3 48
      MediaBrowser.Controller/Entities/Folder.cs
  5. 55 0
      MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
  6. 31 0
      MediaBrowser.Dlna/Properties/AssemblyInfo.cs
  7. 8 0
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  8. 10 0
      MediaBrowser.Mono.sln
  9. 4 0
      MediaBrowser.Providers/Manager/ProviderManager.cs
  10. 16 1
      MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
  11. 174 0
      MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
  12. 1 1
      MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs
  13. 10 1
      MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
  14. 4 0
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  15. 0 2
      MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs
  16. 0 54
      MediaBrowser.Server.Implementations/WebSocket/FleckServer.cs
  17. 0 47
      MediaBrowser.Server.Implementations/WebSocket/FleckWebSocket.cs
  18. 1 0
      MediaBrowser.Server.Implementations/packages.config
  19. 4 0
      MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
  20. 4 0
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  21. 16 0
      MediaBrowser.sln

+ 21 - 1
MediaBrowser.Api/UserService.cs

@@ -189,7 +189,7 @@ namespace MediaBrowser.Api
             {
                 throw new ArgumentNullException("xmlSerializer");
             }
-            
+
             _xmlSerializer = xmlSerializer;
             _userManager = userManager;
             _dtoService = dtoService;
@@ -306,6 +306,26 @@ namespace MediaBrowser.Api
 
             var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
 
+            // Login in the old way if the header is missing
+            if (string.IsNullOrEmpty(auth.Client) ||
+                string.IsNullOrEmpty(auth.Device) ||
+                string.IsNullOrEmpty(auth.DeviceId) ||
+                string.IsNullOrEmpty(auth.Version))
+            {
+                var success = await _userManager.AuthenticateUser(user, request.Password).ConfigureAwait(false);
+
+                if (!success)
+                {
+                    // Unauthorized
+                    throw new UnauthorizedAccessException("Invalid user or password entered.");
+                }
+
+                return new AuthenticationResult
+                {
+                    User = _dtoService.GetUserDto(user)
+                };
+            }
+
             var session = await _sessionMananger.AuthenticateNewSession(user, request.Password, auth.Client, auth.Version,
                         auth.DeviceId, auth.Device, Request.RemoteIp).ConfigureAwait(false);
 

+ 10 - 2
MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs

@@ -114,7 +114,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             }
 
             request.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None;
-            request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);
+
+            request.CachePolicy = options.CachePolicy == Net.HttpRequestCachePolicy.None ?
+                new RequestCachePolicy(RequestCacheLevel.BypassCache) :
+                new RequestCachePolicy(RequestCacheLevel.Revalidate);
+
             request.ConnectionGroupName = GetHostFromUrl(options.Url);
             request.KeepAlive = true;
             request.Method = method;
@@ -144,7 +148,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             }
 
             request.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None;
-            request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);
+            
+            request.CachePolicy = options.CachePolicy == Net.HttpRequestCachePolicy.None ?
+                new RequestCachePolicy(RequestCacheLevel.BypassCache) :
+                new RequestCachePolicy(RequestCacheLevel.Revalidate);
+            
             request.ConnectionGroupName = GetHostFromUrl(options.Url);
             request.KeepAlive = true;
             request.Method = method;

+ 11 - 1
MediaBrowser.Common/Net/HttpRequestOptions.cs

@@ -71,7 +71,9 @@ namespace MediaBrowser.Common.Net
         public string RequestContent { get; set; }
 
         public bool BufferContent { get; set; }
-        
+
+        public HttpRequestCachePolicy CachePolicy { get; set; }
+
         private string GetHeaderValue(string name)
         {
             string value;
@@ -89,7 +91,15 @@ namespace MediaBrowser.Common.Net
             EnableHttpCompression = true;
             BufferContent = true;
 
+            CachePolicy = HttpRequestCachePolicy.None;
+
             RequestHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
         }
     }
+
+    public enum HttpRequestCachePolicy
+    {
+        None = 1,
+        Validate = 2
+    }
 }

+ 3 - 48
MediaBrowser.Controller/Entities/Folder.cs

@@ -305,12 +305,6 @@ namespace MediaBrowser.Controller.Entities
             return GetCachedChildren();
         }
 
-        /// <summary>
-        /// Gets or sets the current validation cancellation token source.
-        /// </summary>
-        /// <value>The current validation cancellation token source.</value>
-        private CancellationTokenSource CurrentValidationCancellationTokenSource { get; set; }
-
         public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
         {
             return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions());
@@ -331,48 +325,9 @@ namespace MediaBrowser.Controller.Entities
             return ValidateChildrenWithCancellationSupport(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService);
         }
 
-        private async Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
+        private Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            // Cancel the current validation, if any
-            if (CurrentValidationCancellationTokenSource != null)
-            {
-                CurrentValidationCancellationTokenSource.Cancel();
-            }
-
-            // Create an inner cancellation token. This can cancel all validations from this level on down,
-            // but nothing above this
-            var innerCancellationTokenSource = new CancellationTokenSource();
-
-            try
-            {
-                CurrentValidationCancellationTokenSource = innerCancellationTokenSource;
-
-                var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(innerCancellationTokenSource.Token, cancellationToken);
-
-                await ValidateChildrenInternal(progress, linkedCancellationTokenSource.Token, recursive, refreshChildMetadata, refreshOptions, directoryService).ConfigureAwait(false);
-            }
-            catch (OperationCanceledException ex)
-            {
-                Logger.Info("ValidateChildren cancelled for " + Name);
-
-                // If the outer cancelletion token in the cause for the cancellation, throw it
-                if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken)
-                {
-                    throw;
-                }
-            }
-            finally
-            {
-                // Null out the token source             
-                if (CurrentValidationCancellationTokenSource == innerCancellationTokenSource)
-                {
-                    CurrentValidationCancellationTokenSource = null;
-                }
-
-                innerCancellationTokenSource.Dispose();
-            }
+            return ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService);
         }
 
         private Dictionary<Guid, BaseItem> GetActualChildrenDictionary()
@@ -384,7 +339,7 @@ namespace MediaBrowser.Controller.Entities
                 var id = child.Id;
                 if (dictionary.ContainsKey(id))
                 {
-                    Logger.Error( "Found folder containing items with duplicate id. Path: {0}, Child Name: {1}",
+                    Logger.Error("Found folder containing items with duplicate id. Path: {0}, Child Name: {1}",
                         Path ?? Name,
                         child.Path ?? child.Name);
                 }

+ 55 - 0
MediaBrowser.Dlna/MediaBrowser.Dlna.csproj

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MediaBrowser.Dlna</RootNamespace>
+    <AssemblyName>MediaBrowser.Dlna</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\SharedVersion.cs">
+      <Link>Properties\SharedVersion.cs</Link>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 31 - 0
MediaBrowser.Dlna/Properties/AssemblyInfo.cs

@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MediaBrowser.Dlna")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MediaBrowser.Dlna")]
+[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c319ebfa-fd9d-42e4-ae74-a40039a6a688")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//

+ 8 - 0
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -27,6 +27,12 @@ namespace MediaBrowser.Model.Configuration
         /// <value><c>true</c> if [enable HTTP level logging]; otherwise, <c>false</c>.</value>
         public bool EnableHttpLevelLogging { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable u pn p].
+        /// </summary>
+        /// <value><c>true</c> if [enable u pn p]; otherwise, <c>false</c>.</value>
+        public bool EnableUPnP { get; set; }
+        
         /// <summary>
         /// Gets or sets the HTTP server port number.
         /// </summary>
@@ -222,6 +228,8 @@ namespace MediaBrowser.Model.Configuration
             EnableAutomaticRestart = true;
             EnablePeoplePrefixSubFolders = true;
 
+            EnableUPnP = true;
+
             MinResumePct = 5;
             MaxResumePct = 90;
             MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds);

+ 10 - 0
MediaBrowser.Mono.sln

@@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBr
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Mono", "MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj", "{175A9388-F352-4586-A6B4-070DED62B644}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Dlna", "MediaBrowser.Dlna\MediaBrowser.Dlna.csproj", "{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -99,6 +101,14 @@ Global
 		{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.Build.0 = Release|Any CPU
 		{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.ActiveCfg = Release|Any CPU
 		{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.Build.0 = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|x86.Build.0 = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(MonoDevelopProperties) = preSolution
 		StartupItem = MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj

+ 4 - 0
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -182,6 +182,10 @@ namespace MediaBrowser.Providers.Manager
 
                 return result;
             }
+            catch (OperationCanceledException)
+            {
+                return new List<RemoteImageInfo>();
+            }
             catch (Exception ex)
             {
                 _logger.ErrorException("{0} failed in GetImageInfos for type {1}", ex, provider.GetType().Name, item.GetType().Name);

+ 16 - 1
MediaBrowser.Providers/TV/MissingEpisodeProvider.cs

@@ -36,7 +36,22 @@ namespace MediaBrowser.Providers.TV
         {
             foreach (var seriesGroup in series)
             {
-                await Run(seriesGroup, cancellationToken).ConfigureAwait(false);
+                try
+                {
+                    await Run(seriesGroup, cancellationToken).ConfigureAwait(false);
+                }
+                catch (OperationCanceledException)
+                {
+                    break;
+                }
+                catch (DirectoryNotFoundException)
+                {
+                    _logger.Warn("Series files missing for series id {0}", seriesGroup.Key);
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error in missing episode provider for series id {0}", ex, seriesGroup.Key);
+                }
             }
         }
 

+ 174 - 0
MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs

@@ -0,0 +1,174 @@
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.Logging;
+using Mono.Nat;
+using System;
+using System.IO;
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.EntryPoints
+{
+    public class ExternalPortForwarding : IServerEntryPoint
+    {
+        private readonly IServerApplicationHost _appHost;
+        private readonly ILogger _logger;
+        private readonly IServerConfigurationManager _config;
+
+        private bool _isStarted;
+
+        public ExternalPortForwarding(ILogger logger, IServerApplicationHost appHost, IServerConfigurationManager config)
+        {
+            _logger = logger;
+            _appHost = appHost;
+            _config = config;
+
+            _config.ConfigurationUpdated += _config_ConfigurationUpdated;
+        }
+
+        void _config_ConfigurationUpdated(object sender, EventArgs e)
+        {
+            var enable = _config.Configuration.EnableUPnP;
+
+            if (enable && !_isStarted)
+            {
+                Reload();
+            }
+            else if (!enable && _isStarted)
+            {
+                DisposeNat();
+            }
+        }
+
+        public void Run()
+        {
+            NatUtility.Logger = new LogWriter(_logger);
+            
+            Reload();
+        }
+
+        private void Reload()
+        {
+            if (_config.Configuration.EnableUPnP)
+            {
+                _logger.Debug("Starting NAT discovery");
+                
+                NatUtility.DeviceFound += NatUtility_DeviceFound;
+                NatUtility.DeviceLost += NatUtility_DeviceLost;
+                NatUtility.UnhandledException += NatUtility_UnhandledException;
+                NatUtility.StartDiscovery();
+
+                _isStarted = true;
+            }
+        }
+
+        void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            var ex = e.ExceptionObject as Exception;
+
+            if (ex == null)
+            {
+                _logger.Error("Unidentified error reported by Mono.Nat");
+            }
+            else
+            {
+                // Seeing some blank exceptions coming through here
+                _logger.ErrorException("Error reported by Mono.Nat: ", ex);
+            }
+        }
+
+        void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
+        {
+            try
+            {
+                var device = e.Device;
+                _logger.Debug("NAT device found: {0}", device.LocalAddress.ToString());
+
+                CreateRules(device);
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error creating port forwarding rules", ex);
+            }
+        }
+
+        private void CreateRules(INatDevice device)
+        {
+            var info = _appHost.GetSystemInfo();
+
+            CreatePortMap(device, info.HttpServerPortNumber);
+
+            if (info.WebSocketPortNumber != info.HttpServerPortNumber)
+            {
+                CreatePortMap(device, info.WebSocketPortNumber);
+            }
+        }
+
+        private void CreatePortMap(INatDevice device, int port)
+        {
+            _logger.Info("Creating port map on port {0}", port);
+
+            device.CreatePortMap(new Mapping(Protocol.Tcp, port, port)
+            {
+                Description = "Media Browser Server"
+            });
+        }
+
+        void NatUtility_DeviceLost(object sender, DeviceEventArgs e)
+        {
+            var device = e.Device;
+            _logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString());
+        }
+
+        public void Dispose()
+        {
+            DisposeNat();
+        }
+
+        private void DisposeNat()
+        {
+            _logger.Debug("Stopping NAT discovery");
+
+            try
+            {
+                NatUtility.DeviceFound -= NatUtility_DeviceFound;
+                NatUtility.DeviceLost -= NatUtility_DeviceLost;
+                NatUtility.UnhandledException -= NatUtility_UnhandledException;
+                NatUtility.StopDiscovery();
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error stopping NAT Discovery", ex);
+            }
+            finally
+            {
+                _isStarted = false;
+            }
+        }
+
+        private class LogWriter : TextWriter
+        {
+            private readonly ILogger _logger;
+
+            public LogWriter(ILogger logger)
+            {
+                _logger = logger;
+            }
+
+            public override Encoding Encoding
+            {
+                get { return Encoding.UTF8; }
+            }
+
+            public override void WriteLine(string format, params object[] arg)
+            {
+                _logger.Debug(format, arg);
+            }
+
+            public override void WriteLine(string value)
+            {
+                _logger.Debug(value);
+            }
+        }
+    }
+}

+ 1 - 1
MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs

@@ -170,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
                 {
                     File.Delete(file.FullName);
                 }
-                catch (IOException ex)
+                catch (Exception ex)
                 {
                     _logger.ErrorException("Error deleting file {0}", ex, file.FullName);
                 }

+ 10 - 1
MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs

@@ -39,7 +39,16 @@ namespace MediaBrowser.Server.Implementations.IO
         /// <summary>
         /// Any file name ending in any of these will be ignored by the watchers
         /// </summary>
-        private readonly IReadOnlyList<string> _alwaysIgnoreFiles = new List<string> { "thumbs.db", "small.jpg", "albumart.jpg" };
+        private readonly IReadOnlyList<string> _alwaysIgnoreFiles = new List<string>
+        {
+            "thumbs.db", 
+            "small.jpg", 
+            "albumart.jpg",
+
+            // WMC temp recording directories that will constantly be written to
+            "TempRec",
+            "TempSBE"
+        };
 
         /// <summary>
         /// The timer lock

+ 4 - 0
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -56,6 +56,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
     </Reference>
+    <Reference Include="Mono.Nat">
+      <HintPath>..\packages\Mono.Nat.1.1.13\lib\Net40\Mono.Nat.dll</HintPath>
+    </Reference>
     <Reference Include="ServiceStack.Api.Swagger">
       <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
     </Reference>
@@ -112,6 +115,7 @@
     <Compile Include="Drawing\UnplayedCountIndicator.cs" />
     <Compile Include="Dto\DtoService.cs" />
     <Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" />
+    <Compile Include="EntryPoints\ExternalPortForwarding.cs" />
     <Compile Include="EntryPoints\LibraryChangedNotifier.cs" />
     <Compile Include="EntryPoints\LoadRegistrations.cs" />
     <Compile Include="EntryPoints\Notifications\Notifier.cs" />

+ 0 - 2
MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs

@@ -154,8 +154,6 @@ namespace MediaBrowser.Server.Implementations.ServerManager
         /// </summary>
         private void ReloadHttpServer(IEnumerable<string> urlPrefixes, bool enableHttpLogging)
         {
-            DisposeHttpServer();
-
             _logger.Info("Loading Http Server");
 
             try

+ 0 - 54
MediaBrowser.Server.Implementations/WebSocket/FleckServer.cs

@@ -1,54 +0,0 @@
-using Fleck;
-using MediaBrowser.Common.Net;
-using System;
-using IWebSocketServer = MediaBrowser.Common.Net.IWebSocketServer;
-
-namespace MediaBrowser.Server.Implementations.WebSocket
-{
-    public class FleckServer : IWebSocketServer
-    {
-        private WebSocketServer _server;
-
-        public void Start(int portNumber)
-        {
-            var server = new WebSocketServer("ws://localhost:" + portNumber);
-
-            server.Start(socket =>
-            {
-                socket.OnOpen = () => OnClientConnected(socket);
-            });
-
-            _server = server;
-        }
-
-        public void Stop()
-        {
-            _server.Dispose();
-        }
-
-        private void OnClientConnected(Fleck.IWebSocketConnection context)
-        {
-            if (WebSocketConnected != null)
-            {
-                var socket = new FleckWebSocket(context);
-
-                WebSocketConnected(this, new WebSocketConnectEventArgs
-                {
-                    WebSocket = socket,
-                    Endpoint = context.ConnectionInfo.ClientIpAddress + ":" + context.ConnectionInfo.ClientPort
-                });
-            }
-        }
-        public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
-
-        public int Port
-        {
-            get { return _server.Port; }
-        }
-
-        public void Dispose()
-        {
-            _server.Dispose();
-        }
-    }
-}

+ 0 - 47
MediaBrowser.Server.Implementations/WebSocket/FleckWebSocket.cs

@@ -1,47 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Net;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using IWebSocketConnection = Fleck.IWebSocketConnection;
-
-namespace MediaBrowser.Server.Implementations.WebSocket
-{
-    public class FleckWebSocket : IWebSocket
-    {
-        private readonly IWebSocketConnection _connection;
-
-        public FleckWebSocket(IWebSocketConnection connection)
-        {
-            _connection = connection;
-
-            _connection.OnMessage = OnReceiveData;
-        }
-
-        public WebSocketState State
-        {
-            get { return _connection.IsAvailable ? WebSocketState.Open : WebSocketState.Closed; }
-        }
-
-        private void OnReceiveData(string data)
-        {
-            if (OnReceive != null)
-            {
-                OnReceive(data);
-            }
-        }
-
-        public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken)
-        {
-            return Task.Run(() => _connection.Send(bytes));
-        }
-
-        public void Dispose()
-        {
-            _connection.Close();
-        }
-
-        public Action<byte[]> OnReceiveBytes { get; set; }
-        public Action<string> OnReceive { get; set; }
-    }
-}

+ 1 - 0
MediaBrowser.Server.Implementations/packages.config

@@ -2,6 +2,7 @@
 <packages>
   <package id="Alchemy" version="2.2.1" targetFramework="net45" />
   <package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
+  <package id="Mono.Nat" version="1.1.13" targetFramework="net45" />
   <package id="morelinq" version="1.0.16006" targetFramework="net45" />
   <package id="System.Data.SQLite.x86" version="1.0.90.0" targetFramework="net45" />
 </packages>

+ 4 - 0
MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj

@@ -100,6 +100,10 @@
       <Project>{442B5058-DCAF-4263-BB6A-F21E31120A1B}</Project>
       <Name>MediaBrowser.Providers</Name>
     </ProjectReference>
+    <ProjectReference Include="..\MediaBrowser.Dlna\MediaBrowser.Dlna.csproj">
+      <Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
+      <Name>MediaBrowser.Dlna</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
       <Project>{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}</Project>
       <Name>MediaBrowser.Model</Name>

+ 4 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -191,6 +191,10 @@
       <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
       <Name>MediaBrowser.Controller</Name>
     </ProjectReference>
+    <ProjectReference Include="..\MediaBrowser.Dlna\MediaBrowser.Dlna.csproj">
+      <Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
+      <Name>MediaBrowser.Dlna</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
       <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
       <Name>MediaBrowser.Model</Name>

+ 16 - 0
MediaBrowser.sln

@@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model.Portable
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ServerApplication", "MediaBrowser.ServerApplication\MediaBrowser.ServerApplication.csproj", "{94ADE4D3-B7EC-45CD-A200-CC469433072B}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Dlna", "MediaBrowser.Dlna\MediaBrowser.Dlna.csproj", "{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -231,6 +233,20 @@ Global
 		{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Win32.ActiveCfg = Release|Any CPU
 		{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x64.ActiveCfg = Release|Any CPU
 		{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x86.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Win32.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x64.ActiveCfg = Release|Any CPU
+		{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE