Skip to content

Commit

Permalink
Add Constructor with custom compression level
Browse files Browse the repository at this point in the history
  • Loading branch information
marci4 committed Oct 22, 2024
1 parent 4f4aed5 commit dfca00b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@
import org.java_websocket.extensions.CompressionExtension;
import org.java_websocket.extensions.ExtensionRequestData;
import org.java_websocket.extensions.IExtension;
import org.java_websocket.framing.BinaryFrame;
import org.java_websocket.framing.CloseFrame;
import org.java_websocket.framing.ContinuousFrame;
import org.java_websocket.framing.DataFrame;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.FramedataImpl1;
import org.java_websocket.framing.TextFrame;

/**
* PerMessage Deflate Extension (<a href="https://tools.ietf.org/html/rfc7692#section-7">7&#46; The
Expand Down Expand Up @@ -53,28 +51,37 @@ public class PerMessageDeflateExtension extends CompressionExtension {
// For WebSocketClients, this variable holds the extension parameters that client himself has requested.
private Map<String, String> requestedParameters = new LinkedHashMap<>();

private int deflaterLevel = Deflater.DEFAULT_COMPRESSION;
private final int compressionLevel;

private Inflater inflater = new Inflater(true);
private Deflater deflater = new Deflater(this.deflaterLevel, true);
private final Inflater inflater;
private final Deflater deflater;

/**
* Get the compression level used for the compressor.
* @return the compression level (0-9)
* Constructor for the PerMessage Deflate Extension (<a href="https://tools.ietf.org/html/rfc7692#section-7">7&#46; Thepermessage-deflate" Extension</a>)
*
* Uses {@link java.util.zip.Deflater#DEFAULT_COMPRESSION} as the compression level for the {@link java.util.zip.Deflater#Deflater(int)}
*/
public PerMessageDeflateExtension() {
this(Deflater.DEFAULT_COMPRESSION);
}

