فهرست منبع

avoid buffering http responses

Luke Pulverenti 8 سال پیش
والد
کامیت
a69ca6c55b
63فایلهای تغییر یافته به همراه448 افزوده شده و 267 حذف شده
  1. 6 2
      MediaBrowser.Api/Dlna/DlnaServerService.cs
  2. 2 1
      MediaBrowser.Api/Images/RemoteImageService.cs
  3. 2 1
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  4. 2 1
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  5. 7 1
      MediaBrowser.Common.Implementations/BaseApplicationHost.cs
  6. 9 6
      MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
  7. 31 0
      MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs
  8. 10 0
      MediaBrowser.Common.Implementations/Logging/NLogger.cs
  9. 5 0
      MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
  10. 4 2
      MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
  11. 4 2
      MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
  12. 1 0
      MediaBrowser.Common.Implementations/packages.config
  13. 11 0
      MediaBrowser.Common/IO/IMemoryStreamProvider.cs
  14. 1 0
      MediaBrowser.Common/MediaBrowser.Common.csproj
  15. 5 0
      MediaBrowser.Controller/LiveTv/ILiveTvService.cs
  16. 2 2
      MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
  17. 2 1
      MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs
  18. 2 1
      MediaBrowser.Dlna/Eventing/EventManager.cs
  19. 0 1
      MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
  20. 6 3
      MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
  21. 0 45
      MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
  22. 1 1
      MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
  23. 5 2
      MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
  24. 7 4
      MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
  25. 7 3
      MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
  26. 2 0
      MediaBrowser.Model/System/SystemInfo.cs
  27. 2 2
      MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs
  28. 2 4
      MediaBrowser.Providers/Genres/GenreImageProvider.cs
  29. 4 2
      MediaBrowser.Providers/Manager/ImageSaver.cs
  30. 7 4
      MediaBrowser.Providers/Manager/ProviderManager.cs
  31. 2 2
      MediaBrowser.Providers/Studios/StudiosImageProvider.cs
  32. 3 1
      MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
  33. 2 1
      MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
  34. 18 9
      MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
  35. 6 0
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  36. 4 2
      MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
  37. 6 2
      MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
  38. 3 7
      MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
  39. 4 4
      MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs
  40. 5 2
      MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
  41. 6 3
      MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs
  42. 32 5
      MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs
  43. 2 1
      MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
  44. 39 8
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  45. 81 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
  46. 0 78
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
  47. 2 1
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
  48. 8 4
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
  49. 6 2
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
  50. 2 1
      MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs
  51. 5 8
      MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs
  52. 9 5
      MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
  53. 6 3
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  54. 6 3
      MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
  55. 1 1
      MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
  56. 5 2
      MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs
  57. 6 3
      MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs
  58. 2 1
      MediaBrowser.Server.Implementations/Session/HttpSessionController.cs
  59. 5 2
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs
  60. 5 2
      MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
  61. 13 11
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  62. 3 0
      MediaBrowser.sln
  63. 2 1
      OpenSubtitlesHandler/Utilities.cs

+ 6 - 2
MediaBrowser.Api/Dlna/DlnaServerService.cs

