Skip to content

Commit

Permalink
Fix #5979 by allowing a configurable etag separator. (#5980)
Browse files Browse the repository at this point in the history
Signed-off-by: Greg Wilkins <gregw@webtide.com>
  • Loading branch information
gregw authored and olamy committed Feb 17, 2021
1 parent 9b28a4a commit 71fb369
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
Expand Up @@ -13,8 +13,21 @@

package org.eclipse.jetty.http;

import java.util.Objects;

import org.eclipse.jetty.util.StringUtil;

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 BR = new CompressedContentFormat("br", ".br");
public static final CompressedContentFormat[] NONE = new CompressedContentFormat[0];
Expand All @@ -27,11 +40,11 @@ public class CompressedContentFormat

public CompressedContentFormat(String encoding, String extension)
{
_encoding = encoding;
_extension = extension;
_etag = "--" + encoding;
_encoding = StringUtil.asciiToLowerCase(encoding);
_extension = StringUtil.asciiToLowerCase(extension);
_etag = ETAG_SEPARATOR + _encoding;
_etagQuote = _etag + "\"";
_contentEncoding = new PreEncodedHttpField(HttpHeader.CONTENT_ENCODING, encoding);
_contentEncoding = new PreEncodedHttpField(HttpHeader.CONTENT_ENCODING, _encoding);
}

@Override
Expand All @@ -40,22 +53,23 @@ public boolean equals(Object o)
if (!(o instanceof CompressedContentFormat))
return false;
CompressedContentFormat ccf = (CompressedContentFormat)o;
if (_encoding == null && ccf._encoding != null)
return false;
if (_extension == null && ccf._extension != null)
return false;
return Objects.equals(_encoding, ccf._encoding) && Objects.equals(_extension, ccf._extension);
}

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)
{
if (etag.equals(tag))
return true;

int dashdash = tag.indexOf("--");
if (dashdash > 0 && dashdash == etag.length() - 1)
return etag.regionMatches(0, tag, 0, dashdash);
int separator = tag.lastIndexOf(ETAG_SEPARATOR);
if (separator > 0 && separator == etag.length() - 1)
return etag.regionMatches(0, tag, 0, separator);
return false;
}
}
Expand Up @@ -119,6 +119,7 @@
* 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
* and sent to the User Agent.
* Note that the suffix used is determined by {@link CompressedContentFormat#ETAG_SEPARATOR}
* </p>
* <p>
* This implementation relies on an Jetty internal {@link org.eclipse.jetty.server.HttpOutput.Interceptor}
Expand Down
Expand Up @@ -26,6 +26,7 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

<<<<<<< HEAD
import jakarta.servlet.AsyncContext;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter;
Expand All @@ -39,6 +40,7 @@
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.CompressedContentFormat;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.LocalConnector;
Expand Down Expand Up @@ -82,7 +84,7 @@ public class GzipHandlerTest
private static final String __micro = __content.substring(0, 10);

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 Server _server;
Expand Down Expand Up @@ -585,7 +587,7 @@ public void testDeleteETagGzipHandler() throws Exception
request.setURI("/ctx/content");
request.setVersion("HTTP/1.0");
request.setHeader("Host", "tester");
request.setHeader("If-Match", "WrongEtag--gzip");
request.setHeader("If-Match", "WrongEtag" + CompressedContentFormat.GZIP._etag);
request.setHeader("accept-encoding", "gzip");

response = HttpTester.parseResponse(_connector.getResponse(request.generate()));
Expand Down

0 comments on commit 71fb369

Please sign in to comment.