/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/ package org.apache.coyote;
/** * Set compression level. * * @param compression One of <code>on</code>, <code>force</code>, <code>off</code> or the minimum compression size * in bytes which implies <code>on</code>
*/ publicvoid setCompression(String compression) { if (compression.equals("on")) { this.compressionLevel = 1;
} elseif (compression.equals("force")) { this.compressionLevel = 2;
} elseif (compression.equals("off")) { this.compressionLevel = 0;
} else { try { // Try to parse compression as an int, which would give the // minimum compression size
setCompressionMinSize(Integer.parseInt(compression)); this.compressionLevel = 1;
} catch (Exception e) { this.compressionLevel = 0;
}
}
}
/** * Return compression level. * * @return The current compression level in string form (off/on/force)
*/ public String getCompression() { switch (compressionLevel) { case 0: return"off"; case 1: return"on"; case 2: return"force";
} return"off";
}
/** * Obtain the String form of the regular expression that defines the user agents to not use gzip with. * * @return The regular expression as a String
*/ public String getNoCompressionUserAgents() { if (noCompressionUserAgents == null) { returnnull;
} else { return noCompressionUserAgents.toString();
}
}
public Pattern getNoCompressionUserAgentsPattern() { return noCompressionUserAgents;
}
/** * Set no compression user agent pattern. Regular expression as supported by {@link Pattern}. e.g.: * <code>gorilla|desesplorer|tigrus</code>. * * @param noCompressionUserAgents The regular expression for user agent strings for which compression should not be * applied
*/ publicvoid setNoCompressionUserAgents(String noCompressionUserAgents) { if (noCompressionUserAgents == null || noCompressionUserAgents.length() == 0) { this.noCompressionUserAgents = null;
} else { this.noCompressionUserAgents = Pattern.compile(noCompressionUserAgents);
}
}
public String getCompressibleMimeType() { return compressibleMimeType;
}
/** * Set Minimum size to trigger compression. * * @param compressionMinSize The minimum content length required for compression in bytes
*/ publicvoid setCompressionMinSize(int compressionMinSize) { this.compressionMinSize = compressionMinSize;
}
/** * Determines if compression should be enabled for the given response and if it is, sets any necessary headers to * mark it as such. * * @param request The request that triggered the response * @param response The response to consider compressing * * @return {@code true} if compression was enabled for the given response, otherwise {@code false}
*/ publicboolean useCompression(Request request, Response response) { // Check if compression is enabled if (compressionLevel == 0) { returnfalse;
}
// Check if content is not already compressed
MessageBytes contentEncodingMB = responseHeaders.getValue("Content-Encoding"); if (contentEncodingMB != null) { // Content-Encoding values are ordered but order is not important // for this check so use a Set rather than a List
Set<String> tokens = new HashSet<>(); try {
TokenList.parseTokenList(responseHeaders.values("Content-Encoding"), tokens);
} catch (IOException e) { // Because we are using StringReader, any exception here is a // Tomcat bug.
log.warn(sm.getString("compressionConfig.ContentEncodingParseFail"), e); returnfalse;
} if (tokens.contains("gzip") || tokens.contains("br")) { returnfalse;
}
}
// If force mode, the length and MIME type checks are skipped if (compressionLevel != 2) { // Check if the response is of sufficient length to trigger the compression long contentLength = response.getContentLengthLong(); if (contentLength != -1 && contentLength < compressionMinSize) { returnfalse;
}
// Check for compatible MIME-TYPE
String[] compressibleMimeTypes = getCompressibleMimeTypes(); if (compressibleMimeTypes != null &&
!startsWithStringArray(compressibleMimeTypes, response.getContentType())) { returnfalse;
}
}
// Check if the resource has a strong ETag
String eTag = responseHeaders.getHeader("ETag"); if (eTag != null && !eTag.trim().startsWith("W/")) { // Has an ETag that doesn't start with "W/..." so it must be a // strong ETag returnfalse;
}
// If processing reaches this far, the response might be compressed. // Therefore, set the Vary header to keep proxies happy
ResponseUtil.addVaryFieldName(responseHeaders, "accept-encoding");
// Check if user-agent supports gzip encoding // Only interested in whether gzip encoding is supported. Other // encodings and weights can be ignored.
Enumeration<String> headerValues = request.getMimeHeaders().values("accept-encoding"); boolean foundGzip = false; while (!foundGzip && headerValues.hasMoreElements()) {
List<AcceptEncoding> acceptEncodings = null; try {
acceptEncodings = AcceptEncoding.parse(new StringReader(headerValues.nextElement()));
} catch (IOException ioe) { // If there is a problem reading the header, disable compression returnfalse;
}
for (AcceptEncoding acceptEncoding : acceptEncodings) { if ("gzip".equalsIgnoreCase(acceptEncoding.getEncoding())) {
foundGzip = true; break;
}
}
}
if (!foundGzip) { returnfalse;
}
// If force mode, the browser checks are skipped if (compressionLevel != 2) { // Check for incompatible Browser
Pattern noCompressionUserAgents = this.noCompressionUserAgents; if (noCompressionUserAgents != null) {
MessageBytes userAgentValueMB = request.getMimeHeaders().getValue("user-agent"); if (userAgentValueMB != null) {
String userAgentValue = userAgentValueMB.toString(); if (noCompressionUserAgents.matcher(userAgentValue).matches()) { returnfalse;
}
}
}
}
// All checks have passed. Compression is enabled.
// Compressed content length is unknown so mark it as such.
response.setContentLength(-1); // Configure the content encoding for compressed content
responseHeaders.setValue("Content-Encoding").setString("gzip");
returntrue;
}
/** * Checks if any entry in the string array starts with the specified value * * @param sArray the StringArray * @param value string
*/ privatestaticboolean startsWithStringArray(String sArray[], String value) { if (value == null) { returnfalse;
} for (String s : sArray) { if (value.startsWith(s)) { returntrue;
}
} returnfalse;
}
}
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.