Skip to content

Commit

Permalink
Merge branch 'jetty-12.0.x' of github.com:jetty/jetty.project into je…
Browse files Browse the repository at this point in the history
…tty-12.0.x
  • Loading branch information
joakime committed Jan 29, 2024
2 parents 64964b6 + b4c260a commit 51824f6
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
[cols="1a,1a", options="header"]
|===
| Jetty 11.0.x | Jetty 12.0.x
| org.eclipse.jetty.fcgi:**fcgi-client** | org.eclipse.jetty.http2:**jetty-fcgi-client**
| org.eclipse.jetty.fcgi:**fcgi-server** | org.eclipse.jetty.http2:**jetty-fcgi-server**
| org.eclipse.jetty.fcgi:**fcgi-client** | org.eclipse.jetty.fcgi:**jetty-fcgi-client**
| org.eclipse.jetty.fcgi:**fcgi-server** | org.eclipse.jetty.fcgi:**jetty-fcgi-server**
| org.eclipse.jetty.http2:**http2-client** | org.eclipse.jetty.http2:**jetty-http2-client**
| org.eclipse.jetty.http2:**http2-common** | org.eclipse.jetty.http2:**jetty-http2-common**
| org.eclipse.jetty.http2:**http2-hpack** | org.eclipse.jetty.http2:**jetty-http2-hpack**
Expand Down Expand Up @@ -69,16 +69,16 @@
| org.eclipse.jetty:**jetty-ant** | Removed -- No Replacement
| org.eclipse.jetty:**jetty-cdi** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-cdi**
| org.eclipse.jetty:**glassfish-jstl** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-glassfish-jstl**
| org.eclipse.jetty:**jetty-jaspi** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-jaspi**
| org.eclipse.jetty:**jetty-jndi** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-jndi**
| org.eclipse.jetty:**jetty-jspc-maven-plugin** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-jspc-maven-plugin**
| org.eclipse.jetty:**jetty-maven-plugin** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-maven-plugin**
| org.eclipse.jetty:**jetty-plus** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-plus**
| org.eclipse.jetty:**jetty-quickstart** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-quickstart**
| org.eclipse.jetty:**jetty-runner** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-runner**
| org.eclipse.jetty:**jetty-servlet** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-servlet**
| org.eclipse.jetty:**jetty-servlets** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-servlets**
| org.eclipse.jetty:**jetty-webapp** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jetty-webapp**
| org.eclipse.jetty:**jetty-jaspi** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jaspi**
| org.eclipse.jetty:**jetty-jndi** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jndi**
| org.eclipse.jetty:**jetty-jspc-maven-plugin** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-jspc-maven-plugin**
| org.eclipse.jetty:**jetty-maven-plugin** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-maven-plugin**
| org.eclipse.jetty:**jetty-plus** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-plus**
| org.eclipse.jetty:**jetty-quickstart** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-quickstart**
| org.eclipse.jetty:**jetty-runner** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-runner**
| org.eclipse.jetty:**jetty-servlet** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-servlet**
| org.eclipse.jetty:**jetty-servlets** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-servlets**
| org.eclipse.jetty:**jetty-webapp** | org.eclipse.jetty.**{ee-all}**:**jetty-{ee-all}-webapp**
|===