@@ -7,6 +7,8 @@ using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 
 
 namespace MediaBrowser.Api.Dlna
 namespace MediaBrowser.Api.Dlna
 {
 {
@@ -109,13 +111,15 @@ 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;
 
 
-        public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar)
+        public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _dlnaManager = dlnaManager;
             _dlnaManager = dlnaManager;
             _contentDirectory = contentDirectory;
             _contentDirectory = contentDirectory;
             _connectionManager = connectionManager;
             _connectionManager = connectionManager;
             _mediaReceiverRegistrar = mediaReceiverRegistrar;
             _mediaReceiverRegistrar = mediaReceiverRegistrar;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         public object Get(GetDescriptionXml request)
         public object Get(GetDescriptionXml request)
@@ -201,7 +205,7 @@ namespace MediaBrowser.Api.Dlna
         {
         {
             using (var response = _dlnaManager.GetIcon(request.Filename))
             using (var response = _dlnaManager.GetIcon(request.Filename))
             {
             {
-                using (var ms = new MemoryStream())
+                using (var ms = _memoryStreamProvider.CreateNew())
                 {
                 {
                     response.Stream.CopyTo(ms);
                     response.Stream.CopyTo(ms);
 
 

+ 2 - 1
MediaBrowser.Api/Images/RemoteImageService.cs

@@ -273,7 +273,8 @@ namespace MediaBrowser.Api.Images
         {
         {
             var result = await _httpClient.GetResponse(new HttpRequestOptions
             var result = await _httpClient.GetResponse(new HttpRequestOptions
             {
             {
-                Url = url
+                Url = url,
+                BufferContent = false
 
 
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
 
 

+ 2 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -811,7 +811,8 @@ namespace MediaBrowser.Api.LiveTv
 
 
             var response = await _httpClient.Get(new HttpRequestOptions
             var response = await _httpClient.Get(new HttpRequestOptions
             {
             {
-                Url = "https://json.schedulesdirect.org/20141201/available/countries"
+                Url = "https://json.schedulesdirect.org/20141201/available/countries",
+                BufferContent = false
 
 
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
 
 

+ 2 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -2469,7 +2469,8 @@ namespace MediaBrowser.Api.Playback
                 Url = "https://mb3admin.com/admin/service/transcoding/report",
                 Url = "https://mb3admin.com/admin/service/transcoding/report",
                 CancellationToken = CancellationToken.None,
                 CancellationToken = CancellationToken.None,
                 LogRequest = false,
                 LogRequest = false,
-                LogErrors = false
+                LogErrors = false,
+                BufferContent = false
             };
             };
             options.RequestContent = JsonSerializer.SerializeToString(dict);
             options.RequestContent = JsonSerializer.SerializeToString(dict);
             options.RequestContentType = "application/json";
             options.RequestContentType = "application/json";

+ 7 - 1
MediaBrowser.Common.Implementations/BaseApplicationHost.cs

@@ -30,6 +30,7 @@ using System.Text;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Common.Implementations
 namespace MediaBrowser.Common.Implementations
 {
 {
@@ -192,6 +193,8 @@ namespace MediaBrowser.Common.Implementations
             get { return Environment.OSVersion.VersionString; }
             get { return Environment.OSVersion.VersionString; }
         }
         }
 
 
+        public IMemoryStreamProvider MemoryStreamProvider { get; set; }
+
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
         /// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
         /// </summary>
         /// </summary>
@@ -231,6 +234,8 @@ namespace MediaBrowser.Common.Implementations
 
 
             JsonSerializer = CreateJsonSerializer();
             JsonSerializer = CreateJsonSerializer();
 
 
+            MemoryStreamProvider = new MemoryStreamProvider();
+
             OnLoggerLoaded(true);
             OnLoggerLoaded(true);
             LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
             LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
 
 
@@ -456,6 +461,7 @@ namespace MediaBrowser.Common.Implementations
 
 
 			RegisterSingleInstance(JsonSerializer);
 			RegisterSingleInstance(JsonSerializer);
 			RegisterSingleInstance(XmlSerializer);
 			RegisterSingleInstance(XmlSerializer);
+            RegisterSingleInstance(MemoryStreamProvider);
 
 
 			RegisterSingleInstance(LogManager);
 			RegisterSingleInstance(LogManager);
 			RegisterSingleInstance(Logger);
 			RegisterSingleInstance(Logger);
@@ -464,7 +470,7 @@ namespace MediaBrowser.Common.Implementations
 
 
 			RegisterSingleInstance(FileSystemManager);
 			RegisterSingleInstance(FileSystemManager);
 
 
-            HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager);
+            HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider);
 			RegisterSingleInstance(HttpClient);
 			RegisterSingleInstance(HttpClient);
 
 
 			NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));
 			NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));

+ 9 - 6
MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs

@@ -42,6 +42,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
         private readonly IApplicationPaths _appPaths;
         private readonly IApplicationPaths _appPaths;
 
 
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="HttpClientManager" /> class.
         /// Initializes a new instance of the <see cref="HttpClientManager" /> class.
@@ -52,7 +53,7 @@ namespace MediaBrowser.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)
+        public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             if (appPaths == null)
             if (appPaths == null)
             {
             {
@@ -65,6 +66,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
 
             _logger = logger;
             _logger = logger;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _memoryStreamProvider = memoryStreamProvider;
             _appPaths = appPaths;
             _appPaths = appPaths;
 
 
             // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
             // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
@@ -269,6 +271,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
                 Url = url,
                 Url = url,
                 ResourcePool = resourcePool,
                 ResourcePool = resourcePool,
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
+                BufferContent = resourcePool != null
             });
             });
         }
         }
 
 
@@ -329,7 +332,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
                 {
                 {
                     using (var stream = _fileSystem.GetFileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
                     using (var stream = _fileSystem.GetFileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
                     {
                     {
-                        var memoryStream = new MemoryStream();
+                        var memoryStream = _memoryStreamProvider.CreateNew();
 
 
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
                         memoryStream.Position = 0;
                         memoryStream.Position = 0;
@@ -363,7 +366,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
 
             using (var responseStream = response.Content)
             using (var responseStream = response.Content)
             {
             {
-                var memoryStream = new MemoryStream();
+                var memoryStream = _memoryStreamProvider.CreateNew();
                 await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
                 await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
                 memoryStream.Position = 0;
                 memoryStream.Position = 0;
 
 
@@ -455,7 +458,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
 
                     using (var stream = httpResponse.GetResponseStream())
                     using (var stream = httpResponse.GetResponseStream())
                     {
                     {
-                        var memoryStream = new MemoryStream();
+                        var memoryStream = _memoryStreamProvider.CreateNew();
 
 
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
 
 
@@ -550,7 +553,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             {
             {
                 Url = url,
                 Url = url,
                 ResourcePool = resourcePool,
                 ResourcePool = resourcePool,
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = resourcePool != null
 
 
             }, postData);
             }, postData);
         }
         }
@@ -560,7 +564,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
         /// </summary>
         /// </summary>
         /// <param name="options">The options.</param>
         /// <param name="options">The options.</param>
         /// <returns>Task{System.String}.</returns>
         /// <returns>Task{System.String}.</returns>
-        /// <exception cref="System.ArgumentNullException">progress</exception>
         public async Task<string> GetTempFile(HttpRequestOptions options)
         public async Task<string> GetTempFile(HttpRequestOptions options)
         {
         {
             var response = await GetTempFileResponse(options).ConfigureAwait(false);
             var response = await GetTempFileResponse(options).ConfigureAwait(false);

+ 31 - 0
MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
+using Microsoft.IO;
+
+namespace MediaBrowser.Common.Implementations.IO
+{
+    public class MemoryStreamProvider : IMemoryStreamProvider
+    {
+        readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager();
+
+        public MemoryStream CreateNew()
+        {
+            return _manager.GetStream();
+        }
+
+        public MemoryStream CreateNew(int capacity)
+        {
+            return _manager.GetStream("RecyclableMemoryStream", capacity);
+        }
+
+        public MemoryStream CreateNew(byte[] buffer)
+        {
+            return _manager.GetStream("RecyclableMemoryStream", buffer, 0, buffer.Length);
+        }
+    }
+}

+ 10 - 0
MediaBrowser.Common.Implementations/Logging/NLogger.cs

@@ -72,6 +72,11 @@ namespace MediaBrowser.Common.Implementations.Logging
         /// <param name="paramList">The param list.</param>
         /// <param name="paramList">The param list.</param>
         public void Debug(string message, params object[] paramList)
         public void Debug(string message, params object[] paramList)
         {
         {
+            if (_logManager.LogSeverity == LogSeverity.Info)
+            {
+                return;
+            }
+
             _logger.Debug(message, paramList);
             _logger.Debug(message, paramList);
         }
         }
 
 
@@ -137,6 +142,11 @@ namespace MediaBrowser.Common.Implementations.Logging
         /// <param name="additionalContent">Content of the additional.</param>
         /// <param name="additionalContent">Content of the additional.</param>
         public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
         public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
         {
         {
+            if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info)
+            {
+                return;
+            }
+
             additionalContent.Insert(0, message + Environment.NewLine);
             additionalContent.Insert(0, message + Environment.NewLine);
 
 
             const char tabChar = '\t';
             const char tabChar = '\t';

+ 5 - 0
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -51,6 +51,10 @@
       <SpecificVersion>False</SpecificVersion>
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
     </Reference>
     </Reference>
+    <Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="MoreLinq">
     <Reference Include="MoreLinq">
       <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
       <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
     </Reference>
     </Reference>
@@ -93,6 +97,7 @@
     <Compile Include="HttpClientManager\HttpClientInfo.cs" />
     <Compile Include="HttpClientManager\HttpClientInfo.cs" />
     <Compile Include="HttpClientManager\HttpClientManager.cs" />
     <Compile Include="HttpClientManager\HttpClientManager.cs" />
     <Compile Include="IO\IsoManager.cs" />
     <Compile Include="IO\IsoManager.cs" />
+    <Compile Include="IO\MemoryStreamProvider.cs" />
     <Compile Include="Logging\LogHelper.cs" />
     <Compile Include="Logging\LogHelper.cs" />
     <Compile Include="Logging\NLogger.cs" />
     <Compile Include="Logging\NLogger.cs" />
     <Compile Include="Logging\NlogManager.cs" />
     <Compile Include="Logging\NlogManager.cs" />

+ 4 - 2
MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs

@@ -169,7 +169,8 @@ namespace MediaBrowser.Common.Implementations.Security
             var options = new HttpRequestOptions()
             var options = new HttpRequestOptions()
             {
             {
                 Url = AppstoreRegUrl,
                 Url = AppstoreRegUrl,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
             options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId);
             options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId);
             options.RequestContent = parameters;
             options.RequestContent = parameters;
@@ -269,7 +270,8 @@ namespace MediaBrowser.Common.Implementations.Security
                         Url = MBValidateUrl,
                         Url = MBValidateUrl,
 
 
                         // Seeing block length errors
                         // Seeing block length errors
-                        EnableHttpCompression = false
+                        EnableHttpCompression = false,
+                        BufferContent = false
                     };
                     };
 
 
                     options.SetPostData(data);
                     options.SetPostData(data);

+ 4 - 2
MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs

@@ -30,7 +30,8 @@ namespace MediaBrowser.Common.Implementations.Updates
                 Url = url,
                 Url = url,
                 EnableKeepAlive = false,
                 EnableKeepAlive = false,
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
-                UserAgent = "Emby/3.0"
+                UserAgent = "Emby/3.0",
+                BufferContent = false
             };
             };
 
 
             if (cacheLength.Ticks > 0)
             if (cacheLength.Ticks > 0)
@@ -105,7 +106,8 @@ namespace MediaBrowser.Common.Implementations.Updates
                 Url = url,
                 Url = url,
                 EnableKeepAlive = false,
                 EnableKeepAlive = false,
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
-                UserAgent = "Emby/3.0"
+                UserAgent = "Emby/3.0",
+                BufferContent = false
             };
             };
 
 
             using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
             using (var stream = await _httpClient.Get(options).ConfigureAwait(false))

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

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
+  <package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net45" />
   <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="NLog" version="4.3.8" targetFramework="net45" />
   <package id="NLog" version="4.3.8" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />

+ 11 - 0
MediaBrowser.Common/IO/IMemoryStreamProvider.cs

@@ -0,0 +1,11 @@
+using System.IO;
+
+namespace MediaBrowser.Common.IO
+{
+    public interface IMemoryStreamProvider
+    {
+        MemoryStream CreateNew();
+        MemoryStream CreateNew(int capacity);
+        MemoryStream CreateNew(byte[] buffer);
+    }
+}

+ 1 - 0
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -60,6 +60,7 @@
     <Compile Include="Extensions\BaseExtensions.cs" />
     <Compile Include="Extensions\BaseExtensions.cs" />
     <Compile Include="Extensions\ResourceNotFoundException.cs" />
     <Compile Include="Extensions\ResourceNotFoundException.cs" />
     <Compile Include="IDependencyContainer.cs" />
     <Compile Include="IDependencyContainer.cs" />
+    <Compile Include="IO\IMemoryStreamProvider.cs" />
     <Compile Include="IO\ProgressStream.cs" />
     <Compile Include="IO\ProgressStream.cs" />
     <Compile Include="IO\StreamDefaults.cs" />
     <Compile Include="IO\StreamDefaults.cs" />
     <Compile Include="Configuration\IApplicationPaths.cs" />
     <Compile Include="Configuration\IApplicationPaths.cs" />

+ 5 - 0
MediaBrowser.Controller/LiveTv/ILiveTvService.cs

@@ -251,4 +251,9 @@ namespace MediaBrowser.Controller.LiveTv
     {
     {
         Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, CancellationToken cancellationToken);
         Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, CancellationToken cancellationToken);
     }
     }
+
+    public interface ISupportsUpdatingDefaults
+    {
+        Task UpdateTimerDefaults(SeriesTimerInfo info, CancellationToken cancellationToken);
+    }
 }
 }

+ 2 - 2
MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs

@@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Net
 
 
             var cancellationTokenSource = new CancellationTokenSource();
             var cancellationTokenSource = new CancellationTokenSource();
 
 
-            Logger.Info("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name);
+            Logger.Debug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name);
 
 
             var timer = SendOnTimer ?
             var timer = SendOnTimer ?
                 new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
                 new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
@@ -267,7 +267,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="connection">The connection.</param>
         /// <param name="connection">The connection.</param>
         private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> connection)
         private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> connection)
         {
         {
-            Logger.Info("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name);
+            Logger.Debug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name);
 
 
             var timer = connection.Item3;
             var timer = connection.Item3;
 
 

+ 2 - 1
MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs

@@ -34,7 +34,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 UserAgent = "Emby",
                 UserAgent = "Emby",
                 RequestContentType = "text/xml; charset=\"utf-8\"",
                 RequestContentType = "text/xml; charset=\"utf-8\"",
                 LogErrorResponseBody = true,
                 LogErrorResponseBody = true,
-                Url = request.ContentDirectoryUrl
+                Url = request.ContentDirectoryUrl,
+                BufferContent = false
             };
             };
 
 
             options.RequestHeaders["SOAPACTION"] = "urn:schemas-upnp-org:service:ContentDirectory:1#Browse";
             options.RequestHeaders["SOAPACTION"] = "urn:schemas-upnp-org:service:ContentDirectory:1#Browse";

+ 2 - 1
MediaBrowser.Dlna/Eventing/EventManager.cs

@@ -141,7 +141,8 @@ namespace MediaBrowser.Dlna.Eventing
             {
             {
                 RequestContent = builder.ToString(),
                 RequestContent = builder.ToString(),
                 RequestContentType = "text/xml",
                 RequestContentType = "text/xml",
-                Url = subscription.CallbackUrl
+                Url = subscription.CallbackUrl,
+                BufferContent = false
             };
             };
 
 
             options.RequestHeaders.Add("NT", subscription.NotificationType);
             options.RequestHeaders.Add("NT", subscription.NotificationType);

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

@@ -133,7 +133,6 @@
     <Compile Include="Ssdp\Datagram.cs" />
     <Compile Include="Ssdp\Datagram.cs" />
     <Compile Include="Server\DescriptionXmlBuilder.cs" />
     <Compile Include="Server\DescriptionXmlBuilder.cs" />
     <Compile Include="Ssdp\DeviceDiscovery.cs" />
     <Compile Include="Ssdp\DeviceDiscovery.cs" />
-    <Compile Include="Ssdp\SsdpHelper.cs" />
     <Compile Include="PlayTo\SsdpHttpClient.cs" />
     <Compile Include="PlayTo\SsdpHttpClient.cs" />
     <Compile Include="Common\StateVariable.cs" />
     <Compile Include="Common\StateVariable.cs" />
     <Compile Include="PlayTo\TransportCommands.cs" />
     <Compile Include="PlayTo\TransportCommands.cs" />

+ 6 - 3
MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs

@@ -70,7 +70,8 @@ namespace MediaBrowser.Dlna.PlayTo
             {
             {
                 Url = url,
                 Url = url,
                 UserAgent = USERAGENT,
                 UserAgent = USERAGENT,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
             };
 
 
             options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture);
             options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture);
