mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
compression cleanups
This commit is contained in:
@@ -74,7 +74,7 @@ abstract class Converter {
|
||||
this.mac = mac;
|
||||
this.compression = compression;
|
||||
if (compression != null)
|
||||
compression.init(getCompressionType(), -1);
|
||||
compression.init(getCompressionType());
|
||||
this.cipherSize = cipher.getIVSize();
|
||||
}
|
||||
|
||||
@@ -86,6 +86,6 @@ abstract class Converter {
|
||||
return compression != null && (authed || !compression.isDelayed());
|
||||
}
|
||||
|
||||
abstract Compression.Type getCompressionType();
|
||||
abstract Compression.Mode getCompressionType();
|
||||
|
||||
}
|
||||
@@ -199,8 +199,8 @@ final class Decoder
|
||||
}
|
||||
|
||||
@Override
|
||||
Compression.Type getCompressionType() {
|
||||
return Compression.Type.Inflater;
|
||||
Compression.Mode getCompressionType() {
|
||||
return Compression.Mode.INFLATE;
|
||||
}
|
||||
|
||||
int getMaxPacketLength() {
|
||||
|
||||
@@ -160,9 +160,8 @@ final class Encoder
|
||||
}
|
||||
|
||||
@Override
|
||||
Compression.Type getCompressionType() {
|
||||
return Compression.Type.Deflater;
|
||||
Compression.Mode getCompressionType() {
|
||||
return Compression.Mode.DEFLATE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -35,34 +35,26 @@
|
||||
*/
|
||||
package net.schmizz.sshj.transport.compression;
|
||||
|
||||
import net.schmizz.sshj.common.SSHPacket;
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
import net.schmizz.sshj.transport.TransportException;
|
||||
|
||||
/** Interface used to compress the stream of data between the SSH server and clients. */
|
||||
public interface Compression {
|
||||
|
||||
/** Enum identifying if this object will be used to compress or uncompress data. */
|
||||
enum Type {
|
||||
Inflater,
|
||||
Deflater
|
||||
enum Mode {
|
||||
INFLATE,
|
||||
DEFLATE
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the given buffer in place.
|
||||
*
|
||||
* @param buffer the buffer containing the data to compress s
|
||||
*/
|
||||
void compress(SSHPacket buffer);
|
||||
|
||||
/**
|
||||
* Initialize this object to either compress or uncompress data. This method must be called prior to any calls to
|
||||
* either <code>compress</code> or <code>uncompress</code>. Once the object has been initialized, only one of
|
||||
* <code>compress</code> or <code>uncompress</code> method can be called.
|
||||
*
|
||||
* @param type
|
||||
* @param level
|
||||
* @param mode
|
||||
*/
|
||||
void init(Type type, int level);
|
||||
void init(Mode mode);
|
||||
|
||||
/**
|
||||
* Delayed compression is an Open-SSH specific feature which informs both the client and server to not compress data
|
||||
@@ -72,13 +64,22 @@ public interface Compression {
|
||||
*/
|
||||
boolean isDelayed();
|
||||
|
||||
/**
|
||||
* Compress the given buffer in place.
|
||||
*
|
||||
* @param buffer the buffer containing the data to compress s
|
||||
*/
|
||||
void compress(Buffer buffer);
|
||||
|
||||
/**
|
||||
* Uncompress the data in a buffer into another buffer.
|
||||
*
|
||||
* @param from the buffer containing the data to uncompress
|
||||
* @param to the buffer receiving the uncompressed data
|
||||
*
|
||||
* @throws TransportException
|
||||
*/
|
||||
void uncompress(SSHPacket from, SSHPacket to)
|
||||
void uncompress(Buffer from, Buffer to)
|
||||
throws TransportException;
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ package net.schmizz.sshj.transport.compression;
|
||||
|
||||
import com.jcraft.jzlib.JZlib;
|
||||
import com.jcraft.jzlib.ZStream;
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
import net.schmizz.sshj.common.DisconnectReason;
|
||||
import net.schmizz.sshj.common.SSHPacket;
|
||||
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||
import net.schmizz.sshj.transport.TransportException;
|
||||
|
||||
@@ -58,64 +58,65 @@ public class ZlibCompression
|
||||
}
|
||||
}
|
||||
|
||||
static private final int BUF_SIZE = 4096;
|
||||
private static final int BUF_SIZE = 4096;
|
||||
|
||||
private final byte[] tempBuf = new byte[BUF_SIZE];
|
||||
|
||||
private ZStream stream;
|
||||
private final byte[] tmpbuf = new byte[BUF_SIZE];
|
||||
|
||||
/** Create a new instance of a ZLib base compression */
|
||||
public ZlibCompression() {
|
||||
}
|
||||
|
||||
public void compress(SSHPacket buffer) {
|
||||
stream.next_in = buffer.array();
|
||||
stream.next_in_index = buffer.rpos();
|
||||
stream.avail_in = buffer.available();
|
||||
buffer.wpos(buffer.rpos());
|
||||
do {
|
||||
stream.next_out = tmpbuf;
|
||||
stream.next_out_index = 0;
|
||||
stream.avail_out = BUF_SIZE;
|
||||
int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
|
||||
switch (status) {
|
||||
case JZlib.Z_OK:
|
||||
buffer.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
|
||||
public void init(Mode mode) {
|
||||
stream = new ZStream();
|
||||
switch (mode) {
|
||||
case DEFLATE:
|
||||
stream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION);
|
||||
break;
|
||||
case INFLATE:
|
||||
stream.inflateInit();
|
||||
break;
|
||||
default:
|
||||
throw new SSHRuntimeException("compress: deflate returned " + status);
|
||||
assert false;
|
||||
}
|
||||
} while (stream.avail_out == 0);
|
||||
}
|
||||
|
||||
public void init(Type type, int level) {
|
||||
stream = new ZStream();
|
||||
if (type == Type.Deflater)
|
||||
stream.deflateInit(level);
|
||||
else
|
||||
stream.inflateInit();
|
||||
}
|
||||
|
||||
public boolean isDelayed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void uncompress(SSHPacket from, SSHPacket to)
|
||||
public void compress(Buffer buffer) {
|
||||
stream.next_in = buffer.array();
|
||||
stream.next_in_index = buffer.rpos();
|
||||
stream.avail_in = buffer.available();
|
||||
buffer.wpos(buffer.rpos());
|
||||
do {
|
||||
stream.next_out = tempBuf;
|
||||
stream.next_out_index = 0;
|
||||
stream.avail_out = BUF_SIZE;
|
||||
final int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
|
||||
if (status == JZlib.Z_OK) {
|
||||
buffer.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
|
||||
} else {
|
||||
throw new SSHRuntimeException("compress: deflate returned " + status);
|
||||
}
|
||||
} while (stream.avail_out == 0);
|
||||
}
|
||||
|
||||
|
||||
public void uncompress(Buffer from, Buffer to)
|
||||
throws TransportException {
|
||||
stream.next_in = from.array();
|
||||
stream.next_in_index = from.rpos();
|
||||
stream.avail_in = from.available();
|
||||
|
||||
while (true) {
|
||||
stream.next_out = tmpbuf;
|
||||
stream.next_out = tempBuf;
|
||||
stream.next_out_index = 0;
|
||||
stream.avail_out = BUF_SIZE;
|
||||
int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
|
||||
final int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
|
||||
switch (status) {
|
||||
case JZlib.Z_OK:
|
||||
to.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
|
||||
to.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
|
||||
break;
|
||||
case JZlib.Z_BUF_ERROR:
|
||||
return; // wtf.. but this works *head spins*
|
||||
return;
|
||||
default:
|
||||
throw new TransportException(DisconnectReason.COMPRESSION_ERROR, "uncompress: inflate returned "
|
||||
+ status);
|
||||
|
||||
Reference in New Issue
Block a user