[[pg-migration-11-to-12-class-packages-names]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bcpio=application/x-bcpio
bin=application/octet-stream
bmp=image/bmp
br=application/brotli
bz2=application/x-bzip2
cab=application/x-cabinet
cdf=application/x-netcdf
chm=application/vnd.ms-htmlhelp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ static Response getOriginalResponse(Response response)

/**
* @param response the HTTP response
* @return the number of response content bytes written so far,
* @return the number of response content bytes written to the network so far,
* or {@code -1} if the number is unknown
*/
static long getContentBytesWritten(Response response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class GzipHandler extends Handler.Wrapper implements GzipFactory
private final IncludeExclude<String> _inflatePaths = new IncludeExclude<>(PathSpecSet.class);
private final IncludeExclude<String> _paths = new IncludeExclude<>(PathSpecSet.class);
private final IncludeExclude<String> _mimeTypes = new IncludeExclude<>(AsciiLowerCaseSet.class);
private HttpField _vary = GzipResponseAndCallback.VARY_ACCEPT_ENCODING;
private HttpField _vary = new PreEncodedHttpField(HttpHeader.VARY, HttpHeader.ACCEPT_ENCODING.asString());

/**
* Instantiates a new GzipHandler.
Expand Down Expand Up @@ -88,7 +88,7 @@ else if (type.startsWith("image/") ||
_mimeTypes.exclude("application/compress");
_mimeTypes.exclude("application/zip");
_mimeTypes.exclude("application/gzip");
_mimeTypes.exclude("application/bzip2");
_mimeTypes.exclude("application/x-bzip2");
_mimeTypes.exclude("application/brotli");
_mimeTypes.exclude("application/x-xz");
_mimeTypes.exclude("application/x-rar-compressed");
Expand Down Expand Up @@ -380,14 +380,16 @@ public DeflaterPool.Entry getDeflaterEntry(Request request, long contentLength)
{
if (contentLength >= 0 && contentLength < _minGzipSize)
{
LOG.debug("{} excluded minGzipSize {}", this, request);
if (LOG.isDebugEnabled())
LOG.debug("{} excluded minGzipSize {}", this, request);
return null;
}

// check the accept encoding header
if (!request.getHeaders().contains(HttpHeader.ACCEPT_ENCODING, "gzip"))
{
LOG.debug("{} excluded not gzip accept {}", this, request);
if (LOG.isDebugEnabled())
LOG.debug("{} excluded not gzip accept {}", this, request);
return null;
}

Expand Down Expand Up @@ -577,18 +579,19 @@ public boolean handle(Request request, Response response, Callback callback) thr
request = new GzipRequest(request, inflatable && tryInflate ? getInflateBufferSize() : -1);
}

if (tryDeflate && _vary != null)
{
// The response may vary based on the presence or lack of Accept-Encoding.
response.getHeaders().ensureField(_vary);
}

// Wrap the response and callback IFF we can be deflated and will try to deflate
if (deflatable && tryDeflate)
{
GzipResponseAndCallback gzipResponseAndCallback = new GzipResponseAndCallback(this, request, response, callback);
response = gzipResponseAndCallback;
callback = gzipResponseAndCallback;
}
else if (tryDeflate && _vary != null)
{
// We are not wrapping the response, but could have if request accepted, so we add a Vary header.
response.getHeaders().ensureField(_vary);
}

// Call handle() with the possibly wrapped request, response and callback
if (next.handle(request, response, callback))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
Expand All @@ -40,17 +39,15 @@

public class GzipResponseAndCallback extends Response.Wrapper implements Callback, Invocable
{
public static Logger LOG = LoggerFactory.getLogger(GzipResponseAndCallback.class);
private static final Logger LOG = LoggerFactory.getLogger(GzipResponseAndCallback.class);

// Per RFC-1952 this is the "unknown" OS value byte.
private static final byte OS_UNKNOWN = (byte)0xFF;
private static final byte[] GZIP_HEADER = new byte[]{
(byte)0x1f, (byte)0x8b, Deflater.DEFLATED, 0, 0, 0, 0, 0, 0, OS_UNKNOWN
};
// Per RFC-1952, the GZIP trailer is 8 bytes
public static final int GZIP_TRAILER_SIZE = 8;

public static final HttpField VARY_ACCEPT_ENCODING = new PreEncodedHttpField(HttpHeader.VARY, HttpHeader.ACCEPT_ENCODING.asString());
private static final int GZIP_TRAILER_SIZE = 8;

private enum GZState
{
Expand All @@ -70,22 +67,19 @@ private enum GZState

private final AtomicReference<GZState> _state = new AtomicReference<>(GZState.MIGHT_COMPRESS);
private final CRC32 _crc = new CRC32();

private final Callback _callback;
private final GzipFactory _factory;
private final HttpField _vary;
private final int _bufferSize;
private final boolean _syncFlush;

private DeflaterPool.Entry _deflaterEntry;
private RetainableByteBuffer _buffer;
private boolean _last;

public GzipResponseAndCallback(GzipHandler handler, Request request, Response response, Callback callback)
{
super(request, response);
_callback = callback;
_factory = handler;
_vary = handler.getVary();
_bufferSize = Math.max(GZIP_HEADER.length + GZIP_TRAILER_SIZE, request.getConnectionMetaData().getHttpConfiguration().getOutputBufferSize());
_syncFlush = handler.isSyncFlush();
}
Expand All @@ -95,10 +89,12 @@ public void succeeded()
{
try
{
// We need to write nothing here to intercept the committing of the response
// and possibly change headers in case write is never called.
write(true, null, Callback.NOOP);
_callback.succeeded();
// We need to write nothing here to intercept the committing of the
// response and possibly change headers in case write is never called.
if (_last)
_callback.succeeded();
else
write(true, null, _callback);
}
finally
{
Expand Down Expand Up @@ -130,6 +126,7 @@ public InvocationType getInvocationType()
@Override
public void write(boolean last, ByteBuffer content, Callback callback)
{
_last = last;
switch (_state.get())
{
case MIGHT_COMPRESS -> commit(last, callback, content);
Expand Down Expand Up @@ -167,27 +164,27 @@ protected void commit(boolean last, Callback callback, ByteBuffer content)
if (LOG.isDebugEnabled())
LOG.debug("commit(last={}, callback={}, content={})", last, callback, BufferUtil.toDetailString(content));

// Are we excluding because of status?
Request request = getRequest();
Response response = this;
HttpFields.Mutable fields = response.getHeaders();

// Are we excluding because of status?
int sc = response.getStatus();
if (sc > 0 && (sc < 200 || sc == 204 || sc == 205 || sc >= 300))
{
LOG.debug("{} exclude by status {}", this, sc);
if (LOG.isDebugEnabled())
LOG.debug("{} exclude by status {}", this, sc);
noCompression();

if (sc == HttpStatus.NOT_MODIFIED_304)
{
String requestEtags = (String)request.getAttribute(GzipHandler.GZIP_HANDLER_ETAGS);
String responseEtag = response.getHeaders().get(HttpHeader.ETAG);
String responseEtag = fields.get(HttpHeader.ETAG);
if (requestEtags != null && responseEtag != null)
{
String responseEtagGzip = etagGzip(responseEtag);
if (requestEtags.contains(responseEtagGzip))
response.getHeaders().put(HttpHeader.ETAG, responseEtagGzip);
if (_vary != null)
response.getHeaders().ensureField(_vary);
fields.put(HttpHeader.ETAG, responseEtagGzip);
}
}

Expand All @@ -196,45 +193,53 @@ protected void commit(boolean last, Callback callback, ByteBuffer content)
}

// Are we excluding because of mime-type?
String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
String ct = fields.get(HttpHeader.CONTENT_TYPE);
if (ct != null)
{
String baseType = HttpField.getValueParameters(ct, null);
if (!_factory.isMimeTypeDeflatable(baseType))
{
LOG.debug("{} exclude by mimeType {}", this, ct);
if (LOG.isDebugEnabled())
LOG.debug("{} exclude by mimeType {}", this, ct);
noCompression();
super.write(last, content, callback);
return;
}
}

// Has the Content-Encoding header already been set?
HttpFields.Mutable fields = response.getHeaders();
String ce = fields.get(HttpHeader.CONTENT_ENCODING);
if (ce != null)
{
LOG.debug("{} exclude by content-encoding {}", this, ce);
if (LOG.isDebugEnabled())
LOG.debug("{} exclude by content-encoding {}", this, ce);
noCompression();
super.write(last, content, callback);
return;
}

// If there is nothing to write, don't compress.
if (last && BufferUtil.isEmpty(content))
{
if (LOG.isDebugEnabled())
LOG.debug("{} exclude by nothing to write", this);
noCompression();
super.write(true, content, callback);
return;
}

// Are we the thread that commits?
if (_state.compareAndSet(GZState.MIGHT_COMPRESS, GZState.COMMITTING))
{
// We are varying the response due to accept encoding header.
if (_vary != null)
fields.ensureField(_vary);

long contentLength = response.getHeaders().getLongField(HttpHeader.CONTENT_LENGTH);
long contentLength = fields.getLongField(HttpHeader.CONTENT_LENGTH);
if (contentLength < 0 && last)
contentLength = BufferUtil.length(content);

_deflaterEntry = _factory.getDeflaterEntry(request, contentLength);
if (_deflaterEntry == null)
{
LOG.debug("{} exclude no deflater", this);
if (LOG.isDebugEnabled())
LOG.debug("{} exclude no deflater", this);
_state.set(GZState.NOT_COMPRESSING);
super.write(last, content, callback);
return;
Expand All @@ -244,12 +249,13 @@ protected void commit(boolean last, Callback callback, ByteBuffer content)
_crc.reset();

// Adjust headers
response.getHeaders().remove(HttpHeader.CONTENT_LENGTH);
fields.remove(HttpHeader.CONTENT_LENGTH);
String etag = fields.get(HttpHeader.ETAG);
if (etag != null)
fields.put(HttpHeader.ETAG, etagGzip(etag));

LOG.debug("{} compressing {}", this, _deflaterEntry);
if (LOG.isDebugEnabled())
LOG.debug("{} compressing {}", this, _deflaterEntry);
_state.set(GZState.COMPRESSING);

if (BufferUtil.isEmpty(content))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.not;
Expand Down Expand Up @@ -291,7 +292,7 @@ public void testBlockingResponse() throws Exception
assertThat(response.getStatus(), is(200));
assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip"));
assertThat(response.get("ETag"), is(CONTENT_ETAG_GZIP));
assertThat(response.getCSV("Vary", false), contains("Accept-Encoding", "Other"));
assertThat(response.getCSV("Vary", false), hasItems("Accept-Encoding", "Other"));

InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
Expand Down Expand Up @@ -547,7 +548,7 @@ public void testEmptyResponseZeroMinGzipSize() throws Exception
response = HttpTester.parseResponse(_connector.getResponse(request.generate()));

assertThat(response.getStatus(), is(200));
assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip"));
assertThat(response.get("Content-Encoding"), nullValue());
assertThat(response.getCSV("Vary", false), contains("Accept-Encoding"));
}

Expand Down Expand Up @@ -580,7 +581,7 @@ public void testExcludeMimeTypes() throws Exception
assertThat(response.getStatus(), is(200));
assertThat("Should not be compressed with gzip", response.get("Content-Encoding"), nullValue());
assertThat(response.get("ETag"), nullValue());
assertThat(response.get("Vary"), nullValue());
assertThat(response.get("Vary"), containsString("Accept-Encoding"));

// Request something that is present on MimeTypes and is also compressible
// by the GzipHandler configuration
Expand Down Expand Up @@ -776,7 +777,7 @@ public void testExcludedMimeTypesWithCharset() throws Exception
assertThat("Response[Content-Type]", response.get("Content-Type"), containsString("text/wibble"));
assertThat("Response[Content-Type]", response.get("Content-Type"), containsString("charset=utf-8"));
assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip")));
assertThat("Response[Vary]", response.get("Vary"), is(nullValue()));
assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding"));

// Response Content checks
UncompressedMetadata metadata = parseResponseContent(response);
Expand Down Expand Up @@ -1473,7 +1474,7 @@ public void testRequestIfModifiedSinceInFutureGzipCompressedResponse(int fileSiz
// Response Content-Encoding check
assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip")));
assertThat("Response[ETag]", response.get("ETag"), nullValue());
assertThat("Response[Vary]", response.get("Vary"), nullValue());
assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding"));
}

/**
Expand Down Expand Up @@ -1555,7 +1556,7 @@ public void testRequestWithMultipleAcceptEncodingHeaders() throws Exception
assertThat(response.getStatus(), is(200));
assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip"));
assertThat(response.get("ETag"), is(CONTENT_ETAG_GZIP));
assertThat(response.getCSV("Vary", false), contains("Accept-Encoding", "Other"));
assertThat(response.getCSV("Vary", false), hasItems("Accept-Encoding", "Other"));

InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
Expand Down
Loading

0 comments on commit 51824f6

Please sign in to comment.