Merge remote-tracking branch 'origin/jetty-10.0.x' into jetty-11.0.x
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
commit
9288e89684
|
@ -18,3 +18,13 @@ markComment: >
|
|||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been closed due to it having no activity.
|
||||
# Issue/PRs having project assigned will not be marked as stale
|
||||
exemptProjects: false
|
||||
|
||||
pulls:
|
||||
daysUntilStale: 15
|
||||
daysUntilClose: false
|
||||
markComment: >
|
||||
This pull request has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
|
16
VERSION.txt
16
VERSION.txt
|
@ -13,6 +13,20 @@ jetty-11.0.6 - 29 June 2021
|
|||
+ 6451 Request#getServletPath() returns null for ROOT mapping
|
||||
+ 6464 Wrong files/lib definitions in certain *-capture.mod files?
|
||||
|
||||
jetty-10.0.6 - 29 June 2021
|
||||
+ 6375 Always check XML `Set` elements with `property` attribute
|
||||
+ 6382 HttpClient TimeoutException message reports transient values
|
||||
+ 6394 Review osgi manifests within Jetty 10
|
||||
+ 6407 Malformed scheme logical expression check in WebSocket
|
||||
ClientUpgradeRequest
|
||||
+ 6410 Ensure Jetty IO uses SocketAddress instead of InetSocketAddress
|
||||
+ 6418 Bad and/or missing Require-Capability for osgi.serviceloader
|
||||
+ 6425 Update to asm 9.1
|
||||
+ 6447 Deprecate support for UTF16 encoding in URIs
|
||||
+ 6451 Request#getServletPath() returns null for ROOT mapping
|
||||
+ 6464 Wrong files/lib definitions in certain *-capture.mod files?
|
||||
+ 6473 Improve alias checking in PathResource
|
||||
|
||||
jetty-11.0.5 - 11 June 2021
|
||||
+ 4772 Jetty WebSocket API onMessage annotation does not support partial
|
||||
messages.
|
||||
|
@ -401,7 +415,7 @@ jetty-11.0.0.beta1 - 10 July 2020
|
|||
SETTINGS Frame.
|
||||
+ 4903 Give better errors for non public Websocket Endpoints
|
||||
+ 4904 WebsocketClient creates more connections than needed
|
||||
+ 4907
|
||||
+ 4907
|
||||
org.eclipse.jetty.websocket.tests.SuspendResumeTest#testSuspendAfterClose
|
||||
+ 4920 Restore ability to delete sessions on stop
|
||||
+ 4921 Quickstart run improperly runs dynamically added context initializers
|
||||
|
|
|
@ -329,7 +329,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
|
||||
final SSLSocket client2 = newClient(proxy);
|
||||
|
||||
threadPool.submit(() ->
|
||||
Future<Object> handshakeFuture = threadPool.submit(() ->
|
||||
{
|
||||
client2.startHandshake();
|
||||
return null;
|
||||
|
@ -361,6 +361,9 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Client Done
|
||||
TLSRecord doneRecord = proxy.readFromClient();
|
||||
assertNotNull(doneRecord);
|
||||
|
||||
// Wait for socket to be done with handshake
|
||||
handshakeFuture.get(5, TimeUnit.SECONDS);
|
||||
// Close
|
||||
client2.close();
|
||||
TLSRecord closeRecord = proxy.readFromClient();
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.jetty.http;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -217,6 +218,7 @@ public class HttpParser
|
|||
private final int _maxHeaderBytes;
|
||||
private final HttpCompliance _complianceMode;
|
||||
private final Utf8StringBuilder _uri = new Utf8StringBuilder(INITIAL_URI_LENGTH);
|
||||
private final FieldCache _fieldCache = new FieldCache();
|
||||
private HttpField _field;
|
||||
private HttpHeader _header;
|
||||
private String _headerString;
|
||||
|
@ -241,11 +243,8 @@ public class HttpParser
|
|||
private boolean _headResponse;
|
||||
private boolean _cr;
|
||||
private ByteBuffer _contentChunk;
|
||||
private Index.Mutable<HttpField> _fieldCache;
|
||||
private int _length;
|
||||
private final StringBuilder _string = new StringBuilder();
|
||||
private int _headerCacheSize = 1024;
|
||||
private boolean _headerCacheCaseSensitive;
|
||||
|
||||
private static HttpCompliance compliance()
|
||||
{
|
||||
|
@ -304,22 +303,22 @@ public class HttpParser
|
|||
|
||||
public int getHeaderCacheSize()
|
||||
{
|
||||
return _headerCacheSize;
|
||||
return _fieldCache.getCapacity();
|
||||
}
|
||||
|
||||
public void setHeaderCacheSize(int headerCacheSize)
|
||||
{
|
||||
_headerCacheSize = headerCacheSize;
|
||||
_fieldCache.setCapacity(headerCacheSize);
|
||||
}
|
||||
|
||||
public boolean isHeaderCacheCaseSensitive()
|
||||
{
|
||||
return _headerCacheCaseSensitive;
|
||||
return _fieldCache.isCaseSensitive();
|
||||
}
|
||||
|
||||
public void setHeaderCacheCaseSensitive(boolean headerCacheCaseSensitive)
|
||||
{
|
||||
_headerCacheCaseSensitive = headerCacheCaseSensitive;
|
||||
_fieldCache.setCaseSensitive(headerCacheCaseSensitive);
|
||||
}
|
||||
|
||||
protected void checkViolation(Violation violation) throws BadMessageException
|
||||
|
@ -746,6 +745,7 @@ public class HttpParser
|
|||
break;
|
||||
|
||||
case LF:
|
||||
_fieldCache.prepare();
|
||||
setState(State.HEADER);
|
||||
_responseHandler.startResponse(_version, _responseStatus, null);
|
||||
break;
|
||||
|
@ -851,6 +851,7 @@ public class HttpParser
|
|||
case LF:
|
||||
if (_responseHandler != null)
|
||||
{
|
||||
_fieldCache.prepare();
|
||||
setState(State.HEADER);
|
||||
_responseHandler.startResponse(_version, _responseStatus, null);
|
||||
}
|
||||
|
@ -881,7 +882,7 @@ public class HttpParser
|
|||
_version = HttpVersion.CACHE.get(takeString());
|
||||
}
|
||||
checkVersion();
|
||||
|
||||
_fieldCache.prepare();
|
||||
setState(State.HEADER);
|
||||
|
||||
_requestHandler.startRequest(_methodString, _uri.toString(), _version);
|
||||
|
@ -905,6 +906,7 @@ public class HttpParser
|
|||
{
|
||||
case LF:
|
||||
String reason = takeString();
|
||||
_fieldCache.prepare();
|
||||
setState(State.HEADER);
|
||||
_responseHandler.startResponse(_version, _responseStatus, reason);
|
||||
continue;
|
||||
|
@ -1026,7 +1028,7 @@ public class HttpParser
|
|||
_field = new HostPortHttpField(_header,
|
||||
CASE_SENSITIVE_FIELD_NAME.isAllowedBy(_complianceMode) ? _headerString : _header.asString(),
|
||||
_valueString);
|
||||
addToFieldCache = true;
|
||||
addToFieldCache = _fieldCache.isEnabled();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1035,7 +1037,7 @@ public class HttpParser
|
|||
if (_field == null)
|
||||
_field = new HttpField(_header, caseInsensitiveHeader(_headerString, _header.asString()), _valueString);
|
||||
if (getHeaderCacheSize() > 0 && _field.contains(HttpHeaderValue.CLOSE.asString()))
|
||||
_fieldCache = NO_CACHE;
|
||||
_fieldCache.setCapacity(-1);
|
||||
break;
|
||||
|
||||
case AUTHORIZATION:
|
||||
|
@ -1046,7 +1048,7 @@ public class HttpParser
|
|||
case COOKIE:
|
||||
case CACHE_CONTROL:
|
||||
case USER_AGENT:
|
||||
addToFieldCache = _field == null;
|
||||
addToFieldCache = _field == null && _fieldCache.cacheable(_header, _valueString);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1054,18 +1056,12 @@ public class HttpParser
|
|||
}
|
||||
|
||||
// Cache field?
|
||||
if (addToFieldCache && _header != null && _valueString != null)
|
||||
if (addToFieldCache)
|
||||
{
|
||||
if (_fieldCache == null)
|
||||
_fieldCache = Index.buildCaseSensitiveMutableVisibleAsciiAlphabet(getHeaderCacheSize());
|
||||
|
||||
if (_field == null)
|
||||
_field = new HttpField(_header, caseInsensitiveHeader(_headerString, _header.asString()), _valueString);
|
||||
if (_field.getValue().length() < getHeaderCacheSize() && !_fieldCache.put(_field))
|
||||
{
|
||||
_fieldCache.clear();
|
||||
_fieldCache.put(_field);
|
||||
}
|
||||
|
||||
_fieldCache.add(_field);
|
||||
}
|
||||
}
|
||||
_handler.parsedHeader(_field != null ? _field : new HttpField(_header, _headerString, _valueString));
|
||||
|
@ -1244,7 +1240,7 @@ public class HttpParser
|
|||
if (buffer.hasRemaining())
|
||||
{
|
||||
// Try a look ahead for the known header name and value.
|
||||
HttpField cachedField = _fieldCache == null ? null : _fieldCache.getBest(buffer, -1, buffer.remaining());
|
||||
HttpField cachedField = _fieldCache.getBest(buffer, -1, buffer.remaining());
|
||||
if (cachedField == null)
|
||||
cachedField = CACHE.getBest(buffer, -1, buffer.remaining());
|
||||
|
||||
|
@ -1911,7 +1907,8 @@ public class HttpParser
|
|||
|
||||
public Index<HttpField> getFieldCache()
|
||||
{
|
||||
return _fieldCache;
|
||||
_fieldCache.prepare();
|
||||
return _fieldCache.getCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2007,4 +2004,87 @@ public class HttpParser
|
|||
LOG.debug(String.format("Illegal character %s in state=%s for buffer %s", token, state, BufferUtil.toDetailString(buffer)));
|
||||
}
|
||||
}
|
||||
|
||||
private static class FieldCache
|
||||
{
|
||||
private int _size = 1024;
|
||||
private Index.Mutable<HttpField> _cache;
|
||||
private List<HttpField> _cacheableFields;
|
||||
private boolean _caseSensitive;
|
||||
|
||||
public int getCapacity()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
public void setCapacity(int size)
|
||||
{
|
||||
_size = size;
|
||||
if (_size <= 0)
|
||||
_cache = NO_CACHE;
|
||||
else
|
||||
_cache = null;
|
||||
}
|
||||
|
||||
public boolean isCaseSensitive()
|
||||
{
|
||||
return _caseSensitive;
|
||||
}
|
||||
|
||||
public void setCaseSensitive(boolean caseSensitive)
|
||||
{
|
||||
_caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return _cache != NO_CACHE;
|
||||
}
|
||||
|
||||
public Index<HttpField> getCache()
|
||||
{
|
||||
return _cache;
|
||||
}
|
||||
|
||||
public HttpField getBest(ByteBuffer buffer, int i, int remaining)
|
||||
{
|
||||
Index.Mutable<HttpField> cache = _cache;
|
||||
return cache == null ? null : _cache.getBest(buffer, i, remaining);
|
||||
}
|
||||
|
||||
public void add(HttpField field)
|
||||
{
|
||||
if (_cache == null)
|
||||
{
|
||||
if (_cacheableFields == null)
|
||||
_cacheableFields = new ArrayList<>();
|
||||
_cacheableFields.add(field);
|
||||
}
|
||||
else if (!_cache.put(field))
|
||||
{
|
||||
_cache.clear();
|
||||
_cache.put(field);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cacheable(HttpHeader header, String valueString)
|
||||
{
|
||||
return isEnabled() && header != null && valueString.length() <= _size;
|
||||
}
|
||||
|
||||
private void prepare()
|
||||
{
|
||||
if (_cache == null && _cacheableFields != null)
|
||||
{
|
||||
_cache = Index.buildMutableVisibleAsciiAlphabet(_caseSensitive, _size);
|
||||
for (HttpField f : _cacheableFields)
|
||||
{
|
||||
if (!_cache.put(f))
|
||||
break;
|
||||
}
|
||||
_cacheableFields.clear();
|
||||
_cacheableFields = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,13 +259,13 @@ public interface Index<V>
|
|||
* @param <V> The type of the index
|
||||
* @return A case sensitive mutable Index tacking visible ASCII alphabet to a max capacity.
|
||||
*/
|
||||
static <V> Mutable<V> buildCaseSensitiveMutableVisibleAsciiAlphabet(int maxCapacity)
|
||||
static <V> Mutable<V> buildMutableVisibleAsciiAlphabet(boolean caseSensitive, int maxCapacity)
|
||||
{
|
||||
if (maxCapacity < 0 || maxCapacity > ArrayTrie.MAX_CAPACITY)
|
||||
return new TreeTrie<>(true);
|
||||
return new TreeTrie<>(caseSensitive);
|
||||
if (maxCapacity == 0)
|
||||
return EmptyTrie.instance(true);
|
||||
return new ArrayTrie<>(true, maxCapacity);
|
||||
return EmptyTrie.instance(caseSensitive);
|
||||
return new ArrayTrie<>(caseSensitive, maxCapacity);
|
||||
}
|
||||
|
||||
static <V> Index<V> empty(boolean caseSensitive)
|
||||
|
|
Loading…
Reference in New Issue