diff --git a/Jenkinsfile b/Jenkinsfile index 5685afe6fad..a3917bf696e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -90,7 +90,7 @@ def getFullBuild(jdk, os) { publisherStrategy: 'EXPLICIT', globalMavenSettingsConfig: settingsName, mavenLocalRepo: localRepo) { - sh "mvn -V -B install -Dmaven.test.failure.ignore=true -Prun-its -e -Pmongodb -T3" + sh "mvn -V -B install -Dmaven.test.failure.ignore=true -e -Pmongodb -T3" } // withMaven doesn't label.. // Report failures in the jenkins UI diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java index e66edf43887..0da45dd88e6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java @@ -150,7 +150,10 @@ public abstract class SslBytesTest } catch (IOException x) { - x.printStackTrace(); + logger.info(x.getClass() + ": " + x.getMessage()); + + if(logger.isDebugEnabled()) + logger.debug(x); } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index 4be2f977bb5..eecc1791f36 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -351,8 +351,7 @@ public class MimeTypes if (type==null) { - if (type==null) - type=__dftMimeMap.get("*"); + type=__dftMimeMap.get("*"); } return type; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index 1e9de93f45a..94a6db34611 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -19,11 +19,15 @@ package org.eclipse.jetty.http; import static org.eclipse.jetty.http.HttpComplianceSection.NO_FIELD_FOLDING; +import static org.hamcrest.Matchers.contains; + import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; +import java.util.Set; import org.eclipse.jetty.http.HttpParser.State; import org.eclipse.jetty.util.BufferUtil; @@ -33,8 +37,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import static org.hamcrest.Matchers.contains; - public class HttpParserTest { static @@ -358,7 +360,63 @@ public class HttpParserTest Assert.assertThat(_bad, Matchers.notNullValue()); Assert.assertThat(_bad, Matchers.containsString("Illegal character")); } - + + @Test + public void testWhiteSpaceBeforeRequest() + { + HttpCompliance[] compliances = new HttpCompliance[] + { + HttpCompliance.RFC7230, HttpCompliance.RFC2616 + }; + + String whitespaces[][] = new String[][] + { + { " ", "Illegal character SPACE" }, + { "\t", "Illegal character HTAB" }, + { "\n", null }, + { "\r", "Bad EOL" }, + { "\r\n", null }, + { "\r\n\r\n", null }, + { "\r\n \r\n", "Illegal character SPACE" }, + { "\r\n\t\r\n", "Illegal character HTAB" }, + { "\r\t\n", "Bad EOL" }, + { "\r\r\n", "Bad EOL" }, + { "\t\r\t\r\n", "Illegal character HTAB" }, + { " \t \r \t \n\n", "Illegal character SPACE" }, + { " \r \t \r\n\r\n\r\n", "Illegal character SPACE" } + }; + + + for (int i = 0; i < compliances.length; i++) + { + HttpCompliance compliance = compliances[i]; + + for (int j = 0; j < whitespaces.length; j++) + { + String request = + whitespaces[j][0] + + "GET / HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Name: value" + j + "\r\n" + + "Connection: close\r\n" + + "\r\n"; + + ByteBuffer buffer = BufferUtil.toBuffer(request); + HttpParser.RequestHandler handler = new Handler(); + HttpParser parser = new HttpParser(handler, 4096, compliance); + _bad = null; + parseAll(parser, buffer); + + String test = "whitespace.[" + compliance + "].[" + j + "]"; + String expected = whitespaces[j][1]; + if (expected==null) + Assert.assertNull(test, _bad); + else + Assert.assertThat(test, _bad, Matchers.containsString(expected)); + } + } + } + @Test public void testNoValue() throws Exception { diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java index 516dbcb9234..2d7b6757d3d 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.http2.hpack; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -254,6 +255,7 @@ public class HpackContext { if (LOG.isDebugEnabled()) LOG.debug(String.format("HdrTbl[%x] !added size %d>%d",hashCode(),size,_maxDynamicTableSizeInBytes)); + _dynamicTable.evictAll(); return null; } _dynamicTableSizeInBytes+=size; @@ -390,7 +392,18 @@ public class HpackContext if (LOG.isDebugEnabled()) LOG.debug(String.format("HdrTbl[%x] entries=%d, size=%d, max=%d",HpackContext.this.hashCode(),_dynamicTable.size(),_dynamicTableSizeInBytes,_maxDynamicTableSizeInBytes)); } - + + private void evictAll() + { + if (LOG.isDebugEnabled()) + LOG.debug(String.format("HdrTbl[%x] evictAll",HpackContext.this.hashCode())); + _fieldMap.clear(); + _nameMap.clear(); + _offset = 0; + _size = 0; + _dynamicTableSizeInBytes = 0; + Arrays.fill(_entries,null); + } } public static class Entry diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java index 1c8e9c5ed5c..28cb913c34f 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java @@ -242,14 +242,9 @@ public class HpackDecoder // emit the field _builder.emit(field); - // if indexed + // if indexed add to dynamic table if (indexed) - { - // add to dynamic table - if (_context.add(field)==null) - throw new BadMessageException(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431,"Indexed field value too large"); - } - + _context.add(field); } } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java index b0869284235..0bb5bb70fe3 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java @@ -329,11 +329,9 @@ public class HpackEncoder } } - // If we want the field referenced, then we add it to our - // table and reference set. + // If we want the field referenced, then we add it to our table and reference set. if (indexed) - if (_context.add(field)==null) - throw new IllegalStateException(); + _context.add(field); } if (_debug) diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java index aa2c6cb3b24..b9e72e7352f 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java @@ -166,6 +166,11 @@ public class MetaDataBuilder return new MetaData.Request(_method,_scheme,_authority,_path,HttpVersion.HTTP_2,fields,_contentLength); if (_status!=0) return new MetaData.Response(HttpVersion.HTTP_2,_status,fields,_contentLength); + if (_path!=null) + fields.put(HttpHeader.C_PATH,_path); + if (_authority!=null) + fields.put(HttpHeader.HOST,_authority.getValue()); + return new MetaData(HttpVersion.HTTP_2,fields,_contentLength); } finally diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java index d6302af2bd6..d6cb341aca9 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java @@ -190,7 +190,19 @@ public class HpackDecoderTest assertTrue(response.getFields().contains(new HttpField(HttpHeader.SERVER,"nghttpx nghttp2/1.12.0"))); assertTrue(response.getFields().contains(new HttpField(HttpHeader.VIA,"1.1 nghttpx"))); } - + + @Test + public void testResize() throws Exception + { + String encoded = "3f6166871e33A13a47497f205f8841E92b043d492d49"; + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + HpackDecoder decoder = new HpackDecoder(4096, 8192); + MetaData metaData = decoder.decode(buffer); + assertThat(metaData.getFields().get(HttpHeader.HOST),is("aHostName")); + assertThat(metaData.getFields().get(HttpHeader.CONTENT_TYPE),is("some/content")); + assertThat(decoder.getHpackContext().getDynamicTableSize(),is(0)); + } + @Test public void testTooBigToIndex() { @@ -198,16 +210,10 @@ public class HpackDecoderTest ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); HpackDecoder decoder = new HpackDecoder(128,8192); - try - { - decoder.decode(buffer); - Assert.fail(); - } - catch (BadMessageException e) - { - assertThat(e.getCode(),equalTo(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431)); - assertThat(e.getReason(),Matchers.startsWith("Indexed field value too large")); - } + MetaData metaData = decoder.decode(buffer); + + assertThat(decoder.getHpackContext().getDynamicTableSize(),is(0)); + assertThat(metaData.getFields().get(HttpHeader.C_PATH),Matchers.startsWith("This is a very large field")); } @Test diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java index 6895bc9d78b..00349c46017 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java @@ -27,10 +27,10 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.TypeUtil; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -249,7 +249,4 @@ public class HpackEncoderTest context.get(HpackContext.STATIC_SIZE+1).getSize()+context.get(HpackContext.STATIC_SIZE+2).getSize())); } - - - } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index 0645430f1a4..703806b8afd 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -835,7 +835,10 @@ public class SocketChannelEndPointTest } catch (InterruptedException | EofException e) { - LOG.info(e); + if(LOG.isDebugEnabled()) + LOG.debug(e); + else + LOG.info(e.getClass().getName()); } catch (Exception e) { diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 375baee1776..d3f9b535aeb 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -42,6 +42,39 @@ true + + org.apache.maven.plugins + maven-invoker-plugin + + + integration-test + + install + integration-test + verify + + + + + ${it.debug} + true + 60 + src/it + ${project.build.directory}/it + + */pom.xml + + ${project.build.directory}/local-repo + src/it/settings.xml + + ${surefireVersion} + + ${skipTests} + + clean + + + @@ -107,45 +140,4 @@ - - - run-its - - - - org.apache.maven.plugins - maven-invoker-plugin - - - integration-test - - install - integration-test - verify - - - - - ${it.debug} - true - 60 - src/it - ${project.build.directory}/it - - */pom.xml - - ${project.build.directory}/local-repo - src/it/settings.xml - - ${surefireVersion} - - - clean - - - - - - - diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index e288c366bfc..eebe394a38a 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -36,6 +36,61 @@ + + org.apache.maven.plugins + maven-invoker-plugin + + + integration-test + + install + integration-test + verify + + + + + ${it.debug} + true + src/it + 60 + ${project.build.directory}/it + + */pom.xml + + ${project.build.directory}/local-repo + src/it/settings.xml + + ${jetty.stopKey} + ${jetty.stopPort} + ${jetty.runPort} + ${surefireVersion} + + ${skipTests} + + clean + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + reserve-ports + pre-integration-test + + reserve-network-port + + + + jetty.stopPort + jetty.runPort + + + + + org.jacoco jacoco-maven-plugin @@ -179,68 +234,4 @@ - - - run-its - - - - org.apache.maven.plugins - maven-invoker-plugin - - - integration-test - - install - integration-test - verify - - - - - ${it.debug} - true - src/it - 60 - ${project.build.directory}/it - - */pom.xml - - ${project.build.directory}/local-repo - src/it/settings.xml - - ${jetty.stopKey} - ${jetty.stopPort} - ${jetty.runPort} - ${surefireVersion} - - - clean - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.0.0 - - - reserve-ports - pre-integration-test - - reserve-network-port - - - - jetty.stopPort - jetty.runPort - - - - - - - - - diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 082581a7d8c..961c29209c2 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -590,25 +590,5 @@ - - jdk11 - - 11 - - - - - org.apache.maven.plugins - maven-surefire-plugin - - ${skipTests} - - **/**/TestJettyOSGiBoot** - - - - - - diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletIOTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletIOTest.java index ea747cfa5cb..1552f524254 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletIOTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletIOTest.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.servlet; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; @@ -695,7 +696,8 @@ public class AsyncServletIOTest LOG.debug("last: "+last); // last non empty line should not contain end chunk - assertThat(last,not(containsString("0"))); + assertThat(last, notNullValue()); + assertThat(last.trim(),not(startsWith("0"))); } assertTrue(_servlet4.completed.await(5, TimeUnit.SECONDS)); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiException.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiException.java index c51b0e66acd..695070f63bb 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiException.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiException.java @@ -26,32 +26,48 @@ import java.util.List; * Wraps multiple exceptions. * * Allows multiple exceptions to be thrown as a single exception. + * + * The MultiException itself should not be thrown instead one of the + * ifExceptionThrow* methods should be called instead. */ @SuppressWarnings("serial") public class MultiException extends Exception { + private static final String DEFAULT_MESSAGE = "Multiple exceptions"; + private List nested; /* ------------------------------------------------------------ */ public MultiException() { - super("Multiple exceptions"); + // Avoid filling in stack trace information. + super(DEFAULT_MESSAGE, null, false, false); + this.nested = new ArrayList<>(); } + + /** + * Create a MultiException which may be thrown. + * + * @param nested The nested exceptions which will be suppressed by this + * exception. + */ + private MultiException(List nested) { + super(DEFAULT_MESSAGE); + this.nested = new ArrayList<>(nested); + + if(nested.size() > 0) { + initCause(nested.get(0)); + } + + for(Throwable t : nested) { + this.addSuppressed(t); + } + } + /* ------------------------------------------------------------ */ public void add(Throwable e) { - if (e==null) - throw new IllegalArgumentException(); - - if(nested == null) - { - initCause(e); - nested = new ArrayList<>(); - } - else - addSuppressed(e); - if (e instanceof MultiException) { MultiException me = (MultiException)e; @@ -105,7 +121,7 @@ public class MultiException extends Exception if (th instanceof Exception) throw (Exception)th; default: - throw this; + throw new MultiException(nested); } } @@ -137,7 +153,7 @@ public class MultiException extends Exception else throw new RuntimeException(th); default: - throw new RuntimeException(this); + throw new RuntimeException(new MultiException(nested)); } } @@ -155,7 +171,9 @@ public class MultiException extends Exception return; if (nested.size()>0) - throw this; + { + throw new MultiException(nested); + } } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiExceptionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiExceptionTest.java index 091d4373fcc..76ff4f5f130 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiExceptionTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiExceptionTest.java @@ -21,10 +21,11 @@ package org.eclipse.jetty.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.io.IOException; - +import org.junit.Assert; import org.junit.Test; +import java.io.IOException; + public class MultiExceptionTest { @@ -37,6 +38,8 @@ public class MultiExceptionTest me.ifExceptionThrow(); me.ifExceptionThrowMulti(); me.ifExceptionThrowRuntime(); + + assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length); } @Test @@ -65,7 +68,7 @@ public class MultiExceptionTest } catch(MultiException e) { - assertTrue(e==me); + assertTrue(e instanceof MultiException); } try @@ -91,19 +94,26 @@ public class MultiExceptionTest { assertTrue(run==e); } + + assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length); } - @Test - public void testTwo() throws Exception - { + private MultiException multiExceptionWithTwo() { MultiException me = new MultiException(); IOException io = new IOException("one"); RuntimeException run = new RuntimeException("one"); me.add(io); me.add(run); - assertEquals(2,me.size()); - + + assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length); + return me; + } + + @Test + public void testTwo() throws Exception + { + MultiException me = multiExceptionWithTwo(); try { me.ifExceptionThrow(); @@ -111,9 +121,11 @@ public class MultiExceptionTest } catch(MultiException e) { - assertTrue(e==me); + assertTrue(e instanceof MultiException); + assertTrue(e.getStackTrace().length > 0); } + me = multiExceptionWithTwo(); try { me.ifExceptionThrowMulti(); @@ -121,9 +133,11 @@ public class MultiExceptionTest } catch(MultiException e) { - assertTrue(e==me); + assertTrue(e instanceof MultiException); + assertTrue(e.getStackTrace().length > 0); } + me = multiExceptionWithTwo(); try { me.ifExceptionThrowRuntime(); @@ -131,9 +145,11 @@ public class MultiExceptionTest } catch(RuntimeException e) { - assertTrue(e.getCause()==me); + assertTrue(e.getCause() instanceof MultiException); + assertTrue(e.getStackTrace().length > 0); } + RuntimeException run = new RuntimeException("one"); me = new MultiException(); me.add(run); me.add(run); @@ -145,7 +161,9 @@ public class MultiExceptionTest } catch(RuntimeException e) { - assertTrue(e.getCause()==me); + assertTrue(e.getCause() instanceof MultiException); + Assert.assertEquals(e.getCause().getCause(), run); + assertTrue(e.getStackTrace().length > 0); } } @@ -158,7 +176,13 @@ public class MultiExceptionTest me.add(io); me.add(run); - assertEquals(2,me.size()); - assertEquals(io,me.getCause()); + + try { + me.ifExceptionThrow(); + } catch (MultiException e) { + assertEquals(io,e.getCause()); + assertEquals(2,e.size()); + } + } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/misbehaving/MisbehavingClassTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/misbehaving/MisbehavingClassTest.java index 415d46d39ee..cb1f78d47e0 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/misbehaving/MisbehavingClassTest.java @@ -18,14 +18,9 @@ package org.eclipse.jetty.websocket.jsr356.misbehaving; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - import java.io.IOException; import java.net.URI; import java.util.concurrent.TimeUnit; - import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; @@ -37,15 +32,15 @@ import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.jsr356.EchoHandler; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; public class MisbehavingClassTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - private static Server server; private static EchoHandler handler; private static URI serverUri; @@ -100,20 +95,21 @@ public class MisbehavingClassTest try (StacklessLogging logging = new StacklessLogging(EndpointRuntimeOnOpen.class, WebSocketSession.class)) { - // expecting IOException during onOpen - expectedException.expect(IOException.class); - expectedException.expectCause(instanceOf(RuntimeException.class)); - container.connectToServer(socket, serverUri); - expectedException.reportMissingExceptionWithMessage("Should have failed .connectToServer()"); - - assertThat("Close should have occurred",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + try + { + container.connectToServer(socket, serverUri); + fail("Should have failed .connectToServer()"); + } + catch (IOException e) + { + assertThat(e.getCause(), instanceOf(RuntimeException.class)); + } - Throwable cause = socket.errors.pop(); - assertThat("Error",cause,instanceOf(RuntimeException.class)); + assertThat("Close should have occurred", socket.closeLatch.await(10,TimeUnit.SECONDS), is(true)); + assertThat("Error", socket.errors.pop(), instanceOf(RuntimeException.class)); } } - @SuppressWarnings("Duplicates") @Test public void testAnnotatedRuntimeOnOpen() throws Exception { @@ -123,16 +119,18 @@ public class MisbehavingClassTest try (StacklessLogging logging = new StacklessLogging(AnnotatedRuntimeOnOpen.class, WebSocketSession.class)) { - // expecting IOException during onOpen - expectedException.expect(IOException.class); - expectedException.expectCause(instanceOf(RuntimeException.class)); - container.connectToServer(socket, serverUri); - expectedException.reportMissingExceptionWithMessage("Should have failed .connectToServer()"); - - assertThat("Close should have occurred",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + try + { + container.connectToServer(socket, serverUri); + fail("Should have failed .connectToServer()"); + } + catch (IOException e) + { + assertThat(e.getCause(), instanceOf(RuntimeException.class)); + } - Throwable cause = socket.errors.pop(); - assertThat("Error",cause,instanceOf(ArrayIndexOutOfBoundsException.class)); + assertThat("Close should have occurred", socket.closeLatch.await(10,TimeUnit.SECONDS), is(true)); + assertThat("Error",socket.errors.pop(), instanceOf(RuntimeException.class)); } } } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java index 6343af16033..d3f81dff5ec 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java @@ -49,7 +49,11 @@ public abstract class TrackingSocket protected void addError(Throwable t) { - LOG.warn(t); + LOG.warn(t.getClass() + ": " + t.getMessage()); + + if(LOG.isDebugEnabled()) + LOG.debug(t); + errorQueue.offer(t); } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java index aaca8301df2..14daae2d31e 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java @@ -40,7 +40,8 @@ public class ByteAccumulator { if (this.length + length > maxSize) { - throw new MessageTooLargeException("Frame is too large"); + String err = String.format("Resulting message size [%,d] is too large for configured max of [%,d]", this.length + length, maxSize); + throw new MessageTooLargeException(err); } byte copy[] = new byte[length - offset]; diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java index 9b862888bb1..e7963d182a8 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java @@ -149,7 +149,7 @@ public abstract class CompressExtension extends AbstractExtension protected ByteAccumulator newByteAccumulator() { - int maxSize = Math.max(getPolicy().getMaxTextMessageSize(),getPolicy().getMaxBinaryMessageBufferSize()); + int maxSize = Math.max(getPolicy().getMaxTextMessageSize(),getPolicy().getMaxBinaryMessageSize()); return new ByteAccumulator(maxSize); } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java new file mode 100644 index 00000000000..e182eae2844 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java @@ -0,0 +1,100 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.extensions.compress; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.MessageTooLargeException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ByteAccumulatorTest +{ + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void testCopyNormal() + { + ByteAccumulator accumulator = new ByteAccumulator(10_000); + + byte hello[] = "Hello".getBytes(UTF_8); + byte space[] = " ".getBytes(UTF_8); + byte world[] = "World".getBytes(UTF_8); + + accumulator.copyChunk(hello, 0, hello.length); + accumulator.copyChunk(space, 0, space.length); + accumulator.copyChunk(world, 0, world.length); + + assertThat("Length", accumulator.getLength(), is(hello.length + space.length + world.length)); + + ByteBuffer out = ByteBuffer.allocate(200); + accumulator.transferTo(out); + String result = BufferUtil.toUTF8String(out); + assertThat("ByteBuffer to UTF8", result, is("Hello World")); + } + + @Test + public void testTransferTo_NotEnoughSpace() + { + ByteAccumulator accumulator = new ByteAccumulator(10_000); + + byte hello[] = "Hello".getBytes(UTF_8); + byte space[] = " ".getBytes(UTF_8); + byte world[] = "World".getBytes(UTF_8); + + accumulator.copyChunk(hello, 0, hello.length); + accumulator.copyChunk(space, 0, space.length); + accumulator.copyChunk(world, 0, world.length); + + int length = hello.length + space.length + world.length; + assertThat("Length", accumulator.getLength(), is(length)); + + ByteBuffer out = ByteBuffer.allocate(length - 2); // intentionally too small ByteBuffer + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(containsString("Not enough space in ByteBuffer")); + accumulator.transferTo(out); + } + + @Test + public void testCopyChunk_NotEnoughSpace() + { + + byte hello[] = "Hello".getBytes(UTF_8); + byte space[] = " ".getBytes(UTF_8); + byte world[] = "World".getBytes(UTF_8); + + int length = hello.length + space.length + world.length; + ByteAccumulator accumulator = new ByteAccumulator(length - 2); // intentionally too small of a max + + accumulator.copyChunk(hello, 0, hello.length); + accumulator.copyChunk(space, 0, space.length); + + expectedException.expect(MessageTooLargeException.class); + expectedException.expectMessage(containsString("too large for configured max")); + accumulator.copyChunk(world, 0, world.length); + } +} diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java index e0bb8fdae4a..6f8b42b5f26 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java @@ -18,10 +18,6 @@ package org.eclipse.jetty.websocket.server; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - import java.io.File; import java.net.URI; import java.util.ArrayList; @@ -49,10 +45,15 @@ import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + @RunWith(Parameterized.class) public class WebSocketUpgradeFilterTest { @@ -343,7 +344,8 @@ public class WebSocketUpgradeFilterTest assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); } } - + + @Ignore("Issue #2605") @Test public void testStopStartOfHandler() throws Exception { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java index 4232727160a..bd5f2a43913 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java @@ -92,8 +92,8 @@ public class MisbehavingClassTest Future connFut = request.sendAsync(); - try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); - StacklessLogging ignore = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class)) + try (StacklessLogging ignore = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class); + BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); @@ -126,8 +126,8 @@ public class MisbehavingClassTest Future connFut = request.sendAsync(); - try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); - StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class)) + try (StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class); + BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); diff --git a/pom.xml b/pom.xml index 601304336d4..35bb8595ec8 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ undefined 1.0.0.RC11 - 6.1.1 + 6.2 1.20 benchmarks 2.21.0 @@ -452,7 +452,7 @@ org.apache.maven.plugins maven-invoker-plugin - 3.0.2-SNAPSHOT + 3.1.0 org.apache.maven.plugins @@ -490,10 +490,6 @@ http://docs.oracle.com/javase/8/docs/api/ http://docs.oracle.com/javaee/7/api/ - @@ -616,7 +612,7 @@ maven-surefire-plugin ${surefireVersion} - 3600 + 3600 @{argLine} -Dfile.encoding=UTF-8 -Duser.language=en -Duser.region=US -showversion -Xmx1g -Xms1g -XX:+PrintGCDetails false 1 @@ -1291,8 +1287,19 @@ org.apache.maven.plugins maven-javadoc-plugin - - --allow-script-in-comments + com.acme + + http://docs.oracle.com/javase/8/docs/api/ + http://docs.oracle.com/javaee/7/api + http://junit.sourceforge.net/javadoc/ + + + + org.apache.xbean.XBean + X + + + diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java index 0784bc77f2b..8a8f6bae1c9 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java @@ -55,6 +55,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Assume; @@ -430,7 +431,7 @@ public class ServerTimeoutsTest extends AbstractTest }); setServerIdleTimeout(idleTimeout); - try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) + try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class, QueuedThreadPool.class)) { DeferredContentProvider contentProvider = new DeferredContentProvider(); CountDownLatch resultLatch = new CountDownLatch(1);