* Fix #5979 by allowing a configurable etag separator. Fix #5979 by allowing a configurable etag separator * updates from review * Updates from review Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
70d6724d93
commit
a8b4927427
|
@ -18,8 +18,21 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.http;
|
package org.eclipse.jetty.http;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
|
||||||
public class CompressedContentFormat
|
public class CompressedContentFormat
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The separator within an etag used to indicate a compressed variant. By default the separator is "--"
|
||||||
|
* So etag for compressed resource that normally has an etag of <code>W/"28c772d6"</code>
|
||||||
|
* is <code>W/"28c772d6--gzip"</code>. The separator may be changed by the
|
||||||
|
* "org.eclipse.jetty.http.CompressedContentFormat.ETAG_SEPARATOR" System property. If changed, it should be changed to a string
|
||||||
|
* that will not be found in a normal etag or at least is very unlikely to be a substring of a normal etag.
|
||||||
|
*/
|
||||||
|
public static final String ETAG_SEPARATOR = System.getProperty(CompressedContentFormat.class.getName() + ".ETAG_SEPARATOR", "--");
|
||||||
|
|
||||||
public static final CompressedContentFormat GZIP = new CompressedContentFormat("gzip", ".gz");
|
public static final CompressedContentFormat GZIP = new CompressedContentFormat("gzip", ".gz");
|
||||||
public static final CompressedContentFormat BR = new CompressedContentFormat("br", ".br");
|
public static final CompressedContentFormat BR = new CompressedContentFormat("br", ".br");
|
||||||
public static final CompressedContentFormat[] NONE = new CompressedContentFormat[0];
|
public static final CompressedContentFormat[] NONE = new CompressedContentFormat[0];
|
||||||
|
@ -32,11 +45,11 @@ public class CompressedContentFormat
|
||||||
|
|
||||||
public CompressedContentFormat(String encoding, String extension)
|
public CompressedContentFormat(String encoding, String extension)
|
||||||
{
|
{
|
||||||
_encoding = encoding;
|
_encoding = StringUtil.asciiToLowerCase(encoding);
|
||||||
_extension = extension;
|
_extension = StringUtil.asciiToLowerCase(extension);
|
||||||
_etag = "--" + encoding;
|
_etag = ETAG_SEPARATOR + _encoding;
|
||||||
_etagQuote = _etag + "\"";
|
_etagQuote = _etag + "\"";
|
||||||
_contentEncoding = new PreEncodedHttpField(HttpHeader.CONTENT_ENCODING, encoding);
|
_contentEncoding = new PreEncodedHttpField(HttpHeader.CONTENT_ENCODING, _encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,12 +58,13 @@ public class CompressedContentFormat
|
||||||
if (!(o instanceof CompressedContentFormat))
|
if (!(o instanceof CompressedContentFormat))
|
||||||
return false;
|
return false;
|
||||||
CompressedContentFormat ccf = (CompressedContentFormat)o;
|
CompressedContentFormat ccf = (CompressedContentFormat)o;
|
||||||
if (_encoding == null && ccf._encoding != null)
|
return Objects.equals(_encoding, ccf._encoding) && Objects.equals(_extension, ccf._extension);
|
||||||
return false;
|
}
|
||||||
if (_extension == null && ccf._extension != null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return _encoding.equalsIgnoreCase(ccf._encoding) && _extension.equalsIgnoreCase(ccf._extension);
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(_encoding, _extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean tagEquals(String etag, String tag)
|
public static boolean tagEquals(String etag, String tag)
|
||||||
|
@ -58,9 +72,9 @@ public class CompressedContentFormat
|
||||||
if (etag.equals(tag))
|
if (etag.equals(tag))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int dashdash = tag.indexOf("--");
|
int separator = tag.lastIndexOf(ETAG_SEPARATOR);
|
||||||
if (dashdash > 0 && dashdash == etag.length() - 1)
|
if (separator > 0 && separator == etag.length() - 1)
|
||||||
return etag.regionMatches(0, tag, 0, dashdash);
|
return etag.regionMatches(0, tag, 0, separator);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* If a ETag is present in the Response headers, and GzipHandler is compressing the
|
* If a ETag is present in the Response headers, and GzipHandler is compressing the
|
||||||
* contents, it will add the {@code --gzip} suffix before the Response headers are committed
|
* contents, it will add the {@code --gzip} suffix before the Response headers are committed
|
||||||
* and sent to the User Agent.
|
* and sent to the User Agent.
|
||||||
|
* Note that the suffix used is determined by {@link CompressedContentFormat#ETAG_SEPARATOR}
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* This implementation relies on an Jetty internal {@link org.eclipse.jetty.server.HttpOutput.Interceptor}
|
* This implementation relies on an Jetty internal {@link org.eclipse.jetty.server.HttpOutput.Interceptor}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.CompressedContentFormat;
|
||||||
import org.eclipse.jetty.http.HttpTester;
|
import org.eclipse.jetty.http.HttpTester;
|
||||||
import org.eclipse.jetty.server.HttpOutput;
|
import org.eclipse.jetty.server.HttpOutput;
|
||||||
import org.eclipse.jetty.server.LocalConnector;
|
import org.eclipse.jetty.server.LocalConnector;
|
||||||
|
@ -87,7 +88,7 @@ public class GzipHandlerTest
|
||||||
private static final String __micro = __content.substring(0, 10);
|
private static final String __micro = __content.substring(0, 10);
|
||||||
|
|
||||||
private static final String __contentETag = String.format("W/\"%x\"", __content.hashCode());
|
private static final String __contentETag = String.format("W/\"%x\"", __content.hashCode());
|
||||||
private static final String __contentETagGzip = String.format("W/\"%x--gzip\"", __content.hashCode());
|
private static final String __contentETagGzip = String.format("W/\"%x" + CompressedContentFormat.GZIP._etag + "\"", __content.hashCode());
|
||||||
private static final String __icontent = "BEFORE" + __content + "AFTER";
|
private static final String __icontent = "BEFORE" + __content + "AFTER";
|
||||||
|
|
||||||
private Server _server;
|
private Server _server;
|
||||||
|
@ -591,7 +592,7 @@ public class GzipHandlerTest
|
||||||
request.setURI("/ctx/content");
|
request.setURI("/ctx/content");
|
||||||
request.setVersion("HTTP/1.0");
|
request.setVersion("HTTP/1.0");
|
||||||
request.setHeader("Host", "tester");
|
request.setHeader("Host", "tester");
|
||||||
request.setHeader("If-Match", "WrongEtag--gzip");
|
request.setHeader("If-Match", "WrongEtag" + CompressedContentFormat.GZIP._etag);
|
||||||
request.setHeader("accept-encoding", "gzip");
|
request.setHeader("accept-encoding", "gzip");
|
||||||
|
|
||||||
response = HttpTester.parseResponse(_connector.getResponse(request.generate()));
|
response = HttpTester.parseResponse(_connector.getResponse(request.generate()));
|
||||||
|
|
Loading…
Reference in New Issue