package io.dropwizard.jetty;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.util.DataSize;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import javax.annotation.Nullable;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.Deflater;
import static java.util.Objects.requireNonNull;
Builds GZIP filters.
Configuration Parameters:
Name
Default
Description
enabled
true
If true, all requests with `gzip` in the `Accept-Encoding` header will have their
response entities compressed and requests with `gzip` in the `Content-Encoding`
header will have their request entities decompressed.
minimumEntitySize
256 bytes
All response entities under this DataSize are not compressed.
bufferSize
8KiB
The DataSize of the buffer to use when compressing.
excludedUserAgentPatterns
(Jetty's default)
A list of regex patterns for User-Agent names from which requests should not be compressed. The default is [".*MSIE 6.0.*"]
compressedMimeTypes
(Jetty's default)
List of MIME types to compress. The default is all types apart the
commonly known image, video, audio and compressed types.
excludedMimeTypes
(Jetty's default)
List of MIME types not to compress. The default is a list of commonly known image, video, audio and
compressed types.
includedPaths
(Jetty's default)
List of paths to consider for compression. The default is all paths.
excludedPaths
(none)
List of paths to exclude from compression. Performs a String.startsWith(String)
comparison to check if the path matches. If it does match then there is no compression. To match subpaths use excludePathPatterns instead.
includedMethods
(Jetty's default)
The list list of HTTP methods to compress. The default is to compress
only GET responses.
deflateCompressionLevel
-1
The compression level used for deflation(compression).
gzipCompatibleInflation
true
This option is unused and deprecated as compressed requests without header info are unsupported
/**
* Builds GZIP filters.
*
* <p/>
* <b>Configuration Parameters:</b>
* <table>
* <tr>
* <td>Name</td>
* <td>Default</td>
* <td>Description</td>
* </tr>
* <tr>
* <td>{@code enabled}</td>
* <td>true</td>
* <td>If true, all requests with `gzip` in the `Accept-Encoding` header will have their
* response entities compressed and requests with `gzip` in the `Content-Encoding`
* header will have their request entities decompressed.</td>
* </tr>
* <tr>
* <td>{@code minimumEntitySize}</td>
* <td>256 bytes</td>
* <td>All response entities under this DataSize are not compressed.</td>
* </tr>
* <tr>
* <td>{@code bufferSize}</td>
* <td>8KiB</td>
* <td>The DataSize of the buffer to use when compressing.</td>
* </tr>
* <tr>
* <td>{@code excludedUserAgentPatterns}</td>
* <td>(Jetty's default)</td>
* <td>A list of regex patterns for User-Agent names from which requests should not be compressed. The default
* is {@code [".*MSIE 6.0.*"]}</td>
* </tr>
* <tr>
* <td>{@code compressedMimeTypes}</td>
* <td>(Jetty's default)</td>
* <td>List of MIME types to compress. The default is all types apart the
* commonly known image, video, audio and compressed types.</td>
* </tr>
* <tr>
* <td>{@code excludedMimeTypes}</td>
* <td>(Jetty's default)</td>
* <td>List of MIME types not to compress. The default is a list of commonly known image, video, audio and
* compressed types.</td>
* </tr>
* <tr>
* <td>{@code includedPaths}</td>
* <td>(Jetty's default)</td>
* <td>List of paths to consider for compression. The default is all paths.</td>
* </tr>
* <tr>
* <td>{@code excludedPaths}</td>
* <td>(none)</td>
* <td>List of paths to exclude from compression. Performs a {@code String.startsWith(String)} comparison to
* check if the path matches. If it does match then there is no compression. To match subpaths use
* excludePathPatterns instead.</td>
* </tr>
* <tr>
* <td>{@code includedMethods}</td>
* <td>(Jetty's default)</td>
* <td>The list list of HTTP methods to compress. The default is to compress
* only GET responses.</td>
* </tr>
* <tr>
* <td>{@code deflateCompressionLevel}</td>
* <td>-1</td>
* <td>The compression level used for deflation(compression).</td>
* </tr>
* <tr>
* <td>{@code gzipCompatibleInflation}</td>
* <td>true</td>
* <td>This option is unused and deprecated as compressed requests without header info are unsupported</td>
* </tr>
* </table>
*/
public class GzipHandlerFactory {
private boolean enabled = true;
@NotNull
private DataSize minimumEntitySize = DataSize.bytes(256);
@NotNull
private DataSize bufferSize = DataSize.kibibytes(8);
// By default compress responses for all user-agents
private Set<String> excludedUserAgentPatterns = new HashSet<>();
@Nullable
private Set<String> compressedMimeTypes;
@Nullable
private Set<String> excludedMimeTypes;
@Nullable
private Set<String> includedMethods;
@Nullable
private Set<String> excludedPaths;
@Nullable
private Set<String> includedPaths;
@Min(Deflater.DEFAULT_COMPRESSION)
@Max(Deflater.BEST_COMPRESSION)
private int deflateCompressionLevel = Deflater.DEFAULT_COMPRESSION;
private boolean gzipCompatibleInflation = true;
private boolean syncFlush = false;
@JsonProperty
public boolean isEnabled() {
return enabled;
}
@JsonProperty
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@JsonProperty
public DataSize getMinimumEntitySize() {
return minimumEntitySize;
}
@JsonProperty
public void setMinimumEntitySize(DataSize size) {
this.minimumEntitySize = requireNonNull(size);
}
@JsonProperty
public DataSize getBufferSize() {
return bufferSize;
}
@JsonProperty
public void setBufferSize(DataSize size) {
this.bufferSize = requireNonNull(size);
}
@JsonProperty
@Nullable
public Set<String> getCompressedMimeTypes() {
return compressedMimeTypes;
}
@JsonProperty
public void setCompressedMimeTypes(Set<String> mimeTypes) {
this.compressedMimeTypes = mimeTypes;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
@Nullable
public Set<String> getExcludedMimeTypes() {
return excludedMimeTypes;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
public void setExcludedMimeTypes(Set<String> mimeTypes) {
this.excludedMimeTypes = mimeTypes;
}
@JsonProperty
public int getDeflateCompressionLevel() {
return deflateCompressionLevel;
}
@JsonProperty
public void setDeflateCompressionLevel(int level) {
this.deflateCompressionLevel = level;
}
Deprecated: gzip handler no longer supports inflate streams
/**
* @deprecated gzip handler no longer supports inflate streams
*/
@JsonProperty
public boolean isGzipCompatibleInflation() {
return gzipCompatibleInflation;
}
Deprecated: gzip handler no longer supports inflate streams
/**
* @deprecated gzip handler no longer supports inflate streams
*/
@Deprecated
@JsonProperty
public void setGzipCompatibleInflation(boolean gzipCompatibleInflation) {
this.gzipCompatibleInflation = gzipCompatibleInflation;
}
public Set<String> getExcludedUserAgentPatterns() {
return excludedUserAgentPatterns;
}
public void setExcludedUserAgentPatterns(Set<String> excludedUserAgentPatterns) {
this.excludedUserAgentPatterns = excludedUserAgentPatterns;
}
@JsonProperty
@Nullable
public Set<String> getIncludedMethods() {
return includedMethods;
}
@JsonProperty
public void setIncludedMethods(Set<String> methods) {
this.includedMethods = methods;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
@Nullable
public Set<String> getExcludedPaths() {
return excludedPaths;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
public void setExcludedPaths(Set<String> paths) {
this.excludedPaths = paths;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
@Nullable
public Set<String> getIncludedPaths() {
return includedPaths;
}
Since: 2.0
/**
* @since 2.0
*/
@JsonProperty
public void setIncludedPaths(Set<String> paths) {
this.includedPaths = paths;
}
@JsonProperty
public boolean isSyncFlush() {
return syncFlush;
}
@JsonProperty
public void setSyncFlush(boolean syncFlush) {
this.syncFlush = syncFlush;
}
public GzipHandler build(@Nullable Handler handler) {
final GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(handler);
gzipHandler.setMinGzipSize((int) minimumEntitySize.toBytes());
gzipHandler.setInflateBufferSize((int) bufferSize.toBytes());
gzipHandler.setCompressionLevel(deflateCompressionLevel);
gzipHandler.setSyncFlush(syncFlush);
if (compressedMimeTypes != null) {
gzipHandler.setIncludedMimeTypes(compressedMimeTypes.toArray(new String[0]));
}
if (excludedMimeTypes != null) {
gzipHandler.setExcludedMimeTypes(excludedMimeTypes.toArray(new String[0]));
}
if (includedMethods != null) {
gzipHandler.setIncludedMethods(includedMethods.toArray(new String[0]));
}
if (excludedPaths != null) {
gzipHandler.setExcludedPaths(excludedPaths.toArray(new String[0]));
}
if (includedPaths != null) {
gzipHandler.setIncludedPaths(includedPaths.toArray(new String[0]));
}
gzipHandler.setExcludedAgentPatterns(excludedUserAgentPatterns.toArray(new String[0]));
return gzipHandler;
}
}