ソースを参照

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.Linq;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 
 namespace MediaBrowser.Api.Dlna
 {
@@ -109,13 +111,15 @@ namespace MediaBrowser.Api.Dlna
         private readonly IMediaReceiverRegistrar _mediaReceiverRegistrar;
 
         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;
             _contentDirectory = contentDirectory;
             _connectionManager = connectionManager;
             _mediaReceiverRegistrar = mediaReceiverRegistrar;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         public object Get(GetDescriptionXml request)
@@ -201,7 +205,7 @@ namespace MediaBrowser.Api.Dlna
         {
             using (var response = _dlnaManager.GetIcon(request.Filename))
             {
-                using (var ms = new MemoryStream())
+                using (var ms = _memoryStreamProvider.CreateNew())
                 {
                     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
             {
-                Url = url
+                Url = url,
+                BufferContent = 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
             {
-                Url = "https://json.schedulesdirect.org/20141201/available/countries"
+                Url = "https://json.schedulesdirect.org/20141201/available/countries",
+                BufferContent = 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",
                 CancellationToken = CancellationToken.None,
                 LogRequest = false,
-                LogErrors = false
+                LogErrors = false,
+                BufferContent = false
             };
             options.RequestContent = JsonSerializer.SerializeToString(dict);
             options.RequestContentType = "application/json";

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

@@ -30,6 +30,7 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Common.Implementations
 {
@@ -192,6 +193,8 @@ namespace MediaBrowser.Common.Implementations
             get { return Environment.OSVersion.VersionString; }
         }
 
+        public IMemoryStreamProvider MemoryStreamProvider { get; set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
         /// </summary>
@@ -231,6 +234,8 @@ namespace MediaBrowser.Common.Implementations
 
             JsonSerializer = CreateJsonSerializer();
 
+            MemoryStreamProvider = new MemoryStreamProvider();
+
             OnLoggerLoaded(true);
             LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
 
@@ -456,6 +461,7 @@ namespace MediaBrowser.Common.Implementations
 
 			RegisterSingleInstance(JsonSerializer);
 			RegisterSingleInstance(XmlSerializer);
+            RegisterSingleInstance(MemoryStreamProvider);
 
 			RegisterSingleInstance(LogManager);
 			RegisterSingleInstance(Logger);
@@ -464,7 +470,7 @@ namespace MediaBrowser.Common.Implementations
 
 			RegisterSingleInstance(FileSystemManager);
 
-            HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager);
+            HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider);
 			RegisterSingleInstance(HttpClient);
 
 			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 IFileSystem _fileSystem;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="HttpClientManager" /> class.
@@ -52,7 +53,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
         /// <exception cref="System.ArgumentNullException">appPaths
         /// or
         /// logger</exception>
-        public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
+        public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
         {
             if (appPaths == null)
             {
@@ -65,6 +66,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
             _logger = logger;
             _fileSystem = fileSystem;
+            _memoryStreamProvider = memoryStreamProvider;
             _appPaths = appPaths;
 
             // 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,
                 ResourcePool = resourcePool,
                 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))
                     {
-                        var memoryStream = new MemoryStream();
+                        var memoryStream = _memoryStreamProvider.CreateNew();
 
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
                         memoryStream.Position = 0;
@@ -363,7 +366,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
             using (var responseStream = response.Content)
             {
-                var memoryStream = new MemoryStream();
+                var memoryStream = _memoryStreamProvider.CreateNew();
                 await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
                 memoryStream.Position = 0;
 
@@ -455,7 +458,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
                     using (var stream = httpResponse.GetResponseStream())
                     {
-                        var memoryStream = new MemoryStream();
+                        var memoryStream = _memoryStreamProvider.CreateNew();
 
                         await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
 
@@ -550,7 +553,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
             {
                 Url = url,
                 ResourcePool = resourcePool,
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = resourcePool != null
 
             }, postData);
         }
@@ -560,7 +564,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
         /// </summary>
         /// <param name="options">The options.</param>
         /// <returns>Task{System.String}.</returns>
-        /// <exception cref="System.ArgumentNullException">progress</exception>
         public async Task<string> GetTempFile(HttpRequestOptions options)
         {
             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>
         public void Debug(string message, params object[] paramList)
         {
+            if (_logManager.LogSeverity == LogSeverity.Info)
+            {
+                return;
+            }
+
             _logger.Debug(message, paramList);
         }
 
@@ -137,6 +142,11 @@ namespace MediaBrowser.Common.Implementations.Logging
         /// <param name="additionalContent">Content of the additional.</param>
         public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
         {
+            if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info)
+            {
+                return;
+            }
+
             additionalContent.Insert(0, message + Environment.NewLine);
 
             const char tabChar = '\t';

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

@@ -51,6 +51,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
     </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">
       <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
     </Reference>
@@ -93,6 +97,7 @@
     <Compile Include="HttpClientManager\HttpClientInfo.cs" />
     <Compile Include="HttpClientManager\HttpClientManager.cs" />
     <Compile Include="IO\IsoManager.cs" />
+    <Compile Include="IO\MemoryStreamProvider.cs" />
     <Compile Include="Logging\LogHelper.cs" />
     <Compile Include="Logging\NLogger.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()
             {
                 Url = AppstoreRegUrl,
-                CancellationToken = CancellationToken.None
+                CancellationToken = CancellationToken.None,
+                BufferContent = false
             };
             options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId);
             options.RequestContent = parameters;
@@ -269,7 +270,8 @@ namespace MediaBrowser.Common.Implementations.Security
                         Url = MBValidateUrl,
 
                         // Seeing block length errors
-                        EnableHttpCompression = false
+                        EnableHttpCompression = false,
+                        BufferContent = false
                     };
 
                     options.SetPostData(data);

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

@@ -30,7 +30,8 @@ namespace MediaBrowser.Common.Implementations.Updates
                 Url = url,
                 EnableKeepAlive = false,
                 CancellationToken = cancellationToken,
-                UserAgent = "Emby/3.0"
+                UserAgent = "Emby/3.0",
+                BufferContent = false
             };
 
             if (cacheLength.Ticks > 0)
@@ -105,7 +106,8 @@ namespace MediaBrowser.Common.Implementations.Updates
                 Url = url,
                 EnableKeepAlive = false,
                 CancellationToken = cancellationToken,
-                UserAgent = "Emby/3.0"
+                UserAgent = "Emby/3.0",
+                BufferContent = 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"?>
 <packages>
   <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="NLog" version="4.3.8" 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\ResourceNotFoundException.cs" />
     <Compile Include="IDependencyContainer.cs" />
+    <Compile Include="IO\IMemoryStreamProvider.cs" />
     <Compile Include="IO\ProgressStream.cs" />
     <Compile Include="IO\StreamDefaults.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);
     }
+
+    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();
 
-            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 ?
                 new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
@@ -267,7 +267,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="connection">The connection.</param>
         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;
 

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

@@ -34,7 +34,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 UserAgent = "Emby",
                 RequestContentType = "text/xml; charset=\"utf-8\"",
                 LogErrorResponseBody = true,
-                Url = request.ContentDirectoryUrl
+                Url = request.ContentDirectoryUrl,
+                BufferContent = false
             };
 
             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(),
                 RequestContentType = "text/xml",
-                Url = subscription.CallbackUrl
+                Url = subscription.CallbackUrl,
+                BufferContent = false
             };
 
             options.RequestHeaders.Add("NT", subscription.NotificationType);

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

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

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