@@ -87,7 +88,8 @@ namespace MediaBrowser.Dlna.PlayTo
             {
             {
                 Url = url,
                 Url = url,
                 UserAgent = USERAGENT,
                 UserAgent = USERAGENT,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
             };
 
 
             options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
             options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
@@ -115,7 +117,8 @@ namespace MediaBrowser.Dlna.PlayTo
                 Url = url,
                 Url = url,
                 UserAgent = USERAGENT,
                 UserAgent = USERAGENT,
                 LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLog,
                 LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLog,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
             };
 
 
             options.RequestHeaders["SOAPAction"] = soapAction;
             options.RequestHeaders["SOAPAction"] = soapAction;

+ 0 - 45
MediaBrowser.Dlna/Ssdp/SsdpHelper.cs

@@ -1,45 +0,0 @@
-using MediaBrowser.Controller.Dlna;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
-    public class SsdpHelper
-    {
-        public static SsdpMessageEventArgs ParseSsdpResponse(byte[] data)
-        {
-            using (var ms = new MemoryStream(data))
-            {
-                using (var reader = new StreamReader(ms, Encoding.ASCII))
-                {
-                    var proto = (reader.ReadLine() ?? string.Empty).Trim();
-                    var method = proto.Split(new[] { ' ' }, 2)[0];
-                    var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-                    for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())
-                    {
-                        line = line.Trim();
-                        if (string.IsNullOrEmpty(line))
-                        {
-                            break;
-                        }
-                        var parts = line.Split(new[] { ':' }, 2);
-
-                        if (parts.Length >= 2)
-                        {
-                            headers[parts[0]] = parts[1].Trim();
-                        }
-                    }
-
-                    return new SsdpMessageEventArgs
-                    {
-                        Method = method,
-                        Headers = headers,
-                        Message = data
-                    };
-                }
-            }
-        }
-    }
-}

+ 1 - 1
MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs

@@ -76,7 +76,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
 
         public static string GetProbeSizeArgument(bool isDvd)
         public static string GetProbeSizeArgument(bool isDvd)
         {
         {
-            return isDvd ? "-probesize 1G -analyzeduration 200M" : string.Empty;
+            return isDvd ? "-probesize 1G -analyzeduration 200M" : " -analyzeduration 2M";
         }
         }
     }
     }
 }
 }

+ 5 - 2
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -24,6 +24,7 @@ using CommonIO;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 
 
 namespace MediaBrowser.MediaEncoding.Encoder
 namespace MediaBrowser.MediaEncoding.Encoder
@@ -79,13 +80,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
         protected readonly Func<IMediaSourceManager> MediaSourceManager;
         protected readonly Func<IMediaSourceManager> MediaSourceManager;
         private readonly IHttpClient _httpClient;
         private readonly IHttpClient _httpClient;
         private readonly IZipClient _zipClient;
         private readonly IZipClient _zipClient;
+        private readonly IMemoryStreamProvider _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;
         private string _originalFFMpegPath;
         private string _originalFFMpegPath;
         private string _originalFFProbePath;
         private string _originalFFProbePath;
 
 
-        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)
+        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)
         {
         {
             _logger = logger;
             _logger = logger;
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
@@ -100,6 +102,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             MediaSourceManager = mediaSourceManager;
             MediaSourceManager = mediaSourceManager;
             _httpClient = httpClient;
             _httpClient = httpClient;
             _zipClient = zipClient;
             _zipClient = zipClient;
+            _memoryStreamProvider = memoryStreamProvider;
             FFProbePath = ffProbePath;
             FFProbePath = ffProbePath;
             FFMpegPath = ffMpegPath;
             FFMpegPath = ffMpegPath;
             _originalFFProbePath = ffProbePath;
             _originalFFProbePath = ffProbePath;
@@ -544,7 +547,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
                         }
                         }
                     }
                     }
 
 
-                    var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol);
+                    var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem, _memoryStreamProvider).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol);
 
 
                     var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
                     var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
 
 

+ 7 - 4
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -9,6 +9,8 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using System.Xml;
 using System.Xml;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
@@ -20,11 +22,13 @@ 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;
 
 
-        public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem)
+        public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _logger = logger;
             _logger = logger;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol)
         public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol)
@@ -187,7 +191,7 @@ namespace MediaBrowser.MediaEncoding.Probing
             xml = "<?xml version=\"1.0\"?>" + xml;
             xml = "<?xml version=\"1.0\"?>" + xml;
 
 
             // <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
             // <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
-            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+            using (var stream = _memoryStreamProvider.CreateNew(Encoding.UTF8.GetBytes(xml)))
             {
             {
                 using (var streamReader = new StreamReader(stream))
                 using (var streamReader = new StreamReader(stream))
                 {
                 {
@@ -573,8 +577,7 @@ namespace MediaBrowser.MediaEncoding.Probing
 
 
         private void NormalizeStreamTitle(MediaStream stream)
         private void NormalizeStreamTitle(MediaStream stream)
         {
         {
-            if (string.Equals(stream.Title, "sdh", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase))
+            if (string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase))
             {
             {
                 stream.Title = null;
                 stream.Title = null;
             }
             }

+ 7 - 3
MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs

@@ -18,6 +18,8 @@ using System.Text;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 using UniversalDetector;
 using UniversalDetector;
 
 
 namespace MediaBrowser.MediaEncoding.Subtitles
 namespace MediaBrowser.MediaEncoding.Subtitles
@@ -32,8 +34,9 @@ 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;
 
 
-        public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager)
+        public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json, IHttpClient httpClient, IMediaSourceManager mediaSourceManager, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _logger = logger;
             _logger = logger;
@@ -43,6 +46,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
             _json = json;
             _json = json;
             _httpClient = httpClient;
             _httpClient = httpClient;
             _mediaSourceManager = mediaSourceManager;
             _mediaSourceManager = mediaSourceManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         private string SubtitleCachePath
         private string SubtitleCachePath
@@ -61,7 +65,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
             bool preserveOriginalTimestamps,
             bool preserveOriginalTimestamps,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
-            var ms = new MemoryStream();
+            var ms = _memoryStreamProvider.CreateNew();
 
 
             try
             try
             {
             {
@@ -202,7 +206,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
 
 
                             var bytes = Encoding.UTF8.GetBytes(text);
                             var bytes = Encoding.UTF8.GetBytes(text);
 
 
-                            return new MemoryStream(bytes);
+                            return _memoryStreamProvider.CreateNew(bytes);
                         }
                         }
                     }
                     }
                 }
                 }

+ 2 - 0
MediaBrowser.Model/System/SystemInfo.cs

@@ -34,6 +34,8 @@ namespace MediaBrowser.Model.System
         /// <value>The mac address.</value>
         /// <value>The mac address.</value>
         public string MacAddress { get; set; }
         public string MacAddress { get; set; }
 
 
+        public string PackageName { get; set; }
+        
         /// <summary>
         /// <summary>
         /// Gets or sets a value indicating whether this instance has pending restart.
         /// Gets or sets a value indicating whether this instance has pending restart.
         /// </summary>
         /// </summary>

+ 2 - 2
MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres
 
 
         public static string ProviderName
         public static string ProviderName
         {
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
         }
 
 
         public bool Supports(IHasImages item)
         public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.GameGenres
             {
             {
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
                 Url = url,
                 Url = url,
-                ResourcePool = GenreImageProvider.ImageDownloadResourcePool
+                BufferContent = false
             });
             });
         }
         }
     }
     }

+ 2 - 4
MediaBrowser.Providers/Genres/GenreImageProvider.cs

@@ -22,8 +22,6 @@ namespace MediaBrowser.Providers.Genres
 
 
         private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
         private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
 
 
