From aecce011e8a27ba4737737b273c53b8202442ef7 Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Tue, 31 Jan 2012 14:34:21 -0800 Subject: [PATCH] Fix #164: HttpContentCompressor accepts encodings whose qvalue is 0 --- .../codec/http/HttpContentCompressor.java | 40 +++++++++++++-- .../codec/http/HttpContentCompressorTest.java | 49 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java index 803c2c53b5..8f455234f2 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java @@ -83,12 +83,42 @@ public class HttpContentCompressor extends HttpContentEncoder { } private ZlibWrapper determineWrapper(String acceptEncoding) { - // FIXME: Use the Q value. - if (acceptEncoding.indexOf("gzip") >= 0) { - return ZlibWrapper.GZIP; + float starQ = -1.0f; + float gzipQ = -1.0f; + float deflateQ = -1.0f; + for (String encoding : acceptEncoding.split(",")) { + float q = 1.0f; + int equalsPos = encoding.indexOf('='); + if (equalsPos != -1) { + try { + q = Float.valueOf(encoding.substring(equalsPos + 1)); + } catch (NumberFormatException e) { + // Ignore encoding + q = 0.0f; + } + } + if (encoding.indexOf("*") >= 0) { + starQ = q; + } else if (encoding.indexOf("gzip") >= 0 && q > gzipQ) { + gzipQ = q; + } else if (encoding.indexOf("deflate") >= 0 && q > deflateQ) { + deflateQ = q; + } } - if (acceptEncoding.indexOf("deflate") >= 0) { - return ZlibWrapper.ZLIB; + if (gzipQ > 0.0f || deflateQ > 0.0f) { + if (gzipQ >= deflateQ) { + return ZlibWrapper.GZIP; + } else { + return ZlibWrapper.ZLIB; + } + } + if (starQ > 0.0f) { + if (gzipQ == -1.0f) { + return ZlibWrapper.GZIP; + } + if (deflateQ == -1.0f) { + return ZlibWrapper.ZLIB; + } } return null; } diff --git a/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java new file mode 100644 index 0000000000..3fb962ccab --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2011 The Netty Project + * + * The Netty Project 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.jboss.netty.handler.codec.http; + +import org.junit.Assert; +import org.junit.Test; + +public class HttpContentCompressorTest { + + private HttpContentCompressor httpContentCompressor = + new HttpContentCompressor(); + + @Test + public void testGetTargetContentEncoding() throws Exception { + HttpContentCompressor compressor = new HttpContentCompressor(); + + String[] tests = { + // Accept-Encoding -> Content-Encoding + "", null, + "*", "gzip", + "*;q=0.0", null, + "gzip", "gzip", + "compress, gzip;q=0.5", "gzip", + "gzip; q=0.5, identity", "gzip", + "gzip ; q=0.1", "gzip", + "gzip; q=0, deflate", "deflate", + " defalte ; q=0 , *;q=0.5", "gzip", + }; + for (int i = 0; i < tests.length; i += 2) { + String acceptEncoding = tests[i]; + String contentEncoding = tests[i + 1]; + String targetEncoding = compressor.getTargetContentEncoding(acceptEncoding); + Assert.assertEquals(contentEncoding, targetEncoding); + } + } +}