@@ -70,7 +70,8 @@ namespace MediaBrowser.Dlna.PlayTo
             {
                 Url = url,
                 UserAgent = USERAGENT,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
 
             options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture);
@@ -87,7 +88,8 @@ namespace MediaBrowser.Dlna.PlayTo
             {
                 Url = url,
                 UserAgent = USERAGENT,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
 
             options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
@@ -115,7 +117,8 @@ namespace MediaBrowser.Dlna.PlayTo
                 Url = url,
                 UserAgent = USERAGENT,
                 LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLog,
-                LogErrorResponseBody = true
+                LogErrorResponseBody = true,
+                BufferContent = false
             };
 
             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)
         {
-            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.Common.Configuration;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 
 namespace MediaBrowser.MediaEncoding.Encoder
@@ -79,13 +80,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
         protected readonly Func<IMediaSourceManager> MediaSourceManager;
         private readonly IHttpClient _httpClient;
         private readonly IZipClient _zipClient;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
         private readonly bool _hasExternalEncoder;
         private string _originalFFMpegPath;
         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;
             _jsonSerializer = jsonSerializer;
@@ -100,6 +102,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             MediaSourceManager = mediaSourceManager;
             _httpClient = httpClient;
             _zipClient = zipClient;
+            _memoryStreamProvider = memoryStreamProvider;
             FFProbePath = ffProbePath;
             FFMpegPath = ffMpegPath;
             _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);
 

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

