diff --git a/Jenkinsfile b/Jenkinsfile index 2ff5e914b5f..a971c18b0f1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -17,20 +17,13 @@ def getFullBuild(jdk, os) { return { node(os) { // System Dependent Locations - def mvntool = tool name: 'maven3.5', type: 'hudson.tasks.Maven$MavenInstallation' - def mvntoolInvoker = tool name: 'maven3.5', type: 'hudson.tasks.Maven$MavenInstallation' - def jdktool = tool name: "$jdk", type: 'hudson.model.JDK' def mvnName = 'maven3.5' def localRepo = "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}" // ".repository" // def settingsName = 'oss-settings.xml' def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true' - // Environment - List mvnEnv = ["PATH+MVN=${mvntool}/bin", "PATH+JDK=${jdktool}/bin", "JAVA_HOME=${jdktool}/", "MAVEN_HOME=${mvntool}"] - mvnEnv.add("MAVEN_OPTS=$mavenOpts") - try - { + try { stage("Checkout - ${jdk}") { checkout scm } @@ -39,21 +32,17 @@ def getFullBuild(jdk, os) { throw e } - try - { + try { stage("Compile - ${jdk}") { - withEnv(mvnEnv) { - timeout(time: 15, unit: 'MINUTES') { - withMaven( - maven: mvnName, - jdk: "$jdk", - publisherStrategy: 'EXPLICIT', - globalMavenSettingsConfig: settingsName, - mavenOpts: mavenOpts, - mavenLocalRepo: localRepo) { - sh "mvn -V -B clean install -DskipTests -T6 -e" - } - + timeout(time: 15, unit: 'MINUTES') { + withMaven( + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: settingsName, + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { + sh "mvn -V -B clean install -DskipTests -T6 -e" } } } @@ -62,20 +51,17 @@ def getFullBuild(jdk, os) { throw e } - try - { + try { stage("Javadoc - ${jdk}") { - withEnv(mvnEnv) { - timeout(time: 20, unit: 'MINUTES') { - withMaven( - maven: mvnName, - jdk: "$jdk", - publisherStrategy: 'EXPLICIT', - globalMavenSettingsConfig: settingsName, - mavenOpts: mavenOpts, - mavenLocalRepo: localRepo) { - sh "mvn -V -B javadoc:javadoc -T6 -e" - } + timeout(time: 20, unit: 'MINUTES') { + withMaven( + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: settingsName, + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { + sh "mvn -V -B javadoc:javadoc -T6 -e" } } } @@ -84,61 +70,56 @@ def getFullBuild(jdk, os) { throw e } - try - { + try { stage("Test - ${jdk}") { - withEnv(mvnEnv) { - timeout(time: 90, unit: 'MINUTES') { - // Run test phase / ignore test failures - withMaven( - maven: mvnName, - jdk: "$jdk", - publisherStrategy: 'EXPLICIT', - globalMavenSettingsConfig: settingsName, - //options: [invokerPublisher(disabled: false)], - mavenOpts: mavenOpts, - mavenLocalRepo: localRepo) { - sh "mvn -V -B install -Dmaven.test.failure.ignore=true -e -Pmongodb -T3 -DmavenHome=${mvntoolInvoker} -Dunix.socket.tmp="+env.JENKINS_HOME - } - // withMaven doesn't label.. - // Report failures in the jenkins UI - junit testResults:'**/target/surefire-reports/TEST-*.xml,**/target/failsafe-reports/TEST-*.xml' - consoleParsers = [[parserName: 'JavaDoc'], + timeout(time: 90, unit: 'MINUTES') { + // Run test phase / ignore test failures + withMaven( + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: settingsName, + //options: [invokerPublisher(disabled: false)], + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { + sh "mvn -V -B install -Dmaven.test.failure.ignore=true -e -Pmongodb -T3 -Dunix.socket.tmp="+env.JENKINS_HOME + } + // withMaven doesn't label.. + // Report failures in the jenkins UI + junit testResults:'**/target/surefire-reports/TEST-*.xml,**/target/failsafe-reports/TEST-*.xml' + consoleParsers = [[parserName: 'JavaDoc'], + [parserName: 'JavaC']]; + if (isMainBuild( jdk )) { + // Collect up the jacoco execution results + def jacocoExcludes = + // build tools + "**/org/eclipse/jetty/ant/**" + ",**/org/eclipse/jetty/maven/**" + + ",**/org/eclipse/jetty/jspc/**" + + // example code / documentation + ",**/org/eclipse/jetty/embedded/**" + ",**/org/eclipse/jetty/asyncrest/**" + + ",**/org/eclipse/jetty/demo/**" + + // special environments / late integrations + ",**/org/eclipse/jetty/gcloud/**" + ",**/org/eclipse/jetty/infinispan/**" + + ",**/org/eclipse/jetty/osgi/**" + ",**/org/eclipse/jetty/spring/**" + + ",**/org/eclipse/jetty/http/spi/**" + + // test classes + ",**/org/eclipse/jetty/tests/**" + ",**/org/eclipse/jetty/test/**"; + jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class', + exclusionPattern: jacocoExcludes, + execPattern : '**/target/jacoco.exec', + classPattern : '**/target/classes', + sourcePattern : '**/src/main/java' + consoleParsers = [[parserName: 'Maven'], + [parserName: 'JavaDoc'], [parserName: 'JavaC']]; - if (isMainBuild( jdk )) { - // Collect up the jacoco execution results - def jacocoExcludes = - // build tools - "**/org/eclipse/jetty/ant/**" + ",**/org/eclipse/jetty/maven/**" + - ",**/org/eclipse/jetty/jspc/**" + - // example code / documentation - ",**/org/eclipse/jetty/embedded/**" + ",**/org/eclipse/jetty/asyncrest/**" + - ",**/org/eclipse/jetty/demo/**" + - // special environments / late integrations - ",**/org/eclipse/jetty/gcloud/**" + ",**/org/eclipse/jetty/infinispan/**" + - ",**/org/eclipse/jetty/osgi/**" + ",**/org/eclipse/jetty/spring/**" + - ",**/org/eclipse/jetty/http/spi/**" + - // test classes - ",**/org/eclipse/jetty/tests/**" + ",**/org/eclipse/jetty/test/**"; - step( [$class : 'JacocoPublisher', - inclusionPattern: '**/org/eclipse/jetty/**/*.class', - exclusionPattern: jacocoExcludes, - execPattern : '**/target/jacoco.exec', - classPattern : '**/target/classes', - sourcePattern : '**/src/main/java'] ) - consoleParsers = [[parserName: 'Maven'], - [parserName: 'JavaDoc'], - [parserName: 'JavaC']]; - } + } - // Report on Maven and Javadoc warnings - step( [$class : 'WarningsPublisher', - consoleParsers: consoleParsers] ) - } - if(isUnstable()) - { - notifyBuild("Unstable / Test Errors", jdk) - } + // Report on Maven and Javadoc warnings + step( [$class : 'WarningsPublisher', + consoleParsers: consoleParsers] ) + } + if(isUnstable()) { + notifyBuild("Unstable / Test Errors", jdk) } } } catch(Exception e) { @@ -149,16 +130,14 @@ def getFullBuild(jdk, os) { try { stage ("Compact3 - ${jdk}") { - withEnv(mvnEnv) { - withMaven( - maven: mvnName, - jdk: "$jdk", - publisherStrategy: 'EXPLICIT', - globalMavenSettingsConfig: settingsName, - mavenOpts: mavenOpts, - mavenLocalRepo: localRepo) { - sh "mvn -f aggregates/jetty-all-compact3 -V -B -Pcompact3 clean install -T5" - } + withMaven( + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: settingsName, + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { + sh "mvn -f aggregates/jetty-all-compact3 -V -B -Pcompact3 clean install -T5" } } } catch(Exception e) { @@ -177,8 +156,7 @@ def isMainBuild(jdk) { // True if this build is part of the "active" branches // for Jetty. -def isActiveBranch() -{ +def isActiveBranch() { def branchName = "${env.BRANCH_NAME}" return ( branchName == "master" || ( branchName.startsWith("jetty-") && branchName.endsWith(".x") ) ); @@ -186,16 +164,13 @@ def isActiveBranch() // Test if the Jenkins Pipeline or Step has marked the // current build as unstable -def isUnstable() -{ +def isUnstable() { return currentBuild.result == "UNSTABLE" } // Send a notification about the build status -def notifyBuild(String buildStatus, String jdk) -{ - if ( !isActiveBranch() ) - { +def notifyBuild(String buildStatus, String jdk) { + if ( !isActiveBranch() ) { // don't send notifications on transient branches return } diff --git a/VERSION.txt b/VERSION.txt index d691f280bfa..dc1a3b1053a 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,5 +1,97 @@ jetty-10.0.0-SNAPSHOT +jetty-9.4.12.v20180830 - 30 August 2018 + + 300 Implement Deflater / Inflater Object Pool + + 307 Monitor contention in AbstractNCSARequestLog + + 321 Remove JaspiAuthenticatorFactory.findServerName(Server, Subject) + + 901 Overriding SSL context KeyStoreType requires explicit override of + TrustStoreType + + 1688 Request with `Content-Encoding: gzip` should not perform parameter + extraction + + 1905 Deprecate jetty-runner now, present warnings when using it on Java 9+ + Runtimes + + 2075 Deprecating MultiException + + 2135 Android 8.1 needs direct buffers for SSL/TLS to work + + 2233 JDK9 Test failure: + org.eclipse.jetty.server.ThreadStarvationTest.testWriteStarvation[https/ssl/tls] + + 2342 File Descriptor Leak: Conscrypt: "Too many open files" + + 2349 HTTP/2 max streams enforcement + + 2398 MultiPartFormInputStream parsing should default to UTF-8, but allowed + to be overridden by Request.setCharacterEncoding() + + 2468 EWYK concurrent produce can fail SSL connections + + 2501 Include accepting connections in connection limit. + + 2530 Client waits forever for cancelled large uploads + + 2560 Review PathResource exception handling + + 2565 HashLoginService silently ignores file:/ config paths from 9.3.x + + 2592 Failing test on Windows: + ServerTimeoutsTest.testAsyncWriteIdleTimeoutFires[transport: HTTP] + + 2597 Failing tests on windows UnixSocketTest + + 2631 IllegalArgumentException: Buffering capacity exceeded, from HttpClient + HEAD Requests to resources referencing large body contents + + 2648 LdapLoginModule fails with forceBinding=true under Java 9 + + 2655 WebSocketClient not removing closed WebSocket Session's from managed + beans + + 2662 Remove unnecessary boxing conversions + + 2663 Guard Throwable.addSuppressed() calls + + 2672 Max local stream count exceeded for HttpClient with HTTP/2 transport + + 2675 Demo rewrite rules prevent URL Session tracking + + 2677 Decode URI before matching against "/favicon.ico" + + 2679 HTTP/2 Spec Compliance + + 2681 Jetty Hot Deployment Module does not stop exploded webapps after + removal from webapps directory + + 2683 NPE in FrameFlusher toString() + + 2684 MimeTypes.getAssumedEncodings() does not work + + 2694 Bad DynamicImport-Package in Websocket Servlet + + 2696 GcloudDataStore dependency generation broken + + 2706 ResourceService may return 404 for unchanged content + + 2711 TLS 1.3 compliance + + 2717 Async requests are not considered when shutting down gracefully + + 2718 NPE using more than one Endpoint.publish + + 2719 property file passed to start.jar is not read + + 2720 config tag can't access property values in WebAppContext + + 2722 Improve configurability for SETTINGS frames + + 2730 Limit concurrent HTTP/2 pushed resources + + 2737 HTTP Authentication parameters containing = + + 2739 AuthenticationProtocolHandler Multiple Challenge Pattern + + 2745 JDBCSessionDataStore schema potential performance issue + + 2746 Move jmh classes to a dedicated module and run those daily or weekly + + 2749 Graceful shutdown causes repeated 503s on keep-alive connections + + 2754 Don't eagerly instantiate @WebListener during annotation scan if it is + explicitly referenced in the webapp descriptor as well + + 2755 Repeatedly stopping/starting an active HttpClient can result in a stuck + ManagedSelector + + 2757 Possible double release of HTTP/2 ByteBuffers + + 2762 Fix typo in jetty.sh + + 2767 WebSocket Policy on JSR356 ClientContainer not represented correctly + + 2775 Make LowResourceMonitor extendable + + 2777 Workaround for Conscrypt's ssl == null + + 2778 Upgrade h2spec-maven-plugin 0.4 + + 2787 BadMessageException wrapped as ServletException not handled + + 2794 Generate p2 repos for Jetty 9.3.24.v20180605 and Jetty 9.2.25.v20180606 + + 2796 Max local stream count exceeded when request fails + + 2798 ThreadPoolBudget logs WARN when minThreads == maxThreads (was: + Reasoning behind ThreadPoolBudget warning logic change on 3/5/18) + + 2807 Exclude TLS_RSA_* ciphers by default + + 2811 SslContextFactory.dump incorrectly uses default enabled for determining + "jre:disabled" flag + + 2817 Change HttpClient and WebSocketClient default to always have SSL + support enabled + + 2821 AuthenticationProtocolHandler should not always cache + Authentication.Result + + 2824 Every call to HttpServletRequest.getParameter*() methods results in a + newly created Map object if both query and body content exist + + 2828 connectionListener of AbstractHTTP2ServerConnectionFactory cause the + low performance of concurrent connect of http2 + + 2832 Wrong initialization of HTTP/2 UnknownBodyParser + + 2835 JarFileResource#lastModified() side effect is URL caching preventing + hot redeploy on Windows + + 2836 Sequential HTTPS requests may not reuse the same connection + + 2844 Clean up webdefault.xml and DefaultServlet doc + + 2846 add unit test for ldap module + + 2847 Wrap Connection.Listener invocations in try/catch + + 2860 Leakage of HttpDestinations in HttpClient + + 2871 Server reads -1 after client resets HTTP/2 stream + jetty-9.4.11.v20180605 - 05 June 2018 + 1785 Support for vhost@connectorname syntax of virtual hosts + 2346 Revert stack trace logging for HTTPChannel.onException @@ -471,8 +563,8 @@ jetty-9.4.5.v20170502 - 02 May 2017 jetty-9.3.20.v20170531 - 31 May 2017 + 523 TLS close behaviour breaking session resumption - + 1108 Improve logging in SslContextFactory when there are no approved - cipher suites + + 1108 Improve logging in SslContextFactory when there are no approved cipher + suites + 1527 Jetty BOM should not depend on jetty-parent + 1556 A timing channel in Password.java + 1567 XmlConfiguration will start the same object multiple times @@ -541,8 +633,9 @@ jetty-9.3.18.v20170406 - 06 April 2017 + 877 Programmatic servlet mappings cannot override mappings from webdefault.xml using quickstart + 1201 X-Forwarded-For incorrectly set in jetty-http-forwarded.xml - + 1316 Request.extract*Parameters() reports context - + 1322 Request.extract*Parameters() throws for bad UTF8 same as for bad ISO88591 + + 1316 Request.extract*Parameters() reports context + + 1322 Request.extract*Parameters() throws for bad UTF8 same as for bad + ISO88591 + 1326 Removed non-standard "%uXXXX" encoding support + 1417 Improve classloader dumping + 1439 Allow UNC paths to function as Resource bases diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index d0fef206a70..4dbddfe05a9 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -151,14 +151,10 @@ jetty-ant 10.0.0-SNAPSHOT - - org.eclipse.jetty - jetty-client - 10.0.0-SNAPSHOT org.eclipse.jetty - jetty-continuation + jetty-client 10.0.0-SNAPSHOT @@ -175,7 +171,7 @@ org.eclipse.jetty jetty-distribution - 9.4.9-SNAPSHOT + 10.0.0-SNAPSHOT tar.gz @@ -202,7 +198,7 @@ org.eclipse.jetty jetty-home - 9.4.9-SNAPSHOT + 10.0.0-SNAPSHOT tar.gz @@ -394,7 +390,6 @@ org.eclipse.jetty.websocket websocket-common 10.0.0-SNAPSHOT - org.eclipse.jetty.websocket websocket-server diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 100d9b319e1..fedede3087c 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -29,7 +29,7 @@ copy-base-assembly-tree - process-resources + package copy-resources @@ -46,68 +46,6 @@ - - org.apache.maven.plugins - maven-antrun-plugin - - - populate distribution from home - process-resources - - run - - - - - - - - - - - set jetty.sh - process-resources - - run - - - - - - - - - removeKeystore - process-resources - - run - - - - - - - - - - - org.apache.maven.plugins - maven-remote-resources-plugin - - - generate-resources - - process - - - - org.eclipse.jetty.toolchain:jetty-distribution-remote-resources:1.2 - - ${assembly-directory} - - - - maven-dependency-plugin @@ -117,7 +55,7 @@ --> unpack-jetty-home - generate-resources + prepare-package unpack @@ -135,10 +73,76 @@ META-INF/** - + + + + org.apache.maven.plugins + maven-antrun-plugin + + + populate distribution from home + prepare-package + + run + + + + + + + + + + + set jetty.sh + prepare-package + + run + + + + + + + + + removeKeystore + prepare-package + + run + + + + + + + + + + + org.apache.maven.plugins + maven-remote-resources-plugin + + + prepare-package + + process + + + + org.eclipse.jetty.toolchain:jetty-distribution-remote-resources:1.2 + + ${assembly-directory} + + + + + + maven-dependency-plugin + copy - process-resources + prepare-package copy @@ -210,7 +214,7 @@ unpack-test-webapp-config - process-resources + prepare-package unpack @@ -232,7 +236,7 @@ unpack-test-jaas-config - process-resources + prepare-package unpack @@ -254,7 +258,7 @@ unpack-test-jndi-config - process-resources + prepare-package unpack @@ -276,7 +280,7 @@ unpack-test-spec-config - process-resources + prepare-package unpack @@ -297,7 +301,7 @@ unpack-documentation - process-resources + prepare-package unpack @@ -326,7 +330,7 @@ --> setup home - process-classes + package org.eclipse.jetty.start.Main @@ -344,7 +348,7 @@ --> setup demo-base-startd - process-classes + package org.eclipse.jetty.start.Main diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java index 38afbd8e310..0d23a9eba50 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java @@ -777,4 +777,56 @@ public class StreamResetTest extends AbstractTest Assert.assertTrue(writeLatch.await(5, TimeUnit.SECONDS)); } + + @Test + public void testResetBeforeBlockingRead() throws Exception + { + CountDownLatch requestLatch = new CountDownLatch(1); + CountDownLatch readLatch = new CountDownLatch(1); + CountDownLatch failureLatch = new CountDownLatch(1); + start(new HttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException + { + try + { + requestLatch.countDown(); + readLatch.await(); + + // Attempt to read after reset must throw. + request.getInputStream().read(); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + catch (IOException expected) + { + failureLatch.countDown(); + } + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + + MetaData.Request request = newRequest("GET", new HttpFields()); + HeadersFrame frame = new HeadersFrame(request, null, false); + FuturePromise promise = new FuturePromise<>(); + client.newStream(frame, promise, new Stream.Listener.Adapter()); + Stream stream = promise.get(5, TimeUnit.SECONDS); + ByteBuffer content = ByteBuffer.wrap(new byte[1024]); + stream.data(new DataFrame(stream.getId(), content, true), Callback.NOOP); + + Assert.assertTrue(requestLatch.await(5, TimeUnit.SECONDS)); + + stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); + // Wait for the reset to arrive to the server and be processed. + Thread.sleep(1000); + + // Try to read on server. + readLatch.countDown(); + // Read on server should fail. + Assert.assertTrue(failureLatch.await(5, TimeUnit.SECONDS)); + } } diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 1f13e6b672b..22c3f285ddb 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -10,6 +10,8 @@ Jetty JAAS support ${project.groupId}.jaas + + 2.0.0-M24 @@ -39,5 +41,64 @@ jetty-test-helper test + + org.slf4j + slf4j-simple + test + + + org.apache.directory.server + apacheds-all + ${apacheds.version} + test + + + + org.apache.directory.shared + shared-ldap-schema + + + org.apache.directory.api + api-ldap-schema-data + + + + + org.apache.directory.server + apacheds-server-integ + ${apacheds.version} + test + + + + org.apache.directory.shared + shared-ldap-schema + + + org.apache.directory.api + api-ldap-schema-data + + + + + org.apache.directory.server + apacheds-core-integ + ${apacheds.version} + test + + + + org.apache.directory.shared + shared-ldap-schema + + + org.apache.directory.api + api-ldap-schema-data + + + diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java index bb6b5da68d2..6b9cd86c28e 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java @@ -304,7 +304,7 @@ public class LdapLoginModule extends AbstractLoginModule } } - LOG.debug("user cred is: " + ldapCredential); + if(LOG.isDebugEnabled()) LOG.debug("user cred is: " + ldapCredential); return ldapCredential; } @@ -341,7 +341,7 @@ public class LdapLoginModule extends AbstractLoginModule private List getUserRolesByDn(DirContext dirContext, String userDn) throws LoginException, NamingException { - List roleList = new ArrayList(); + List roleList = new ArrayList<>(); if (dirContext == null || _roleBaseDn == null || _roleMemberAttribute == null || _roleObjectClass == null) { @@ -357,11 +357,11 @@ public class LdapLoginModule extends AbstractLoginModule Object[] filterArguments = {_roleObjectClass, _roleMemberAttribute, userDn}; NamingEnumeration results = dirContext.search(_roleBaseDn, filter, filterArguments, ctls); - LOG.debug("Found user roles?: " + results.hasMoreElements()); + if(LOG.isDebugEnabled()) LOG.debug("Found user roles?: " + results.hasMoreElements()); while (results.hasMoreElements()) { - SearchResult result = (SearchResult)results.nextElement(); + SearchResult result = results.nextElement(); Attributes attributes = result.getAttributes(); @@ -425,7 +425,8 @@ public class LdapLoginModule extends AbstractLoginModule if (_forceBindingLogin) { authed = bindingLogin(webUserName, webCredential); - } else + } + else { // This sets read and the credential UserInfo userInfo = getUserInfo(webUserName); @@ -458,7 +459,7 @@ public class LdapLoginModule extends AbstractLoginModule { if (_debug) { - e.printStackTrace(); + LOG.info( e ); } throw new LoginException("IO Error performing login."); } @@ -466,7 +467,7 @@ public class LdapLoginModule extends AbstractLoginModule { if (_debug) { - e.printStackTrace(); + LOG.info( e ); } throw new LoginException("Error obtaining user info."); } @@ -556,7 +557,7 @@ public class LdapLoginModule extends AbstractLoginModule throw new LoginException("User not found."); } - return (SearchResult)results.nextElement(); + return results.nextElement(); } diff --git a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java new file mode 100644 index 00000000000..62261b02201 --- /dev/null +++ b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java @@ -0,0 +1,177 @@ +// +// ======================================================================== +// 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.jaas; + +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifs; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.CreatePartition; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.apache.directory.server.ldap.LdapServer; +import org.eclipse.jetty.jaas.spi.LdapLoginModule; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.UserIdentity; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag; +import javax.security.auth.login.Configuration; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +/** + * JAASLdapLoginServiceTest + * + * + */ +@RunWith( FrameworkRunner.class) +@CreateLdapServer( transports = { @CreateTransport(protocol = "LDAP" ) } ) +@CreateDS(allowAnonAccess = false, partitions = { + @CreatePartition(name = "Users Partition", suffix = "ou=people,dc=jetty,dc=org"), + @CreatePartition(name = "Groups Partition", suffix = "ou=groups,dc=jetty,dc=org")}) +@ApplyLdifs({ + // Entry 1 + "dn: ou=people,dc=jetty,dc=org", + "objectClass: organizationalunit", + "objectClass: top", + "ou: people", + // Entry # 2 + "dn:uid=someone, ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: someone", + "sn: sn test", + "userPassword: complicatedpassword", + // Entry # 3 + "dn:uid=someoneelse, ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: someoneelse", + "sn: sn test", + "userPassword: verycomplicatedpassword", + // Entry 4 + "dn: ou=groups,dc=jetty,dc=org", + "objectClass: organizationalunit", + "objectClass: top", + "ou: groups", + // Entry 5 + "dn: cn=developers,ou=groups,dc=jetty,dc=org", + "objectClass: groupOfUniqueNames", + "objectClass: top", + "ou: groups", + "description: People who try to build good software", + "uniquemember: uid=someone, ou=people, dc=jetty,dc=org", + "cn: developers", + // Entry 6 + "dn: cn=admin,ou=groups,dc=jetty,dc=org", + "objectClass: groupOfUniqueNames", + "objectClass: top", + "ou: groups", + "description: People who try to run software build by developers", + "uniquemember: uid=someone, ou=people, dc=jetty,dc=org", + "uniquemember: uid=someoneelse, ou=people, dc=jetty,dc=org", + "cn: admin" +}) +public class JAASLdapLoginServiceTest +{ + private static LdapServer _ldapServer; + + public static LdapServer getLdapServer() { + return _ldapServer; + } + + public static void setLdapServer(LdapServer ldapServer) { + _ldapServer = ldapServer; + } + + public static class TestConfiguration extends Configuration + { + private boolean forceBindingLogin; + + public TestConfiguration( boolean forceBindingLogin ) + { + this.forceBindingLogin = forceBindingLogin; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) + { + Map options = new HashMap<>( ); + options.put( "hostname", "localhost" ); + options.put( "port", Integer.toString(_ldapServer.getTransports()[0].getPort())); + options.put( "contextFactory", "com.sun.jndi.ldap.LdapCtxFactory" ); + options.put( "bindDn", "uid=admin,ou=system"); + options.put( "bindPassword", "secret"); + options.put( "userBaseDn", "ou=people,dc=jetty,dc=org" ); + options.put( "roleBaseDn","ou=groups,dc=jetty,dc=org"); + options.put( "roleNameAttribute", "cn" ); + options.put( "forceBindingLogin", Boolean.toString( forceBindingLogin ) ); + AppConfigurationEntry entry = new AppConfigurationEntry( LdapLoginModule.class.getCanonicalName(), LoginModuleControlFlag.REQUIRED, options); + + return new AppConfigurationEntry[] {entry}; + } + + } + + + @Test + public void testLdapUserIdentity() throws Exception + { + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(new TestConfiguration(false)); + Request request = new Request(null, null); + UserIdentity userIdentity = ls.login( "someone", "complicatedpassword", request); + assertNotNull( userIdentity ); + assertTrue( userIdentity.isUserInRole( "developers", null) ); + assertTrue( userIdentity.isUserInRole( "admin", null) ); + assertFalse( userIdentity.isUserInRole( "blabla", null) ); + + userIdentity = ls.login( "someoneelse", "verycomplicatedpassword", request); + assertNotNull( userIdentity ); + assertFalse( userIdentity.isUserInRole( "developers", null) ); + assertTrue( userIdentity.isUserInRole( "admin", null) ); + assertFalse( userIdentity.isUserInRole( "blabla", null) ); + } + + @Test + public void testLdapUserIdentityBindingLogin() throws Exception + { + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(new TestConfiguration(true)); + Request request = new Request(null, null); + UserIdentity userIdentity = ls.login( "someone", "complicatedpassword", request); + assertNotNull( userIdentity ); + assertTrue( userIdentity.isUserInRole( "developers", null) ); + assertTrue( userIdentity.isUserInRole( "admin", null) ); + assertFalse( userIdentity.isUserInRole( "blabla", null) ); + + userIdentity = ls.login( "someone", "wrongpassword", request); + assertNull( userIdentity ); + + } + +} diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 262f8960177..34fe9594eae 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -111,6 +111,11 @@ apache-jsp ${project.version} + + org.eclipse.jetty + apache-jstl + ${project.version} + org.apache.ant ant diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java index 1a491a4c069..28f6d2622e1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java @@ -477,7 +477,7 @@ public class HttpInput extends ServletInputStream implements Runnable private void consume(Content content) { - if (content instanceof EofContent) + if (!isError() && content instanceof EofContent) { if (content == EARLY_EOF_CONTENT) _state = EARLY_EOF; diff --git a/pom.xml b/pom.xml index 919af1aac75..239e755d01b 100644 --- a/pom.xml +++ b/pom.xml @@ -206,7 +206,7 @@ @@ -1025,6 +1025,11 @@ slf4j-api ${slf4j.version} + + org.slf4j + slf4j-simple + ${slf4j.version} + com.github.jnr jnr-unixsocket @@ -1247,7 +1252,8 @@ aggregate-site @@ -1257,7 +1263,7 @@ org.apache.maven.plugins maven-javadoc-plugin - com.acme + com.acme,*.jmh http://docs.oracle.com/javase/8/docs/api/ http://docs.oracle.com/javaee/7/api @@ -1307,7 +1313,7 @@ org.eclipse.cbi.maven.plugins eclipse-jarsigner-plugin - ${cbi-plugins.version} + ${cbi-plugins.version} sign diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 8a0fe6907ec..68bf56de792 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -139,7 +139,7 @@ copy - generate-resources + package copy