/**
* Constructor for the PerMessage Deflate Extension (<a href="https://tools.ietf.org/html/rfc7692#section-7">7&#46; Thepermessage-deflate" Extension</a>)
*
* @param compressionLevel The compression level passed to the {@link java.util.zip.Deflater#Deflater(int)}
*/
public int getDeflaterLevel() {
return this.deflaterLevel;
public PerMessageDeflateExtension(int compressionLevel) {
this.compressionLevel = compressionLevel;
this.deflater = new Deflater(this.compressionLevel, true);
this.inflater = new Inflater(true);
}

/**
* Set the compression level used for the compressor.
* @param level the compression level (0-9)
* Get the compression level used for the compressor.
* @return the compression level
*/
public void setDeflaterLevel(int level) {
this.deflater.setLevel(level);
this.deflaterLevel = level;
//If the compression level is changed, the next invocation of deflate will compress the input available so far with the old level (and may be flushed); the new level will take effect only after that invocation.
this.deflater.deflate(new byte[0]);
public int getCompressionLevel() {
return this.compressionLevel;
}

/**
Expand Down Expand Up @@ -334,11 +341,10 @@ public String getProvidedExtensionAsServer() {

@Override
public IExtension copyInstance() {
PerMessageDeflateExtension clone = new PerMessageDeflateExtension();
PerMessageDeflateExtension clone = new PerMessageDeflateExtension(this.getCompressionLevel());
clone.setThreshold(this.getThreshold());
clone.setClientNoContextTakeover(this.isClientNoContextTakeover());
clone.setServerNoContextTakeover(this.isServerNoContextTakeover());
clone.setDeflaterLevel(this.getDeflaterLevel());
return clone;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.java_websocket.extensions;

import static java.util.zip.GZIPInputStream.GZIP_MAGIC;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand All @@ -10,10 +9,9 @@
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import org.java_websocket.exceptions.InvalidDataException;
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
import org.java_websocket.framing.BinaryFrame;
import org.java_websocket.framing.ContinuousFrame;
import org.java_websocket.framing.TextFrame;
import org.junit.Test;
Expand Down Expand Up @@ -55,8 +53,7 @@ public void testDecodeFrameIfRSVIsNotSet() throws InvalidDataException {

@Test
public void testDecodeFrameNoCompression() throws InvalidDataException {
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension();
deflateExtension.setDeflaterLevel(Deflater.NO_COMPRESSION);
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension(Deflater.NO_COMPRESSION);
deflateExtension.setThreshold(0);
String str = "This is a highly compressable text"
+ "This is a highly compressable text"
Expand All @@ -76,8 +73,7 @@ public void testDecodeFrameNoCompression() throws InvalidDataException {

@Test
public void testDecodeFrameBestSpeedCompression() throws InvalidDataException {
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension();
deflateExtension.setDeflaterLevel(Deflater.BEST_SPEED);
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension(Deflater.BEST_SPEED);
deflateExtension.setThreshold(0);
String str = "This is a highly compressable text"
+ "This is a highly compressable text"
Expand All @@ -103,8 +99,7 @@ public void testDecodeFrameBestSpeedCompression() throws InvalidDataException {

@Test
public void testDecodeFrameBestCompression() throws InvalidDataException {
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension();
deflateExtension.setDeflaterLevel(Deflater.BEST_COMPRESSION);
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension(Deflater.BEST_COMPRESSION);
deflateExtension.setThreshold(0);
String str = "This is a highly compressable text"
+ "This is a highly compressable text"
Expand All @@ -128,35 +123,6 @@ public void testDecodeFrameBestCompression() throws InvalidDataException {
assertArrayEquals(message, frame.getPayloadData().array());
}

@Test
public void testDecodeFrameSwitchCompression() throws InvalidDataException {
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension();
deflateExtension.setDeflaterLevel(Deflater.NO_COMPRESSION);
deflateExtension.setThreshold(0);
String str = "This is a highly compressable text"
+ "This is a highly compressable text"
+ "This is a highly compressable text"
+ "This is a highly compressable text"
+ "This is a highly compressable text";
byte[] message = str.getBytes();
TextFrame frame = new TextFrame();
frame.setPayload(ByteBuffer.wrap(message));

Deflater localDeflater = new Deflater(Deflater.BEST_COMPRESSION,true);
localDeflater.setInput(ByteBuffer.wrap(message).array());
byte[] buffer = new byte[1024];
int bytesCompressed = localDeflater.deflate(buffer, 0, buffer.length, Deflater.SYNC_FLUSH);

// Change the deflater level after the creation and switch to a new deflater level
// Compression strategy should be applied instantly since we call .deflate manually
deflateExtension.setDeflaterLevel(Deflater.BEST_COMPRESSION);
deflateExtension.encodeFrame(frame);
byte[] payloadArray = frame.getPayloadData().array();
assertArrayEquals(Arrays.copyOfRange(buffer,0, bytesCompressed), Arrays.copyOfRange(payloadArray,0,payloadArray.length));
assertTrue(frame.isRSV1());
deflateExtension.decodeFrame(frame);
assertArrayEquals(message, frame.getPayloadData().array());
}

@Test
public void testEncodeFrame() {
Expand Down Expand Up @@ -304,41 +270,31 @@ public void testCopyInstance() {
assertEquals(deflateExtension.getThreshold(), newDeflateExtension.getThreshold());
assertEquals(deflateExtension.isClientNoContextTakeover(), newDeflateExtension.isClientNoContextTakeover());
assertEquals(deflateExtension.isServerNoContextTakeover(), newDeflateExtension.isServerNoContextTakeover());
assertEquals(deflateExtension.getDeflaterLevel(), newDeflateExtension.getDeflaterLevel());
assertEquals(deflateExtension.getCompressionLevel(), newDeflateExtension.getCompressionLevel());


deflateExtension = new PerMessageDeflateExtension();
deflateExtension = new PerMessageDeflateExtension(Deflater.BEST_COMPRESSION);
deflateExtension.setThreshold(512);
deflateExtension.setServerNoContextTakeover(false);
deflateExtension.setClientNoContextTakeover(true);
deflateExtension.setDeflaterLevel(Deflater.BEST_COMPRESSION);
newDeflateExtension = (PerMessageDeflateExtension)deflateExtension.copyInstance();

assertEquals(deflateExtension.getThreshold(), newDeflateExtension.getThreshold());
assertEquals(deflateExtension.isClientNoContextTakeover(), newDeflateExtension.isClientNoContextTakeover());
assertEquals(deflateExtension.isServerNoContextTakeover(), newDeflateExtension.isServerNoContextTakeover());
assertEquals(deflateExtension.getDeflaterLevel(), newDeflateExtension.getDeflaterLevel());
assertEquals(deflateExtension.getCompressionLevel(), newDeflateExtension.getCompressionLevel());


deflateExtension = new PerMessageDeflateExtension();
deflateExtension = new PerMessageDeflateExtension(Deflater.NO_COMPRESSION);
deflateExtension.setThreshold(64);
deflateExtension.setServerNoContextTakeover(true);
deflateExtension.setClientNoContextTakeover(false);
deflateExtension.setDeflaterLevel(Deflater.NO_COMPRESSION);
newDeflateExtension = (PerMessageDeflateExtension)deflateExtension.copyInstance();

assertEquals(deflateExtension.getThreshold(), newDeflateExtension.getThreshold());
assertEquals(deflateExtension.isClientNoContextTakeover(), newDeflateExtension.isClientNoContextTakeover());
assertEquals(deflateExtension.isServerNoContextTakeover(), newDeflateExtension.isServerNoContextTakeover());
assertEquals(deflateExtension.getDeflaterLevel(), newDeflateExtension.getDeflaterLevel());
}

@Test
public void testDeflaterLevel() {
PerMessageDeflateExtension deflateExtension = new PerMessageDeflateExtension();
assertEquals(Deflater.DEFAULT_COMPRESSION, deflateExtension.getDeflaterLevel());
deflateExtension.setDeflaterLevel(Deflater.BEST_SPEED);
assertEquals(Deflater.BEST_SPEED, deflateExtension.getDeflaterLevel());
assertEquals(deflateExtension.getCompressionLevel(), newDeflateExtension.getCompressionLevel());
}

@Test
Expand All @@ -347,6 +303,6 @@ public void testDefaults() {
assertFalse(deflateExtension.isClientNoContextTakeover());
assertTrue(deflateExtension.isServerNoContextTakeover());
assertEquals(1024, deflateExtension.getThreshold());
assertEquals(Deflater.DEFAULT_COMPRESSION, deflateExtension.getDeflaterLevel());
assertEquals(Deflater.DEFAULT_COMPRESSION, deflateExtension.getCompressionLevel());
}
}

0 comments on commit dfca00b

Please sign in to comment.