-        public static SemaphoreSlim ImageDownloadResourcePool = new SemaphoreSlim(5, 5);
-
         public GenreImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
         public GenreImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
         {
         {
             _config = config;
             _config = config;
@@ -38,7 +36,7 @@ namespace MediaBrowser.Providers.Genres
 
 
         public static string ProviderName
         public static string ProviderName
         {
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
         }
 
 
         public bool Supports(IHasImages item)
         public bool Supports(IHasImages item)
@@ -138,7 +136,7 @@ namespace MediaBrowser.Providers.Genres
             {
             {
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
                 Url = url,
                 Url = url,
-                ResourcePool = ImageDownloadResourcePool
+                BufferContent = false
             });
             });
         }
         }
     }
     }

+ 4 - 2
MediaBrowser.Providers/Manager/ImageSaver.cs

@@ -38,6 +38,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;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ImageSaver" /> class.
         /// Initializes a new instance of the <see cref="ImageSaver" /> class.
@@ -46,12 +47,13 @@ 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)
+        public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _config = config;
             _config = config;
             _libraryMonitor = libraryMonitor;
             _libraryMonitor = libraryMonitor;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
             _logger = logger;
             _logger = logger;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -124,7 +126,7 @@ namespace MediaBrowser.Providers.Manager
             var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
             var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
 
 
             // If there are more than one output paths, the stream will need to be seekable
             // If there are more than one output paths, the stream will need to be seekable
-            var memoryStream = new MemoryStream();
+            var memoryStream = _memoryStreamProvider.CreateNew();
             using (source)
             using (source)
             {
             {
                 await source.CopyToAsync(memoryStream).ConfigureAwait(false);
                 await source.CopyToAsync(memoryStream).ConfigureAwait(false);

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

@@ -20,6 +20,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
 
 
 namespace MediaBrowser.Providers.Manager
 namespace MediaBrowser.Providers.Manager
@@ -64,6 +65,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;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ProviderManager" /> class.
         /// Initializes a new instance of the <see cref="ProviderManager" /> class.
@@ -73,7 +75,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)
+        public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _logger = logManager.GetLogger("ProviderManager");
             _logger = logManager.GetLogger("ProviderManager");
             _httpClient = httpClient;
             _httpClient = httpClient;
@@ -83,6 +85,7 @@ namespace MediaBrowser.Providers.Manager
             _appPaths = appPaths;
             _appPaths = appPaths;
             _libraryManagerFactory = libraryManagerFactory;
             _libraryManagerFactory = libraryManagerFactory;
             _json = json;
             _json = json;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -142,12 +145,12 @@ namespace MediaBrowser.Providers.Manager
 
 
         public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
         public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
         {
         {
-            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
+            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
         }
         }
 
 
         public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
         public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
         {
         {
-            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
+            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
         }
         }
 
 
         public Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
         public Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
@@ -159,7 +162,7 @@ namespace MediaBrowser.Providers.Manager
 
 
             var fileStream = _fileSystem.GetFileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true);
             var fileStream = _fileSystem.GetFileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true);
 
 
-            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
+            return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, fileStream, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
         }
         }
 
 
         public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(IHasImages item, RemoteImageQuery query, CancellationToken cancellationToken)
         public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(IHasImages item, RemoteImageQuery query, CancellationToken cancellationToken)

+ 2 - 2
MediaBrowser.Providers/Studios/StudiosImageProvider.cs

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios
 
 
         public static string ProviderName
         public static string ProviderName
         {
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
         }
 
 
         public bool Supports(IHasImages item)
         public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.Studios
             {
             {
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
                 Url = url,
                 Url = url,
-                ResourcePool = GenreImageProvider.ImageDownloadResourcePool
+                BufferContent = false
             });
             });
         }
         }
     }
     }

+ 3 - 1
MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs

@@ -21,6 +21,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Xml;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Providers.TV
 namespace MediaBrowser.Providers.TV
 {
 {
@@ -38,6 +39,7 @@ 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;
 
 
         public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager)
         public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager)
         {
         {
@@ -238,7 +240,7 @@ namespace MediaBrowser.Providers.TV
                 DeleteXmlFiles(seriesDataPath);
                 DeleteXmlFiles(seriesDataPath);
 
 
                 // Copy to memory stream because we need a seekable stream
                 // Copy to memory stream because we need a seekable stream
-                using (var ms = new MemoryStream())
+                using (var ms = _memoryStreamProvider.CreateNew())
                 {
                 {
                     await zipStream.CopyToAsync(ms).ConfigureAwait(false);
                     await zipStream.CopyToAsync(ms).ConfigureAwait(false);
 
 

+ 2 - 1
MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs

@@ -127,7 +127,8 @@ namespace MediaBrowser.Server.Implementations.Connect
 
 
                 // Seeing block length errors with our server
                 // Seeing block length errors with our server
                 EnableHttpCompression = false,
                 EnableHttpCompression = false,
-                PreferIpv4 = preferIpv4
+                PreferIpv4 = preferIpv4,
+                BufferContent = false
 
 
             }).ConfigureAwait(false))
             }).ConfigureAwait(false))
             {
             {

+ 18 - 9
MediaBrowser.Server.Implementations/Connect/ConnectManager.cs

@@ -266,7 +266,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             options.SetPostData(postData);
             options.SetPostData(postData);
@@ -314,7 +315,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             options.SetPostData(postData);
             options.SetPostData(postData);
@@ -464,7 +466,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             var accessToken = Guid.NewGuid().ToString("N");
             var accessToken = Guid.NewGuid().ToString("N");
@@ -599,7 +602,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             var accessToken = Guid.NewGuid().ToString("N");
             var accessToken = Guid.NewGuid().ToString("N");
@@ -652,7 +656,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             var postData = new Dictionary<string, string>
             var postData = new Dictionary<string, string>
@@ -726,7 +731,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
-                Url = url
+                Url = url,
+                BufferContent = false
             };
             };
 
 
             SetServerAccessToken(options);
             SetServerAccessToken(options);
@@ -790,7 +796,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = false
             };
             };
 
 
             SetServerAccessToken(options);
             SetServerAccessToken(options);
@@ -1078,7 +1085,8 @@ namespace MediaBrowser.Server.Implementations.Connect
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             };
 
 
             var postData = new Dictionary<string, string>
             var postData = new Dictionary<string, string>
@@ -1126,7 +1134,8 @@ namespace MediaBrowser.Server.Implementations.Connect
 
 
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
-                Url = GetConnectUrl("user/authenticate")
+                Url = GetConnectUrl("user/authenticate"),
+                BufferContent = false
             };
             };
 
 
             options.SetPostData(new Dictionary<string, string>
             options.SetPostData(new Dictionary<string, string>

+ 6 - 0
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -1176,6 +1176,12 @@ namespace MediaBrowser.Server.Implementations.Dto
                     .Except(foundArtists, new DistinctNameComparer())
                     .Except(foundArtists, new DistinctNameComparer())
                     .Select(i =>
                     .Select(i =>
                     {
                     {
+                        // This should not be necessary but we're seeing some cases of it
+                        if (string.IsNullOrWhiteSpace(i))
+                        {
+                            return null;
+                        }
+
                         var artist = _libraryManager.GetArtist(i);
                         var artist = _libraryManager.GetArtist(i);
                         if (artist != null)
                         if (artist != null)
                         {
                         {

+ 4 - 2
MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs

@@ -64,7 +64,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                 EnableHttpCompression = false,
                 EnableHttpCompression = false,
 
 
                 LogRequest = false,
                 LogRequest = false,
-                LogErrors = logErrors
+                LogErrors = logErrors,
+                BufferContent = false
             };
             };
 
 
             options.SetPostData(data);
             options.SetPostData(data);
@@ -114,7 +115,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                 EnableHttpCompression = false,
                 EnableHttpCompression = false,
 
 
                 LogRequest = false,
                 LogRequest = false,
-                LogErrors = logErrors
+                LogErrors = logErrors,
+                BufferContent = false
             };
             };
 
 
             options.SetPostData(data);
             options.SetPostData(data);

+ 6 - 2
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -19,6 +19,7 @@ using System.Linq;
 using System.Reflection;
 using System.Reflection;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Security;
 using MediaBrowser.Common.Security;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Extensions;
@@ -45,16 +46,18 @@ 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;
 
 
         public HttpListenerHost(IApplicationHost applicationHost,
         public HttpListenerHost(IApplicationHost applicationHost,
             ILogManager logManager,
             ILogManager logManager,
             IServerConfigurationManager config,
             IServerConfigurationManager config,
             string serviceName,
             string serviceName,
-            string defaultRedirectPath, INetworkManager networkManager, params Assembly[] assembliesWithServices)
+            string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamProvider memoryStreamProvider, params Assembly[] assembliesWithServices)
             : base(serviceName, assembliesWithServices)
             : base(serviceName, assembliesWithServices)
         {
         {
             DefaultRedirectPath = defaultRedirectPath;
             DefaultRedirectPath = defaultRedirectPath;
             _networkManager = networkManager;
             _networkManager = networkManager;
+            _memoryStreamProvider = memoryStreamProvider;
             _config = config;
             _config = config;
 
 
             _logger = logManager.GetLogger("HttpServer");
             _logger = logManager.GetLogger("HttpServer");
@@ -95,6 +98,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
             container.Adapter = _containerAdapter;
             container.Adapter = _containerAdapter;
 
 
+            Plugins.RemoveAll(x => x is NativeTypesFeature);
             Plugins.Add(new SwaggerFeature());
             Plugins.Add(new SwaggerFeature());
             Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"));
             Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"));
 
 
@@ -179,7 +183,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
         private IHttpListener GetListener()
         private IHttpListener GetListener()
         {
         {
-            return new WebSocketSharpListener(_logger, CertificatePath);
+            return new WebSocketSharpListener(_logger, CertificatePath, _memoryStreamProvider);
         }
         }
 
 
         private void OnWebSocketConnecting(WebSocketConnectingEventArgs args)
         private void OnWebSocketConnecting(WebSocketConnectingEventArgs args)

+ 3 - 7
MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Common;
 using MediaBrowser.Common;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
@@ -15,23 +16,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <summary>
         /// <summary>
         /// Creates the server.
         /// Creates the server.
         /// </summary>
         /// </summary>
-        /// <param name="applicationHost">The application host.</param>
-        /// <param name="logManager">The log manager.</param>
-        /// <param name="config">The configuration.</param>
-        /// <param name="_networkmanager">The _networkmanager.</param>
-        /// <param name="serverName">Name of the server.</param>
-        /// <param name="defaultRedirectpath">The default redirectpath.</param>
         /// <returns>IHttpServer.</returns>
         /// <returns>IHttpServer.</returns>
         public static IHttpServer CreateServer(IApplicationHost applicationHost,
         public static IHttpServer CreateServer(IApplicationHost applicationHost,
             ILogManager logManager,
             ILogManager logManager,
             IServerConfigurationManager config, 
             IServerConfigurationManager config, 
             INetworkManager _networkmanager,
             INetworkManager _networkmanager,
+            IMemoryStreamProvider streamProvider,
             string serverName, 
             string serverName, 
             string defaultRedirectpath)
             string defaultRedirectpath)
         {
         {
             LogManager.LogFactory = new ServerLogFactory(logManager);
             LogManager.LogFactory = new ServerLogFactory(logManager);
 
 
-            return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager);
+            return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager, streamProvider);
         }
         }
     }
     }
 }
 }

