Skip to content

[Zlib] Falls back to use BouncyCastle if BCL doesn't support #1453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Private keys can be encrypted using one of the following cipher methods:

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

## Framework Support

Expand Down
2 changes: 2 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ for:
- echo build
- dotnet build -f net8.0 -c Debug test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
- dotnet build -f net8.0 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
- dotnet build -f net48 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you run .NET Framework on Linux? :) You should run it on Windows.


test_script:
- sh: echo "Run unit tests"
- 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
- sh: echo "Run integration tests"
- 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
- 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.NET Framework 4.8 on Linux.


-
matrix:
Expand Down
27 changes: 24 additions & 3 deletions src/Renci.SshNet/Compression/Zlib.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#if NET6_0_OR_GREATER
using System.IO;
using System.IO;
#if NET6_0_OR_GREATER
using System.IO.Compression;
#else
using Org.BouncyCastle.Utilities.Zlib;
#endif

namespace Renci.SshNet.Compression
{
Expand All @@ -11,8 +14,13 @@ namespace Renci.SshNet.Compression
public class Zlib : Compressor
#pragma warning restore CA1724 // Type names should not match namespaces
{
#if NET6_0_OR_GREATER
private readonly ZLibStream _compressor;
private readonly ZLibStream _decompressor;
#else
private readonly ZOutputStream _compressor;
private readonly ZOutputStream _decompressor;
#endif
private MemoryStream _compressorStream;
private MemoryStream _decompressorStream;
private bool _isDisposed;
Expand All @@ -37,8 +45,13 @@ protected Zlib(bool delayedCompression)
_compressorStream = new MemoryStream();
_decompressorStream = new MemoryStream();

#if NET6_0_OR_GREATER
_compressor = new ZLibStream(_compressorStream, CompressionMode.Compress);
_decompressor = new ZLibStream(_decompressorStream, CompressionMode.Decompress);
#else
_compressor = new ZOutputStream(_compressorStream, level: JZlib.Z_DEFAULT_COMPRESSION) { FlushMode = JZlib.Z_PARTIAL_FLUSH };
_decompressor = new ZOutputStream(_decompressorStream) { FlushMode = JZlib.Z_PARTIAL_FLUSH };
#endif
}

/// <inheritdoc/>
Expand All @@ -61,6 +74,7 @@ protected override byte[] CompressCore(byte[] data, int offset, int length)
/// <inheritdoc/>
protected override byte[] DecompressCore(byte[] data, int offset, int length)
{
#if NET6_0_OR_GREATER
_decompressorStream.Write(data, offset, length);
_decompressorStream.Position = 0;

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

return outputStream.ToArray();
#else
_decompressorStream.SetLength(0);

_decompressor.Write(data, offset, length);
_decompressor.Flush();

return _decompressorStream.ToArray();
#endif
}

/// <summary>
Expand Down Expand Up @@ -106,4 +128,3 @@ protected override void Dispose(bool disposing)
}
}
}
#endif
4 changes: 1 addition & 3 deletions src/Renci.SshNet/Compression/ZlibOpenSsh.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if NET6_0_OR_GREATER
namespace Renci.SshNet.Compression
namespace Renci.SshNet.Compression
{
/// <summary>
/// Represents the "zlib@openssh.com" compression algorithm.
Expand All @@ -21,4 +20,3 @@ public override string Name
}
}
}
#endif
2 changes: 0 additions & 2 deletions src/Renci.SshNet/ConnectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,7 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
CompressionAlgorithms = new Dictionary<string, Func<Compressor>>
{
{ "none", null },
#if NET6_0_OR_GREATER
{ "zlib@openssh.com", () => new ZlibOpenSsh() },
#endif
};

ChannelRequests = new Dictionary<string, RequestInfo>
Expand Down
2 changes: 0 additions & 2 deletions test/Renci.SshNet.IntegrationTests/CompressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ public void None()
DoTest(new KeyValuePair<string, Func<Compressor>>("none", null));
}

#if NET6_0_OR_GREATER
[TestMethod]
public void ZlibOpenSsh()
{
DoTest(new KeyValuePair<string, Func<Compressor>>("zlib@openssh.com", () => new ZlibOpenSsh()));
}
#endif

private void DoTest(KeyValuePair<string, Func<Compressor>> compressor)
{
Expand Down