@ -5,6 +5,7 @@ using System.Linq;
using Nancy ;
using Nancy.Bootstrapper ;
using NLog ;
using NzbDrone.Common.EnvironmentInfo ;
using NzbDrone.Common.Extensions ;
namespace NzbDrone.Api.Extensions.Pipelines
@ -15,9 +16,14 @@ namespace NzbDrone.Api.Extensions.Pipelines
public int Order = > 0 ;
private readonly Action < Action < Stream > , Stream > _writeGZipStream ;
public GzipCompressionPipeline ( Logger logger )
{
_logger = logger ;
// On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case.
_writeGZipStream = PlatformInfo . IsMono ? WriteGZipStreamMono : ( Action < Action < Stream > , Stream > ) WriteGZipStream ;
}
public void Register ( IPipelines pipelines )
@ -43,14 +49,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
var contents = response . Contents ;
response . Headers [ "Content-Encoding" ] = "gzip" ;
response . Contents = responseStream = >
{
using ( var gzip = new GZipStream ( responseStream , CompressionMode . Compress , true ) )
using ( var buffered = new BufferedStream ( gzip , 8192 ) )
{
contents . Invoke ( buffered ) ;
}
} ;
response . Contents = responseStream = > _writeGZipStream ( contents , responseStream ) ;
}
}
@ -61,6 +60,25 @@ namespace NzbDrone.Api.Extensions.Pipelines
}
}
private static void WriteGZipStreamMono ( Action < Stream > innerContent , Stream targetStream )
{
using ( var membuffer = new MemoryStream ( ) )
{
WriteGZipStream ( innerContent , membuffer ) ;
membuffer . Position = 0 ;
membuffer . CopyTo ( targetStream ) ;
}
}
private static void WriteGZipStream ( Action < Stream > innerContent , Stream targetStream )
{
using ( var gzip = new GZipStream ( targetStream , CompressionMode . Compress , true ) )
using ( var buffered = new BufferedStream ( gzip , 8192 ) )
{
innerContent . Invoke ( buffered ) ;
}
}
private static bool ContentLengthIsTooSmall ( Response response )
{
var contentLength = response . Headers . GetValueOrDefault ( "Content-Length" ) ;