+ 4 - 4
MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs

@@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
             if (boundary == null)
             if (boundary == null)
                 return;
                 return;
 
 
-            using (var requestStream = GetSubStream(InputStream))
+            using (var requestStream = GetSubStream(InputStream, _memoryStreamProvider))
             {
             {
                 //DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request
                 //DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request
                 //Not ending with \r\n?
                 //Not ending with \r\n?
-                var ms = new MemoryStream(32 * 1024);
+                var ms = _memoryStreamProvider.CreateNew(32 * 1024);
                 await requestStream.CopyToAsync(ms).ConfigureAwait(false);
                 await requestStream.CopyToAsync(ms).ConfigureAwait(false);
 
 
                 var input = ms;
                 var input = ms;
@@ -229,9 +229,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
 
         async Task LoadWwwForm()
         async Task LoadWwwForm()
         {
         {
-            using (Stream input = GetSubStream(InputStream))
+            using (Stream input = GetSubStream(InputStream, _memoryStreamProvider))
             {
             {
-                using (var ms = new MemoryStream())
+                using (var ms = _memoryStreamProvider.CreateNew())
                 {
                 {
                     await input.CopyToAsync(ms).ConfigureAwait(false);
                     await input.CopyToAsync(ms).ConfigureAwait(false);
                     ms.Position = 0;
                     ms.Position = 0;

+ 5 - 2
MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs

@@ -9,6 +9,7 @@ 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 MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 {
 {
@@ -18,11 +19,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
 
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly string _certificatePath;
         private readonly string _certificatePath;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
 
-        public WebSocketSharpListener(ILogger logger, string certificatePath)
+        public WebSocketSharpListener(ILogger logger, string certificatePath, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _logger = logger;
             _logger = logger;
             _certificatePath = certificatePath;
             _certificatePath = certificatePath;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         public Action<Exception, IRequest> ErrorHandler { get; set; }
         public Action<Exception, IRequest> ErrorHandler { get; set; }
@@ -148,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
         {
         {
             var operationName = httpContext.Request.GetOperationName();
             var operationName = httpContext.Request.GetOperationName();
 
 
-            var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger);
+            var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger, _memoryStreamProvider);
             req.RequestAttributes = req.GetAttributes();
             req.RequestAttributes = req.GetAttributes();
 
 
             return req;
             return req;

+ 6 - 3
MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Text;
 using System.Text;
 using Funq;
 using Funq;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using ServiceStack;
 using ServiceStack;
 using ServiceStack.Host;
 using ServiceStack.Host;
@@ -16,11 +17,13 @@ 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 IMemoryStreamProvider _memoryStreamProvider;
 
 
-        public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger)
+        public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             this.OperationName = operationName;
             this.OperationName = operationName;
             this.RequestAttributes = requestAttributes;
             this.RequestAttributes = requestAttributes;
+            _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);
 
 
@@ -403,7 +406,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
             set
             set
             {
             {
                 bufferedStream = value
                 bufferedStream = value
-                    ? bufferedStream ?? new MemoryStream(request.InputStream.ReadFully())
+                    ? bufferedStream ?? _memoryStreamProvider.CreateNew(request.InputStream.ReadFully())
                     : null;
                     : null;
             }
             }
         }
         }
@@ -447,7 +450,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
             }
             }
         }
         }
 
 
-        static Stream GetSubStream(Stream stream)
+        static Stream GetSubStream(Stream stream, IMemoryStreamProvider streamProvider)
         {
         {
             if (stream is MemoryStream)
             if (stream is MemoryStream)
             {
             {

+ 32 - 5
MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs

@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 using ServiceStack;
 using ServiceStack;
 
 
 namespace MediaBrowser.Server.Implementations.HttpServer
 namespace MediaBrowser.Server.Implementations.HttpServer
@@ -17,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         private ILogger Logger { get; set; }
         private ILogger Logger { get; set; }
 
 
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-        
+
         /// <summary>
         /// <summary>
         /// Gets or sets the source stream.
         /// Gets or sets the source stream.
         /// </summary>
         /// </summary>
@@ -39,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
         public Action OnComplete { get; set; }
         public Action OnComplete { get; set; }
         public Action OnError { get; set; }
         public Action OnError { get; set; }
+        private readonly byte[] _bytes;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="StreamWriter" /> class.
         /// Initializes a new instance of the <see cref="StreamWriter" /> class.
@@ -73,6 +75,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         public StreamWriter(byte[] source, string contentType, ILogger logger)
         public StreamWriter(byte[] source, string contentType, ILogger logger)
             : this(new MemoryStream(source), contentType, logger)
             : this(new MemoryStream(source), contentType, logger)
         {
         {
+            if (string.IsNullOrEmpty(contentType))
+            {
+                throw new ArgumentNullException("contentType");
+            }
+
+            _bytes = source;
+            Logger = logger;
+
+            Options["Content-Type"] = contentType;
+
+            Options["Content-Length"] = source.Length.ToString(UsCulture);
         }
         }
 
 
         private const int BufferSize = 81920;
         private const int BufferSize = 81920;
@@ -85,9 +98,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
         {
             try
             try
             {
             {
-                using (var src = SourceStream)
+                if (_bytes != null)
                 {
                 {
-                    src.CopyTo(responseStream, BufferSize);
+                    responseStream.Write(_bytes, 0, _bytes.Length);
+                }
+                else
+                {
+                    using (var src = SourceStream)
+                    {
+                        src.CopyTo(responseStream, BufferSize);
+                    }
                 }
                 }
             }
             }
             catch (Exception ex)
             catch (Exception ex)
@@ -114,9 +134,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
         {
             try
             try
             {
             {
-                using (var src = SourceStream)
+                if (_bytes != null)
+                {
+                    await responseStream.WriteAsync(_bytes, 0, _bytes.Length);
+                }
+                else
                 {
                 {
-                    await src.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false);
+                    using (var src = SourceStream)
+                    {
+                        await src.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false);
+                    }
                 }
                 }
             }
             }
             catch (Exception ex)
             catch (Exception ex)

+ 2 - 1
MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs

@@ -846,7 +846,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
                 Url = ApiUrl + "/lineups/" + info.ListingsId,
                 Url = ApiUrl + "/lineups/" + info.ListingsId,
                 UserAgent = UserAgent,
                 UserAgent = UserAgent,
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
             };
 
 
             httpOptions.RequestHeaders["token"] = token;
             httpOptions.RequestHeaders["token"] = token;

+ 39 - 8
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -558,7 +558,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return item;
             return item;
         }
         }
 
 
-        private async Task<LiveTvProgram> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
+        private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
         {
         {
             var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
             var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
 
 
@@ -671,13 +671,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 }
                 }
             }
             }
 
 
+            var isUpdated = false;
             if (isNew)
             if (isNew)
             {
             {
-                await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
             }
             }
             else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
             else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
             {
             {
-                await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+                isUpdated = true;
             }
             }
             else
             else
             {
             {
@@ -687,13 +687,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 if (!string.Equals(etag, item.ExternalEtag, StringComparison.OrdinalIgnoreCase))
                 if (!string.Equals(etag, item.ExternalEtag, StringComparison.OrdinalIgnoreCase))
                 {
                 {
                     item.ExternalEtag = etag;
                     item.ExternalEtag = etag;
-                    await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+                    isUpdated = true;
                 }
                 }
             }
             }
 
 
-            _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem));
-
-            return item;
+            return new Tuple<LiveTvProgram, bool, bool>(item, isNew, isUpdated);
         }
         }
 
 
         private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
         private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
@@ -1289,9 +1287,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
 
                     }).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
                     }).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
 
 
