in core/src/main/java/org/apache/cxf/transport/common/gzip/GZIPOutInterceptor.java [172:273]
public UseGzip gzipPermitted(Message message) {
UseGzip permitted = UseGzip.NO;
if (supportedPayloadContentTypes != null && message.containsKey(Message.CONTENT_TYPE)
&& !supportedPayloadContentTypes.contains(message.get(Message.CONTENT_TYPE))) {
return permitted;
}
if (MessageUtils.isRequestor(message)) {
LOG.fine("Requestor role, so gzip enabled");
Object o = message.getContextualProperty(USE_GZIP_KEY);
if (o instanceof UseGzip) {
permitted = (UseGzip)o;
} else if (o instanceof String) {
permitted = UseGzip.valueOf((String)o);
} else {
permitted = force ? UseGzip.YES : UseGzip.NO;
}
message.put(GZIP_ENCODING_KEY, "gzip");
addHeader(message, "Accept-Encoding", "gzip;q=1.0, identity; q=0.5, *;q=0");
} else {
LOG.fine("Response role, checking accept-encoding");
Exchange exchange = message.getExchange();
Message request = exchange.getInMessage();
Map<String, List<String>> requestHeaders = CastUtils.cast((Map<?, ?>)request
.get(Message.PROTOCOL_HEADERS));
if (requestHeaders != null) {
List<String> acceptEncodingHeader = CastUtils.cast(HttpHeaderHelper
.getHeader(requestHeaders, HttpHeaderHelper.ACCEPT_ENCODING));
List<String> jmsEncodingHeader = CastUtils.cast(requestHeaders.get(SOAP_JMS_CONTENTENCODING));
if (jmsEncodingHeader != null && jmsEncodingHeader.contains("gzip")) {
permitted = UseGzip.YES;
message.put(GZIP_ENCODING_KEY, "gzip");
}
if (acceptEncodingHeader != null) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Accept-Encoding header: " + acceptEncodingHeader);
}
// Accept-Encoding is a comma separated list of entries, so
// we split it into its component parts and build two
// lists, one with all the "q=0" encodings and the other
// with the rest (no q, or q=<non-zero>).
List<String> zeros = new ArrayList<>(3);
List<String> nonZeros = new ArrayList<>(3);
for (String headerLine : acceptEncodingHeader) {
String[] encodings = ENCODINGS.split(headerLine.trim());
for (String enc : encodings) {
Matcher m = ZERO_Q.matcher(enc);
if (m.find()) {
zeros.add(enc.substring(0, m.start()));
} else if (enc.indexOf(';') >= 0) {
nonZeros.add(enc.substring(0, enc.indexOf(';')));
} else {
nonZeros.add(enc);
}
}
}
// identity encoding is permitted if (a) it is not
// specifically disabled by an identity;q=0 and (b) if
// there is a *;q=0 then there is also an explicit
// identity[;q=<non-zero>]
//
// [x-]gzip is permitted if (a) there is an explicit
// [x-]gzip[;q=<non-zero>], or (b) there is a
// *[;q=<non-zero>] and no [x-]gzip;q=0 to disable it.
boolean identityEnabled = !zeros.contains("identity")
&& (!zeros.contains("*") || nonZeros.contains("identity"));
boolean gzipEnabled = nonZeros.contains("gzip")
|| (nonZeros.contains("*") && !zeros.contains("gzip"));
boolean xGzipEnabled = nonZeros.contains("x-gzip")
|| (nonZeros.contains("*") && !zeros.contains("x-gzip"));
if (identityEnabled && !gzipEnabled && !xGzipEnabled) {
permitted = UseGzip.NO;
} else if (identityEnabled && gzipEnabled) {
permitted = UseGzip.YES;
message.put(GZIP_ENCODING_KEY, "gzip");
} else if (identityEnabled && xGzipEnabled) {
permitted = UseGzip.YES;
message.put(GZIP_ENCODING_KEY, "x-gzip");
} else if (!identityEnabled && gzipEnabled) {
permitted = UseGzip.FORCE;
message.put(GZIP_ENCODING_KEY, "gzip");
} else if (!identityEnabled && xGzipEnabled) {
permitted = UseGzip.FORCE;
message.put(GZIP_ENCODING_KEY, "x-gzip");
} else {
throw new Fault(new org.apache.cxf.common.i18n.Message("NO_SUPPORTED_ENCODING",
BUNDLE));
}
} else {
LOG.fine("No accept-encoding header");
}
}
}
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("gzip permitted: " + permitted);
}
return permitted;
}