Skip to content

Commit

Permalink
Merge pull request payara#5407 from JamesHillyard/FISH-376
Browse files Browse the repository at this point in the history
FISH-376 Allow finer configuration details of HTTP GZIP compression
  • Loading branch information
JamesHillyard committed Oct 11, 2021
1 parent 5eadaa9 commit 48d861f
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 2 deletions.
10 changes: 9 additions & 1 deletion appserver/admingui/web/src/main/resources/grizzly/httpAttr.inc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
-->

<!-- Portions Copyright [2017-2018] [Payara Foundation and/or its affiliates.] -->
<!-- Portions Copyright [2017-2021] [Payara Foundation and/or its affiliates.] -->

<!-- grizzly/httpAttr.inc -->

Expand Down Expand Up @@ -167,6 +167,14 @@
<sun:dropDown id="Compression" selected="#{pageSession.httpMap['compression']}" labels={"on","off","force"} />
</sun:property>

<sun:property id="CompressionLevel" labelAlign="left" noWrap="#{true}" overlapLabel="#{false}" label="$resource{i18n_web.http.CompressionLevel}" helpText="$resource{i18n_web.http.CompressionLevelHelp}">
<sun:dropDown id="CompressionLevel" selected="#{pageSession.httpMap['compressionLevel']}" labels={"-1","0","1","2","3","4","5","6","7","8","9"} />
</sun:property>

<sun:property id="CompressionStrategy" labelAlign="left" noWrap="#{true}" overlapLabel="#{false}" label="$resource{i18n_web.http.CompressionStrategy}" helpText="$resource{i18n_web.http.CompressionStrategyHelp}">
<sun:dropDown id="compressionStrategy" selected="#{pageSession.httpMap['compressionStrategy']}" labels={"Default","Filtered","Huffman Only"} />
</sun:property>

<sun:property id="CompressableMimeType" labelAlign="left" noWrap="#{true}" overlapLabel="#{false}" label="$resource{i18n_web.http.CompressableMimeType}" helpText="$resource{i18n_web.http.CompressableMimeTypeHelp}" >
<sun:textField id="CompressableMimeType" columns="$int{50}" maxLength="#{sessionScope.fieldLengths['maxLength.http.CompressableMimeType']}" text="#{pageSession.httpMap['compressableMimeType']}" />
</sun:property>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# only if the new code is made subject to such option by the copyright
# holder.
#
# Portions Copyright [2016-2020] [Payara Foundation and/or its affiliates.]
# Portions Copyright [2016-2021] [Payara Foundation and/or its affiliates.]

button.GetStatistics=Get Statistics

Expand Down Expand Up @@ -316,6 +316,10 @@ http.Trace=Trace:
http.TraceHelp=Enable TRACE operation
http.Compression=Compression:
http.CompressionHelp=Enable HTTP/1.1 GZIP compression to save server bandwidth
http.CompressionLevel=Compression Level:
http.CompressionLevelHelp=-1 corresponds to the default level, 0 is no compression, 1 is best speed and 9 is best compression
http.CompressionStrategy=Compression Strategy:
http.CompressionStrategyHelp=Compression encoding strategy to be used
http.AuthPassThrough=Auth Pass Through:
http.AuthPassThroughHelp=Indicate that the network listener receives traffic from an SSL-terminating proxy server
http.Chunking=Chunking:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://github.com/payara/Payara/blob/master/LICENSE.txt
* See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* The Payara Foundation designates this particular file as subject to the "Classpath"
* exception as provided by the Payara Foundation in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package fish.payara.samples.http;

import com.gargoylesoftware.htmlunit.WebClient;
import fish.payara.samples.CliCommands;
import fish.payara.samples.PayaraArquillianTestRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;

import static org.junit.Assert.assertTrue;

/**
* @author James Hillyard
*/

@RunWith(PayaraArquillianTestRunner.class)
public class CompressionTest {
private static long uncompressedSize;
private long compressionLevelNegativeOne;
private long compressionLevelOne;
private long compressionLevelNine;

private static WebClient WEB_CLIENT;
private static final String URL = "http://localhost:8080";

private static final String CONFIG_COMPRESSION_STRATEGY =
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.compression-strategy=";
private static final String CONFIG_COMPRESSION_LEVEL =
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.compression-level=";

@BeforeClass
public static void beforeClass() throws Exception {
WEB_CLIENT = new WebClient();
WEB_CLIENT.getOptions().setThrowExceptionOnFailingStatusCode(false);
uncompressedSize = WEB_CLIENT.getPage(URL).getWebResponse().getContentLength();

CliCommands.payaraGlassFish("set",
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.http2-enabled=false");
CliCommands.payaraGlassFish("set",
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.compression=on");
WEB_CLIENT.addRequestHeader("Accept-Encoding", "gzip,deflate");
}

//Resets http-listener-1 back to its original state
@AfterClass
public static void afterClass() {
CliCommands.payaraGlassFish("set",
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.http2-enabled=true");
CliCommands.payaraGlassFish("set",
"configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.compression=off");
}

@Test
public void defaultCompressionStrategyLevelsTest() throws IOException {
CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_STRATEGY + "Default'");
getCompressionLevelValues();
//Check default compression is smaller than uncompressed
assertTrue(compressionLevelNegativeOne < uncompressedSize);
//Check fastest compression is bigger than default compression
assertTrue(compressionLevelOne > compressionLevelNegativeOne);
//Check fastest compression is bigger than best compression
assertTrue(compressionLevelOne > compressionLevelNine);
}

@Test
public void filteredCompressionStrategyLevelsTest() throws IOException {
CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_STRATEGY + "Filtered'");
getCompressionLevelValues();
//Check default compression is smaller than uncompressed
assertTrue(compressionLevelNegativeOne < uncompressedSize);
//Check fastest compression is bigger than default compression
assertTrue(compressionLevelOne > compressionLevelNegativeOne);
//Check fastest compression is bigger than best compression
assertTrue(compressionLevelOne > compressionLevelNine);
}

@Test
public void huffmanCompressionStrategyLevelsTest() throws IOException {
CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_STRATEGY + "Huffman Only'");
getCompressionLevelValues();
//Check default compression is smaller than uncompressed
assertTrue(compressionLevelNegativeOne < uncompressedSize);
//Huffman Only is not affected by compression level in this test case.
}

private void getCompressionLevelValues() throws IOException {
CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_LEVEL + "1'");
compressionLevelOne = WEB_CLIENT.getPage(URL).getWebResponse().getContentLength();

CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_LEVEL + "9'");
compressionLevelNine = WEB_CLIENT.getPage(URL).getWebResponse().getContentLength();

