Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x
This commit is contained in:
commit
42155e889b
|
@ -304,11 +304,11 @@ public class HpackEncoder
|
||||||
|
|
||||||
String encoding = null;
|
String encoding = null;
|
||||||
|
|
||||||
// Is there an entry for the field?
|
// Is there an index entry for the field?
|
||||||
Entry entry = _context.get(field);
|
Entry entry = _context.get(field);
|
||||||
if (entry != null)
|
if (entry != null)
|
||||||
{
|
{
|
||||||
// Known field entry, so encode it as indexed
|
// This is a known indexed field, send as static or dynamic indexed.
|
||||||
if (entry.isStatic())
|
if (entry.isStatic())
|
||||||
{
|
{
|
||||||
buffer.put(((StaticEntry)entry).getEncodedField());
|
buffer.put(((StaticEntry)entry).getEncodedField());
|
||||||
|
@ -326,10 +326,10 @@ public class HpackEncoder
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Unknown field entry, so we will have to send literally.
|
// Unknown field entry, so we will have to send literally, but perhaps add an index.
|
||||||
final boolean indexed;
|
final boolean indexed;
|
||||||
|
|
||||||
// But do we know it's name?
|
// Do we know its name?
|
||||||
HttpHeader header = field.getHeader();
|
HttpHeader header = field.getHeader();
|
||||||
|
|
||||||
// Select encoding strategy
|
// Select encoding strategy
|
||||||
|
@ -347,12 +347,11 @@ public class HpackEncoder
|
||||||
if (_debug)
|
if (_debug)
|
||||||
encoding = indexed ? "PreEncodedIdx" : "PreEncoded";
|
encoding = indexed ? "PreEncodedIdx" : "PreEncoded";
|
||||||
}
|
}
|
||||||
// has the custom header name been seen before?
|
else if (name == null && fieldSize < _context.getMaxDynamicTableSize())
|
||||||
else if (name == null)
|
|
||||||
{
|
{
|
||||||
// unknown name and value, so let's index this just in case it is
|
// unknown name and value that will fit in dynamic table, so let's index
|
||||||
// the first time we have seen a custom name or a custom field.
|
// this just in case it is the first time we have seen a custom name or a
|
||||||
// unless the name is changing, this is worthwhile
|
// custom field. Unless the name is once only, this is worthwhile
|
||||||
indexed = true;
|
indexed = true;
|
||||||
encodeName(buffer, (byte)0x40, 6, field.getName(), null);
|
encodeName(buffer, (byte)0x40, 6, field.getName(), null);
|
||||||
encodeValue(buffer, true, field.getValue());
|
encodeValue(buffer, true, field.getValue());
|
||||||
|
@ -361,7 +360,7 @@ public class HpackEncoder
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// known custom name, but unknown value.
|
// Known name, but different value.
|
||||||
// This is probably a custom field with changing value, so don't index.
|
// This is probably a custom field with changing value, so don't index.
|
||||||
indexed = false;
|
indexed = false;
|
||||||
encodeName(buffer, (byte)0x00, 4, field.getName(), null);
|
encodeName(buffer, (byte)0x00, 4, field.getName(), null);
|
||||||
|
@ -400,9 +399,9 @@ public class HpackEncoder
|
||||||
(huffman ? "HuffV" : "LitV") +
|
(huffman ? "HuffV" : "LitV") +
|
||||||
(neverIndex ? "!!Idx" : "!Idx");
|
(neverIndex ? "!!Idx" : "!Idx");
|
||||||
}
|
}
|
||||||
else if (fieldSize >= _context.getMaxDynamicTableSize() || header == HttpHeader.CONTENT_LENGTH && field.getValue().length() > 2)
|
else if (fieldSize >= _context.getMaxDynamicTableSize() || header == HttpHeader.CONTENT_LENGTH && !"0".equals(field.getValue()))
|
||||||
{
|
{
|
||||||
// Non indexed if field too large or a content length for 3 digits or more
|
// The field is too large or a non zero content length, so do not index.
|
||||||
indexed = false;
|
indexed = false;
|
||||||
encodeName(buffer, (byte)0x00, 4, header.asString(), name);
|
encodeName(buffer, (byte)0x00, 4, header.asString(), name);
|
||||||
encodeValue(buffer, true, field.getValue());
|
encodeValue(buffer, true, field.getValue());
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpFields;
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.http.MetaData;
|
import org.eclipse.jetty.http.MetaData;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
@ -145,6 +146,54 @@ public class HpackEncoderTest
|
||||||
assertEquals(5, encoder.getHpackContext().size());
|
assertEquals(5, encoder.getHpackContext().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLargeFieldsNotIndexed()
|
||||||
|
{
|
||||||
|
HpackEncoder encoder = new HpackEncoder(38 * 5);
|
||||||
|
HpackContext ctx = encoder.getHpackContext();
|
||||||
|
|
||||||
|
ByteBuffer buffer = BufferUtil.allocate(4096);
|
||||||
|
|
||||||
|
// Index little fields
|
||||||
|
int pos = BufferUtil.flipToFill(buffer);
|
||||||
|
encoder.encode(buffer, new HttpField("Name", "Value"));
|
||||||
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
|
int dynamicTableSize = ctx.getDynamicTableSize();
|
||||||
|
assertThat(dynamicTableSize, Matchers.greaterThan(0));
|
||||||
|
|
||||||
|
// Do not index big field
|
||||||
|
StringBuilder largeName = new StringBuilder("largeName-");
|
||||||
|
String filler = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
||||||
|
while (largeName.length() < ctx.getMaxDynamicTableSize())
|
||||||
|
largeName.append(filler, 0, Math.min(filler.length(), ctx.getMaxDynamicTableSize() - largeName.length()));
|
||||||
|
pos = BufferUtil.flipToFill(buffer);
|
||||||
|
encoder.encode(buffer, new HttpField(largeName.toString(), "Value"));
|
||||||
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
|
assertThat(ctx.getDynamicTableSize(), Matchers.is(dynamicTableSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndexContentLength()
|
||||||
|
{
|
||||||
|
HpackEncoder encoder = new HpackEncoder(38 * 5);
|
||||||
|
HpackContext ctx = encoder.getHpackContext();
|
||||||
|
|
||||||
|
ByteBuffer buffer = BufferUtil.allocate(4096);
|
||||||
|
|
||||||
|
// Index zero content length
|
||||||
|
int pos = BufferUtil.flipToFill(buffer);
|
||||||
|
encoder.encode(buffer, new HttpField(HttpHeader.CONTENT_LENGTH, "0"));
|
||||||
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
|
int dynamicTableSize = ctx.getDynamicTableSize();
|
||||||
|
assertThat(dynamicTableSize, Matchers.greaterThan(0));
|
||||||
|
|
||||||
|
// Do not index non zero content length
|
||||||
|
pos = BufferUtil.flipToFill(buffer);
|
||||||
|
encoder.encode(buffer, new HttpField(HttpHeader.CONTENT_LENGTH, "42"));
|
||||||
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
|
assertThat(ctx.getDynamicTableSize(), Matchers.is(dynamicTableSize));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNeverIndexSetCookie() throws Exception
|
public void testNeverIndexSetCookie() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,21 +34,31 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
*/
|
*/
|
||||||
public class FooContextListener implements ServletContextListener
|
public class FooContextListener implements ServletContextListener
|
||||||
{
|
{
|
||||||
|
static int ___initialized;
|
||||||
|
static int __destroyed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce)
|
public void contextInitialized(ServletContextEvent sce)
|
||||||
{
|
{
|
||||||
|
++___initialized;
|
||||||
|
|
||||||
ServletRegistration defaultRego = sce.getServletContext().getServletRegistration("default");
|
ServletRegistration defaultRego = sce.getServletContext().getServletRegistration("default");
|
||||||
Collection<String> mappings = defaultRego.getMappings();
|
Collection<String> mappings = defaultRego.getMappings();
|
||||||
assertThat("/", is(in(mappings)));
|
assertThat("/", is(in(mappings)));
|
||||||
|
|
||||||
Set<String> otherMappings = sce.getServletContext().getServletRegistration("foo").addMapping("/");
|
ServletRegistration rego = sce.getServletContext().getServletRegistration("foo");
|
||||||
assertTrue(otherMappings.isEmpty());
|
if (rego != null)
|
||||||
Collection<String> fooMappings = sce.getServletContext().getServletRegistration("foo").getMappings();
|
{
|
||||||
assertThat("/", is(in(fooMappings)));
|
Set<String> otherMappings = rego.addMapping("/");
|
||||||
|
assertTrue(otherMappings.isEmpty());
|
||||||
|
Collection<String> fooMappings = rego.getMappings();
|
||||||
|
assertThat("/", is(in(fooMappings)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce)
|
public void contextDestroyed(ServletContextEvent sce)
|
||||||
{
|
{
|
||||||
|
++__destroyed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class TestQuickStart
|
||||||
fooHolder.setName("foo");
|
fooHolder.setName("foo");
|
||||||
quickstart.getServletHandler().addServlet(fooHolder);
|
quickstart.getServletHandler().addServlet(fooHolder);
|
||||||
ListenerHolder lholder = new ListenerHolder();
|
ListenerHolder lholder = new ListenerHolder();
|
||||||
lholder.setListener(new FooContextListener());
|
lholder.setClassName("org.eclipse.jetty.quickstart.FooContextListener");
|
||||||
quickstart.getServletHandler().addListener(lholder);
|
quickstart.getServletHandler().addListener(lholder);
|
||||||
server.setHandler(quickstart);
|
server.setHandler(quickstart);
|
||||||
server.setDryRun(true);
|
server.setDryRun(true);
|
||||||
|
@ -177,4 +177,30 @@ public class TestQuickStart
|
||||||
assertEquals("ascii", webapp.getDefaultRequestCharacterEncoding());
|
assertEquals("ascii", webapp.getDefaultRequestCharacterEncoding());
|
||||||
assertEquals("utf-16", webapp.getDefaultResponseCharacterEncoding());
|
assertEquals("utf-16", webapp.getDefaultResponseCharacterEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListenersNotCalledInPreConfigure() throws Exception
|
||||||
|
{
|
||||||
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
Server server = new Server();
|
||||||
|
|
||||||
|
WebAppContext quickstart = new WebAppContext();
|
||||||
|
quickstart.addConfiguration(new QuickStartConfiguration());
|
||||||
|
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE);
|
||||||
|
quickstart.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, "origin");
|
||||||
|
|
||||||
|
//add a listener directly to the ContextHandler so it is there when we start -
|
||||||
|
//if you add them to the ServletHandler (like StandardDescriptorProcessor does)
|
||||||
|
//then they are not added to the ContextHandler in a pre-generate.
|
||||||
|
quickstart.addEventListener(new FooContextListener());
|
||||||
|
quickstart.setResourceBase(testDir.getAbsolutePath());
|
||||||
|
server.setHandler(quickstart);
|
||||||
|
server.setDryRun(true);
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
assertTrue(quickstartXml.exists());
|
||||||
|
assertEquals(0, FooContextListener.___initialized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -956,6 +956,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
|
|
||||||
protected void callContextInitialized(ServletContextListener l, ServletContextEvent e)
|
protected void callContextInitialized(ServletContextListener l, ServletContextEvent e)
|
||||||
{
|
{
|
||||||
|
if (getServer().isDryRun())
|
||||||
|
return;
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("contextInitialized: {}->{}", e, l);
|
LOG.debug("contextInitialized: {}->{}", e, l);
|
||||||
l.contextInitialized(e);
|
l.contextInitialized(e);
|
||||||
|
@ -963,6 +966,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
|
|
||||||
protected void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
|
protected void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
|
||||||
{
|
{
|
||||||
|
if (getServer().isDryRun())
|
||||||
|
return;
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("contextDestroyed: {}->{}", e, l);
|
LOG.debug("contextDestroyed: {}->{}", e, l);
|
||||||
l.contextDestroyed(e);
|
l.contextDestroyed(e);
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -1287,7 +1287,7 @@
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-sources</id>
|
<id>attach-sources</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>jar</goal>
|
<goal>jar-no-fork</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
|
@ -167,7 +167,7 @@ if proceedyn "Are you sure you want to release using above? (y/N)" n; then
|
||||||
# This is equivalent to 'mvn release:perform'
|
# This is equivalent to 'mvn release:perform'
|
||||||
if proceedyn "Build/Deploy from tag $TAG_NAME? (Y/n)" y; then
|
if proceedyn "Build/Deploy from tag $TAG_NAME? (Y/n)" y; then
|
||||||
git checkout $TAG_NAME
|
git checkout $TAG_NAME
|
||||||
mvn clean package source:jar javadoc:jar gpg:sign javadoc:aggregate-jar deploy \
|
mvn clean package javadoc:aggregate-jar deploy \
|
||||||
-Peclipse-release $DEPLOY_OPTS
|
-Peclipse-release $DEPLOY_OPTS
|
||||||
reportMavenTestFailures
|
reportMavenTestFailures
|
||||||
git checkout $GIT_BRANCH_ID
|
git checkout $GIT_BRANCH_ID
|
||||||
|
|
Loading…
Reference in New Issue