@@ -9,6 +9,8 @@ using System.Linq;
 using System.Text;
 using System.Xml;
 using CommonIO;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
@@ -20,11 +22,13 @@ namespace MediaBrowser.MediaEncoding.Probing
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
-        public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem)
+        public ProbeResultNormalizer(ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
         {
             _logger = logger;
             _fileSystem = fileSystem;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         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 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))
                 {
@@ -573,8 +577,7 @@ namespace MediaBrowser.MediaEncoding.Probing
 
         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;
             }

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

@@ -18,6 +18,8 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
 using UniversalDetector;
 
 namespace MediaBrowser.MediaEncoding.Subtitles
@@ -32,8 +34,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
         private readonly IJsonSerializer _json;
         private readonly IHttpClient _httpClient;
         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;
             _logger = logger;
@@ -43,6 +46,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
             _json = json;
             _httpClient = httpClient;
             _mediaSourceManager = mediaSourceManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         private string SubtitleCachePath
@@ -61,7 +65,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
             bool preserveOriginalTimestamps,
             CancellationToken cancellationToken)
         {
-            var ms = new MemoryStream();
+            var ms = _memoryStreamProvider.CreateNew();
 
             try
             {
@@ -202,7 +206,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
 
                             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>
         public string MacAddress { get; set; }
 
+        public string PackageName { get; set; }
+        
         /// <summary>
         /// Gets or sets a value indicating whether this instance has pending restart.
         /// </summary>

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

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres
 
         public static string ProviderName
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
 
         public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.GameGenres
             {
                 CancellationToken = cancellationToken,
                 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);
 
-        public static SemaphoreSlim ImageDownloadResourcePool = new SemaphoreSlim(5, 5);
-
         public GenreImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
         {
             _config = config;
@@ -38,7 +36,7 @@ namespace MediaBrowser.Providers.Genres
 
         public static string ProviderName
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
 
         public bool Supports(IHasImages item)
@@ -138,7 +136,7 @@ namespace MediaBrowser.Providers.Genres
             {
                 CancellationToken = cancellationToken,
                 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 IFileSystem _fileSystem;
         private readonly ILogger _logger;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         /// <summary>
         /// 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="fileSystem">The file system.</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;
             _libraryMonitor = libraryMonitor;
             _fileSystem = fileSystem;
             _logger = logger;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         /// <summary>
@@ -124,7 +126,7 @@ namespace MediaBrowser.Providers.Manager
             var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
 
             // 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)
             {
                 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.Tasks;
 using CommonIO;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Providers.Manager
@@ -64,6 +65,7 @@ namespace MediaBrowser.Providers.Manager
         private IExternalId[] _externalIds;
 
         private readonly Func<ILibraryManager> _libraryManagerFactory;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         /// <summary>
         /// 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="logManager">The log manager.</param>
         /// <param name="fileSystem">The file system.</param>
-        public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json)
+        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");
             _httpClient = httpClient;
@@ -83,6 +85,7 @@ namespace MediaBrowser.Providers.Manager
             _appPaths = appPaths;
             _libraryManagerFactory = libraryManagerFactory;
             _json = json;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         /// <summary>
@@ -142,12 +145,12 @@ namespace MediaBrowser.Providers.Manager
 
         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)
         {
-            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)
@@ -159,7 +162,7 @@ namespace MediaBrowser.Providers.Manager
 
             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)

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

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios
 
         public static string ProviderName
         {
-            get { return "Media Browser Designs"; }
+            get { return "Emby Designs"; }
         }
 
         public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.Studios
             {
                 CancellationToken = cancellationToken,
                 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.Xml;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Providers.TV
 {
@@ -38,6 +39,7 @@ namespace MediaBrowser.Providers.TV
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
         private readonly ILogger _logger;
         private readonly ILibraryManager _libraryManager;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager)
         {
@@ -238,7 +240,7 @@ namespace MediaBrowser.Providers.TV
                 DeleteXmlFiles(seriesDataPath);
 
                 // 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);
 

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

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

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

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

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

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

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

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

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

@@ -1,4 +1,5 @@
 using MediaBrowser.Common;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Net;
@@ -15,23 +16,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <summary>
         /// Creates the server.
         /// </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>
         public static IHttpServer CreateServer(IApplicationHost applicationHost,
             ILogManager logManager,
             IServerConfigurationManager config, 
             INetworkManager _networkmanager,
+            IMemoryStreamProvider streamProvider,
             string serverName, 
             string defaultRedirectpath)
         {
             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)
                 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
                 //Not ending with \r\n?
-                var ms = new MemoryStream(32 * 1024);
+                var ms = _memoryStreamProvider.CreateNew(32 * 1024);
                 await requestStream.CopyToAsync(ms).ConfigureAwait(false);
 
                 var input = ms;
@@ -229,9 +229,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
         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);
                     ms.Position = 0;

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

@@ -9,6 +9,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 {
@@ -18,11 +19,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
         private readonly ILogger _logger;
         private readonly string _certificatePath;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
-        public WebSocketSharpListener(ILogger logger, string certificatePath)
+        public WebSocketSharpListener(ILogger logger, string certificatePath, IMemoryStreamProvider memoryStreamProvider)
         {
             _logger = logger;
             _certificatePath = certificatePath;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         public Action<Exception, IRequest> ErrorHandler { get; set; }
@@ -148,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
         {
             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();
 
             return req;

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

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using Funq;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Model.Logging;
 using ServiceStack;
 using ServiceStack.Host;
@@ -16,11 +17,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
         public Container Container { get; set; }
         private readonly HttpListenerRequest request;
         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.RequestAttributes = requestAttributes;
+            _memoryStreamProvider = memoryStreamProvider;
             this.request = httpContext.Request;
             this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
 
@@ -403,7 +406,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
             set
             {
                 bufferedStream = value
-                    ? bufferedStream ?? new MemoryStream(request.InputStream.ReadFully())
+                    ? bufferedStream ?? _memoryStreamProvider.CreateNew(request.InputStream.ReadFully())
                     : 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)
             {

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

@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 using ServiceStack;
 
 namespace MediaBrowser.Server.Implementations.HttpServer
@@ -17,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         private ILogger Logger { get; set; }
 
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-        
+
         /// <summary>
         /// Gets or sets the source stream.
         /// </summary>
@@ -39,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
         public Action OnComplete { get; set; }
         public Action OnError { get; set; }
+        private readonly byte[] _bytes;
 
         /// <summary>
         /// 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)
             : 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;
@@ -85,9 +98,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
             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)
@@ -114,9 +134,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
             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)

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

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

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

@@ -558,7 +558,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             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);
 
@@ -671,13 +671,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 }
             }
 
+            var isUpdated = false;
             if (isNew)
             {
-                await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
             }
             else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
             {
-                await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+                isUpdated = true;
             }
             else
             {
@@ -687,13 +687,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 if (!string.Equals(etag, item.ExternalEtag, StringComparison.OrdinalIgnoreCase))
                 {
                     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)
@@ -1289,9 +1287,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
                     }).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
 
+                    var newPrograms = new List<LiveTvProgram>();
+                    var updatedPrograms = new List<LiveTvProgram>();
+
                     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);
 