CliCommands.payaraGlassFish("set", "'" + CONFIG_COMPRESSION_LEVEL + "-1'");
compressionLevelNegativeOne = WEB_CLIENT.getPage(URL).getWebResponse().getContentLength();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,8 @@ public void configHttpProperties(Http http, Transport transport, Ssl ssl) {
setMaxSavePostSize(Integer.parseInt(http.getMaxSavePostSizeBytes()));
setProperty("compression", http.getCompression());
setProperty("compressableMimeType", http.getCompressableMimeType());
setProperty("compressionLevel", http.getCompressionLevel());
setProperty("compressionStrategy", http.getCompressionStrategy());
if (http.getNoCompressionUserAgents() != null) {
setProperty("noCompressionUserAgents", http.getNoCompressionUserAgents());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,8 @@ protected Set<ContentEncoding> configureContentEncodings(final Http http) {

protected Set<ContentEncoding> configureCompressionEncodings(Http http) {
final String mode = http.getCompression();
final int compressionStrategy = getCompressionStrategyAsInt(http.getCompressionStrategy());
final int compressionLevel = Integer.parseInt(http.getCompressionLevel());
int compressionMinSize = Integer.parseInt(http.getCompressionMinSizeBytes());
CompressionMode compressionMode;
try {
Expand Down Expand Up @@ -1123,6 +1125,8 @@ protected Set<ContentEncoding> configureCompressionEncodings(Http http) {
final ContentEncoding gzipContentEncoding = new GZipContentEncoding(
GZipContentEncoding.DEFAULT_IN_BUFFER_SIZE,
GZipContentEncoding.DEFAULT_OUT_BUFFER_SIZE,
compressionLevel,
compressionStrategy,
new CompressionEncodingFilter(compressionMode, compressionMinSize,
compressableMimeTypes,
noCompressionUserAgents,
Expand Down Expand Up @@ -1183,4 +1187,18 @@ private static SelectionKeyHandler getSelectionKeyHandlerByName(final String nam
}
return null;
}

private int getCompressionStrategyAsInt(String compressionStrategy) {
switch (compressionStrategy) {
case "Default":
return 0;
case "Filtered":
return 1;
case "Huffman Only":
return 2;
default:
LOGGER.severe("Compression Strategy had an unexpected value.");
throw new IllegalStateException("Unexpected value: " + compressionStrategy);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public interface Http extends ConfigBeanProxy, PropertyBag {
boolean ALLOW_PAYLOAD_FOR_UNDEFINED_HTTP_METHODS = false;

int COMPRESSION_MIN_SIZE = 2048;
int COMPRESSION_LEVEL = -1;
int CONNECTION_UPLOAD_TIMEOUT = 300000;
int HEADER_BUFFER_LENGTH = 8192;
int KEEP_ALIVE_TIMEOUT = 30;
Expand All @@ -95,6 +96,8 @@ public interface Http extends ConfigBeanProxy, PropertyBag {
String COMPRESSABLE_MIME_TYPE = "text/html,text/xml,text/plain";
String COMPRESSION = "off";
String COMPRESSION_PATTERN = "on|off|force|\\d+";
String COMPRESSION_STRATEGY = "Default";
String COMPRESSION_STRATEGY_PATTERN = "Filtered|Default|Huffman Only|\\d+";
String DEFAULT_ADAPTER = "org.glassfish.grizzly.http.server.StaticHttpHandler";
String URI_ENCODING = "UTF-8";
String SCHEME_PATTERN = "http|https";
Expand Down Expand Up @@ -150,6 +153,17 @@ public interface Http extends ConfigBeanProxy, PropertyBag {

void setCompression(String compression);

@Attribute(defaultValue = "" + COMPRESSION_LEVEL, dataType = Integer.class)
String getCompressionLevel();

void setCompressionLevel(String level);

@Attribute(defaultValue = COMPRESSION_STRATEGY, dataType = String.class)
@Pattern(regexp = COMPRESSION_STRATEGY_PATTERN)
String getCompressionStrategy();

void setCompressionStrategy(String compressionStrategy);

@Attribute(defaultValue = "" + COMPRESSION_MIN_SIZE, dataType = Integer.class)
String getCompressionMinSizeBytes();

Expand Down

0 comments on commit 48d861f

Please sign in to comment.