Skip to content

Commit c614f54

Browse files
Zlib compression uses BouncyCastle as a fallback if BCL does not support. (#1453)
Co-authored-by: Wojciech Nagórski <[email protected]>
1 parent 9f429f7 commit c614f54

File tree

6 files changed

+28
-11
lines changed

6 files changed

+28
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ Private keys can be encrypted using one of the following cipher methods:
134134

135135
**SSH.NET** supports the following compression algorithms:
136136
* none (default)
137-
* zlib<span></span>@openssh.com (.NET 6 and higher)
137+
* zlib<span></span>@openssh.com
138138

139139
## Framework Support
140140

appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ for:
2121
- echo build
2222
- dotnet build -f net8.0 -c Debug test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
2323
- dotnet build -f net8.0 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
24+
- dotnet build -f net48 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
2425

2526
test_script:
2627
- sh: echo "Run unit tests"
2728
- sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_unit_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_unit_test_net_8_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
2829
- sh: echo "Run integration tests"
2930
- sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_8_coverage.xml test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
31+
- sh: dotnet test -f net48 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_48_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_48_coverage.xml --filter Name~Zlib test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
3032

3133
-
3234
matrix:

src/Renci.SshNet/Compression/Zlib.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
#if NET6_0_OR_GREATER
2-
using System.IO;
1+
using System.IO;
2+
#if NET6_0_OR_GREATER
33
using System.IO.Compression;
4+
#else
5+
using Org.BouncyCastle.Utilities.Zlib;
6+
#endif
47

58
namespace Renci.SshNet.Compression
69
{
@@ -11,8 +14,13 @@ namespace Renci.SshNet.Compression
1114
public class Zlib : Compressor
1215
#pragma warning restore CA1724 // Type names should not match namespaces
1316
{
17+
#if NET6_0_OR_GREATER
1418
private readonly ZLibStream _compressor;
1519
private readonly ZLibStream _decompressor;
20+
#else
21+
private readonly ZOutputStream _compressor;
22+
private readonly ZOutputStream _decompressor;
23+
#endif
1624
private MemoryStream _compressorStream;
1725
private MemoryStream _decompressorStream;
1826
private bool _isDisposed;
@@ -37,8 +45,13 @@ protected Zlib(bool delayedCompression)
3745
_compressorStream = new MemoryStream();
3846
_decompressorStream = new MemoryStream();
3947

48+
#if NET6_0_OR_GREATER
4049
_compressor = new ZLibStream(_compressorStream, CompressionMode.Compress);
4150
_decompressor = new ZLibStream(_decompressorStream, CompressionMode.Decompress);
51+
#else
52+
_compressor = new ZOutputStream(_compressorStream, level: JZlib.Z_DEFAULT_COMPRESSION) { FlushMode = JZlib.Z_PARTIAL_FLUSH };
53+
_decompressor = new ZOutputStream(_decompressorStream) { FlushMode = JZlib.Z_PARTIAL_FLUSH };
54+
#endif
4255
}
4356

4457
/// <inheritdoc/>
@@ -61,6 +74,7 @@ protected override byte[] CompressCore(byte[] data, int offset, int length)
6174
/// <inheritdoc/>
6275
protected override byte[] DecompressCore(byte[] data, int offset, int length)
6376
{
77+
#if NET6_0_OR_GREATER
6478
_decompressorStream.Write(data, offset, length);
6579
_decompressorStream.Position = 0;
6680

@@ -70,6 +84,14 @@ protected override byte[] DecompressCore(byte[] data, int offset, int length)
7084
_decompressorStream.SetLength(0);
7185

7286
return outputStream.ToArray();
87+
#else
88+
_decompressorStream.SetLength(0);
89+
90+
_decompressor.Write(data, offset, length);
91+
_decompressor.Flush();
92+
93+
return _decompressorStream.ToArray();
94+
#endif
7395
}
7496

7597
/// <summary>
@@ -106,4 +128,3 @@ protected override void Dispose(bool disposing)
106128
}
107129
}
108130
}
109-
#endif

src/Renci.SshNet/Compression/ZlibOpenSsh.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#if NET6_0_OR_GREATER
2-
namespace Renci.SshNet.Compression
1+
namespace Renci.SshNet.Compression
32
{
43
/// <summary>
54
/// Represents the "[email protected]" compression algorithm.
@@ -21,4 +20,3 @@ public override string Name
2120
}
2221
}
2322
}
24-
#endif

src/Renci.SshNet/ConnectionInfo.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,7 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
426426
CompressionAlgorithms = new Dictionary<string, Func<Compressor>>
427427
{
428428
{ "none", null },
429-
#if NET6_0_OR_GREATER
430429
{ "[email protected]", () => new ZlibOpenSsh() },
431-
#endif
432430
};
433431

434432
ChannelRequests = new Dictionary<string, RequestInfo>

test/Renci.SshNet.IntegrationTests/CompressionTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ public void None()
1919
DoTest(new KeyValuePair<string, Func<Compressor>>("none", null));
2020
}
2121

22-
#if NET6_0_OR_GREATER
2322
[TestMethod]
2423
public void ZlibOpenSsh()
2524
{
2625
DoTest(new KeyValuePair<string, Func<Compressor>>("[email protected]", () => new ZlibOpenSsh()));
2726
}
28-
#endif
2927

3028
private void DoTest(KeyValuePair<string, Func<Compressor>> compressor)
3129
{

0 commit comments

Comments
 (0)