@@ -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.IsNews = isNews;
                     currentChannel.IsSports = isSports;

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

@@ -12,6 +12,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Model.Dlna;
 
 namespace MediaBrowser.Server.Implementations.LiveTv
 {
@@ -138,7 +139,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             try
             {
-                await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false);
+                await AddMediaInfoInternal(stream, isAudio, cancellationToken).ConfigureAwait(false);
             }
             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)
         {
             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 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
                 {
                     Url = string.Format("{0}/discover.json", url),
-                    CancellationToken = CancellationToken.None
+                    CancellationToken = CancellationToken.None,
+                    BufferContent = false
                 }))
                 {
                     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
             {
                 Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
-                CancellationToken = cancellationToken
+                CancellationToken = cancellationToken,
+                BufferContent = false
             };
             using (var stream = await _httpClient.Get(options))
             {
@@ -124,7 +125,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     CancellationToken = cancellationToken,
                     CacheLength = TimeSpan.FromDays(1),
                     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);
@@ -165,7 +167,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             {
                 Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
                 CancellationToken = cancellationToken,
-                TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
+                TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
+                BufferContent = false
             }))
             {
                 var tuners = new List<LiveTvTunerInfo>();
@@ -538,7 +541,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 using (var stream = await _httpClient.Get(new HttpRequestOptions
                 {
                     Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
-                    CancellationToken = CancellationToken.None
+                    CancellationToken = CancellationToken.None,
+                    BufferContent = false
                 }))
                 {
                     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.Server.Implementations.LiveTv.EmbyTV;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 {
@@ -139,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             }).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)
         {
@@ -186,7 +187,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             {
                 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();
 
@@ -196,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     }
                     catch (Exception ex)
                     {
+                        _logger.ErrorException("Error writing HDHR data to stream", 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",
                 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))

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

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

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

@@ -10,6 +10,7 @@ using System.Data;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.Persistence
 {
@@ -18,10 +19,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
     /// </summary>
     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)
         {
             _jsonSerializer = jsonSerializer;
+            _memoryStreamProvider = memoryStreamProvider;
             DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
         }
 
@@ -82,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             cancellationToken.ThrowIfCancellationRequested();
 
-            var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
+            var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider);
 
             using (var connection = await CreateConnection().ConfigureAwait(false))
             {
@@ -166,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     foreach (var displayPreference in displayPreferences)
                     {
 
-                        var serialized = _jsonSerializer.SerializeToBytes(displayPreference);
+                        var serialized = _jsonSerializer.SerializeToBytes(displayPreference, _memoryStreamProvider);
 
                         using (var cmd = connection.CreateCommand())
                         {
@@ -246,7 +250,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     {
                         if (reader.Read())
                         {
-                            using (var stream = reader.GetMemoryStream(0))
+                            using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
                             {
                                 return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
                             }
@@ -283,7 +287,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     {
                         while (reader.Read())
                         {
-                            using (var stream = reader.GetMemoryStream(0))
+                            using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
                             {
                                 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.Tasks;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Playlists;
@@ -95,11 +96,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _updateInheritedTagsCommand;
 
         public const int LatestSchemaVersion = 109;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
         /// </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)
         {
             if (config == null)
@@ -113,6 +115,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             _config = config;
             _jsonSerializer = jsonSerializer;
+            _memoryStreamProvider = memoryStreamProvider;
 
             _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
             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.GetType().FullName;
-                    _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item);
+                    _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider);
 
                     _saveItemCommand.GetParameter(index++).Value = item.Path;
 
@@ -1075,7 +1078,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             BaseItem item = null;
 
-            using (var stream = reader.GetMemoryStream(1))
+            using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
             {
                 try
                 {

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

@@ -9,6 +9,7 @@ using System.Data;
 using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.Persistence
 {
@@ -18,10 +19,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
     public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
     {
         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;
+            _memoryStreamProvider = memoryStreamProvider;
 
             DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
         }
@@ -75,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             cancellationToken.ThrowIfCancellationRequested();
 
-            var serialized = _jsonSerializer.SerializeToBytes(user);
+            var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider);
 
             cancellationToken.ThrowIfCancellationRequested();
 
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                         {
                             var id = reader.GetGuid(0);
 
-                            using (var stream = reader.GetMemoryStream(1))
+                            using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
                             {
                                 var user = _jsonSerializer.DeserializeFromStream<User>(stream);
                                 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)
         {
-            return base.IsVisible(user) && GetChildren(user, false).Any();
+            return base.IsVisible(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.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.ServerManager
 {
@@ -72,6 +73,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
         private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>();
 
         private bool _disposed;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         /// <summary>
         /// 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="configurationManager">The configuration manager.</param>
         /// <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)
             {
@@ -100,6 +102,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
             _jsonSerializer = jsonSerializer;
             _applicationHost = applicationHost;
             ConfigurationManager = configurationManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         /// <summary>
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
                 return;
             }
 
-            var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
+            var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _memoryStreamProvider)
             {
                 OnReceive = ProcessWebSocketMessageReceived,
                 Url = e.Url,

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

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

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

@@ -30,6 +30,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.Sync
 {
@@ -51,6 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly Func<IMediaSourceManager> _mediaSourceManager;
         private readonly IJsonSerializer _json;
         private readonly ITaskManager _taskManager;
+        private readonly IMemoryStreamProvider _memoryStreamProvider;
 
         private ISyncProvider[] _providers = { };
 
@@ -60,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sync
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
         public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
 
-        public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager)
+        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;
             _repo = repo;
@@ -78,6 +80,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _mediaSourceManager = mediaSourceManager;
             _json = json;
             _taskManager = taskManager;
+            _memoryStreamProvider = memoryStreamProvider;
         }
 
         public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -95,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         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)

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

@@ -12,6 +12,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
 using Interfaces.IO;
+using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Server.Implementations.Sync
 {
@@ -28,8 +29,9 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly IFileSystem _fileSystem;
         private readonly IApplicationPaths _appPaths;
         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;
             _json = json;
@@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _target = target;
             _fileSystem = fileSystem;
             _appPaths = appPaths;
+            _memoryStreamProvider = memoryStreamProvider;
             _appHost = appHost;
         }
 
@@ -90,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         private async Task SaveData(List<LocalItem> items, CancellationToken cancellationToken)
         {
-            using (var stream = new MemoryStream())
+            using (var stream = _memoryStreamProvider.CreateNew())
             {
                 _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);
             
-            var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector());
+            var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamProvider);
             DisplayPreferencesRepository = displayPreferencesRepo;
             RegisterSingleInstance(DisplayPreferencesRepository);
 
-            var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector());
+            var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamProvider);
             ItemRepository = itemRepo;
             RegisterSingleInstance(ItemRepository);
 
@@ -465,17 +465,17 @@ namespace MediaBrowser.Server.Startup.Common
             LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, this);
             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<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");
             RegisterSingleInstance(HttpServer, false);
             progress.Report(10);
 
-            ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager);
+            ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamProvider);
             RegisterSingleInstance(ServerManager);
 
             var innerProgress = new ActionableProgress<double>();
@@ -487,7 +487,7 @@ namespace MediaBrowser.Server.Startup.Common
             TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
             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);
 
             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<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);
 
             await displayPreferencesRepo.Initialize().ConfigureAwait(false);
@@ -665,7 +665,7 @@ namespace MediaBrowser.Server.Startup.Common
                 () => SubtitleEncoder,
                 () => MediaSourceManager,
                 HttpClient,
-                ZipClient);
+                ZipClient, MemoryStreamProvider);
 
             MediaEncoder = mediaEncoder;
             RegisterSingleInstance(MediaEncoder);
@@ -679,7 +679,7 @@ namespace MediaBrowser.Server.Startup.Common
         {
             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);
 
@@ -1132,7 +1132,8 @@ namespace MediaBrowser.Server.Startup.Common
                 SupportsLibraryMonitor = SupportsLibraryMonitor,
                 EncoderLocationType = MediaEncoder.EncoderLocationType,
                 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,
                     LogErrors = false,
                     LogRequest = false,
-                    TimeoutMs = 30000
+                    TimeoutMs = 30000,
+                    BufferContent = 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}"
 EndProject
 Global
+	GlobalSection(Performance) = preSolution
+		HasPerformanceSessions = true
+	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Mixed Platforms = Debug|Mixed Platforms

+ 2 - 1
OpenSubtitlesHandler/Utilities.cs

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