+                    var newPrograms = new List<LiveTvProgram>();
+                    var updatedPrograms = new List<LiveTvProgram>();
+
                     foreach (var program in channelPrograms)
                     foreach (var program in channelPrograms)
                     {
                     {
-                        var programItem = await GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
+                        var programTuple = GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken);
+                        var programItem = programTuple.Item1;
+
+                        if (programTuple.Item2)
+                        {
+                            newPrograms.Add(programItem);
+                        }
+                        else if (programTuple.Item3)
+                        {
+                            updatedPrograms.Add(programItem);
+                        }
 
 
                         programs.Add(programItem.Id);
                         programs.Add(programItem.Id);
 
 
@@ -1321,6 +1332,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                         }
                         }
                     }
                     }
 
 
+                    if (newPrograms.Count > 0)
+                    {
+                        await _libraryManager.CreateItems(newPrograms, cancellationToken).ConfigureAwait(false);
+                    }
+
+                    // TODO: Do this in bulk
+                    foreach (var program in updatedPrograms)
+                    {
+                        await _libraryManager.UpdateItem(program, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+                    }
+
+                    foreach (var program in newPrograms)
+                    {
+                        _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions(_fileSystem));
+                    }
+                    foreach (var program in updatedPrograms)
+                    {
+                        _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions(_fileSystem));
+                    }
+
                     currentChannel.IsMovie = isMovie;
                     currentChannel.IsMovie = isMovie;
                     currentChannel.IsNews = isNews;
                     currentChannel.IsNews = isNews;
                     currentChannel.IsSports = isSports;
                     currentChannel.IsSports = isSports;

+ 81 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs

@@ -12,6 +12,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Model.Dlna;
 
 
 namespace MediaBrowser.Server.Implementations.LiveTv
 namespace MediaBrowser.Server.Implementations.LiveTv
 {
 {
@@ -138,7 +139,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
 
             try
             try
             {
             {
-                await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false);
+                await AddMediaInfoInternal(stream, isAudio, cancellationToken).ConfigureAwait(false);
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -207,6 +208,85 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
             }
         }
         }
 
 
+        private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
+        {
+            var originalRuntime = mediaSource.RunTimeTicks;
+
+            var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+            {
+                InputPath = mediaSource.Path,
+                Protocol = mediaSource.Protocol,
+                MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
+                ExtractChapters = false
+
+            }, cancellationToken).ConfigureAwait(false);
+
+            mediaSource.Bitrate = info.Bitrate;
+            mediaSource.Container = info.Container;
+            mediaSource.Formats = info.Formats;
+            mediaSource.MediaStreams = info.MediaStreams;
+            mediaSource.RunTimeTicks = info.RunTimeTicks;
+            mediaSource.Size = info.Size;
+            mediaSource.Timestamp = info.Timestamp;
+            mediaSource.Video3DFormat = info.Video3DFormat;
+            mediaSource.VideoType = info.VideoType;
+
+            mediaSource.DefaultSubtitleStreamIndex = null;
+
+            // Null this out so that it will be treated like a live stream
+            if (!originalRuntime.HasValue)
+            {
+                mediaSource.RunTimeTicks = null;
+            }
+
+            var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
+
+            if (audioStream == null || audioStream.Index == -1)
+            {
+                mediaSource.DefaultAudioStreamIndex = null;
+            }
+            else
+            {
+                mediaSource.DefaultAudioStreamIndex = audioStream.Index;
+            }
+
+            var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video);
+            if (videoStream != null)
+            {
+                if (!videoStream.BitRate.HasValue)
+                {
+                    var width = videoStream.Width ?? 1920;
+
+                    if (width >= 1900)
+                    {
+                        videoStream.BitRate = 8000000;
+                    }
+
+                    else if (width >= 1260)
+                    {
+                        videoStream.BitRate = 3000000;
+                    }
+
+                    else if (width >= 700)
+                    {
+                        videoStream.BitRate = 1000000;
+                    }
+                }
+            }
+
+            // Try to estimate this
+            if (!mediaSource.Bitrate.HasValue)
+            {
+                var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
+
+                if (total > 0)
+                {
+                    mediaSource.Bitrate = total;
+                }
+            }
+        }
+
+
         public Task CloseMediaSource(string liveStreamId)
         public Task CloseMediaSource(string liveStreamId)
         {
         {
             return _liveTvManager.CloseLiveStream(liveStreamId);
             return _liveTvManager.CloseLiveStream(liveStreamId);

+ 0 - 78
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs

@@ -252,84 +252,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
             //}
             //}
         }
         }
 
 
-        private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
-        {
-            var originalRuntime = mediaSource.RunTimeTicks;
-
-            var info = await MediaEncoder.GetMediaInfo(new MediaInfoRequest
-            {
-                InputPath = mediaSource.Path,
-                Protocol = mediaSource.Protocol,
-                MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
-                ExtractChapters = false
-
-            }, cancellationToken).ConfigureAwait(false);
-
-            mediaSource.Bitrate = info.Bitrate;
-            mediaSource.Container = info.Container;
-            mediaSource.Formats = info.Formats;
-            mediaSource.MediaStreams = info.MediaStreams;
-            mediaSource.RunTimeTicks = info.RunTimeTicks;
-            mediaSource.Size = info.Size;
-            mediaSource.Timestamp = info.Timestamp;
-            mediaSource.Video3DFormat = info.Video3DFormat;
-            mediaSource.VideoType = info.VideoType;
-
-            mediaSource.DefaultSubtitleStreamIndex = null;
-
-            // Null this out so that it will be treated like a live stream
-            if (!originalRuntime.HasValue)
-            {
-                mediaSource.RunTimeTicks = null;
-            }
-
-            var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
-
-            if (audioStream == null || audioStream.Index == -1)
-            {
-                mediaSource.DefaultAudioStreamIndex = null;
-            }
-            else
-            {
-                mediaSource.DefaultAudioStreamIndex = audioStream.Index;
-            }
-
-            var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video);
-            if (videoStream != null)
-            {
-                if (!videoStream.BitRate.HasValue)
-                {
-                    var width = videoStream.Width ?? 1920;
-
-                    if (width >= 1900)
-                    {
-                        videoStream.BitRate = 8000000;
-                    }
-
-                    else if (width >= 1260)
-                    {
-                        videoStream.BitRate = 3000000;
-                    }
-
-                    else if (width >= 700)
-                    {
-                        videoStream.BitRate = 1000000;
-                    }
-                }
-            }
-
-            // Try to estimate this
-            if (!mediaSource.Bitrate.HasValue)
-            {
-                var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
-
-                if (total > 0)
-                {
-                    mediaSource.Bitrate = total;
-                }
-            }
-        }
-
         protected abstract bool IsValidChannelId(string channelId);
         protected abstract bool IsValidChannelId(string channelId);
 
 
         protected LiveTvOptions GetConfiguration()
         protected LiveTvOptions GetConfiguration()

+ 2 - 1
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs

@@ -88,7 +88,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 using (var stream = await _httpClient.Get(new HttpRequestOptions
                 using (var stream = await _httpClient.Get(new HttpRequestOptions
                 {
                 {
                     Url = string.Format("{0}/discover.json", url),
                     Url = string.Format("{0}/discover.json", url),
-                    CancellationToken = CancellationToken.None
+                    CancellationToken = CancellationToken.None,
+                    BufferContent = false
                 }))
                 }))
                 {
                 {
                     var response = _json.DeserializeFromStream<HdHomerunHost.DiscoverResponse>(stream);
                     var response = _json.DeserializeFromStream<HdHomerunHost.DiscoverResponse>(stream);

+ 8 - 4
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -72,7 +72,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             var options = new HttpRequestOptions
             var options = new HttpRequestOptions
             {
             {
                 Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
                 Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = false
             };
             };
             using (var stream = await _httpClient.Get(options))
             using (var stream = await _httpClient.Get(options))
             {
             {
@@ -124,7 +125,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     CancellationToken = cancellationToken,
                     CancellationToken = cancellationToken,
                     CacheLength = TimeSpan.FromDays(1),
                     CacheLength = TimeSpan.FromDays(1),
                     CacheMode = CacheMode.Unconditional,
                     CacheMode = CacheMode.Unconditional,
-                    TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
+                    TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
+                    BufferContent = false
                 }))
                 }))
                 {
                 {
                     var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
                     var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
@@ -165,7 +167,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             {
             {
                 Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
                 Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
                 CancellationToken = cancellationToken,
                 CancellationToken = cancellationToken,
-                TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
+                TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
+                BufferContent = false
             }))
             }))
             {
             {
                 var tuners = new List<LiveTvTunerInfo>();
                 var tuners = new List<LiveTvTunerInfo>();
@@ -538,7 +541,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 using (var stream = await _httpClient.Get(new HttpRequestOptions
                 using (var stream = await _httpClient.Get(new HttpRequestOptions
                 {
                 {
                     Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
                     Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
-                    CancellationToken = CancellationToken.None
+                    CancellationToken = CancellationToken.None,
+                    BufferContent = false
                 }))
                 }))
                 {
                 {
                     var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
                     var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);

+ 6 - 2
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs

@@ -12,6 +12,7 @@ using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Server.Implementations.LiveTv.EmbyTV;
 using MediaBrowser.Server.Implementations.LiveTv.EmbyTV;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Linq;
 
 
 namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 {
 {
@@ -139,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
         }
         }
 
 
-        private List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>> _additionalStreams = new List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>>();
+        private readonly List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>> _additionalStreams = new List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>>();
 
 
         public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
         public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
         {
         {
@@ -186,7 +187,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             {
             {
                 await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
                 await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
 
 
-                foreach (var additionalStream in _additionalStreams)
+                var additionalStreams = _additionalStreams.ToList();
+                foreach (var additionalStream in additionalStreams)
                 {
                 {
                     cancellationToken.ThrowIfCancellationRequested();
                     cancellationToken.ThrowIfCancellationRequested();
 
 
@@ -196,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     }
                     }
                     catch (Exception ex)
                     catch (Exception ex)
                     {
                     {
+                        _logger.ErrorException("Error writing HDHR data to stream", ex);
+
                         PopAdditionalStream(additionalStream, ex);
                         PopAdditionalStream(additionalStream, ex);
                     }
                     }
                 }
                 }

+ 2 - 1
MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs

@@ -81,7 +81,8 @@ namespace MediaBrowser.Server.Implementations.News
             {
             {
                 Url = "http://emby.media/community/index.php?/blog/rss/1-media-browser-developers-blog",
                 Url = "http://emby.media/community/index.php?/blog/rss/1-media-browser-developers-blog",
                 Progress = new Progress<double>(),
                 Progress = new Progress<double>(),
-                UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36"
+                UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36",
+                BufferContent = false
             };
             };
 
 
             using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false))
             using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false))

+ 5 - 8
MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Model.Serialization;
 using System;
 using System;
 using System.Data;
 using System.Data;
 using System.IO;
 using System.IO;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.Persistence
 namespace MediaBrowser.Server.Implementations.Persistence
 {
 {
@@ -51,18 +52,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <summary>
         /// <summary>
         /// Gets a stream from a DataReader at a given ordinal
         /// Gets a stream from a DataReader at a given ordinal
         /// </summary>
         /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="ordinal">The ordinal.</param>
         /// <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)
+        public static Stream GetMemoryStream(this IDataReader reader, int ordinal, IMemoryStreamProvider streamProvider)
         {
         {
             if (reader == null)
             if (reader == null)
             {
             {
                 throw new ArgumentNullException("reader");
                 throw new ArgumentNullException("reader");
             }
             }
 
 
-            var memoryStream = new MemoryStream();
+            var memoryStream = streamProvider.CreateNew();
             var num = 0L;
             var num = 0L;
             var array = new byte[4096];
             var array = new byte[4096];
             long bytes;
             long bytes;
@@ -132,18 +131,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <summary>
         /// <summary>
         /// Serializes to bytes.
         /// Serializes to bytes.
         /// </summary>
         /// </summary>
-        /// <param name="json">The json.</param>
-        /// <param name="obj">The obj.</param>
         /// <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)
+        public static byte[] SerializeToBytes(this IJsonSerializer json, object obj, IMemoryStreamProvider streamProvider)
         {
         {
             if (obj == null)
             if (obj == null)
             {
             {
                 throw new ArgumentNullException("obj");
                 throw new ArgumentNullException("obj");
             }
             }
 
 
-            using (var stream = new MemoryStream())
+            using (var stream = streamProvider.CreateNew())
             {
             {
                 json.SerializeToStream(obj, stream);
                 json.SerializeToStream(obj, stream);
                 return stream.ToArray();
                 return stream.ToArray();

+ 9 - 5
MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs

@@ -10,6 +10,7 @@ using System.Data;
 using System.IO;
 using System.IO;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.Persistence
 namespace MediaBrowser.Server.Implementations.Persistence
 {
 {
@@ -18,10 +19,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
     /// </summary>
     /// </summary>
     public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
     public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
     {
     {
-        public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector)
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
+
+        public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider)
             : base(logManager, dbConnector)
             : base(logManager, dbConnector)
         {
         {
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
+            _memoryStreamProvider = memoryStreamProvider;
             DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
             DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
         }
         }
 
 
@@ -82,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
+            var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider);
 
 
             using (var connection = await CreateConnection().ConfigureAwait(false))
             using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
@@ -166,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     foreach (var displayPreference in displayPreferences)
                     foreach (var displayPreference in displayPreferences)
                     {
                     {
 
 
-                        var serialized = _jsonSerializer.SerializeToBytes(displayPreference);
+                        var serialized = _jsonSerializer.SerializeToBytes(displayPreference, _memoryStreamProvider);
 
 
                         using (var cmd = connection.CreateCommand())
                         using (var cmd = connection.CreateCommand())
                         {
                         {
@@ -246,7 +250,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     {
                     {
                         if (reader.Read())
                         if (reader.Read())
                         {
                         {
-                            using (var stream = reader.GetMemoryStream(0))
+                            using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
                             {
                             {
                                 return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
                                 return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
                             }
                             }
@@ -283,7 +287,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     {
                     {
                         while (reader.Read())
                         while (reader.Read())
                         {
                         {
-                            using (var stream = reader.GetMemoryStream(0))
+                            using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
                             {
                             {
                                 list.Add(_jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream));
                                 list.Add(_jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream));
                             }
                             }

+ 6 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -19,6 +19,7 @@ using System.Text;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Playlists;
@@ -95,11 +96,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;
 
 
         /// <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)
+        public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector, IMemoryStreamProvider memoryStreamProvider)
             : base(logManager, connector)
             : base(logManager, connector)
         {
         {
             if (config == null)
             if (config == null)
@@ -113,6 +115,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             _config = config;
             _config = config;
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
+            _memoryStreamProvider = memoryStreamProvider;
 
 
             _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
             _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
             DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
             DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
@@ -724,7 +727,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
                     _saveItemCommand.GetParameter(index++).Value = item.Id;
                     _saveItemCommand.GetParameter(index++).Value = item.Id;
                     _saveItemCommand.GetParameter(index++).Value = item.GetType().FullName;
                     _saveItemCommand.GetParameter(index++).Value = item.GetType().FullName;
-                    _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item);
+                    _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider);
 
 
                     _saveItemCommand.GetParameter(index++).Value = item.Path;
                     _saveItemCommand.GetParameter(index++).Value = item.Path;
 
 
@@ -1075,7 +1078,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             BaseItem item = null;
             BaseItem item = null;
 
 
-            using (var stream = reader.GetMemoryStream(1))
+            using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
             {
             {
                 try
                 try
                 {
                 {

+ 6 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs

@@ -9,6 +9,7 @@ using System.Data;
 using System.IO;
 using System.IO;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.Persistence
 namespace MediaBrowser.Server.Implementations.Persistence
 {
 {
@@ -18,10 +19,12 @@ 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;
 
 
-        public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector) : base(logManager, dbConnector)
+        public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider) : base(logManager, dbConnector)
         {
         {
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
+            _memoryStreamProvider = memoryStreamProvider;
 
 
             DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
             DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
         }
         }
@@ -75,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            var serialized = _jsonSerializer.SerializeToBytes(user);
+            var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider);
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                         {
                         {
                             var id = reader.GetGuid(0);
                             var id = reader.GetGuid(0);
 
 
-                            using (var stream = reader.GetMemoryStream(1))
+                            using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
                             {
                             {
                                 var user = _jsonSerializer.DeserializeFromStream<User>(stream);
                                 var user = _jsonSerializer.DeserializeFromStream<User>(stream);
                                 user.Id = id;
                                 user.Id = id;

+ 1 - 1
MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs

@@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
 
 
         public override bool IsVisible(User user)
         public override bool IsVisible(User user)
         {
         {
-            return base.IsVisible(user) && GetChildren(user, false).Any();
+            return base.IsVisible(user);
         }
         }
 
 
         protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
         protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)

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

@@ -13,6 +13,7 @@ using System.Linq;
 using System.Net.Sockets;
 using System.Net.Sockets;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.ServerManager
 namespace MediaBrowser.Server.Implementations.ServerManager
 {
 {
@@ -72,6 +73,7 @@ namespace MediaBrowser.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;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ServerManager" /> class.
         /// Initializes a new instance of the <see cref="ServerManager" /> class.
@@ -81,7 +83,7 @@ namespace MediaBrowser.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)
+        public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             if (applicationHost == null)
             if (applicationHost == null)
             {
             {
@@ -100,6 +102,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
             _applicationHost = applicationHost;
             _applicationHost = applicationHost;
             ConfigurationManager = configurationManager;
             ConfigurationManager = configurationManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
                 return;
                 return;
             }
             }
 
 
-            var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
+            var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _memoryStreamProvider)
             {
             {
                 OnReceive = ProcessWebSocketMessageReceived,
                 OnReceive = ProcessWebSocketMessageReceived,
                 Url = e.Url,
                 Url = e.Url,

+ 6 - 3
MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs

@@ -9,6 +9,7 @@ using System.Collections.Specialized;
 using System.IO;
 using System.IO;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 using UniversalDetector;
 using UniversalDetector;
 
 
 namespace MediaBrowser.Server.Implementations.ServerManager
 namespace MediaBrowser.Server.Implementations.ServerManager
@@ -78,7 +79,8 @@ namespace MediaBrowser.Server.Implementations.ServerManager
         /// </summary>
         /// </summary>
         /// <value>The query string.</value>
         /// <value>The query string.</value>
         public NameValueCollection QueryString { get; set; }
         public NameValueCollection QueryString { get; set; }
-        
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
+
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
         /// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
         /// </summary>
         /// </summary>
@@ -87,7 +89,7 @@ namespace MediaBrowser.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)
+        public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             if (socket == null)
             if (socket == null)
             {
             {
@@ -113,6 +115,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
             _socket.OnReceive = OnReceiveInternal;
             _socket.OnReceive = OnReceiveInternal;
             RemoteEndPoint = remoteEndPoint;
             RemoteEndPoint = remoteEndPoint;
             _logger = logger;
             _logger = logger;
+            _memoryStreamProvider = memoryStreamProvider;
 
 
             socket.Closed += socket_Closed;
             socket.Closed += socket_Closed;
         }
         }
@@ -149,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
         {
         {
             try
             try
             {
             {
-                using (var ms = new MemoryStream(bytes))
+                using (var ms = _memoryStreamProvider.CreateNew(bytes))
                 {
                 {
                     var detector = new CharsetDetector();
                     var detector = new CharsetDetector();
                     detector.Feed(ms);
                     detector.Feed(ms);

+ 2 - 1
MediaBrowser.Server.Implementations/Session/HttpSessionController.cs

@@ -75,7 +75,8 @@ namespace MediaBrowser.Server.Implementations.Session
             await _httpClient.Post(new HttpRequestOptions
             await _httpClient.Post(new HttpRequestOptions
             {
             {
                 Url = url,
                 Url = url,
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = false
 
 
             }).ConfigureAwait(false);
             }).ConfigureAwait(false);
         }
         }

+ 5 - 2
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -30,6 +30,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using CommonIO;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.Sync
 namespace MediaBrowser.Server.Implementations.Sync
 {
 {
@@ -51,6 +52,7 @@ namespace MediaBrowser.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 ISyncProvider[] _providers = { };
         private ISyncProvider[] _providers = { };
 
 
@@ -60,7 +62,7 @@ namespace MediaBrowser.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)
+        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)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _repo = repo;
             _repo = repo;
@@ -78,6 +80,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _mediaSourceManager = mediaSourceManager;
             _mediaSourceManager = mediaSourceManager;
             _json = json;
             _json = json;
             _taskManager = taskManager;
             _taskManager = taskManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
         }
 
 
         public void AddParts(IEnumerable<ISyncProvider> providers)
         public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -95,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
         public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
         {
         {
-            return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost, _logger, _json, _fileSystem, _config.CommonApplicationPaths));
+            return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost, _logger, _json, _fileSystem, _config.CommonApplicationPaths, _memoryStreamProvider));
         }
         }
 
 
         public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
         public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)

+ 5 - 2
MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs

@@ -12,6 +12,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using CommonIO;
 using CommonIO;
 using Interfaces.IO;
 using Interfaces.IO;
+using MediaBrowser.Common.IO;
 
 
 namespace MediaBrowser.Server.Implementations.Sync
 namespace MediaBrowser.Server.Implementations.Sync
 {
 {
@@ -28,8 +29,9 @@ namespace MediaBrowser.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;
 
 
-        public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
+        public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths, IMemoryStreamProvider memoryStreamProvider)
         {
         {
             _logger = logger;
             _logger = logger;
             _json = json;
             _json = json;
@@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _target = target;
             _target = target;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
             _appPaths = appPaths;
             _appPaths = appPaths;
+            _memoryStreamProvider = memoryStreamProvider;
             _appHost = appHost;
             _appHost = appHost;
         }
         }
 
 
@@ -90,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         private async Task SaveData(List<LocalItem> items, CancellationToken cancellationToken)
         private async Task SaveData(List<LocalItem> items, CancellationToken cancellationToken)
         {
         {
-            using (var stream = new MemoryStream())
+            using (var stream = _memoryStreamProvider.CreateNew())
             {
             {
                 _json.SerializeToStream(items, stream);
                 _json.SerializeToStream(items, stream);
 
 

+ 13 - 11
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -436,11 +436,11 @@ namespace MediaBrowser.Server.Startup.Common
 
 
             UserRepository = await GetUserRepository().ConfigureAwait(false);
             UserRepository = await GetUserRepository().ConfigureAwait(false);
             
             
-            var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector());
+            var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamProvider);
             DisplayPreferencesRepository = displayPreferencesRepo;
             DisplayPreferencesRepository = displayPreferencesRepo;
             RegisterSingleInstance(DisplayPreferencesRepository);
             RegisterSingleInstance(DisplayPreferencesRepository);
 
 
-            var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector());
+            var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamProvider);
             ItemRepository = itemRepo;
             ItemRepository = itemRepo;
             RegisterSingleInstance(ItemRepository);
             RegisterSingleInstance(ItemRepository);
 
 
@@ -465,17 +465,17 @@ namespace MediaBrowser.Server.Startup.Common
             LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, this);
             LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, this);
             RegisterSingleInstance(LibraryMonitor);
             RegisterSingleInstance(LibraryMonitor);
 
 
-            ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer);
+            ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamProvider);
             RegisterSingleInstance(ProviderManager);
             RegisterSingleInstance(ProviderManager);
 
 
             RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
             RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
 
 
-            HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, "Emby", "web/index.html");
+            HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamProvider, "Emby", "web/index.html");
             HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
             HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
             RegisterSingleInstance(HttpServer, false);
             RegisterSingleInstance(HttpServer, false);
             progress.Report(10);
             progress.Report(10);
 
 
-            ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager);
+            ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamProvider);
             RegisterSingleInstance(ServerManager);
             RegisterSingleInstance(ServerManager);
 
 
             var innerProgress = new ActionableProgress<double>();
             var innerProgress = new ActionableProgress<double>();
@@ -487,7 +487,7 @@ namespace MediaBrowser.Server.Startup.Common
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
             RegisterSingleInstance(TVSeriesManager);
             RegisterSingleInstance(TVSeriesManager);
 
 
-            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer, TaskManager);
+            SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer, TaskManager, MemoryStreamProvider);
             RegisterSingleInstance(SyncManager);
             RegisterSingleInstance(SyncManager);
 
 
             DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
             DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
@@ -573,7 +573,7 @@ namespace MediaBrowser.Server.Startup.Common
             RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
             RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
             RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager));
             RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager));
 
 
-            SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager);
+            SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider);
             RegisterSingleInstance(SubtitleEncoder);
             RegisterSingleInstance(SubtitleEncoder);
 
 
             await displayPreferencesRepo.Initialize().ConfigureAwait(false);
             await displayPreferencesRepo.Initialize().ConfigureAwait(false);
@@ -665,7 +665,7 @@ namespace MediaBrowser.Server.Startup.Common
                 () => SubtitleEncoder,
                 () => SubtitleEncoder,
                 () => MediaSourceManager,
                 () => MediaSourceManager,
                 HttpClient,
                 HttpClient,
-                ZipClient);
+                ZipClient, MemoryStreamProvider);
 
 
             MediaEncoder = mediaEncoder;
             MediaEncoder = mediaEncoder;
             RegisterSingleInstance(MediaEncoder);
             RegisterSingleInstance(MediaEncoder);
@@ -679,7 +679,7 @@ namespace MediaBrowser.Server.Startup.Common
         {
         {
             try
             try
             {
             {
-                var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector());
+                var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector(), MemoryStreamProvider);
 
 
                 await repo.Initialize().ConfigureAwait(false);
                 await repo.Initialize().ConfigureAwait(false);
 
 
@@ -1132,7 +1132,8 @@ namespace MediaBrowser.Server.Startup.Common
                 SupportsLibraryMonitor = SupportsLibraryMonitor,
                 SupportsLibraryMonitor = SupportsLibraryMonitor,
                 EncoderLocationType = MediaEncoder.EncoderLocationType,
                 EncoderLocationType = MediaEncoder.EncoderLocationType,
                 SystemArchitecture = NativeApp.Environment.SystemArchitecture,
                 SystemArchitecture = NativeApp.Environment.SystemArchitecture,
-                SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel
+                SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel,
+                PackageName = _startupOptions.GetOption("package")
             };
             };
         }
         }
 
 
@@ -1237,7 +1238,8 @@ namespace MediaBrowser.Server.Startup.Common
                     LogErrorResponseBody = false,
                     LogErrorResponseBody = false,
                     LogErrors = false,
                     LogErrors = false,
                     LogRequest = false,
                     LogRequest = false,
-                    TimeoutMs = 30000
+                    TimeoutMs = 30000,
+                    BufferContent = false
 
 
                 }, "POST").ConfigureAwait(false))
                 }, "POST").ConfigureAwait(false))
                 {
                 {

+ 3 - 0
MediaBrowser.sln

@@ -67,6 +67,9 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Nat", "Mono.Nat\Mono.Nat.csproj", "{D7453B88-2266-4805-B39B-2B5A2A33E1BA}"
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Nat", "Mono.Nat\Mono.Nat.csproj", "{D7453B88-2266-4805-B39B-2B5A2A33E1BA}"
 EndProject
 EndProject
 Global
 Global
+	GlobalSection(Performance) = preSolution
+		HasPerformanceSessions = true
+	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Mixed Platforms = Debug|Mixed Platforms
 		Debug|Mixed Platforms = Debug|Mixed Platforms

+ 2 - 1
OpenSubtitlesHandler/Utilities.cs

@@ -201,7 +201,8 @@ namespace OpenSubtitlesHandler
                 // Response parsing will fail with this enabled
                 // Response parsing will fail with this enabled
                 EnableHttpCompression = false,
                 EnableHttpCompression = false,
 
 
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = false
             };
             };
 
 
             if (string.IsNullOrEmpty(options.UserAgent))
             if (string.IsNullOrEmpty(options.UserAgent))