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; } }