Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.txt63
-rw-r--r--VERSION.txt158
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java3
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java10
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyHandlers.java2
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ProxyServer.java29
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java3
-rw-r--r--jetty-aggregate/jetty-all-server/pom.xml17
-rw-r--r--jetty-aggregate/jetty-all/pom.xml17
-rw-r--r--jetty-aggregate/jetty-client/pom.xml20
-rw-r--r--jetty-aggregate/jetty-plus/pom.xml17
-rw-r--r--jetty-aggregate/jetty-server/pom.xml17
-rw-r--r--jetty-aggregate/jetty-servlet/pom.xml17
-rw-r--r--jetty-aggregate/jetty-webapp/pom.xml19
-rw-r--r--jetty-aggregate/pom.xml18
-rw-r--r--jetty-ajp/pom.xml12
-rw-r--r--jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java2
-rw-r--r--jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Generator.java49
-rw-r--r--jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java28
-rw-r--r--jetty-ajp/src/test/java/org/eclipse/jetty/ajp/Ajp13ConnectionTest.java88
-rw-r--r--jetty-ajp/src/test/java/org/eclipse/jetty/ajp/TestAjpParser.java191
-rw-r--r--jetty-annotations/pom.xml14
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractConfiguration.java182
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java79
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java55
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassNameResolver.java4
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java14
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java33
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java19
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java22
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java72
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java45
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java22
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/Util.java14
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java210
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java173
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java83
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java40
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java169
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java138
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java40
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java108
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java66
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java8
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java41
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java52
-rw-r--r--jetty-client/pom.xml28
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java8
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java18
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java48
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java70
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java40
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java23
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java25
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java2
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java4
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java13
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionTest.java231
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java151
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java128
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java88
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java109
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java249
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java17
-rw-r--r--jetty-continuation/pom.xml10
-rw-r--r--jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java30
-rw-r--r--jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java10
-rw-r--r--jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java1
-rw-r--r--jetty-deploy/pom.xml27
-rw-r--r--jetty-deploy/src/main/config/etc/jetty-deploy.xml52
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java27
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java4
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ContextDeployer.java29
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java9
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/WebAppDeployer.java5
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java1
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java2
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java2
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java5
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java72
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java2
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java4
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java76
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/MavenTestingUtils.java6
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java33
-rw-r--r--jetty-deploy/src/test/resources/jetty-deploy-wars.xml29
-rw-r--r--jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml6
-rw-r--r--jetty-distribution/pom.xml231
-rw-r--r--jetty-distribution/src/main/assembly/jetty-assembly.xml2
-rw-r--r--jetty-distribution/src/main/resources/README.txt74
-rwxr-xr-xjetty-distribution/src/main/resources/bin/jetty.sh712
-rw-r--r--jetty-distribution/src/main/resources/contexts-available/resources.xml (renamed from jetty-distribution/src/main/resources/contexts/javadoc.xml)9
-rw-r--r--jetty-distribution/src/main/resources/etc/jetty.conf13
-rw-r--r--jetty-distribution/src/main/resources/javadoc/README.txt15
-rw-r--r--jetty-distribution/src/main/resources/javadoc/contents.html4
-rw-r--r--jetty-distribution/src/main/resources/lib/ext/.donotdelete (renamed from jetty-util/src/test/java/org/eclipse/jetty/util/RunningStatsTest.java)0
-rw-r--r--jetty-distribution/src/main/resources/logs/.donotdelete0
-rw-r--r--jetty-distribution/src/main/resources/start.ini53
-rw-r--r--jetty-distribution/src/main/resources/webapps/.donotdelete0
-rw-r--r--jetty-http/pom.xml17
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/AbstractGenerator.java47
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java2
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java101
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java237
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java19
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java168
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java206
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java233
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java146
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java120
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java226
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java11
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/PathMapTest.java66
-rw-r--r--jetty-io/pom.xml12
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java11
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/BufferUtil.java57
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java42
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java28
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java545
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java81
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java17
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java122
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java65
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java220
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslSelectChannelEndPoint.java (renamed from jetty-http/src/main/java/org/eclipse/jetty/http/ssl/SslSelectChannelEndPoint.java)249
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/BufferCacheTest.java79
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/BufferTest.java123
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/BufferUtilTest.java85
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java75
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java46
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/ThreadLocalBuffersTest.java120
-rw-r--r--jetty-jaspi/pom.xml10
-rw-r--r--jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java9
-rw-r--r--jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java1
-rw-r--r--jetty-jmx/pom.xml17
-rw-r--r--jetty-jmx/src/main/config/etc/jetty-jmx.xml44
-rw-r--r--jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java66
-rw-r--r--jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java6
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties1
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties1
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties5
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties12
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties4
-rw-r--r--jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java37
-rw-r--r--jetty-jndi/pom.xml25
-rw-r--r--jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java2
-rw-r--r--jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java4
-rw-r--r--jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java2
-rw-r--r--jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java28
-rw-r--r--jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java105
-rw-r--r--jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java47
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF2
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/pom.xml11
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/pom.xml.tycho13
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java6
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java11
-rw-r--r--jetty-osgi/jetty-osgi-boot-logback/pom.xml11
-rw-r--r--jetty-osgi/jetty-osgi-boot-logback/pom.xml.tycho2
-rw-r--r--jetty-osgi/jetty-osgi-boot-warurl/pom.xml11
-rw-r--r--jetty-osgi/jetty-osgi-boot-warurl/pom.xml.tycho14
-rw-r--r--jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java2
-rw-r--r--jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF81
-rw-r--r--jetty-osgi/jetty-osgi-boot/build.properties13
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/README2
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jdbcRealm.properties72
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ajp.xml18
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio-ssl.xml25
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio.xml23
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-debug.xml23
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-fileserver.xml37
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jaas.xml35
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jmx.xml59
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-logging.xml32
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml148
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-plus.xml81
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-proxy.xml64
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-rewrite.xml77
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-setuid.xml17
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ssl.xml29
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-sslengine.xml25
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-stats.xml19
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-win32-service.xml28
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-xinetd.xml56
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml289
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.conf5
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.properties1
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/webdefault.xml404
-rw-r--r--jetty-osgi/jetty-osgi-boot/pom.xml11
-rw-r--r--jetty-osgi/jetty-osgi-boot/pom.xml.tycho24
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java111
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java45
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java51
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java12
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java2
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java253
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java28
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java161
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java149
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java422
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java84
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java214
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyHomeHelper.java272
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java55
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java28
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java619
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java (renamed from jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerExtender.java)143
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java979
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java15
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java2
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java5
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java129
-rw-r--r--jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF2
-rw-r--r--jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml1
-rw-r--r--jetty-osgi/jetty-osgi-httpservice/pom.xml11
-rw-r--r--jetty-osgi/jetty-osgi-httpservice/pom.xml.tycho12
-rw-r--r--jetty-osgi/pom.xml30
-rw-r--r--jetty-plus/pom.xml17
-rw-r--r--jetty-plus/src/main/config/etc/jetty-plus.xml5
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java5
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java3
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java2
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractLoginModule.java6
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/DataSourceLoginModule.java7
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/JDBCLoginModule.java12
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java14
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java1
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java6
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java8
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java9
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java2
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/Configuration.java28
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java4
-rw-r--r--jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java132
-rw-r--r--jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java160
-rw-r--r--jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java71
-rw-r--r--jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java34
-rw-r--r--jetty-policy/pom.xml20
-rw-r--r--jetty-policy/src/main/config/etc/jetty-policy.xml4
-rw-r--r--jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java5
-rw-r--r--jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java156
-rw-r--r--jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyTest.java107
-rw-r--r--jetty-policy/src/test/java/org/eclipse/jetty/policy/PolicyContextTest.java121
-rw-r--r--jetty-rewrite/pom.xml10
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java2
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java41
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java2
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java47
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java32
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java36
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java48
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/LegacyRuleTest.java51
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java146
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java73
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java26
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java31
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java55
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java36
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java47
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java37
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java41
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java81
-rw-r--r--jetty-security/pom.xml13
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java8
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java29
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java230
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java17
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java7
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java5
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java5
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java23
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java7
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java3
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java2
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java2
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java15
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java2
-rw-r--r--jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java139
-rw-r--r--jetty-server/pom.xml15
-rw-r--r--jetty-server/src/main/config/etc/jetty-bio-ssl.xml4
-rw-r--r--jetty-server/src/main/config/etc/jetty-bio.xml2
-rw-r--r--jetty-server/src/main/config/etc/jetty-debug.xml2
-rw-r--r--jetty-server/src/main/config/etc/jetty-proxy.xml4
-rw-r--r--jetty-server/src/main/config/etc/jetty-requestlog.xml33
-rw-r--r--jetty-server/src/main/config/etc/jetty-ssl.xml4
-rw-r--r--jetty-server/src/main/config/etc/jetty-xinetd.xml2
-rw-r--r--jetty-server/src/main/config/etc/jetty.xml118
-rw-r--r--jetty-server/src/main/config/etc/realm.properties21
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java119
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java16
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java22
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java4
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java120
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java10
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java338
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Request.java50
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java5
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Response.java62
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Server.java97
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java11
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java29
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java7
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java81
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java491
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java6
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java85
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java8
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java4
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java6
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java348
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxyHandler.java847
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java23
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java68
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java10
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java12
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java59
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java107
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java19
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java8
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java22
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java8
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslCertificates.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java7
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java48
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java221
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java38
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java109
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java142
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelServerTest.java13
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java35
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java55
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java24
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java135
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java543
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java213
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java88
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/InclusiveByteRangeTest.java27
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java209
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java206
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java78
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java109
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java12
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ServerTest.java14
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/SocketServerTest.java12
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java447
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java69
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/AbstractProxyHandlerTest.java173
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java43
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java233
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java395
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectSSLTest.java221
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectTest.java517
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ScopedHandlerTest.java61
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java172
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java46
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java255
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslRenegotiateTest.java110
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java175
-rw-r--r--jetty-servlet/pom.xml10
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java290
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java63
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java10
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java14
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java22
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java17
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java25
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java6
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java4
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java165
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java158
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java36
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java55
-rw-r--r--jetty-servlets/pom.xml10
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java14
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java546
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java201
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java9
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java129
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java344
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java71
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java332
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java68
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java81
-rw-r--r--jetty-start/pom.xml8
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Config.java6
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Main.java436
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/log/RedirectedStreamLogger.java299
-rw-r--r--jetty-start/src/main/resources/org/eclipse/jetty/start/start.config8
-rw-r--r--jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt100
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/ConfigTest.java192
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java19
-rw-r--r--jetty-util/pom.xml12
-rw-r--r--jetty-util/src/main/config/etc/jetty-logging.xml2
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java6
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java22
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/HostMap.java101
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java358
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java3
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java13
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/PatternMatcher.java4
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java356
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java5
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java234
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java12
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java1247
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java9
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java7
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java80
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java208
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/Logger.java98
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/LoggerLog.java166
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java118
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java425
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java6
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java54
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java11
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java10
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java4
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java8
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java9
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java52
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java7
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ArrayQueueTest.java16
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java20
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java26
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/IPAddressMapTest.java172
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java37
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/MultiExceptionTest.java11
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java18
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java42
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/StringMapTest.java50
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java45
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java56
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/URITest.java30
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java29
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBufferTest.java10
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBuilderTest.java11
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java10
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java16
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java52
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java32
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java27
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java21
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java14
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java53
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java8
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java12
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/thread/TimeoutTest.java30
-rw-r--r--jetty-webapp/pom.xml54
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java262
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java2
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java141
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java68
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java41
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java (renamed from jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Fragment.java)5
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java8
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JarScanner.java2
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java25
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java911
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java2
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java282
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/TagLibConfiguration.java3
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java33
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java315
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java131
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java54
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlProcessor.java758
-rw-r--r--jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java877
-rw-r--r--jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java91
-rw-r--r--jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java79
-rw-r--r--jetty-websocket/pom.xml12
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnection.java103
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java44
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGenerator.java39
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParser.java22
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java10
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorTest.java66
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadTest.java223
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageTest.java28
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserTest.java91
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTest.java76
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTestServer.java42
-rw-r--r--jetty-xml/pom.xml15
-rw-r--r--jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java9
-rw-r--r--jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java17
-rw-r--r--jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java62
-rw-r--r--jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml2
-rw-r--r--linux-packaging.xml242
-rw-r--r--pom.xml351
-rw-r--r--test-continuation-jetty6/pom.xml12
-rw-r--r--test-continuation/pom.xml10
-rw-r--r--test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java12
-rw-r--r--test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java48
-rw-r--r--test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/ServletTest.java2
-rw-r--r--test-jetty-webapp/pom.xml62
-rw-r--r--test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml93
-rw-r--r--test-jetty-webapp/src/main/assembly/web-bundle.xml35
-rw-r--r--test-jetty-webapp/src/main/config/contexts-available/move-context.xml (renamed from test-jetty-webapp/src/main/config/contexts/demo.xml)4
-rw-r--r--test-jetty-webapp/src/main/config/contexts/test.d/override-web.xml10
-rw-r--r--test-jetty-webapp/src/main/config/contexts/test.xml15
-rw-r--r--test-jetty-webapp/src/main/config/etc/jetty-testrealm.xml23
-rw-r--r--test-jetty-webapp/src/main/config/etc/realm.properties (renamed from jetty-osgi/jetty-osgi-boot/jettyhome/etc/realm.properties)0
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/Counter.java28
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/Date2Tag.java49
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/DateTag.java66
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/Dump.java33
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/TestFilter.java32
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java21
-rw-r--r--test-jetty-webapp/src/main/webapp/META-INF/MANIFEST.MF20
-rw-r--r--test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib.tld28
-rw-r--r--test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib2.tld35
-rw-r--r--test-jetty-webapp/src/main/webapp/WEB-INF/tags/panel.tag17
-rw-r--r--test-jetty-webapp/src/main/webapp/WEB-INF/web.xml39
-rw-r--r--test-jetty-webapp/src/main/webapp/index.html7
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/bean1.jsp15
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/bean2.jsp15
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/dump.jsp23
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/expr.jsp23
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/index.html18
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/tag.jsp16
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/tag2.jsp19
-rw-r--r--test-jetty-webapp/src/main/webapp/jsp/tagfile.jsp37
-rw-r--r--test-jetty-webapp/src/main/webapp/remote.html33
-rw-r--r--test-jetty-webapp/src/main/webapp/ws/index.html2
-rw-r--r--test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java20
-rw-r--r--tests/pom.xml19
-rw-r--r--tests/test-integration/pom.xml2
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/AbstractJettyTestCase.java98
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java29
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java57
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/MavenTestingUtils.java220
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/PathAssert.java40
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpTest.java9
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpsTest.java12
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java123
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java9
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java9
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java2
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java3
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTester.java2
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java11
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTester.java6
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java22
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java10
-rw-r--r--tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java1
-rw-r--r--tests/test-loginservice/pom.xml68
-rw-r--r--tests/test-loginservice/src/test/java/org/eclipse/jetty/JdbcLoginServiceTest.java453
-rw-r--r--tests/test-loginservice/src/test/resources/createdb.sql40
-rw-r--r--tests/test-loginservice/src/test/resources/jdbcrealm.properties15
-rw-r--r--tests/test-sessions/test-hash-sessions/pom.xml14
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java7
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/LightLoadTest.java8
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java8
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java8
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java6
-rw-r--r--tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java8
-rw-r--r--tests/test-sessions/test-jdbc-sessions/pom.xml14
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java9
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java8
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java8
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java5
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java10
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LocalSessionScavengingTest.java7
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java7
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java10
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java9
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java9
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionMigrationTest.java13
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/pom.xml7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClientCrossContextSessionTest.java9
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLightLoadTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java10
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractNewSessionTest.java10
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractOrphanedSessionTest.java15
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractReentrantRequestSessionTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractServerCrossContextSessionTest.java9
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionMigrationTest.java7
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java5
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java9
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/MavenTestingUtils.java221
-rw-r--r--tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/PathAssert.java40
593 files changed, 25325 insertions, 17035 deletions
diff --git a/README.txt b/README.txt
index 640c7e9b43..118cf1a413 100644
--- a/README.txt
+++ b/README.txt
@@ -1,62 +1,17 @@
-JETTY
-=====
+This is a source checkout of the Jetty webserver.
-The Jetty project is a 100% Java HTTP Server, HTTP Client
-and Servlet Container.
-
-
-The Jetty @ eclipse project is based on the Jetty project at codehaus
-
- http://jetty.codehaus.org
-
-Ongoing development is now at the eclipse foundation
-
- http://www.eclipse.org/jetty/
-
-
-Jetty @ eclipse is open source and is dual licensed using the apache 2.0 and
-eclipse public license 1.0. You may choose either license when distributing
-jetty.
-
-
-
-BUILDING JETTY
-==============
-
-Jetty uses maven 2 as its build system. Maven will fetch
-the dependancies, build the server and assemble a runnable
-version:
+To build, use:
mvn install
+The jetty distribution will be built in
+ jetty-distribution/target/distribution
-RUNNING JETTY
-=============
-
-The run directory is either the top-level of a binary release
-or jetty-distribution/target/assembly-prep directory when built from
-source.
-
-To run with the default options:
-
- java -jar start.jar
-
-To run with specific configuration file(s)
-
- java -jar start.jar etc/jetty.xml
-
-To see the available options
-
- java -jar start.jar --help
-
-To run with JSP support
-
- java -jar start.jar OPTIONS=Server,jsp
-
-To run with JMX support
-
- java -jar start.jar OPTIONS=Server,jmx etc/jetty-jmx.xml etc/jetty.xml
-
+The first build may take a long time as maven downloads all the
+dependencies.
+The tests do a lot of stress testing, and on some machines it is
+neccessary to set the file descriptor limit to greater than 2048
+for the tests to all pass successfully.
diff --git a/VERSION.txt b/VERSION.txt
index 919f1812ea..a40c39d7f8 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1,18 +1,159 @@
-jetty-8.0.0.M1 8 April 2010
+jetty-8.0.0.M1 12 July 2010
+ 306350 Ensure jars excluded by ordering are not scanned for annotations
+ + JETTY-1224 Change jetty-8 merge rules for fragment descriptors and annotations
+ Ensure <absolute-ordering> in web.xml overrides relative <ordering> in fragments
+ Ensure empty <absolute-ordering> implies exclusion of all fragments
+ Ensure servlet-api jar class inheritance hierarchy is scanned
+
+jetty-7.1.5.v20100705
+ + Update ecj to 3.6 Helios release drop
+ + 288194 Add blacklist/whitelist to ProxyServlet and ProxyHandler
+ + 296570 EOFException for HttpExchange when HttpClient.stop called.
+ + 311550 The WebAppProvider should allow setTempDirectory
+ + 316449 Websocket disconnect fix
+ + 316584 Exception on startup if temp path has spaces and extractWAR=false
+ + 316597 Removed null check and fixed name in Resource#hrefEncodeURI
+ + 316970 jetty.sh fails to find JETTY_HOME in standard directories
+ + 316973 jetty.sh claims java installation is invalid
+ + 316976 removed quotes of JAVA_OPTIONS in jetty.sh
+ + 317019 Date HTTP header not sent for HTTP/1.0 requests
+ + 317759 Allow roles and constraints to be added after init
+ + 317906 OPTIONS correctly handles TRACE
+ + 318308 Correct quoting of unicode control characters
+ + 318470 unboxing NPE protection in HttpConnection
+ + 318551 Optional uncheck Printwriter
+ + JETTY-1237 Save local/remote address to be available after close
+
+jetty-7.1.4.v20100610
+ + 298551 SslSocketConnector does not need keystore stream
+ + 295715 AbstractSessionManager decoupled from Context
+ + 292326 Stop continuations if server is stopped.
+ + 292814 Make QoSFilter and DoSFilter JMX manageable
+ + 293222 Improve request log to handle/show asynchronous latency
+ + 294212 Can not customize session cookie path
+ + 301608 Deregister shutdown hooks
+ + 302350 org.eclipse.jetty.server.NCSARequestLog is missing JavaDoc
+ + 303661 jetty.sh failes if JETTY_HOME is not writeable
+ + 304100 Better document JMX setup in jetty-jmx.xml
+ + 305300 AsyncContext.start dispatches runnable
+ + 314299 Create test harness for JDBCLoginService
+ + 314581 Implement the Sec-Websocket handshake
+ + 315190 CrossOriginFilter avoid headers not understood by WebSocket
+ + 315687 included init script fails to test for JETTY_HOME as empty
+ + 315715 Improved Cookie version handling. Server.setMaxCookieVersion
+ + 315744 Fixed STOP.PORT and STOP.KEY in start.jar
+ + 315748 Removed --fromDaemon from start.jar (replaced with --daemon)
+ + 315925 Improved context xml configuration handling
+ + 315995 Incorrect package name in system classes list
+ + 316119 Fixed maxIdleTime for SocketEndPoint
+ + 316254 Implement @DeclareRoles
+ + 316334 Breaking change on org.eclipse.jetty.client.HttpExchange
+ + 316399 Debug output in MultiPartFilter
+ + 316413 Restarting webapp for packed war fails
+ + 316557 OSGi HttpService failure due to undeployed context handlers
+ + JETTY-547 Delay close after shutdown until request read
+ + JETTY-1231 Support context request log handler
+
+jetty-7.1.3.v20100526
+ + 296567 HttpClient RedirectListener handles new HttpDestination
+ + 297598 JDBCLoginService uses hardcoded credential class
+ + 305898 Websocket handles query string in URI
+ + 307457 Exchanges are left unhandled when connection is lost
+ + 313205 Unable to run test-jdbc-sessions tests
+ + 314177 JSTL support is broken
+ + 314009 jetty.xml configuration file on command line
+ + 314459 support maven3 for builds
+
+jetty-7.1.2.v20100523
+ + 308866 Update test suite to JUnit4 - Module jetty-util
+ + 312948 Recycle SSL crypto buffers
+ + 313196 randomly allocate ports for session test.
+ + 313278 Implement octet ranges in IPAccessHandler
+ + 313336 secure websockets
+ + 314009 updated README.txt
+ + Update links to jetty website and wiki on test webapp
+
+jetty-7.1.1.v20100517
+ + 302344 Make the list of available contexts if root context is not configured optional
+ + 304803 Remove TypeUtil Integer and Long caches
+ + 306226 HttpClient should allow changing the keystore and truststore type
+ + 308857 Update test suite to JUnit4 - Module jetty-jndi
+ + 308856 Update test suite to JUnit4 - Module jetty-jmx
+ + 308860 Update test suite to JUnit4 - Module jetty-rewrite
+ + 308850 Update test suite to JUnit4 - Module jetty-annotations
+ + 308853 Update test suite to JUnit4 - Module jetty-deploy
+ + 308854 Update test suite to JUnit4 - Module jetty-http
+ + 308859 Update test suite to JUnit4 - Module jetty-policy
+ + 308858 Update test suite to JUnit4 - Module jetty-plus
+ + 308863 Update test suite to JUnit4 - Module jetty-servlet
+ + 308855 Update test suite to JUnit4 - Module jetty-io
+ + 308862 Update test suite to JUnit4 - Module jetty-server
+ + 308867 Update test suite to JUnit4 - Module jetty-webapp
+ + 310918 Fixed write blocking for client HttpConnection
+ + 312526 Protect shutdown thread initialization during shutdown
+
+jetty-7.1.0 5 May 2010
+ + 306353 fixed cross context dispatch to root context.
+ + 311154 Added deprecated StringBuffer API for backwards compatibility
+ + 311554 Protect shutdown thread from Server#doStop
+ + 312243 Optimized timeout handling
+
+jetty-7.1.0.RC1 5 May 2010
+ + 286889 Allow System and Server classes to be set on Server instance and when applied to all webapps
+ + 291448 SessionManager has isCheckingRemoteSessionIdEncoding
+ + 296650 JETTY-1198 reset idle timeout on request body chunks
+ + 297104 HTTP CONNECT does not work correct with SSL destinations
+ + 306782 Close connection when expected 100 continues is not sent
+ + 308848 Update test suite to JUnit4 - Module jetty-ajp
+ + 308861 Update test suite to JUnit4 - Module jetty-security
+ + 308864 Update test suite to JUnit4 - Module jetty-servlets
+ + 308865 Update test suite to JUnit4 - Module jetty-start
+ + 308868 Update test suite to JUnit4 - Module jetty-websocket
+ + 308869 Update test suite to JUnit4 - Module jetty-xml
+ + 309153 Hide extracted WEB-INF/lib when running a non-extracted war
+ + 309369 Added WebSocketLoadTest
+ + 309686 Fixed response buffers usage
+ + 310094 Improved start.jar options handling and configs
+ + 310382 NPE protection when WAR is not a file
+ + 310562 SslSocketConnector fails to start if excludeCipherSuites is set
+ + 310634 Get the localport when opening a server socket.
+ + 310703 Update test suite to JUnit4 - Module tests/test-integration
+ + 310918 Synchronize content exchange
+ + 311154 Use Appendable in preference to StringBuilder/StringBuffer in APIs
+ + 311362 Optional org.eclipse.jetty.util.log.stderr.SOURCE
+ + JETTY-1030 - Improve jetty.sh script
+ + JETTY-1142 Replace Set-Cookies with same name
+
+jetty-7.1.0.RC0 27 April 2010
+ + 294563 Websocket client connection
+ + 297104 Improve handling of CONNECT method
+ 306349 ProxyServlet does not work unless deployed at /
+ + 307294 Add AbstractLifeCycle.AbstractLifeCycleListener implementation
+ 307847 Fixed combining mime type parameters
+ 307898 Handle large/async websocket messages
+ + 308009 ObjectMBean incorrectly casts getTargetException() to Exception
+ + 308420 convert jetty-plus.xml to use DeploymentManager
+ + 308925 Protect the test webapp from remote access
+ + 309466 Removed synchronization from StdErrLog
+ + 309765 Added JSP module
+ + 310051 _configurationClasses now defaults to null in WebAppContext
+ + 310094 Improved start.jar usage and config files
+ + 310431 Default ErrorHandler as server Bean
+ + 310467 Allow SocketConnector to create generic Connection objects
+ + 310603 Make Logger interface consistent
+ + 310605 Make a clean room implementation of the JSP logger bridge
+ + Add AnnotationConfiguration to jetty-plus.xml
+ + Fix jetty-plus.xml reference to addLifeCycle
+ + JETTY-1200 SSL NIO Endpoint wraps non NIO buffers
+ JETTY-1202 Use platform default algorithm for SecureRandom
+ Merged 7.0.2.v20100331
+ Add NPE protection to ContainerInitializerConfiguration
+ Temporarily remove jetty-osgi module to clarify jsp version compatibility
+ + JETTY-1212 handle long content lengths
+ + JETTY-1214 avoid ISE when scavenging invalid session
+ + JETTY-903 Stop both caches
-
-jetty-7.0.2.v20100331
+jetty-7.0.2.v20100331 31 March 2010
+ 297552 Don't call Continuation timeouts from acceptor tick
+ 298236 Additional unit tests for jetty-client
+ 306783 NPE in StdErrLog when Throwable is null
@@ -25,6 +166,17 @@ jetty-7.0.2.v20100331
+ Ensure webapps with no WEB-INF don't scan WEB-INF/lib
+ Allow Configuration array to be set on Server instance for all web apps
+jetty-6.1.24 21 April 2010
+ + JETTY-903 Stop both caches
+ + JETTY-1198 reset idle timeout on request body chunks
+ + JETTY-1200 SSL NIO Endpoint wraps non NIO buffers
+ + JETTY-1211 SetUID loadlibrary name and debug
+ + 308925 Protect the test webapp from remote access
+ + COMETD-99 ClientImpl logs exceptions in listeners with "debug" level
+ + COMETD-100 ClientImpl logs "null" as clientId
+ + COMETD-107 Reloading the application with reload extension does not fire /meta/connect handlers until long poll timeout expires
+ + Upgraded to cometd 1.1.1 client
+
jetty-6.1.23 2 April 2010
+ JSON parses NaN as null
+ Updated JSP to 2.1.v20091210
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java
index d9bf0a3446..6cf59bad31 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/FileServerXml.java
@@ -10,7 +10,8 @@ import org.eclipse.jetty.xml.XmlConfiguration;
* This server is identical to {@link FileServer}, except that it
* is configured via an {@link XmlConfiguration} config file that
* does the identical work.
- * @see http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/resources/fileserver.xml
+ * <p>
+ * See <a href="http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/src/main/resources/fileserver.xml">fileserver.xml</a>
*/
public class FileServerXml
{
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index 12a4fa6018..27f9d30bac 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -73,6 +73,16 @@ public class LikeJettyXml
ssl_connector.setTruststore(jetty_home + "/etc/keystore");
ssl_connector.setTrustPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
ssl_connector.setStatsOn(true);
+ ssl_connector.setExcludeCipherSuites(
+ new String[] {
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+ });
server.addConnector(ssl_connector);
HandlerCollection handlers = new HandlerCollection();
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyHandlers.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyHandlers.java
index 45e512f8b6..59608de10c 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyHandlers.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyHandlers.java
@@ -50,7 +50,7 @@ import org.eclipse.jetty.util.ajax.JSON;
* <li>{@link HandlerWrapper} which will nest one handler inside another. In
* this example, the HelloHandler is nested inside a HandlerWrapper that sets
* the greeting as a request attribute.
- * <li>{@link ListHandler} which will call a collection of handlers until the
+ * <li>{@link HandlerList} which will call a collection of handlers until the
* request is marked as handled. In this example, a list is used to combine the
* param handler (which only handles the request if there are parameters) and
* the wrapper handler. Frequently handler lists are terminated with the
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ProxyServer.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ProxyServer.java
index d8862c0c4b..a7fbfd6735 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ProxyServer.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ProxyServer.java
@@ -13,10 +13,12 @@
package org.eclipse.jetty.embedded;
-import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.bio.SocketConnector;
-import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.ProxyHandler;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.ProxyServlet;
public class ProxyServer
@@ -24,18 +26,25 @@ public class ProxyServer
public static void main(String[] args) throws Exception
{
Server server = new Server();
- Connector connector = new SocketConnector();
+ SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(8080);
- server.setConnectors(new Connector[]
- { connector });
+ server.addConnector(connector);
- ServletHandler handler = new ServletHandler();
- server.setHandler(handler);
+ HandlerCollection handlers = new HandlerCollection();
+ server.setHandler(handlers);
- handler.addServletWithMapping(ProxyServlet.class,"/");
+ ServletContextHandler context = new ServletContextHandler(handlers, "/", ServletContextHandler.SESSIONS);
+ ServletHolder proxyServlet = new ServletHolder(ProxyServlet.class);
+ proxyServlet.setInitParameter("whiteList", "google.com, www.eclipse.org");
+ proxyServlet.setInitParameter("blackList", "google.com/calendar/*, www.eclipse.org/committers/");
+ context.addServlet(proxyServlet, "/*");
+
+ ProxyHandler proxy = new ProxyHandler();
+ proxy.setWhite(new String[]{"mail.google.com"});
+ proxy.addWhite("www.google.com");
+ handlers.addHandler(proxy);
server.start();
- server.join();
}
}
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
index 73579c25c3..7224824cb3 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.embedded;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -49,7 +50,7 @@ public class SecuredHelloHandler
knownRoles.add("user");
knownRoles.add("admin");
- security.setConstraintMappings(new ConstraintMapping[] {mapping}, knownRoles);
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml
index 0ddae93427..0bcb8a40ac 100644
--- a/jetty-aggregate/jetty-all-server/pom.xml
+++ b/jetty-aggregate/jetty-all-server/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: All Server</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,6 +29,22 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml
index aacac05879..747e7244c9 100644
--- a/jetty-aggregate/jetty-all/pom.xml
+++ b/jetty-aggregate/jetty-all/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: All core Jetty</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,6 +29,22 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/jetty-client/pom.xml b/jetty-aggregate/jetty-client/pom.xml
index 14c5b85450..d7dc050ade 100644
--- a/jetty-aggregate/jetty-client/pom.xml
+++ b/jetty-aggregate/jetty-client/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: HTTP Client</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,11 +29,26 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins
- </groupId>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml
index 1781a798ec..228a8579f5 100644
--- a/jetty-aggregate/jetty-plus/pom.xml
+++ b/jetty-aggregate/jetty-plus/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: Plus Server</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,6 +29,22 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/jetty-server/pom.xml b/jetty-aggregate/jetty-server/pom.xml
index 333f8a0ce0..a7ccc33e04 100644
--- a/jetty-aggregate/jetty-server/pom.xml
+++ b/jetty-aggregate/jetty-server/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: HTTP Server</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,6 +29,22 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/jetty-servlet/pom.xml b/jetty-aggregate/jetty-servlet/pom.xml
index 3d9ff026b3..d7e4930f28 100644
--- a/jetty-aggregate/jetty-servlet/pom.xml
+++ b/jetty-aggregate/jetty-servlet/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: Servlet Server</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -28,6 +29,22 @@
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/jetty-webapp/pom.xml b/jetty-aggregate/jetty-webapp/pom.xml
index 781383a458..d713f165f1 100644
--- a/jetty-aggregate/jetty-webapp/pom.xml
+++ b/jetty-aggregate/jetty-webapp/pom.xml
@@ -10,6 +10,7 @@
<name>Jetty :: Aggregate :: WebApp Server</name>
<build>
+ <sourceDirectory>${project.build.directory}/sources</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -21,13 +22,29 @@
<goal>unpack-dependencies</goal>
</goals>
<configuration>
- <includes>**</includes>
+ <includes>META-INF/**,org/eclipse/**</includes>
<excludes>**/MANIFEST.MF,javax/**</excludes>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
diff --git a/jetty-aggregate/pom.xml b/jetty-aggregate/pom.xml
index d8b1f2c762..e93bd41d46 100644
--- a/jetty-aggregate/pom.xml
+++ b/jetty-aggregate/pom.xml
@@ -11,6 +11,24 @@
<name>Jetty :: Aggregate Project</name>
<packaging>pom</packaging>
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <configuration>
+ <!-- No Point running PMD on aggregate projects -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <!-- No Point running Findbugs on aggregate projects -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
<modules>
<module>jetty-server</module>
diff --git a/jetty-ajp/pom.xml b/jetty-ajp/pom.xml
index 1a7f4dce06..1fe20ca944 100644
--- a/jetty-ajp/pom.xml
+++ b/jetty-ajp/pom.xml
@@ -54,14 +54,13 @@
</execution>
</executions>
</plugin>
-
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.ajp.*</onlyAnalyze>
+ </configuration>
</plugin>
-
</plugins>
</build>
<dependencies>
@@ -73,6 +72,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
index 8f81643f98..807cc6fd98 100644
--- a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
+++ b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
@@ -34,8 +34,6 @@ import org.eclipse.jetty.server.Server;
* Connection implementation of the Ajp13 protocol. <p/> XXX Refactor to remove
* duplication of HttpConnection
*
- *
- *
*/
public class Ajp13Connection extends HttpConnection
{
diff --git a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Generator.java b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Generator.java
index 10f0b4e25a..ce2efa1bc8 100644
--- a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Generator.java
+++ b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Generator.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.ajp;
@@ -28,13 +28,12 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.util.StringUtil;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
/**
- *
- *
- */
+ *
+ *
+ */
public class Ajp13Generator extends AbstractGenerator
{
private static HashMap __headerHash = new HashMap();
@@ -117,6 +116,19 @@ public class Ajp13Generator extends AbstractGenerator
/* ------------------------------------------------------------ */
@Override
+ public boolean isRequest()
+ {
+ return false;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public boolean isResponse()
+ {
+ return true;
+ }
+ /* ------------------------------------------------------------ */
+ @Override
public void reset(boolean returnBuffers)
{
super.reset(returnBuffers);
@@ -142,10 +154,9 @@ public class Ajp13Generator extends AbstractGenerator
_last = false;
_head = false;
_noContent = false;
- _close = false;
+ _persistent = true;
-
_header = null; // Buffer for HTTP header (and maybe small _content)
_buffer = null; // Buffer for copy of passed _content
@@ -157,7 +168,7 @@ public class Ajp13Generator extends AbstractGenerator
/* ------------------------------------------------------------ */
/**
* Add content.
- *
+ *
* @param content
* @param last
* @throws IllegalArgumentException
@@ -239,7 +250,7 @@ public class Ajp13Generator extends AbstractGenerator
/* ------------------------------------------------------------ */
/**
* Add content.
- *
+ *
* @param b
* byte
* @return true if the buffers are full
@@ -289,7 +300,7 @@ public class Ajp13Generator extends AbstractGenerator
/**
* Prepare buffer for unchecked writes. Prepare the generator buffer to
* receive unchecked writes
- *
+ *
* @return the available space in the buffer.
* @throws IOException
*/
@@ -342,8 +353,8 @@ public class Ajp13Generator extends AbstractGenerator
_last = _last | allContentAdded;
boolean has_server = false;
- if (_version == HttpVersions.HTTP_1_0_ORDINAL)
- _close = true;
+ if (_persistent==null)
+ _persistent=(_version > HttpVersions.HTTP_1_0_ORDINAL);
// get a header buffer
if (_header == null)
@@ -363,7 +374,7 @@ public class Ajp13Generator extends AbstractGenerator
if (_reason == null)
_reason=HttpGenerator.getReasonBuffer(_status);
if (_reason == null)
- _reason = new ByteArrayBuffer(TypeUtil.toString(_status));
+ _reason = new ByteArrayBuffer(Integer.toString(_status));
addBuffer(_reason);
if (_status == 100 || _status == 204 || _status == 304)
@@ -380,7 +391,7 @@ public class Ajp13Generator extends AbstractGenerator
int num_fields = 0;
if (fields != null)
- {
+ {
// Add headers
int s=fields.size();
for (int f=0;f<s;f++)
@@ -389,7 +400,7 @@ public class Ajp13Generator extends AbstractGenerator
if (field==null)
continue;
num_fields++;
-
+
byte[] codes = (byte[]) __headerHash.get(field.getName());
if (codes != null)
{
@@ -440,7 +451,7 @@ public class Ajp13Generator extends AbstractGenerator
/* ------------------------------------------------------------ */
/**
* Complete the message.
- *
+ *
* @throws IOException
*/
@Override
@@ -494,7 +505,7 @@ public class Ajp13Generator extends AbstractGenerator
{
int len = -1;
int to_flush = ((_header != null && _header.length() > 0) ? 4 : 0) | ((_buffer != null && _buffer.length() > 0) ? 2 : 0);
-
+
switch (to_flush)
{
@@ -591,8 +602,6 @@ public class Ajp13Generator extends AbstractGenerator
total += len;
}
-
-
return total;
}
catch (IOException e)
diff --git a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java
index 9e94bdad38..0aabac5611 100644
--- a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java
+++ b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.ajp;
@@ -16,16 +16,16 @@ package org.eclipse.jetty.ajp;
import java.io.IOException;
import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.util.log.Log;
/**
- *
- *
- *
+ *
+ *
+ *
*/
public class Ajp13SocketConnector extends SocketConnector
{
@@ -33,12 +33,13 @@ public class Ajp13SocketConnector extends SocketConnector
static boolean __allowShutdown = false;
public Ajp13SocketConnector()
{
- super.setHeaderBufferSize(Ajp13Packet.MAX_DATA_SIZE);
+ super.setRequestHeaderSize(Ajp13Packet.MAX_DATA_SIZE);
+ super.setResponseHeaderSize(Ajp13Packet.MAX_DATA_SIZE);
super.setRequestBufferSize(Ajp13Packet.MAX_DATA_SIZE);
super.setResponseBufferSize(Ajp13Packet.MAX_DATA_SIZE);
// IN AJP protocol the socket stay open, so
- // by default the time out is set to 900 seconds
- super.setMaxIdleTime(900000);
+ // by default the time out is set to 0 seconds
+ super.setMaxIdleTime(0);
}
@Override
@@ -47,8 +48,8 @@ public class Ajp13SocketConnector extends SocketConnector
super.doStart();
Log.info("AJP13 is not a secure protocol. Please protect port {}",Integer.toString(getLocalPort()));
}
-
-
+
+
/* ------------------------------------------------------------ */
/* (non-Javadoc)
@@ -60,11 +61,14 @@ public class Ajp13SocketConnector extends SocketConnector
super.customize(endpoint,request);
if (request.isSecure())
request.setScheme(HttpSchemes.HTTPS);
+
+ System.err.println("Customize "+endpoint+" "+request);
+
}
/* ------------------------------------------------------------ */
@Override
- protected HttpConnection newHttpConnection(EndPoint endpoint)
+ protected Connection newConnection(EndPoint endpoint)
{
return new Ajp13Connection(this,endpoint,getServer());
}
diff --git a/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/Ajp13ConnectionTest.java b/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/Ajp13ConnectionTest.java
index be12b4cc46..1bf169ac8f 100644
--- a/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/Ajp13ConnectionTest.java
+++ b/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/Ajp13ConnectionTest.java
@@ -4,61 +4,81 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.ajp;
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
+import java.net.SocketTimeoutException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
-public class Ajp13ConnectionTest extends TestCase
+public class Ajp13ConnectionTest
{
- private Server _server;
- private Ajp13SocketConnector _connector;
+ private static Server _server;
+ private static Ajp13SocketConnector _connector;
private Socket _client;
- protected void setUp() throws Exception
+ @BeforeClass
+ public static void startServer() throws Exception
{
_server=new Server();
_connector=new Ajp13SocketConnector();
_connector.setPort(0);
- _connector.setMaxIdleTime(100);
_server.setConnectors(new Connector[] { _connector });
_server.setHandler(new Handler());
_server.start();
+ }
- _client=new Socket("localhost",_connector.getLocalPort());
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ _connector.close();
+ _server.stop();
+ }
+ @Before
+ public void openSocket() throws Exception
+ {
+ _client=new Socket("localhost",_connector.getLocalPort());
+ _client.setSoTimeout(500);
}
- protected void tearDown() throws Exception
+ @After
+ public void closeSocket() throws Exception
{
_client.close();
- _connector.close();
- _server.stop();
}
+ @Test
public void testPacket1() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -71,6 +91,7 @@ public class Ajp13ConnectionTest extends TestCase
assertTrue(true);
}
+ @Test
public void testPacket2() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -83,6 +104,7 @@ public class Ajp13ConnectionTest extends TestCase
assertTrue(true);
}
+ @Test
public void testPacket3() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -95,6 +117,7 @@ public class Ajp13ConnectionTest extends TestCase
assertTrue(true);
}
+ @Test
public void testSSLPacketWithIntegerKeySize() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -107,6 +130,7 @@ public class Ajp13ConnectionTest extends TestCase
assertTrue(true);
}
+ @Test
public void testSSLPacketWithStringKeySize() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -119,19 +143,21 @@ public class Ajp13ConnectionTest extends TestCase
assertTrue(true);
}
+ @Test
public void testPacketWithBody() throws Exception
{
OutputStream os=_client.getOutputStream();
- os.write(TypeUtil.fromHexString(getTestHeader()));
+ os.write(TypeUtil.fromHexString(getTestHeader()));
os.write(TypeUtil.fromHexString(getTestShortBody()));
os.write(TypeUtil.fromHexString(getTestTinyBody()));
-
+
readResponse(_client);
assertTrue(true);
}
+ @Test
public void testPacketWithChunkedBody() throws Exception
{
OutputStream os=_client.getOutputStream();
@@ -261,41 +287,29 @@ public class Ajp13ConnectionTest extends TestCase
private String getTestTinyBody()
{
StringBuffer body = new StringBuffer("");
-
+
body.append("123400042d2d0d0a");
-
+
return body.toString();
-
+
}
-
+
// TODO: char array instead of string?
private String readResponse(Socket _client) throws IOException
{
- BufferedReader br=null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
{
- br=new BufferedReader(new InputStreamReader(_client.getInputStream()));
-
- StringBuffer sb=new StringBuffer();
- String line;
- while ((line=br.readLine()) != null)
- {
- sb.append(line);
- sb.append('\n');
- }
-
- return sb.toString();
+ IO.copy(_client.getInputStream(),bout);
}
- finally
+ catch(SocketTimeoutException e)
{
- if (br != null)
- {
- br.close();
- }
+ Log.ignore(e);
}
+ return bout.toString("utf-8");
}
-
+
public static class Handler extends AbstractHandler
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
diff --git a/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/TestAjpParser.java b/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/TestAjpParser.java
index 710b4264cc..b89d2b3381 100644
--- a/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/TestAjpParser.java
+++ b/jetty-ajp/src/test/java/org/eclipse/jetty/ajp/TestAjpParser.java
@@ -4,48 +4,51 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.ajp;
import java.io.IOException;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.TypeUtil;
+import org.junit.Test;
-public class TestAjpParser extends TestCase
-{
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+public class TestAjpParser
+{
+ @Test
public void testPacket1() throws Exception
{
String packet = "123401070202000f77696474683d20485454502f312e300000122f636f6e74726f6c2f70726f647563742f2200000e3230382e32372e3230332e31323800ffff000c7777772e756c74612e636f6d000050000005a006000a6b6565702d616c69766500a00b000c7777772e756c74612e636f6d00a00e002b4d6f7a696c6c612f342e302028636f6d70617469626c653b20426f726465724d616e6167657220332e302900a0010043696d6167652f6769662c20696d6167652f782d786269746d61702c20696d6167652f6a7065672c20696d6167652f706a7065672c20696d6167652f706d672c202a2f2a00a008000130000600067570726f64310008000a4145533235362d53484100ff";
byte[] src = TypeUtil.fromHexString(packet);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
-
+
parser.parseAvailable();
-
+
assertTrue(true);
- }
-
+ }
+
+ @Test
public void testPacket2() throws Exception
{
String packet="1234020102020008485454502f312e3100000f2f6363632d7777777777772f61616100000c38382e3838382e38382e383830ffff00116363632e6363636363636363632e636f6d0001bb010009a00b00116363632e6363636363636363632e636f6d00a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004039324643303544413043444141443232303137413743443141453939353132413330443938363838423843433041454643364231363035323543433232353341000b0100ff";
@@ -58,8 +61,9 @@ public class TestAjpParser extends TestCase
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parse();
assertTrue(true);
- }
-
+ }
+
+ @Test
public void testPacket3() throws Exception
{
String packet="1234028f02020008485454502f312e3100000d2f666f726d746573742e6a737000000d3139322e3136382e342e31383000ffff00107777772e777265636b6167652e6f726700005000000aa0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a00200075554462d382c2a00a003000c677a69702c6465666c61746500a004000e656e2d67622c656e3b713d302e3500a006000a6b6565702d616c69766500a00900f95048505345535349443d37626361383232616638333466316465373663633630336366636435313938633b20667041757468436f6f6b69653d433035383430394537393344364245434633324230353234344242303039343230383344443645443533304230454637464137414544413745453231313538333745363033454435364332364446353531383635333335423433374531423637414641343533364345304546323342333642323133374243423932333943363631433131443330393842333938414546334546334146454344423746353842443b204a53455353494f4e49443d7365366331623864663432762e6a657474793300a00b00107777772e777265636b6167652e6f726700000a6b6565702d616c69766500000333303000a00e00654d6f7a696c6c612f352e3020285831313b20553b204c696e7578207838365f36343b20656e2d55533b2072763a312e382e302e3929204765636b6f2f3230303631323035202844656269616e2d312e382e302e392d3129204570697068616e792f322e313400a008000130000600066a657474793300ff";
@@ -73,79 +77,80 @@ public class TestAjpParser extends TestCase
parser.parse();
assertTrue(true);
}
-
-
+
+ @Test
public void testSSLPacketWithIntegerKeySize() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b0100ff";
byte[] src = TypeUtil.fromHexString(packet);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
-
+
parser.parseAvailable();
-
+
assertTrue(true);
}
+ @Test
public void testSSLPacketWithStringKeySize() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b000332353600ff";
byte[] src = TypeUtil.fromHexString(packet);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
-
+
parser.parseAvailable();
-
+
assertTrue(true);
}
+ @Test
public void testSSLPacketFragment() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b0100ff";
byte[] src = TypeUtil.fromHexString(packet);
-
+
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
-
+
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
-
+
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
-
+
assertTrue(true);
}
-
-
-
+
+ @Test
public void testPacketWithBody() throws Exception
{
String packet=getTestHeader();
@@ -154,7 +159,7 @@ public class TestAjpParser extends TestCase
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
-
+
final int count[]={0};
Ajp13Generator gen = new Ajp13Generator(buffers,endp)
{
@@ -167,29 +172,28 @@ public class TestAjpParser extends TestCase
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(gen);
-
+
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(0,count[0]);
-
+
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString(getTestShortBody())));
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(1,count[0]);
-
+
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString(getTestTinyBody())));
parser.parseNext();
parser.parseNext();
assertEquals(0,parser.getState());
assertEquals(1,count[0]);
-
+
assertTrue(true);
}
-
-
+ @Test
public void testPacketWithChunkedBody() throws Exception
{
String packet="123400ff02040008485454502f312e3100000f2f746573742f64756d702f696e666f0000093132372e302e302e3100ffff00096c6f63616c686f7374000050000007a00e000d4a6176612f312e352e305f313100a00b00096c6f63616c686f737400a0010034746578742f68746d6c2c20696d6167652f6769662c20696d6167652f6a7065672c202a3b20713d2e322c202a2f2a3b20713d2e3200a006000a6b6565702d616c69766500a00700216170706c69636174696f6e2f782d7777772d666f726d2d75726c656e636f6465640000115472616e736665722d456e636f64696e670000076368756e6b656400000c4d61782d466f727761726473000002313000ff";
@@ -198,7 +202,7 @@ public class TestAjpParser extends TestCase
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
-
+
final int count[]={0};
Ajp13Generator gen = new Ajp13Generator(buffers,endp)
{
@@ -211,105 +215,100 @@ public class TestAjpParser extends TestCase
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(gen);
-
+
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(1,count[0]);
-
+
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("1234007e007c7468656e616d653d746865253230717569636b25323062726f776e253230666f782532306a756d70732532306f766572253230746f2532307468652532306c617a79253230646f67253230544845253230515549434b25323042524f574e253230464f582532304a554d50532532304f564552253230544f25323054")));
while (parser.parseNext()>0);
assertEquals(1,parser.getState());
assertEquals(2,count[0]);
-
+
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("12340042004048452532304c415a59253230444f472532302676616c75656f66323d6162636465666768696a6b6c6d6e6f707172737475767778797a31323334353637383930")));
while (parser.parseNext()>0);
assertEquals(1,parser.getState());
assertEquals(3,count[0]);
-
+
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("123400020000")));
while (parser.getState()!=0 && parser.parseNext()>0);
assertEquals(0,parser.getState());
assertEquals(3,count[0]);
-
+
assertTrue(true);
}
-
-
-
+ @Test
public void testPacketFragment() throws Exception
{
String packet = "123401070202000f77696474683d20485454502f312e300000122f636f6e74726f6c2f70726f647563742f2200000e3230382e32372e3230332e31323800ffff000c7777772e756c74612e636f6d000050000005a006000a6b6565702d616c69766500a00b000c7777772e756c74612e636f6d00a00e002b4d6f7a696c6c612f342e302028636f6d70617469626c653b20426f726465724d616e6167657220332e302900a0010043696d6167652f6769662c20696d6167652f782d786269746d61702c20696d6167652f6a7065672c20696d6167652f706a7065672c20696d6167652f706d672c202a2f2a00a008000130000600067570726f64310008000a4145533235362d53484100ff";
byte[] src = TypeUtil.fromHexString(packet);
-
+
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
-
+
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
-
+
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
-
+
assertTrue(true);
}
-
-
-
+
+ @Test
public void testPacketFragmentWithBody() throws Exception
{
String packet = getTestHeader()+getTestBody();
byte[] src = TypeUtil.fromHexString(packet);
-
+
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
-
+
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
-
+
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
-
+
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
-
+
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
-
+
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
-
+
assertTrue(true);
}
-
-
+
private String getTestHeader()
{
StringBuffer header = new StringBuffer("");
-
-
+
header.append("1234026902040008485454502f31");
header.append("2e310000162f61646d696e2f496d6167");
header.append("6555706c6f61642e68746d00000a3130");
@@ -350,17 +349,13 @@ public class TestAjpParser extends TestCase
header.append("3130000500176964303d4974656d2669");
header.append("64313d32266964323d696d673200ff");
-
return header.toString();
-
}
private String getTestBody()
{
StringBuffer body = new StringBuffer("");
-
-
-
+
body.append("123402f902f72d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d3934333833323534323630");
@@ -409,17 +404,15 @@ public class TestAjpParser extends TestCase
body.append("0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d3934");
body.append("33383332353432363038372d2d0d0a");
-
-
+
return body.toString();
-
}
-
-
+
+
private String getTestShortBody()
{
StringBuffer body = new StringBuffer("");
-
+
body.append("123402f702f52d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d3934333833323534323630");
@@ -468,25 +461,20 @@ public class TestAjpParser extends TestCase
body.append("0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d3934");
body.append("33383332353432363038372d2d");
-
-
+
return body.toString();
-
}
private String getTestTinyBody()
{
StringBuffer body = new StringBuffer("");
-
+
body.append("123400042d2d0d0a");
-
+
return body.toString();
-
}
-
-
+
private static class EH implements Ajp13Parser.EventHandler
{
-
public void content(Buffer ref) throws IOException
{
// System.err.println(ref);
@@ -515,7 +503,7 @@ public class TestAjpParser extends TestCase
public void parsedProtocol(Buffer protocol) throws IOException
{
// System.err.println(protocol);
-
+
}
public void parsedQueryString(Buffer value) throws IOException
@@ -526,13 +514,13 @@ public class TestAjpParser extends TestCase
public void parsedRemoteAddr(Buffer addr) throws IOException
{
// System.err.println("addr="+addr);
-
+
}
public void parsedRemoteHost(Buffer host) throws IOException
{
// System.err.println("host="+host);
-
+
}
public void parsedRequestAttribute(String key, Buffer value) throws IOException
@@ -542,7 +530,7 @@ public class TestAjpParser extends TestCase
public void parsedServerName(Buffer name) throws IOException
{
- // System.err.println("Server:: "+name);
+ // System.err.println("Server:: "+name);
}
public void parsedServerPort(int port) throws IOException
@@ -552,7 +540,7 @@ public class TestAjpParser extends TestCase
public void parsedSslSecure(boolean secure) throws IOException
{
- // System.err.println("Secure:: "+secure);
+ // System.err.println("Secure:: "+secure);
}
public void parsedUri(Buffer uri) throws IOException
@@ -604,13 +592,10 @@ public class TestAjpParser extends TestCase
{
// System.err.println(key+":: "+value);
}
-
+
public void parsedRequestAttribute(String key, int value) throws IOException
{
// System.err.println(key+":: "+value);
}
-
}
-
-
}
diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml
index 01e1b1b27b..e619f7747c 100644
--- a/jetty-annotations/pom.xml
+++ b/jetty-annotations/pom.xml
@@ -33,25 +33,25 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
-
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.annotations.*</onlyAnalyze>
+ </configuration>
</plugin>
-
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractConfiguration.java
index 3b2e8ce837..f245642b9d 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractConfiguration.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractConfiguration.java
@@ -17,17 +17,15 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import javax.servlet.ServletContext;
-
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.Descriptor;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
+import org.eclipse.jetty.webapp.FragmentDescriptor;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
-import org.eclipse.jetty.webapp.WebXmlProcessor;
-import org.eclipse.jetty.webapp.Descriptor;
-import org.eclipse.jetty.webapp.Fragment;
import org.eclipse.jetty.webapp.Descriptor.MetaDataComplete;
@@ -35,15 +33,20 @@ public abstract class AbstractConfiguration implements Configuration
{
public static final String CONTAINER_JAR_RESOURCES = WebInfConfiguration.CONTAINER_JAR_RESOURCES;
public static final String WEB_INF_JAR_RESOURCES = WebInfConfiguration.WEB_INF_JAR_RESOURCES;
- public static final String METADATA_COMPLETE = WebXmlProcessor.METADATA_COMPLETE;
- public static final String WEBXML_CLASSNAMES = WebXmlProcessor.WEBXML_CLASSNAMES;
-
+ public static final String WEB_INF_ORDERED_JAR_RESOURCES = WebInfConfiguration.WEB_INF_ORDERED_JAR_RESOURCES;
+ public static final String METADATA_COMPLETE = MetaData.METADATA_COMPLETE;
+ public static final String WEBXML_CLASSNAMES = MetaData.WEBXML_CLASSNAMES;
+ public static final String DISCOVERED_ANNOTATIONS = "org.eclipse.jetty.discoveredAnnotations";
+
public void parseContainerPath (final WebAppContext context, final AnnotationParser parser)
throws Exception
{
//if no pattern for the container path is defined, then by default scan NOTHING
Log.debug("Scanning container jars");
-
+ List<DiscoveredAnnotation> discoveredAnnotations = new ArrayList<DiscoveredAnnotation>();
+ context.setAttribute(DISCOVERED_ANNOTATIONS, discoveredAnnotations);
+
+
//Convert from Resource to URI
ArrayList<URI> containerUris = new ArrayList<URI>();
List<Resource> jarResources = (List<Resource>)context.getAttribute(CONTAINER_JAR_RESOURCES);
@@ -71,59 +74,71 @@ public abstract class AbstractConfiguration implements Configuration
return false;
}
});
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException ("No metadata");
+
+ metaData.addDiscoveredAnnotations((List<DiscoveredAnnotation>)context.getAttribute(DISCOVERED_ANNOTATIONS));
+ context.removeAttribute(DISCOVERED_ANNOTATIONS);
}
public void parseWebInfLib (final WebAppContext context, final AnnotationParser parser)
throws Exception
{
- WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (webXmlProcessor == null)
- throw new IllegalStateException ("No processor for web xml");
-
- List<Fragment> frags = webXmlProcessor.getFragments();
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException ("No metadata");
- // + get all WEB-INF/lib jars
- // + those that are not in ORDERED_LIBS are ignored (they are excluded by ordering)
- // + those that have web-fragment.xml and metadata-complete are ignored
+ List<FragmentDescriptor> frags = metaData.getFragments();
+ //email from Rajiv Mordani jsrs 315 7 April 2010
+ //jars that do not have a web-fragment.xml are still considered fragments
+ //they have to participate in the ordering
ArrayList<URI> webInfUris = new ArrayList<URI>();
- List<Resource> jarResources = (List<Resource>)context.getAttribute(WEB_INF_JAR_RESOURCES);
- List<String> orderedJars = (List<String>)context.getAttribute(ServletContext.ORDERED_LIBS);
- for (Resource r : jarResources)
+
+ List<Resource> jars = (List<Resource>)context.getAttribute(WEB_INF_ORDERED_JAR_RESOURCES);
+
+ //No ordering just use the jars in any order
+ if (jars == null || jars.isEmpty())
+ jars = (List<Resource>)context.getAttribute(WEB_INF_JAR_RESOURCES);
+
+ List<DiscoveredAnnotation> discoveredAnnotations = new ArrayList<DiscoveredAnnotation>();
+ context.setAttribute(DISCOVERED_ANNOTATIONS, discoveredAnnotations);
+
+ for (Resource r : jars)
{
+ discoveredAnnotations.clear(); //start fresh for each jar
URI uri = r.getURI();
- Fragment f = getFragmentFromJar(r, frags);
+ FragmentDescriptor f = getFragmentFromJar(r, frags);
- //check if the jar has a web-fragment.xml
- if (f == null) //no web-fragment.xml, so scan it
- webInfUris.add(uri);
- else
+ //if a jar has no web-fragment.xml we scan it (because it is not exluded by the ordering)
+ //or if it has a fragment we scan it if it is not metadata complete
+ if (f == null || !isMetaDataComplete(f))
{
- //check if web-fragment is metadata-complete and if it has been excluded from ordering
- if (!isMetaDataComplete(f) && !isExcluded(r, orderedJars))
- webInfUris.add(uri);
+ parser.parse(uri,
+ new ClassNameResolver()
+ {
+ public boolean isExcluded (String name)
+ {
+ if (context.isSystemClass(name)) return true;
+ if (context.isServerClass(name)) return false;
+ return false;
+ }
+
+ public boolean shouldOverride (String name)
+ {
+ //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
+ if (context.isParentLoaderPriority())
+ return false;
+ return true;
+ }
+ });
+
+ metaData.addDiscoveredAnnotations(r, discoveredAnnotations);
}
}
-
- parser.parse(webInfUris.toArray(new URI[webInfUris.size()]),
- new ClassNameResolver()
- {
- public boolean isExcluded (String name)
- {
- if (context.isSystemClass(name)) return true;
- if (context.isServerClass(name)) return false;
- return false;
- }
-
- public boolean shouldOverride (String name)
- {
- //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
- if (context.isParentLoaderPriority())
- return false;
- return true;
- }
- });
+ context.removeAttribute(DISCOVERED_ANNOTATIONS);
}
public void parseWebInfClasses (final WebAppContext context, final AnnotationParser parser)
@@ -135,6 +150,13 @@ public abstract class AbstractConfiguration implements Configuration
Resource classesDir = context.getWebInf().addPath("classes/");
if (classesDir.exists())
{
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException ("No metadata");
+
+ List<DiscoveredAnnotation> discoveredAnnotations = new ArrayList<DiscoveredAnnotation>();
+ context.setAttribute(DISCOVERED_ANNOTATIONS, discoveredAnnotations);
+
parser.parse(classesDir,
new ClassNameResolver()
{
@@ -153,46 +175,22 @@ public abstract class AbstractConfiguration implements Configuration
return true;
}
});
+
+ //TODO - where to set the annotations discovered from WEB-INF/classes?
+ metaData.addDiscoveredAnnotations (discoveredAnnotations);
+ context.removeAttribute(DISCOVERED_ANNOTATIONS);
}
}
}
- public void parse25Classes (final WebAppContext context, final AnnotationParser parser)
- throws Exception
- {
- //only parse servlets, filters and listeners from web.xml
- if (Log.isDebugEnabled()) Log.debug("Scanning only classes from web.xml");
- ArrayList<String> classNames = (ArrayList<String>)context.getAttribute(WEBXML_CLASSNAMES);
- for (String s : classNames)
- {
- Class clazz = Loader.loadClass(null, s);
- parser.parse(clazz, new ClassNameResolver()
- {
- public boolean isExcluded (String name)
- {
- if (context.isSystemClass(name)) return true;
- if (context.isServerClass(name)) return false;
- return false;
- }
-
- public boolean shouldOverride (String name)
- {
- //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
- if (context.isParentLoaderPriority())
- return false;
- return true;
- }
- }, true);
- }
-
- }
+
- public Fragment getFragmentFromJar (Resource jar, List<Fragment> frags)
+ public FragmentDescriptor getFragmentFromJar (Resource jar, List<FragmentDescriptor> frags)
throws Exception
{
//check if the jar has a web-fragment.xml
- Fragment d = null;
- for (Fragment frag: frags)
+ FragmentDescriptor d = null;
+ for (FragmentDescriptor frag: frags)
{
Resource fragResource = frag.getResource(); //eg jar:file:///a/b/c/foo.jar!/META-INF/web-fragment.xml
if (Resource.isContainedIn(fragResource,jar))
@@ -209,28 +207,4 @@ public abstract class AbstractConfiguration implements Configuration
{
return (d!=null && d.getMetaDataComplete() == MetaDataComplete.True);
}
-
- public boolean isExcluded (Resource jar, List<String> orderedJars)
- {
- if (jar == null)
- return false;
-
- //no ordering, jar cannot be excluded
- if (orderedJars == null)
- return false;
-
- //ordering that excludes all jars
- if (orderedJars.isEmpty())
- return true;
-
- //ordering applied, check jar is in it
- String fullname = jar.getName();
- int i = fullname.indexOf(".jar");
- int j = fullname.lastIndexOf("/", i);
- String name = fullname.substring(j+1,i+4);
- if (orderedJars.contains(name))
- return false;
-
- return true;
- }
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
index 75b089fd0c..bb03499d8e 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
@@ -24,6 +24,7 @@ import javax.servlet.annotation.HandlesTypes;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
/**
@@ -34,6 +35,8 @@ import org.eclipse.jetty.webapp.WebAppContext;
public class AnnotationConfiguration extends AbstractConfiguration
{
public static final String CLASS_INHERITANCE_MAP = "org.eclipse.jetty.classInheritanceMap";
+
+
public void preConfigure(final WebAppContext context) throws Exception
{
@@ -59,13 +62,12 @@ public class AnnotationConfiguration extends AbstractConfiguration
//Only scan jars and classes if metadata is not complete and the web app is version 3.0, or
//a 2.5 version webapp that has specifically asked to discover annotations
if (Log.isDebugEnabled()) Log.debug("parsing annotations");
-
+
AnnotationParser parser = new AnnotationParser();
//Discoverable annotations - those that you have to look for without loading a class
parser.registerAnnotationHandler("javax.servlet.annotation.WebServlet", new WebServletAnnotationHandler(context));
parser.registerAnnotationHandler("javax.servlet.annotation.WebFilter", new WebFilterAnnotationHandler(context));
parser.registerAnnotationHandler("javax.servlet.annotation.WebListener", new WebListenerAnnotationHandler(context));
-
ClassInheritanceHandler classHandler = new ClassInheritanceHandler();
parser.registerClassHandler(classHandler);
registerServletContainerInitializerAnnotationHandlers(context, parser);
@@ -74,17 +76,30 @@ public class AnnotationConfiguration extends AbstractConfiguration
{
if (Log.isDebugEnabled()) Log.debug("Scanning all classses for annotations: webxmlVersion="+context.getServletContext().getEffectiveMajorVersion()+" configurationDiscovered="+context.isConfigurationDiscovered());
parseContainerPath(context, parser);
- parseWebInfLib (context, parser);
+ //email from Rajiv Mordani jsrs 315 7 April 2010
+ // If there is a <others/> then the ordering should be
+ // WEB-INF/classes the order of the declared elements + others.
+ // In case there is no others then it is
+ // WEB-INF/classes + order of the elements.
parseWebInfClasses(context, parser);
+ parseWebInfLib (context, parser);
}
- else
- {
- if (Log.isDebugEnabled()) Log.debug("Scanning only classes in web.xml for annotations");
- parse25Classes(context, parser);
- }
//save the type inheritance map created by the parser for later reference
context.setAttribute(CLASS_INHERITANCE_MAP, classHandler.getMap());
+
+ /*
+ * processing is now done in metadata.resolve()
+ *
+ //TODO change the time at which the discovered annotations are applied. According to the
+ //servlet spec p.81, the annotations associated with a fragment have to be applied directly
+ //after those of the fragment's descriptor. For now, to make progress, we just process them
+ //as we have been doing, ie after all the descriptors have been processed.
+ for (ClassAnnotation annotation:discoveredAnnotations)
+ {
+ annotation.apply();
+ }
+ */
}
}
@@ -105,6 +120,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
public void registerServletContainerInitializerAnnotationHandlers (WebAppContext context, AnnotationParser parser)
+ throws Exception
{
//TODO verify my interpretation of the spec. That is, that metadata-complete has nothing
//to do with finding the ServletContainerInitializers, classes designated to be of interest to them,
@@ -125,7 +141,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
{
for (ServletContainerInitializer service : loadedInitializers)
{
- if (!isFromExcludedJar(context, orderedJars, service))
+ if (!isFromExcludedJar(context, service))
{
HandlesTypes annotation = service.getClass().getAnnotation(HandlesTypes.class);
ContainerInitializer initializer = new ContainerInitializer();
@@ -147,10 +163,10 @@ public class AnnotationConfiguration extends AbstractConfiguration
}
}
else
- Log.info("No classes in HandlesTypes on initializer "+service.getClass());
+ if (Log.isDebugEnabled()) Log.debug("No classes in HandlesTypes on initializer "+service.getClass());
}
else
- Log.info("No annotation on initializer "+service.getClass());
+ if (Log.isDebugEnabled()) Log.debug("No annotation on initializer "+service.getClass());
}
}
}
@@ -163,26 +179,29 @@ public class AnnotationConfiguration extends AbstractConfiguration
* @param service
* @return
*/
- public boolean isFromExcludedJar (WebAppContext context, List<String> orderedJars, ServletContainerInitializer service)
+ public boolean isFromExcludedJar (WebAppContext context, ServletContainerInitializer service)
+ throws Exception
{
- boolean isExcluded = false;
-
- try
- {
- String loadingJarName = Thread.currentThread().getContextClassLoader().getResource(service.getClass().getName().replace('.','/')+".class").toString();
-
- int i = loadingJarName.indexOf(".jar");
- int j = loadingJarName.lastIndexOf("/", i);
- loadingJarName = loadingJarName.substring(j+1,i+4);
-
- if (orderedJars != null)
- isExcluded = orderedJars.contains(loadingJarName);
- }
- catch (Exception e)
- {
- Log.warn("Problem determining jar containing ServletContaininerInitializer "+service, e);
- }
+ List<String> orderedLibs = (List<String>)context.getAttribute(ServletContext.ORDERED_LIBS);
+
+ //If no ordering, nothing is excluded
+ if (orderedLibs == null)
+ return false;
+
+ //ordering that does not include any jars, everything excluded
+ if (orderedLibs.isEmpty())
+ return true;
+
+
+ String loadingJarName = Thread.currentThread().getContextClassLoader().getResource(service.getClass().getName().replace('.','/')+".class").toString();
+
+ int i = loadingJarName.indexOf(".jar");
+ if (i < 0)
+ return false; //not from a jar therefore not from WEB-INF so not excludable
+
+ int j = loadingJarName.lastIndexOf("/", i);
+ loadingJarName = loadingJarName.substring(j+1,i+4);
- return isExcluded;
+ return (!orderedLibs.contains(loadingJarName));
}
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index 56577ef0de..85b0d039cf 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -43,7 +43,7 @@ import org.objectweb.asm.commons.EmptyVisitor;
public class AnnotationParser
{
protected List<String> _parsedClassNames = new ArrayList<String>();
- protected Map<String, DiscoverableAnnotationHandler> _annotationHandlers = new HashMap<String, DiscoverableAnnotationHandler>();
+ protected Map<String, List<DiscoverableAnnotationHandler>> _annotationHandlers = new HashMap<String, List<DiscoverableAnnotationHandler>>();
protected List<ClassHandler> _classHandlers = new ArrayList<ClassHandler>();
protected List<MethodHandler> _methodHandlers = new ArrayList<MethodHandler>();
protected List<FieldHandler> _fieldHandlers = new ArrayList<FieldHandler>();
@@ -310,12 +310,15 @@ public class AnnotationParser
public void visitEnd()
{
super.visitEnd();
-
+
//call all AnnotationHandlers with classname, annotation name + values
- DiscoverableAnnotationHandler handler = AnnotationParser.this._annotationHandlers.get(_annotationName);
- if (handler != null)
+ List<DiscoverableAnnotationHandler> handlers = AnnotationParser.this._annotationHandlers.get(_annotationName);
+ if (handlers != null)
{
- handler.handleClass(_className, _version, _access, _signature, _superName, _interfaces, _annotationName, _annotationValues);
+ for (DiscoverableAnnotationHandler h:handlers)
+ {
+ h.handleClass(_className, _version, _access, _signature, _superName, _interfaces, _annotationName, _annotationValues);
+ }
}
}
};
@@ -340,10 +343,13 @@ public class AnnotationParser
{
super.visitEnd();
//call all AnnotationHandlers with classname, method, annotation name + values
- DiscoverableAnnotationHandler handler = AnnotationParser.this._annotationHandlers.get(_annotationName);
- if (handler != null)
+ List<DiscoverableAnnotationHandler> handlers = AnnotationParser.this._annotationHandlers.get(_annotationName);
+ if (handlers != null)
{
- handler.handleMethod(_className, name, access, methodDesc, signature, exceptions, _annotationName, _annotationValues);
+ for (DiscoverableAnnotationHandler h:handlers)
+ {
+ h.handleMethod(_className, name, access, methodDesc, signature, exceptions, _annotationName, _annotationValues);
+ }
}
}
};
@@ -369,10 +375,13 @@ public class AnnotationParser
public void visitEnd()
{
super.visitEnd();
- DiscoverableAnnotationHandler handler = AnnotationParser.this._annotationHandlers.get(_annotationName);
- if (handler != null)
+ List<DiscoverableAnnotationHandler> handlers = AnnotationParser.this._annotationHandlers.get(_annotationName);
+ if (handlers != null)
{
- handler.handleField(_className, fieldName, access, fieldType, signature, value, _annotationName, _annotationValues);
+ for (DiscoverableAnnotationHandler h:handlers)
+ {
+ h.handleField(_className, fieldName, access, fieldType, signature, value, _annotationName, _annotationValues);
+ }
}
}
};
@@ -383,9 +392,22 @@ public class AnnotationParser
}
+ /**
+ * Register a handler that will be called back when the named annotation is
+ * encountered on a class.
+ *
+ * @param annotationName
+ * @param handler
+ */
public void registerAnnotationHandler (String annotationName, DiscoverableAnnotationHandler handler)
{
- _annotationHandlers.put(annotationName, handler);
+ List<DiscoverableAnnotationHandler> handlers = _annotationHandlers.get(annotationName);
+ if (handlers == null)
+ {
+ handlers = new ArrayList<DiscoverableAnnotationHandler>();
+ _annotationHandlers.put(annotationName, handlers);
+ }
+ handlers.add(handler);
}
public void registerClassHandler (ClassHandler handler)
@@ -499,7 +521,6 @@ public class AnnotationParser
* Only class files in jar files will be scanned.
* @param loader
* @param visitParents
- * @param jarNamePattern
* @param nullInclusive
* @param resolver
* @throws Exception
@@ -588,6 +609,14 @@ public class AnnotationParser
scanner.scan(null, uris, true);
}
+ public void parse (URI uri, final ClassNameResolver resolver)
+ throws Exception
+ {
+ if (uri == null)
+ return;
+ URI[] uris = {uri};
+ parse(uris, resolver);
+ }
private void scanClass (InputStream is)
throws IOException
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassNameResolver.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassNameResolver.java
index a76544306d..9aa6f3ea07 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassNameResolver.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassNameResolver.java
@@ -21,7 +21,7 @@ public interface ClassNameResolver
* Based on the execution context, should the class represented
* by "name" be excluded from consideration?
* @param name
- * @return
+ * @return true if classname is excluded
*/
public boolean isExcluded (String name);
@@ -31,7 +31,7 @@ public interface ClassNameResolver
* represented by "name" is detected, should the existing
* one be overridden or not?
* @param name
- * @return
+ * @return true if name should be overridden
*/
public boolean shouldOverride (String name);
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
index 051b8074fd..e224855d69 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
@@ -32,7 +32,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
/**
* @param introspectAncestors
@@ -40,7 +40,7 @@ public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotat
public DeclareRolesAnnotationHandler(WebAppContext context)
{
super(false);
- _wac = context;
+ _context = context;
}
@@ -57,15 +57,11 @@ public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotat
return;
String[] roles = declareRoles.value();
-
+
if (roles != null && roles.length > 0)
{
- HashSet<String> union = new HashSet<String>();
- Set<String> existing = ((ConstraintSecurityHandler)_wac.getSecurityHandler()).getRoles();
- if (existing != null)
- union.addAll(existing);
- union.addAll(Arrays.asList(roles));
- ((ConstraintSecurityHandler)_wac.getSecurityHandler()).setRoles(union);
+ for (String r:roles)
+ ((ConstraintSecurityHandler)_context.getSecurityHandler()).addRole(r);
}
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java
index 24e28104fb..24a21c5dd0 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java
@@ -19,6 +19,8 @@ import javax.servlet.annotation.MultipartConfig;
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.webapp.Descriptor;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
/**
@@ -28,13 +30,13 @@ import org.eclipse.jetty.webapp.WebAppContext;
*/
public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
public MultiPartConfigAnnotationHandler(WebAppContext context)
{
//TODO verify that MultipartConfig is not inheritable
super(false);
- _wac = context;
+ _context = context;
}
/**
* @see org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler#doHandle(java.lang.Class)
@@ -48,24 +50,41 @@ public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnno
if (multi == null)
return;
-
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+
//TODO: The MultipartConfigElement needs to be set on the ServletHolder's Registration.
//How to identify the correct Servlet? If the Servlet has no WebServlet annotation on it, does it mean that this MultipartConfig
//annotation applies to all declared instances in web.xml/programmatically?
//Assuming TRUE for now.
-
- ServletHolder[] holders = _wac.getServletHandler().getServlets();
+ ServletHolder holder = getServletHolderForClass(clazz);
+ if (holder != null)
+ {
+ Descriptor d = metaData.getOriginDescriptor(holder.getName()+".servlet.multipart-config");
+ //if a descriptor has already set the value for multipart config, do not
+ //let the annotation override it
+ if (d == null)
+ {
+ metaData.setOrigin(holder.getName()+".servlet.multipart-config");
+ holder.getRegistration().setMultipartConfig(new MultipartConfigElement(multi));
+ }
+ }
+ }
+
+ private ServletHolder getServletHolderForClass (Class clazz)
+ {
+ ServletHolder holder = null;
+ ServletHolder[] holders = _context.getServletHandler().getServlets();
if (holders != null)
{
for (ServletHolder h : holders)
{
if (h.getClassName().equals(clazz.getName()))
{
- h.getRegistration().setMultipartConfig(new MultipartConfigElement(multi));
+ holder = h;
}
}
}
+ return holder;
}
-
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java
index 1cae8bc7b3..357cd4e39f 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java
@@ -21,18 +21,19 @@ import javax.annotation.PostConstruct;
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
protected LifeCycleCallbackCollection _callbacks;
public PostConstructAnnotationHandler (WebAppContext wac)
{
super(true);
- _wac = wac;
- _callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
+ _context = wac;
+ _callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
}
@@ -55,7 +56,17 @@ public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnota
throw new IllegalStateException(m+" throws checked exceptions");
if (Modifier.isStatic(m.getModifiers()))
throw new IllegalStateException(m+" is static");
-
+
+ //ServletSpec 3.0 p80 If web.xml declares even one post-construct then all post-constructs
+ //in fragments must be ignored. Otherwise, they are additive.
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ MetaData.Origin origin = metaData.getOrigin("post-construct");
+ if (origin != null &&
+ (origin == MetaData.Origin.WebXml ||
+ origin == MetaData.Origin.WebDefaults ||
+ origin == MetaData.Origin.WebOverride))
+ return;
+
PostConstructCallback callback = new PostConstructCallback();
callback.setTarget(clazz.getName(), m.getName());
_callbacks.add(callback);
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java
index 5e551e1422..3b593f5ca7 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java
@@ -21,23 +21,23 @@ import javax.annotation.PreDestroy;
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- WebAppContext _wac;
+ WebAppContext _context;
LifeCycleCallbackCollection _callbacks;
public PreDestroyAnnotationHandler (WebAppContext wac)
{
super(true);
- _wac = wac;
- _callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
+ _context = wac;
+ _callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
}
public void doHandle(Class clazz)
- {
-
+ {
//Check that the PreDestroy is on a class that we're interested in
if (Util.isServletType(clazz))
{
@@ -55,7 +55,17 @@ public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotatio
throw new IllegalStateException(m+" throws checked exceptions");
if (Modifier.isStatic(m.getModifiers()))
throw new IllegalStateException(m+" is static");
-
+
+ //ServletSpec 3.0 p80 If web.xml declares even one predestroy then all predestroys
+ //in fragments must be ignored. Otherwise, they are additive.
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ MetaData.Origin origin = metaData.getOrigin("pre-destroy");
+ if (origin != null &&
+ (origin == MetaData.Origin.WebXml ||
+ origin == MetaData.Origin.WebDefaults ||
+ origin == MetaData.Origin.WebOverride))
+ return;
+
PreDestroyCallback callback = new PreDestroyCallback();
callback.setTarget(clazz.getName(), m.getName());
_callbacks.add(callback);
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java
index eb2a249e6f..c3e5548146 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java
@@ -26,18 +26,20 @@ import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectab
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.MetaData.Origin;
public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
protected InjectionCollection _injections;
public ResourceAnnotationHandler (WebAppContext wac)
{
super(true);
- _wac = wac;
- _injections = (InjectionCollection)_wac.getAttribute(InjectionCollection.INJECTION_COLLECTION);
+ _context = wac;
+ _injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
}
@@ -78,8 +80,8 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
try
{
- if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name,mappedName))
- if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name,mappedName))
+ if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name,mappedName))
+ if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name,mappedName))
throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
}
catch (NamingException e)
@@ -109,29 +111,41 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
}
//work out default name
- String name = clazz.getCanonicalName()+"/"+field.getName();
-
+ String name = clazz.getCanonicalName()+"/"+field.getName();
//allow @Resource name= to override the field name
name = (resource.name()!=null && !resource.name().trim().equals("")? resource.name(): name);
String mappedName = (resource.mappedName()!=null && !resource.mappedName().trim().equals("")?resource.mappedName():null);
//get the type of the Field
Class type = field.getType();
-
- //check if an injection has already been setup for this target by web.xml
- Injection webXmlInjection = _injections.getInjection(name, clazz, field);
- if (webXmlInjection == null)
+
+ //Servlet Spec 3.0 p. 76
+ //If a descriptor has specified at least 1 injection target for this
+ //resource, then it overrides this annotation
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ if (metaData.getOriginDescriptor("resource-ref."+name+".injection") != null)
+ {
+ //at least 1 injection was specified for this resource by a descriptor, so
+ //it overrides this annotation
+ return;
+ }
+
+ //No injections for this resource in any descriptors, so we can add it
+ //Does the injection already exist?
+ Injection injection = _injections.getInjection(name, clazz, field);
+ if (injection == null)
{
+ //No injection has been specified, add it
try
{
- boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName);
+ boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
if (!bound)
- bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName);
+ bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
if (!bound)
bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
if (!bound)
{
- //see if there is an env-entry value been bound from web.xml
+ //see if there is an env-entry value been bound
try
{
InitialContext ic = new InitialContext();
@@ -149,11 +163,14 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
{
Log.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
// Make the Injection for it if the binding succeeded
- Injection injection = new Injection();
+ injection = new Injection();
injection.setTarget(clazz, field, type);
injection.setJndiName(name);
injection.setMappingName(mappedName);
_injections.add(injection);
+
+ //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
+ metaData.setOrigin("resource-ref."+name+".injection");
}
else if (!Util.isEnvEntryType(type))
{
@@ -182,7 +199,6 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
*
* This will generate a JNDI entry, and an Injection to be
* processed when an instance of the class is created.
- * @param injections
*/
public void handleMethod(Class clazz, Method method)
{
@@ -245,19 +261,31 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
Class paramType = method.getParameterTypes()[0];
Class resourceType = resource.type();
+
+ //Servlet Spec 3.0 p. 76
+ //If a descriptor has specified at least 1 injection target for this
+ //resource, then it overrides this annotation
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ if (metaData.getOriginDescriptor("resource-ref."+name+".injection") != null)
+ {
+ //at least 1 injection was specified for this resource by a descriptor, so
+ //it overrides this annotation
+ return;
+ }
+
//check if an injection has already been setup for this target by web.xml
- Injection webXmlInjection = _injections.getInjection(name, clazz, method, paramType);
- if (webXmlInjection == null)
+ Injection injection = _injections.getInjection(name, clazz, method, paramType);
+ if (injection == null)
{
try
{
//try binding name to environment
//try the webapp's environment first
- boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName);
+ boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
//try the server's environment
if (!bound)
- bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName);
+ bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
//try the jvm's environment
if (!bound)
@@ -284,11 +312,13 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
{
Log.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
// Make the Injection for it
- Injection injection = new Injection();
+ injection = new Injection();
injection.setTarget(clazz, method,paramType,resourceType);
injection.setJndiName(name);
injection.setMappingName(mappedName);
_injections.add(injection);
+ //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
+ metaData.setOrigin("resource-ref."+name+".injection");
}
else if (!Util.isEnvEntryType(paramType))
{
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java
index 1c17208770..cf849771d7 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java
@@ -20,24 +20,27 @@ import javax.servlet.Servlet;
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.plus.annotation.RunAsCollection;
+import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.Descriptor;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
public RunAsAnnotationHandler (WebAppContext wac)
{
//Introspect only the given class for a RunAs annotation, as it is a class level annotation,
//and according to Common Annotation Spec p2-6 a class-level annotation is not inheritable.
super(false);
- _wac = wac;
+ _context = wac;
}
public void doHandle (Class clazz)
{
- RunAsCollection runAsCollection = (RunAsCollection)_wac.getAttribute(RunAsCollection.RUNAS_COLLECTION);
+ RunAsCollection runAsCollection = (RunAsCollection)_context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
if (!Servlet.class.isAssignableFrom(clazz))
return;
@@ -48,10 +51,22 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
String role = runAs.value();
if (role != null)
{
- org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs();
- ra.setTargetClassName(clazz.getCanonicalName());
- ra.setRoleName(role);
- runAsCollection.add(ra);
+ ServletHolder holder = getServletHolderForClass(clazz);
+ if (holder != null)
+ {
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ Descriptor d = metaData.getOriginDescriptor(holder.getName()+".servlet.run-as");
+ //if a descriptor has already set the value for run-as, do not
+ //let the annotation override it
+ if (d == null)
+ {
+ metaData.setOrigin(holder.getName()+".servlet.run-as");
+ org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs();
+ ra.setTargetClassName(clazz.getCanonicalName());
+ ra.setRoleName(role);
+ runAsCollection.add(ra);
+ }
+ }
}
else
Log.warn("Bad value for @RunAs annotation on class "+clazz.getName());
@@ -71,4 +86,20 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
Log.warn("@RunAs annotation ignored on method: "+className+"."+methodName+" "+signature);
}
+ private ServletHolder getServletHolderForClass (Class clazz)
+ {
+ ServletHolder holder = null;
+ ServletHolder[] holders = _context.getServletHandler().getServlets();
+ if (holders != null)
+ {
+ for (ServletHolder h : holders)
+ {
+ if (h.getClassName().equals(clazz.getName()))
+ {
+ holder = h;
+ }
+ }
+ }
+ return holder;
+ }
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java
index b6556a7ace..aac9748b61 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java
@@ -52,12 +52,12 @@ import org.eclipse.jetty.webapp.WebAppContext;
public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
- private WebAppContext _wac;
+ private WebAppContext _context;
public ServletSecurityAnnotationHandler(WebAppContext wac)
{
super(false);
- _wac = wac;
+ _context = wac;
}
/**
@@ -65,7 +65,7 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
*/
public void doHandle(Class clazz)
{
- if (!(_wac.getSecurityHandler() instanceof ConstraintAware))
+ if (!(_context.getSecurityHandler() instanceof ConstraintAware))
{
Log.warn("SecurityHandler not ConstraintAware, skipping security annotation processing");
return;
@@ -79,7 +79,7 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
//of the url patterns defined for this servlet, then skip the security annotation.
List<ServletMapping> servletMappings = getServletMappings(clazz.getCanonicalName());
- List<ConstraintMapping> constraintMappings = LazyList.array2List(((ConstraintAware)_wac.getSecurityHandler()).getConstraintMappings());
+ List<ConstraintMapping> constraintMappings = ((ConstraintAware)_context.getSecurityHandler()).getConstraintMappings();
if (constraintsExist(servletMappings, constraintMappings))
{
@@ -87,6 +87,9 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
return;
}
+ //Make a fresh list
+ constraintMappings = new ArrayList<ConstraintMapping>();
+
//Get the values that form the constraints that will apply unless there are HttpMethodConstraints to augment them
HttpConstraint defaults = servletSecurity.value();
@@ -102,9 +105,10 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
servletSecurity.httpMethodConstraints()));
//set up the security constraints produced by the annotation
- ConstraintAware securityHandler = (ConstraintAware)_wac.getSecurityHandler();
-
- securityHandler.setConstraintMappings((ConstraintMapping[]) LazyList.toArray(constraintMappings,ConstraintMapping.class),securityHandler.getRoles());
+ ConstraintAware securityHandler = (ConstraintAware)_context.getSecurityHandler();
+
+ for (ConstraintMapping m:constraintMappings)
+ securityHandler.addConstraintMapping(m);
}
@@ -234,11 +238,11 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
protected List<ServletMapping> getServletMappings(String className)
{
List<ServletMapping> results = new ArrayList<ServletMapping>();
- ServletMapping[] mappings = _wac.getServletHandler().getServletMappings();
+ ServletMapping[] mappings = _context.getServletHandler().getServletMappings();
for (ServletMapping mapping : mappings)
{
//Check the name of the servlet that this mapping applies to, and then find the ServletHolder for it to find it's class
- ServletHolder holder = _wac.getServletHandler().getServlet(mapping.getServletName());
+ ServletHolder holder = _context.getServletHandler().getServlet(mapping.getServletName());
if (holder.getClassName().equals(className))
results.add(mapping);
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/Util.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/Util.java
index b920ab711e..5b394efeb6 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/Util.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/Util.java
@@ -21,8 +21,6 @@ import org.objectweb.asm.Type;
/**
* Util
- *
- *
*/
public class Util
{
@@ -37,8 +35,16 @@ public class Util
/**
* Check if the presented method belongs to a class that is one
* of the classes with which a servlet container should be concerned.
- * @param m
- * @return
+ * @param c
+ * @return true if class is a type of one of the following:
+ * ({@link javax.servlet.Servlet},
+ * {@link javax.servlet.Filter},
+ * {@link javax.servlet.ServletContextListener},
+ * {@link javax.servlet.ServletContextAttributeListener},
+ * {@link javax.servlet.ServletRequestListener},
+ * {@link javax.servlet.ServletRequestAttributeListener},
+ * {@link javax.servlet.http.HttpSessionListener},
+ * {@link javax.servlet.http.HttpSessionAttributeListener})
*/
public static boolean isServletType (Class c)
{
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java
new file mode 100644
index 0000000000..5a101f60cf
--- /dev/null
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java
@@ -0,0 +1,210 @@
+// ========================================================================
+// Copyright (c) 2010 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.annotations;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
+
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.Holder;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
+import org.eclipse.jetty.webapp.MetaData;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.MetaData.Origin;
+
+/**
+ * WebFilterAnnotation
+ *
+ *
+ */
+public class WebFilterAnnotation extends DiscoveredAnnotation
+{
+
+ /**
+ * @param context
+ * @param className
+ */
+ public WebFilterAnnotation(WebAppContext context, String className)
+ {
+ super(context, className);
+ }
+
+ /**
+ * @see org.eclipse.jetty.annotations.ClassAnnotation#apply()
+ */
+ public void apply()
+ {
+ // TODO verify against rules for annotation v descriptor
+
+ Class clazz = getTargetClass();
+ if (clazz == null)
+ {
+ Log.warn(_className+" cannot be loaded");
+ return;
+ }
+
+
+ //Servlet Spec 8.1.2
+ if (!Filter.class.isAssignableFrom(clazz))
+ {
+ Log.warn(clazz.getName()+" is not assignable from javax.servlet.Filter");
+ return;
+ }
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+
+ WebFilter filterAnnotation = (WebFilter)clazz.getAnnotation(WebFilter.class);
+
+ if (filterAnnotation.value().length > 0 && filterAnnotation.urlPatterns().length > 0)
+ {
+ Log.warn(clazz.getName()+" defines both @WebFilter.value and @WebFilter.urlPatterns");
+ return;
+ }
+
+ String name = (filterAnnotation.filterName().equals("")?clazz.getName():filterAnnotation.filterName());
+ String[] urlPatterns = filterAnnotation.value();
+ if (urlPatterns.length == 0)
+ urlPatterns = filterAnnotation.urlPatterns();
+
+ FilterHolder holder = _context.getServletHandler().getFilter(name);
+ if (holder == null)
+ {
+ //Filter with this name does not already exist, so add it
+ holder = _context.getServletHandler().newFilterHolder(Holder.Source.ANNOTATION);
+ holder.setName(name);
+
+ holder.setHeldClass(clazz);
+ metaData.setOrigin(name+".filter.filter-class");
+
+ holder.setDisplayName(filterAnnotation.displayName());
+ metaData.setOrigin(name+".filter.display-name");
+
+ for (WebInitParam ip: filterAnnotation.initParams())
+ {
+ holder.setInitParameter(ip.name(), ip.value());
+ metaData.setOrigin(name+".filter.init-param."+ip.name());
+ }
+
+ FilterMapping mapping = new FilterMapping();
+ mapping.setFilterName(holder.getName());
+
+ if (urlPatterns.length > 0)
+ {
+ ArrayList paths = new ArrayList();
+ for (String s:urlPatterns)
+ {
+ paths.add(Util.normalizePattern(s));
+ }
+ mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
+ }
+
+ if (filterAnnotation.servletNames().length > 0)
+ {
+ ArrayList<String> names = new ArrayList<String>();
+ for (String s : filterAnnotation.servletNames())
+ {
+ names.add(s);
+ }
+ mapping.setServletNames((String[])names.toArray(new String[names.size()]));
+ }
+
+ EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
+ for (DispatcherType d : filterAnnotation.dispatcherTypes())
+ {
+ dispatcherSet.add(d);
+ }
+ mapping.setDispatcherTypes(dispatcherSet);
+ metaData.setOrigin(name+".filter.mappings");
+
+ holder.setAsyncSupported(filterAnnotation.asyncSupported());
+ metaData.setOrigin(name+".filter.async-supported");
+
+ _context.getServletHandler().addFilter(holder);
+ _context.getServletHandler().addFilterMapping(mapping);
+ }
+ else
+ {
+ //A Filter definition for the same name already exists from web.xml
+ //ServletSpec 3.0 p81 if the Filter is already defined and has mappings,
+ //they override the annotation. If it already has DispatcherType set, that
+ //also overrides the annotation. Init-params are additive, but web.xml overrides
+ //init-params of the same name.
+ for (WebInitParam ip: filterAnnotation.initParams())
+ {
+ //if (holder.getInitParameter(ip.name()) == null)
+ if (metaData.getOrigin(name+".filter.init-param."+ip.name())==Origin.NotSet)
+ {
+ holder.setInitParameter(ip.name(), ip.value());
+ metaData.setOrigin(name+".filter.init-param."+ip.name());
+ }
+ }
+
+ FilterMapping[] mappings = _context.getServletHandler().getFilterMappings();
+ boolean mappingExists = false;
+ if (mappings != null)
+ {
+ for (FilterMapping m:mappings)
+ {
+ if (m.getFilterName().equals(name))
+ {
+ mappingExists = true;
+ break;
+ }
+ }
+ }
+ //if a descriptor didn't specify at least one mapping, use the mappings from the annotation and the DispatcherTypes
+ //from the annotation
+ if (!mappingExists)
+ {
+ FilterMapping mapping = new FilterMapping();
+ mapping.setFilterName(holder.getName());
+
+ if (urlPatterns.length > 0)
+ {
+ ArrayList paths = new ArrayList();
+ for (String s:urlPatterns)
+ {
+ paths.add(Util.normalizePattern(s));
+ }
+ mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
+ }
+ if (filterAnnotation.servletNames().length > 0)
+ {
+ ArrayList<String> names = new ArrayList<String>();
+ for (String s : filterAnnotation.servletNames())
+ {
+ names.add(s);
+ }
+ mapping.setServletNames((String[])names.toArray(new String[names.size()]));
+ }
+
+ EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
+ for (DispatcherType d : filterAnnotation.dispatcherTypes())
+ {
+ dispatcherSet.add(d);
+ }
+ mapping.setDispatcherTypes(dispatcherSet);
+ _context.getServletHandler().addFilterMapping(mapping);
+ metaData.setOrigin(name+".filter.mappings");
+ }
+ }
+ }
+
+}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java
index b252dafb7c..5ee2d729fb 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2009 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 2009-2010 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
@@ -13,178 +13,33 @@
package org.eclipse.jetty.annotations;
-import java.util.ArrayList;
-import java.util.EnumSet;
import java.util.List;
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.annotation.WebInitParam;
-
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.servlet.FilterMapping;
-import org.eclipse.jetty.servlet.Holder;
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
import org.eclipse.jetty.webapp.WebAppContext;
+/**
+ * WebFilterAnnotationHandler
+ *
+ *
+ */
public class WebFilterAnnotationHandler implements DiscoverableAnnotationHandler
{
- protected WebAppContext _wac;
-
+ protected WebAppContext _context;
+
public WebFilterAnnotationHandler (WebAppContext wac)
{
- _wac = wac;
+ _context = wac;
}
-
+
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
- Class clazz = null;
- try
- {
- clazz = Loader.loadClass(null, className);
- }
- catch (Exception e)
- {
- Log.warn(e);
- return;
- }
-
- //Servlet Spec 8.1.2
- if (!Filter.class.isAssignableFrom(clazz))
- {
- Log.warn(clazz.getName()+" is not assignable from javax.servlet.Filter");
- return;
- }
-
- WebFilter filterAnnotation = (WebFilter)clazz.getAnnotation(WebFilter.class);
-
- if (filterAnnotation.value().length > 0 && filterAnnotation.urlPatterns().length > 0)
- {
- Log.warn(clazz.getName()+" defines both @WebFilter.value and @WebFilter.urlPatterns");
- return;
- }
-
- String name = (filterAnnotation.filterName().equals("")?clazz.getName():filterAnnotation.filterName());
- String[] urlPatterns = filterAnnotation.value();
- if (urlPatterns.length == 0)
- urlPatterns = filterAnnotation.urlPatterns();
-
- FilterHolder holder = _wac.getServletHandler().getFilter(name);
- if (holder == null)
- {
- //Filter with this name does not already exist, so add it
- holder = _wac.getServletHandler().newFilterHolder(Holder.Source.ANNOTATION);
- holder.setHeldClass(clazz);
- holder.setName(name);
- holder.setDisplayName(filterAnnotation.displayName());
-
- for (WebInitParam ip: filterAnnotation.initParams())
- {
- holder.setInitParameter(ip.name(), ip.value());
- }
-
- FilterMapping mapping = new FilterMapping();
- mapping.setFilterName(holder.getName());
-
- if (urlPatterns.length > 0)
- {
- ArrayList paths = new ArrayList();
- for (String s:urlPatterns)
- {
- paths.add(Util.normalizePattern(s));
- }
- mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
- }
-
- if (filterAnnotation.servletNames().length > 0)
- {
- ArrayList<String> names = new ArrayList<String>();
- for (String s : filterAnnotation.servletNames())
- {
- names.add(s);
- }
- mapping.setServletNames((String[])names.toArray(new String[names.size()]));
- }
-
- EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
- for (DispatcherType d : filterAnnotation.dispatcherTypes())
- {
- dispatcherSet.add(d);
- }
- mapping.setDispatcherTypes(dispatcherSet);
-
- holder.setAsyncSupported(filterAnnotation.asyncSupported());
-
- _wac.getServletHandler().addFilter(holder);
- _wac.getServletHandler().addFilterMapping(mapping);
- }
- else
- {
- //A Filter definition for the same name already exists from web.xml
- //ServletSpec 3.0 p81 if the Filter is already defined and has mappings,
- //they override the annotation. If it already has DispatcherType set, that
- //also overrides the annotation. Init-params are additive, but web.xml overrides
- //init-params of the same name.
- for (WebInitParam ip: filterAnnotation.initParams())
- {
- if (holder.getInitParameter(ip.name()) == null)
- holder.setInitParameter(ip.name(), ip.value());
- }
-
- FilterMapping[] mappings = _wac.getServletHandler().getFilterMappings();
- boolean mappingExists = false;
- if (mappings != null)
- {
- for (FilterMapping m:mappings)
- {
- if (m.getFilterName().equals(name))
- {
- mappingExists = true;
- break;
- }
- }
- }
- //if the web.xml didn't specify at least one mapping, use the mappings from the annotation and the DispatcherTypes
- //from the annotation
- if (!mappingExists)
- {
- FilterMapping mapping = new FilterMapping();
- mapping.setFilterName(holder.getName());
-
- if (urlPatterns.length > 0)
- {
- ArrayList paths = new ArrayList();
- for (String s:urlPatterns)
- {
- paths.add(Util.normalizePattern(s));
- }
- mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
- }
- if (filterAnnotation.servletNames().length > 0)
- {
- ArrayList<String> names = new ArrayList<String>();
- for (String s : filterAnnotation.servletNames())
- {
- names.add(s);
- }
- mapping.setServletNames((String[])names.toArray(new String[names.size()]));
- }
-
- EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
- for (DispatcherType d : filterAnnotation.dispatcherTypes())
- {
- dispatcherSet.add(d);
- }
- mapping.setDispatcherTypes(dispatcherSet);
-
- _wac.getServletHandler().addFilterMapping(mapping);
- }
- }
+ WebFilterAnnotation wfAnnotation = new WebFilterAnnotation(_context, className);
+ ((List<DiscoveredAnnotation>)_context.getAttribute(AnnotationConfiguration.DISCOVERED_ANNOTATIONS)).add(wfAnnotation);
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
@@ -198,5 +53,5 @@ public class WebFilterAnnotationHandler implements DiscoverableAnnotationHandler
{
Log.warn ("@WebFilter not applicable for methods: "+className+"."+methodName+" "+signature);
}
-
+
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java
new file mode 100644
index 0000000000..a92a27c9c5
--- /dev/null
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java
@@ -0,0 +1,83 @@
+// ========================================================================
+// Copyright (c) 2006-2009 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.annotations;
+
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
+import org.eclipse.jetty.webapp.MetaData;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.MetaData.Origin;
+
+/**
+ * WebListenerAnnotation
+ *
+ *
+ */
+public class WebListenerAnnotation extends DiscoveredAnnotation
+{
+
+ /**
+ * @param context
+ * @param className
+ */
+ public WebListenerAnnotation(WebAppContext context, String className)
+ {
+ super(context, className);
+ }
+
+ /**
+ * @see org.eclipse.jetty.annotations.ClassAnnotation#apply()
+ */
+ public void apply()
+ {
+ // TODO check algorithm against ordering rules for descriptors v annotations
+
+ Class clazz = getTargetClass();
+
+ if (clazz == null)
+ {
+ Log.warn(_className+" cannot be loaded");
+ return;
+ }
+
+ try
+ {
+ if (ServletContextListener.class.isAssignableFrom(clazz) ||
+ ServletContextAttributeListener.class.isAssignableFrom(clazz) ||
+ ServletRequestListener.class.isAssignableFrom(clazz) ||
+ ServletRequestAttributeListener.class.isAssignableFrom(clazz) ||
+ HttpSessionListener.class.isAssignableFrom(clazz) ||
+ HttpSessionAttributeListener.class.isAssignableFrom(clazz))
+ {
+ java.util.EventListener listener = (java.util.EventListener)clazz.newInstance();
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+ if (metaData.getOrigin(clazz.getName()+".listener") == Origin.NotSet)
+ _context.addEventListener(listener);
+ }
+ else
+ Log.warn(clazz.getName()+" does not implement one of the servlet listener interfaces");
+ }
+ catch (Exception e)
+ {
+ Log.warn(e);
+ }
+ }
+}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java
index e3ff3e50e9..262973862c 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2009 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 2009-2010 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
@@ -14,55 +14,27 @@ package org.eclipse.jetty.annotations;
import java.util.List;
-import javax.servlet.ServletContextAttributeListener;
-import javax.servlet.ServletContextListener;
-import javax.servlet.ServletRequestAttributeListener;
-import javax.servlet.ServletRequestListener;
-import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionListener;
-
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
import org.eclipse.jetty.webapp.WebAppContext;
public class WebListenerAnnotationHandler implements DiscoverableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
public WebListenerAnnotationHandler (WebAppContext wac)
{
- _wac = wac;
+ _context = wac;
}
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
- Class clazz = null;
- try
- {
- clazz = Loader.loadClass(null, className);
-
- if (ServletContextListener.class.isAssignableFrom(clazz) ||
- ServletContextAttributeListener.class.isAssignableFrom(clazz) ||
- ServletRequestListener.class.isAssignableFrom(clazz) ||
- ServletRequestAttributeListener.class.isAssignableFrom(clazz) ||
- HttpSessionListener.class.isAssignableFrom(clazz) ||
- HttpSessionAttributeListener.class.isAssignableFrom(clazz))
- {
- java.util.EventListener listener = (java.util.EventListener)clazz.newInstance();
- _wac.addEventListener(listener);
- }
- else
- Log.warn(clazz.getName()+" does not implement one of the servlet listener interfaces");
- }
- catch (Exception e)
- {
- Log.warn(e);
- return;
- }
+ WebListenerAnnotation wlAnnotation = new WebListenerAnnotation(_context, className);
+ ((List<DiscoveredAnnotation>)_context.getAttribute(AnnotationConfiguration.DISCOVERED_ANNOTATIONS)).add(wlAnnotation);
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java
new file mode 100644
index 0000000000..ee78f38030
--- /dev/null
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java
@@ -0,0 +1,169 @@
+// ========================================================================
+// Copyright (c) 2010 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.annotations;
+
+import java.util.ArrayList;
+
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+
+import org.eclipse.jetty.servlet.Holder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletMapping;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
+import org.eclipse.jetty.webapp.MetaData;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.MetaData.Origin;
+
+/**
+ * WebServletAnnotation
+ *
+ *
+ */
+public class WebServletAnnotation extends DiscoveredAnnotation
+{
+
+ public WebServletAnnotation (WebAppContext context, String className)
+ {
+ super(context, className);
+ }
+
+ /**
+ * @see org.eclipse.jetty.annotations.ClassAnnotation#apply()
+ */
+ public void apply()
+ {
+ //TODO check this algorithm with new rules for applying descriptors and annotations in order
+ Class clazz = getTargetClass();
+
+ if (clazz == null)
+ {
+ Log.warn(_className+" cannot be loaded");
+ return;
+ }
+
+ //Servlet Spec 8.1.1
+ if (!HttpServlet.class.isAssignableFrom(clazz))
+ {
+ Log.warn(clazz.getName()+" is not assignable from javax.servlet.http.HttpServlet");
+ return;
+ }
+
+ WebServlet annotation = (WebServlet)clazz.getAnnotation(WebServlet.class);
+
+ if (annotation.urlPatterns().length > 0 && annotation.value().length > 0)
+ {
+ Log.warn(clazz.getName()+ " defines both @WebServlet.value and @WebServlet.urlPatterns");
+ return;
+ }
+
+ String[] urlPatterns = annotation.value();
+ if (urlPatterns.length == 0)
+ urlPatterns = annotation.urlPatterns();
+
+ if (urlPatterns.length == 0)
+ {
+ Log.warn(clazz.getName()+ " defines neither @WebServlet.value nor @WebServlet.urlPatterns");
+ return;
+ }
+
+ //canonicalize the patterns
+ ArrayList<String> urlPatternList = new ArrayList<String>();
+ for (String p : urlPatterns)
+ urlPatternList.add(Util.normalizePattern(p));
+
+ String servletName = (annotation.name().equals("")?clazz.getName():annotation.name());
+
+ MetaData metaData = ((MetaData)_context.getAttribute(MetaData.METADATA));
+
+ //Find out if a <servlet> of this type already exists with this name
+ ServletHolder[] holders = _context.getServletHandler().getServlets();
+ boolean isNew = true;
+ ServletHolder holder = null;
+ if (holders != null)
+ {
+ for (ServletHolder h : holders)
+ {
+ if (h.getClassName().equals(clazz.getName()) && h.getName().equals(servletName))
+ {
+ holder = h;
+ isNew = false;
+ break;
+ }
+ }
+ }
+
+ if (isNew)
+ {
+ //No servlet of this name has already been defined, either by a descriptor
+ //or another annotation (which would be impossible).
+ holder = _context.getServletHandler().newServletHolder(Holder.Source.ANNOTATION);
+ holder.setHeldClass(clazz);
+ metaData.setOrigin(servletName+".servlet.servlet-class");
+
+ holder.setName(servletName);
+ holder.setDisplayName(annotation.displayName());
+ metaData.setOrigin(servletName+".servlet.display-name");
+
+ holder.setInitOrder(annotation.loadOnStartup());
+ metaData.setOrigin(servletName+".servlet.load-on-startup");
+
+ holder.setAsyncSupported(annotation.asyncSupported());
+ metaData.setOrigin(servletName+".servlet.async-supported");
+
+ for (WebInitParam ip:annotation.initParams())
+ {
+ holder.setInitParameter(ip.name(), ip.value());
+ metaData.setOrigin(servletName+".servlet.init-param."+ip.name());
+ }
+
+ _context.getServletHandler().addServlet(holder);
+ ServletMapping mapping = new ServletMapping();
+ mapping.setServletName(holder.getName());
+ mapping.setPathSpecs( LazyList.toStringArray(urlPatternList));
+ _context.getServletHandler().addServletMapping(mapping);
+ metaData.setOrigin(servletName+".servlet.mappings");
+ }
+ else
+ {
+ //check if the existing servlet has each init-param from the annotation
+ //if not, add it
+ for (WebInitParam ip:annotation.initParams())
+ {
+ //if (holder.getInitParameter(ip.name()) == null)
+ if (metaData.getOrigin(servletName+".servlet.init-param"+ip.name())==Origin.NotSet)
+ {
+ holder.setInitParameter(ip.name(), ip.value());
+ metaData.setOrigin(servletName+".servlet.init-param."+ip.name());
+ }
+ }
+
+ //check the url-patterns, if there annotation has a new one, add it
+ ServletMapping[] mappings = _context.getServletHandler().getServletMappings();
+
+ //ServletSpec 3.0 p81 If a servlet already has url mappings from a
+ //descriptor the annotation is ignored
+ if (mappings == null && metaData.getOriginDescriptor(servletName+".servlet.mappings") != null)
+ {
+ ServletMapping mapping = new ServletMapping();
+ mapping.setServletName(servletName);
+ mapping.setPathSpecs(LazyList.toStringArray(urlPatternList));
+ _context.getServletHandler().addServletMapping(mapping);
+ }
+ }
+ }
+}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java
index 10b9ce2ea5..d869b98be0 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java
@@ -13,25 +13,12 @@
package org.eclipse.jetty.annotations;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-import java.util.ListIterator;
-
-import javax.servlet.annotation.MultipartConfig;
-import javax.servlet.annotation.WebInitParam;
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.servlet.Holder;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.servlet.ServletMapping;
-import org.eclipse.jetty.util.LazyList;
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
import org.eclipse.jetty.webapp.WebAppContext;
/**
@@ -42,29 +29,18 @@ import org.eclipse.jetty.webapp.WebAppContext;
*/
public class WebServletAnnotationHandler implements DiscoverableAnnotationHandler
{
- protected WebAppContext _wac;
+ protected WebAppContext _context;
public WebServletAnnotationHandler (WebAppContext wac)
{
- _wac = wac;
+ _context = wac;
}
/**
- * Handle a WebServlet annotation.
- *
- * If web.xml does not define a servlet of the same name, then this is an entirely
- * new servlet definition.
+ * Handle discovering a WebServlet annotation.
*
- * Otherwise, the values from web.xml override the values from the annotation except for:
- *
- * <ul>
- * <li>init-params: if the annotation contains a different init-param name, then it is added to the
- * effective init-params for the servlet<li>
- * <li>url-patterns: if the annotation contains a different url-pattern, then it is added to the
- * effective url-patterns for the servlet</li>
- * </ul>
*
* @see org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler#handleClass(java.lang.String, int, int, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, java.util.List)
*/
@@ -74,110 +50,8 @@ public class WebServletAnnotationHandler implements DiscoverableAnnotationHandle
if (!"javax.servlet.annotation.WebServlet".equals(annotationName))
return;
- //TODO Do we want to load the class now and look at the annotation values
- //with reflection, or do we want to use the raw annotation values from
- //asm parsing?
- Class clazz;
- try
- {
- clazz = Loader.loadClass(null, className);
- }
- catch (Exception e)
- {
- Log.warn(e);
- return;
- }
-
- //Servlet Spec 8.1.1
- if (!HttpServlet.class.isAssignableFrom(clazz))
- {
- Log.warn(clazz.getName()+" is not assignable from javax.servlet.http.HttpServlet");
- return;
- }
-
- WebServlet annotation = (WebServlet)clazz.getAnnotation(WebServlet.class);
-
- if (annotation.urlPatterns().length > 0 && annotation.value().length > 0)
- {
- Log.warn(clazz.getName()+ " defines both @WebServlet.value and @WebServlet.urlPatterns");
- return;
- }
-
- String[] urlPatterns = annotation.value();
- if (urlPatterns.length == 0)
- urlPatterns = annotation.urlPatterns();
-
- if (urlPatterns.length == 0)
- {
- Log.warn(clazz.getName()+ " defines neither @WebServlet.value nor @WebServlet.urlPatterns");
- return;
- }
- //canonicalize the patterns
- ArrayList<String> urlPatternList = new ArrayList<String>();
- for (String p : urlPatterns)
- urlPatternList.add(Util.normalizePattern(p));
-
- String servletName = (annotation.name().equals("")?clazz.getName():annotation.name());
-
- //Find out if a <servlet> from web.xml of this type already exists with this name
- ServletHolder[] holders = _wac.getServletHandler().getServlets();
- boolean isNew = true;
- ServletHolder holder = null;
- if (holders != null)
- {
- for (ServletHolder h : holders)
- {
- if (h.getClassName().equals(clazz.getName()) && h.getName().equals(servletName))
- {
- holder = h;
- isNew = false;
- break;
- }
- }
- }
-
- if (isNew)
- {
- holder = _wac.getServletHandler().newServletHolder(Holder.Source.ANNOTATION);
- holder.setHeldClass(clazz);
- holder.setName(servletName);
- holder.setDisplayName(annotation.displayName());
- holder.setInitOrder(annotation.loadOnStartup());
- holder.setAsyncSupported(annotation.asyncSupported());
- for (WebInitParam ip:annotation.initParams())
- {
- holder.setInitParameter(ip.name(), ip.value());
- }
-
- _wac.getServletHandler().addServlet(holder);
- ServletMapping mapping = new ServletMapping();
- mapping.setServletName(holder.getName());
- mapping.setPathSpecs( LazyList.toStringArray(urlPatternList));
- _wac.getServletHandler().addServletMapping(mapping);
- }
- else
- {
- //check if the existing servlet has each init-param from the annotation
- //if not, add it
- for (WebInitParam ip:annotation.initParams())
- {
- if (holder.getInitParameter(ip.name()) == null)
- holder.setInitParameter(ip.name(), ip.value());
- }
-
- //check the url-patterns, if there annotation has a new one, add it
- ServletMapping[] mappings = _wac.getServletHandler().getServletMappings();
-
- //ServletSpec 3.0 p81 If a servlet already has url mappings from a
- //descriptor the annotation is ignored
- if (mappings == null)
- {
- ServletMapping mapping = new ServletMapping();
- mapping.setServletName(servletName);
- mapping.setPathSpecs(LazyList.toStringArray(urlPatternList));
- _wac.getServletHandler().addServletMapping(mapping);
- }
- }
+ WebServletAnnotation annotation = new WebServletAnnotation (_context, className);
+ ((List<DiscoveredAnnotation>)_context.getAttribute(AnnotationConfiguration.DISCOVERED_ANNOTATIONS)).add(annotation);
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java
index af1ec022c6..764aaddaf0 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java
@@ -14,18 +14,16 @@
package org.eclipse.jetty.annotations;
import java.io.File;
-import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
-import java.util.List;
+
+import junit.framework.TestCase;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.Fragment;
+import org.eclipse.jetty.webapp.FragmentDescriptor;
import org.eclipse.jetty.webapp.WebAppContext;
-import junit.framework.TestCase;
-
/**
* TestAnnotationConfiguration
*
@@ -34,31 +32,7 @@ import junit.framework.TestCase;
public class TestAnnotationConfiguration extends TestCase
{
- /**
- * Test method for {@link org.eclipse.jetty.annotations.AbstractConfiguration#parseWebInfLib(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.annotations.AnnotationParser)}.
- */
- public void testExclusions()
- throws Exception
- {
- AnnotationConfiguration config = new AnnotationConfiguration();
- WebAppContext wac = new WebAppContext();
-
- Resource r = Resource.newResource("file:///home/janb/file.jar");
- List<String> orderedJars = new ArrayList<String>();
-
- //empty ordering excludes all jars
- assertTrue(config.isExcluded(r, orderedJars));
-
- //an ordering with name included
- orderedJars.add("file.jar");
- orderedJars.add("abc.jar");
- orderedJars.add("xyz.jar");
- assertFalse(config.isExcluded(r, orderedJars));
-
- //an ordering with name excluded
- orderedJars.remove("file.jar");
- assertTrue(config.isExcluded(r, orderedJars));
- }
+
public void testGetFragmentFromJar ()
@@ -74,9 +48,9 @@ public class TestAnnotationConfiguration extends TestCase
AnnotationConfiguration config = new AnnotationConfiguration();
WebAppContext wac = new WebAppContext();
- List<Fragment> frags = new ArrayList<Fragment>();
- frags.add(new Fragment(Resource.newResource("jar:"+url+"file.jar!/fooa.props"), null));
- frags.add(new Fragment(Resource.newResource("jar:"+url+"file2.jar!/foob.props"), null));
+ List<FragmentDescriptor> frags = new ArrayList<FragmentDescriptor>();
+ frags.add(new FragmentDescriptor(Resource.newResource("jar:"+url+"file.jar!/fooa.props"), null));
+ frags.add(new FragmentDescriptor(Resource.newResource("jar:"+url+"file2.jar!/foob.props"), null));
assertNotNull(config.getFragmentFromJar(jar1, frags));
}
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java
index e89133ef84..7cfc0aafe4 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.annotations;
@@ -16,22 +16,24 @@ package org.eclipse.jetty.annotations;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-
import javax.naming.Context;
import javax.naming.InitialContext;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.util.MultiMap;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
/**
- * TestAnnotationInheritance
- *
*
*/
-public class TestAnnotationInheritance extends TestCase
+public class TestAnnotationInheritance
{
List<String> classNames = new ArrayList<String>();
@@ -41,7 +43,7 @@ public class TestAnnotationInheritance extends TestCase
public final List<String> annotatedClassNames = new ArrayList<String>();
public final List<String> annotatedMethods = new ArrayList<String>();
public final List<String> annotatedFields = new ArrayList<String>();
-
+
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
@@ -50,7 +52,7 @@ public class TestAnnotationInheritance extends TestCase
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
List<Value> values)
- {
+ {
annotatedFields.add(className+"."+fieldName);
}
@@ -58,29 +60,28 @@ public class TestAnnotationInheritance extends TestCase
List<Value> values)
{
annotatedMethods.add(className+"."+methodName);
- }
+ }
}
-
-
- public void tearDown () throws Exception
+
+ @After
+ public void destroy() throws Exception
{
classNames.clear();
InitialContext ic = new InitialContext();
Context comp = (Context)ic.lookup("java:comp");
comp.destroySubcontext("env");
}
-
-
- public void testParseClassNames ()
- throws Exception
- {
+
+ @Test
+ public void testParseClassNames() throws Exception
+ {
classNames.add(ClassA.class.getName());
classNames.add(ClassB.class.getName());
-
- SampleHandler handler = new SampleHandler();
+
+ SampleHandler handler = new SampleHandler();
AnnotationParser parser = new AnnotationParser();
parser.registerAnnotationHandler("org.eclipse.jetty.annotations.Sample", handler);
- parser.parse(classNames, new ClassNameResolver ()
+ parser.parse(classNames, new ClassNameResolver ()
{
public boolean isExcluded(String name)
{
@@ -90,12 +91,12 @@ public class TestAnnotationInheritance extends TestCase
public boolean shouldOverride(String name)
{
return false;
- }
- });
-
+ }
+ });
+
//check we got 2 class annotations
assertEquals(2, handler.annotatedClassNames.size());
-
+
//check we got all annotated methods on each class
assertEquals (7, handler.annotatedMethods.size());
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassA.a"));
@@ -105,22 +106,19 @@ public class TestAnnotationInheritance extends TestCase
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassA.l"));
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassB.a"));
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassB.c"));
-
+
//check we got all annotated fields on each class
assertEquals(1, handler.annotatedFields.size());
- assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
+ assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
}
-
-
-
-
- public void testParseClass ()
- throws Exception
+
+ @Test
+ public void testParseClass() throws Exception
{
SampleHandler handler = new SampleHandler();
AnnotationParser parser = new AnnotationParser();
parser.registerAnnotationHandler("org.eclipse.jetty.annotations.Sample", handler);
- parser.parse(ClassB.class, new ClassNameResolver ()
+ parser.parse(ClassB.class, new ClassNameResolver ()
{
public boolean isExcluded(String name)
{
@@ -130,12 +128,12 @@ public class TestAnnotationInheritance extends TestCase
public boolean shouldOverride(String name)
{
return false;
- }
- }, true);
-
+ }
+ }, true);
+
//check we got 2 class annotations
assertEquals(2, handler.annotatedClassNames.size());
-
+
//check we got all annotated methods on each class
assertEquals (7, handler.annotatedMethods.size());
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassA.a"));
@@ -145,15 +143,14 @@ public class TestAnnotationInheritance extends TestCase
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassA.l"));
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassB.a"));
assertTrue (handler.annotatedMethods.contains("org.eclipse.jetty.annotations.ClassB.c"));
-
+
//check we got all annotated fields on each class
assertEquals(1, handler.annotatedFields.size());
- assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
+ assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
}
-
-
- public void testExclusions()
- throws Exception
+
+ @Test
+ public void testExclusions() throws Exception
{
AnnotationParser parser = new AnnotationParser();
SampleHandler handler = new SampleHandler();
@@ -168,7 +165,7 @@ public class TestAnnotationInheritance extends TestCase
public boolean shouldOverride(String name)
{
return false;
- }
+ }
});
assertEquals (0, handler.annotatedClassNames.size());
assertEquals (0, handler.annotatedFields.size());
@@ -188,32 +185,30 @@ public class TestAnnotationInheritance extends TestCase
public boolean shouldOverride(String name)
{
return false;
- }
+ }
});
assertEquals (1, handler.annotatedClassNames.size());
}
-
- public void testTypeInheritanceHandling ()
- throws Exception
+
+ @Test
+ public void testTypeInheritanceHandling() throws Exception
{
AnnotationParser parser = new AnnotationParser();
ClassInheritanceHandler handler = new ClassInheritanceHandler();
parser.registerClassHandler(handler);
-
+
class Foo implements InterfaceD
{
-
}
-
+
classNames.clear();
classNames.add(ClassA.class.getName());
classNames.add(ClassB.class.getName());
classNames.add(InterfaceD.class.getName());
classNames.add(Foo.class.getName());
-
-
+
parser.parse(classNames, null);
-
+
MultiMap map = handler.getMap();
assertNotNull(map);
assertFalse(map.isEmpty());
@@ -230,5 +225,4 @@ public class TestAnnotationInheritance extends TestCase
assertEquals ("org.eclipse.jetty.annotations.ClassB", classes[0]);
assertEquals(Foo.class.getName(), classes[1]);
}
-
}
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
index b4586feb4b..bef8867a7b 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
@@ -4,41 +4,36 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.annotations;
+
import java.util.Arrays;
import java.util.List;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-
-
-public class TestAnnotationParser extends TestCase
+public class TestAnnotationParser
{
-
- public void testSampleAnnotation ()
- throws Exception
- {
-
-
+ @Test
+ public void testSampleAnnotation() throws Exception
+ {
String[] classNames = new String[]{"org.eclipse.jetty.annotations.ClassA"};
AnnotationParser parser = new AnnotationParser();
-
-
+
class SampleAnnotationHandler implements DiscoverableAnnotationHandler
{
- List<String> methods = Arrays.asList("a", "b", "c", "d", "l");
-
-
+ private List<String> methods = Arrays.asList("a", "b", "c", "d", "l");
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
@@ -62,7 +57,7 @@ public class TestAnnotationParser extends TestCase
List<Value> values)
{
System.err.println("Sample annotated method : classname="+className+" methodName="+methodName+" access="+access+" desc="+desc+" signature="+signature);
-
+
org.objectweb.asm.Type retType = org.objectweb.asm.Type.getReturnType(desc);
System.err.println("REturn type = "+retType);
org.objectweb.asm.Type[] params = org.objectweb.asm.Type.getArgumentTypes(desc);
@@ -70,23 +65,22 @@ public class TestAnnotationParser extends TestCase
System.err.println("No params");
else
System.err.println(params.length+" params");
-
+
if (exceptions == null)
System.err.println("No exceptions");
else
System.err.println(exceptions.length+" exceptions");
-
+
assertEquals("org.eclipse.jetty.annotations.ClassA", className);
- assertTrue(methods.contains(methodName));
- assertEquals("org.eclipse.jetty.annotations.Sample", annotation);
+ assertTrue(methods.contains(methodName));
+ assertEquals("org.eclipse.jetty.annotations.Sample", annotation);
}
-
}
-
+
parser.registerAnnotationHandler("org.eclipse.jetty.annotations.Sample", new SampleAnnotationHandler());
-
+
long start = System.currentTimeMillis();
- parser.parse(classNames, new ClassNameResolver ()
+ parser.parse(classNames, new ClassNameResolver ()
{
public boolean isExcluded(String name)
{
@@ -97,28 +91,26 @@ public class TestAnnotationParser extends TestCase
{
return false;
}
-
+
});
long end = System.currentTimeMillis();
System.err.println("Time to parse class: "+((end-start)));
- }
+ }
-
- public void testMultiAnnotation ()
- throws Exception
+ @Test
+ public void testMultiAnnotation() throws Exception
{
String[] classNames = new String[]{"org.eclipse.jetty.annotations.ClassB"};
AnnotationParser parser = new AnnotationParser();
-
-
+
class MultiAnnotationHandler implements DiscoverableAnnotationHandler
{
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
assertTrue("org.eclipse.jetty.annotations.ClassB".equals(className));
-
+
for (Value anv: values)
{
System.err.println(anv.toString());
@@ -134,7 +126,7 @@ public class TestAnnotationParser extends TestCase
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
List<Value> values)
- {
+ {
assertTrue("org.eclipse.jetty.annotations.ClassB".equals(className));
assertTrue("a".equals(methodName));
for (Value anv: values)
@@ -143,7 +135,7 @@ public class TestAnnotationParser extends TestCase
}
}
}
-
+
parser.registerAnnotationHandler("org.eclipse.jetty.annotations.Multi", new MultiAnnotationHandler());
parser.parse(classNames, null);
}
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java
index e236f5ee11..beb2c4aacc 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java
@@ -257,14 +257,14 @@ public class TestSecurityAnnotationConversions extends TestCase
compareResults (expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings());
}
- private void compareResults (ConstraintMapping[] expectedMappings, ConstraintMapping[] actualMappings)
+ private void compareResults (ConstraintMapping[] expectedMappings, List<ConstraintMapping> actualMappings)
{
assertNotNull(actualMappings);
- assertEquals(expectedMappings.length, actualMappings.length);
+ assertEquals(expectedMappings.length, actualMappings.size());
- for (int k=0; k < actualMappings.length; k++)
+ for (int k=0; k < actualMappings.size(); k++)
{
- ConstraintMapping am = actualMappings[k];
+ ConstraintMapping am = actualMappings.get(k);
boolean matched = false;
for (int i=0; i< expectedMappings.length && !matched; i++)
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java
index 67a1aa6c7c..f7f6c7ffdc 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java
@@ -4,58 +4,60 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.annotations;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import java.util.ArrayList;
-import java.util.List;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
-import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
-import org.eclipse.jetty.annotations.AnnotationParser.Value;
-import org.eclipse.jetty.annotations.AnnotationParser.ListValue;
-import org.eclipse.jetty.annotations.AnnotationParser.SimpleValue;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.RunAsCollection;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletMapping;
+import org.eclipse.jetty.webapp.DiscoveredAnnotation;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
-
-
-import junit.framework.TestCase;
+import org.junit.Test;
/**
* TestServletAnnotations
*
*
*/
-public class TestServletAnnotations extends TestCase
+public class TestServletAnnotations
{
-
-
- public void testServletAnnotation()
- throws Exception
+ @Test
+ public void testServletAnnotation() throws Exception
{
List<String> classes = new ArrayList<String>();
classes.add("org.eclipse.jetty.annotations.ServletC");
AnnotationParser parser = new AnnotationParser();
WebAppContext wac = new WebAppContext();
+ wac.setAttribute(MetaData.METADATA, new MetaData(wac));
LifeCycleCallbackCollection collection = new LifeCycleCallbackCollection();
wac.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, collection);
RunAsCollection runAsCollection = new RunAsCollection();
wac.setAttribute(RunAsCollection.RUNAS_COLLECTION, runAsCollection);
+ List<DiscoveredAnnotation> discoveredAnnotations = new ArrayList<DiscoveredAnnotation>();
+ wac.setAttribute(AnnotationConfiguration.DISCOVERED_ANNOTATIONS, discoveredAnnotations);
parser.registerAnnotationHandler("javax.servlet.annotation.WebServlet", new WebServletAnnotationHandler(wac));
- parser.parse(classes, new ClassNameResolver ()
+ parser.parse(classes, new ClassNameResolver ()
{
public boolean isExcluded(String name)
{
@@ -66,8 +68,12 @@ public class TestServletAnnotations extends TestCase
{
return false;
}
-
});
+
+ assertEquals(1, discoveredAnnotations.size());
+ assertTrue(discoveredAnnotations.get(0) instanceof WebServletAnnotation);
+
+ discoveredAnnotations.get(0).apply();
ServletHolder[] holders = wac.getServletHandler().getServlets();
assertNotNull(holders);
@@ -88,6 +94,7 @@ public class TestServletAnnotations extends TestCase
throws Exception
{
WebAppContext wac = new WebAppContext();
+ wac.setAttribute(MetaData.METADATA, new MetaData(wac));
ConstraintSecurityHandler sh = new ConstraintSecurityHandler();
wac.setSecurityHandler(sh);
sh.setRoles(new HashSet<String>(Arrays.asList(new String[]{"humpty", "dumpty"})));
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java
index 50cc21c608..6fdef5830c 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java
@@ -2,14 +2,10 @@ package org.eclipse.jetty.annotations.resources;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
-
import javax.naming.Context;
import javax.naming.InitialContext;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.annotations.AnnotationIntrospector;
import org.eclipse.jetty.annotations.AnnotationParser;
import org.eclipse.jetty.annotations.ClassNameResolver;
@@ -19,11 +15,17 @@ import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
+import org.junit.Test;
-public class TestResourceAnnotations extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestResourceAnnotations
{
+ @Test
public void testResourceAnnotations ()
throws Exception
{
@@ -32,6 +34,7 @@ public class TestResourceAnnotations extends TestCase
wac.setServer(server);
InjectionCollection injections = new InjectionCollection();
wac.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
+ wac.setAttribute(MetaData.METADATA, new MetaData(wac));
InitialContext ic = new InitialContext();
Context comp = (Context)ic.lookup("java:comp");
Context env = comp.createSubcontext("env");
@@ -39,13 +42,12 @@ public class TestResourceAnnotations extends TestCase
org.eclipse.jetty.plus.jndi.EnvEntry resourceA = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", new Integer(1000), false);
org.eclipse.jetty.plus.jndi.EnvEntry resourceB = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", new Integer(2000), false);
-
AnnotationIntrospector parser = new AnnotationIntrospector();
ResourceAnnotationHandler handler = new ResourceAnnotationHandler(wac);
parser.registerHandler(handler);
parser.introspect(ResourceA.class);
parser.introspect(ResourceB.class);
-
+
//processing classA should give us these jndi name bindings:
// java:comp/env/myf
// java:comp/env/org.eclipse.jetty.annotations.resources.ResourceA/g
@@ -54,73 +56,71 @@ public class TestResourceAnnotations extends TestCase
// java:comp/env/resA
// java:comp/env/org.eclipse.jetty.annotations.resources.ResourceB/f
// java:comp/env/org.eclipse.jetty.annotations.resources.ResourceA/n
- //
+ //
assertEquals(resourceB.getObjectToBind(), env.lookup("myf"));
assertEquals(resourceA.getObjectToBind(), env.lookup("mye"));
assertEquals(resourceA.getObjectToBind(), env.lookup("resA"));
- assertEquals(resourceA.getObjectToBind(), env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/g"));
+ assertEquals(resourceA.getObjectToBind(), env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/g"));
assertEquals(resourceA.getObjectToBind(), env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/h"));
assertEquals(resourceB.getObjectToBind(), env.lookup("org.eclipse.jetty.annotations.resources.ResourceB/f"));
assertEquals(resourceB.getObjectToBind(), env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/n"));
-
+
//we should have Injections
assertNotNull(injections);
-
+
List<Injection> resBInjections = injections.getInjections(ResourceB.class.getCanonicalName());
assertNotNull(resBInjections);
-
+
//only 1 field injection because the other has no Resource mapping
assertEquals(1, resBInjections.size());
Injection fi = resBInjections.get(0);
assertEquals ("f", fi.getTarget().getName());
-
+
//3 method injections on class ResourceA, 4 field injections
List<Injection> resAInjections = injections.getInjections(ResourceA.class.getCanonicalName());
assertNotNull(resAInjections);
assertEquals(7, resAInjections.size());
int fieldCount = 0;
int methodCount = 0;
- Iterator<Injection> itor = resAInjections.iterator();
- while (itor.hasNext())
+ for (Injection x : resAInjections)
{
- Injection x = itor.next();
if (x.isField())
fieldCount++;
- else
+ else
methodCount++;
}
assertEquals(4, fieldCount);
assertEquals(3, methodCount);
-
-
+
//test injection
ResourceB binst = new ResourceB();
injections.inject(binst);
-
+
//check injected values
Field f = ResourceB.class.getDeclaredField ("f");
f.setAccessible(true);
assertEquals(resourceB.getObjectToBind() , f.get(binst));
-
+
//@Resource(mappedName="resA") //test the default naming scheme but using a mapped name from the environment
- f = ResourceA.class.getDeclaredField("g");
+ f = ResourceA.class.getDeclaredField("g");
f.setAccessible(true);
assertEquals(resourceA.getObjectToBind(), f.get(binst));
-
+
//@Resource(name="resA") //test using the given name as the name from the environment
f = ResourceA.class.getDeclaredField("j");
f.setAccessible(true);
assertEquals(resourceA.getObjectToBind(), f.get(binst));
-
+
//@Resource(mappedName="resB") //test using the default name on an inherited field
- f = ResourceA.class.getDeclaredField("n");
+ f = ResourceA.class.getDeclaredField("n");
f.setAccessible(true);
assertEquals(resourceB.getObjectToBind(), f.get(binst));
-
+
comp.destroySubcontext("env");
}
+ @Test
public void testResourcesAnnotation ()
throws Exception
{
diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml
index 66528ca613..cc725dd86b 100644
--- a/jetty-client/pom.xml
+++ b/jetty-client/pom.xml
@@ -23,6 +23,11 @@
<goals>
<goal>manifest</goal>
</goals>
+ <configuration>
+ <instructions>
+ <Import-Package>javax.net.*,*</Import-Package>
+ </instructions>
+ </configuration>
</execution>
</executions>
</plugin>
@@ -33,18 +38,18 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.client.*</onlyAnalyze>
+ </configuration>
</plugin>
-
</plugins>
</build>
<dependencies>
@@ -58,16 +63,17 @@
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${project.version}</version>
<scope>test</scope>
- </dependency>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -85,5 +91,11 @@
<scope>test</scope>
</dependency>
-->
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java
index de1e9933dd..c36cb6834d 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java
@@ -35,14 +35,14 @@ public class CachedExchange extends HttpExchange
_responseFields = cacheHeaders ? new HttpFields() : null;
}
- public int getResponseStatus()
+ public synchronized int getResponseStatus()
{
if (getStatus() < HttpExchange.STATUS_PARSING_HEADERS)
throw new IllegalStateException("Response not received yet");
return _responseStatus;
}
- public HttpFields getResponseFields()
+ public synchronized HttpFields getResponseFields()
{
if (getStatus() < HttpExchange.STATUS_PARSING_CONTENT)
throw new IllegalStateException("Headers not completely received yet");
@@ -50,14 +50,14 @@ public class CachedExchange extends HttpExchange
}
@Override
- protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+ protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{
_responseStatus = status;
super.onResponseStatus(version, status, reason);
}
@Override
- protected void onResponseHeader(Buffer name, Buffer value) throws IOException
+ protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
{
if (_responseFields != null)
_responseFields.add(name, value);
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java
index 2e0b3411f4..5673cef584 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java
@@ -45,14 +45,14 @@ public class ContentExchange extends CachedExchange
super(cacheFields);
}
- public String getResponseContent() throws UnsupportedEncodingException
+ public synchronized String getResponseContent() throws UnsupportedEncodingException
{
if (_responseContent != null)
return _responseContent.toString(_encoding);
return null;
}
- public byte[] getResponseContentBytes()
+ public synchronized byte[] getResponseContentBytes()
{
if (_responseContent != null)
return _responseContent.toByteArray();
@@ -60,7 +60,7 @@ public class ContentExchange extends CachedExchange
}
@Override
- protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+ protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{
if (_responseContent!=null)
_responseContent.reset();
@@ -68,7 +68,7 @@ public class ContentExchange extends CachedExchange
}
@Override
- protected void onResponseHeader(Buffer name, Buffer value) throws IOException
+ protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
{
super.onResponseHeader(name, value);
int header = HttpHeaders.CACHE.getOrdinal(name);
@@ -92,7 +92,7 @@ public class ContentExchange extends CachedExchange
}
@Override
- protected void onResponseContent(Buffer content) throws IOException
+ protected synchronized void onResponseContent(Buffer content) throws IOException
{
super.onResponseContent(content);
if (_responseContent == null)
@@ -101,7 +101,7 @@ public class ContentExchange extends CachedExchange
}
@Override
- protected void onRetry() throws IOException
+ protected synchronized void onRetry() throws IOException
{
if (_fileForUpload != null)
{
@@ -112,17 +112,17 @@ public class ContentExchange extends CachedExchange
super.onRetry();
}
- private InputStream getInputStream() throws IOException
+ private synchronized InputStream getInputStream() throws IOException
{
return new FileInputStream(_fileForUpload);
}
- public File getFileForUpload()
+ public synchronized File getFileForUpload()
{
return _fileForUpload;
}
- public void setFileForUpload(File fileForUpload) throws IOException
+ public synchronized void setFileForUpload(File fileForUpload) throws IOException
{
this._fileForUpload = fileForUpload;
setRequestContentSource(getInputStream());
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 0ee716cf16..be20cc49c6 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -75,11 +75,8 @@ import org.eclipse.jetty.util.thread.Timeout;
* be allocated from a destination, so that multiple request sources are not multiplexed
* over the same connection.
*
- *
- *
- *
- * @see {@link HttpExchange}
- * @see {@link HttpDestination}
+ * @see HttpExchange
+ * @see HttpDestination
*/
public class HttpClient extends HttpBuffers implements Attributes
{
@@ -212,10 +209,6 @@ public class HttpClient extends HttpBuffers implements Attributes
}
/* ------------------------------------------------------------ */
- /**
- * @param name
- * @return
- */
public void clearAttributes()
{
_attributes.clearAttributes();
@@ -287,7 +280,7 @@ public class HttpClient extends HttpBuffers implements Attributes
/**
* returns the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
*
- * @return
+ * @return the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
*/
public RealmResolver getRealmResolver()
{
@@ -303,7 +296,7 @@ public class HttpClient extends HttpBuffers implements Attributes
/**
* Registers a listener that can listen to the stream of execution between the client and the
- * server and influence events. Sequential calls to the method wrapper sequentially wrap the preceeding
+ * server and influence events. Sequential calls to the method wrapper sequentially wrap the preceding
* listener in a delegation model.
* <p/>
* NOTE: the SecurityListener is a special listener which doesn't need to be added via this
@@ -320,7 +313,8 @@ public class HttpClient extends HttpBuffers implements Attributes
}
_registeredListeners.add(listenerClass);
}
-
+
+ /* ------------------------------------------------------------ */
public LinkedList<String> getRegisteredListeners()
{
return _registeredListeners;
@@ -528,7 +522,7 @@ public class HttpClient extends HttpBuffers implements Attributes
* if a keystore location has been provided then client will attempt to use it as the keystore,
* otherwise we simply ignore certificates and run with a loose ssl context.
*
- * @return
+ * @return the SSL context
* @throws IOException
*/
protected SSLContext getSSLContext() throws IOException
@@ -807,12 +801,36 @@ public class HttpClient extends HttpBuffers implements Attributes
/* ------------------------------------------------------------ */
public void setKeyManagerPassword(String keyManagerPassword)
{
- this._keyManagerPassword = new Password(keyManagerPassword).toString();;
+ this._keyManagerPassword = new Password(keyManagerPassword).toString();
}
/* ------------------------------------------------------------ */
public void setTrustStorePassword(String trustStorePassword)
{
- this._trustStorePassword = new Password(trustStorePassword).toString();;
+ this._trustStorePassword = new Password(trustStorePassword).toString();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getKeyStoreType()
+ {
+ return this._keyStoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setKeyStoreType(String keyStoreType)
+ {
+ this._keyStoreType = keyStoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getTrustStoreType()
+ {
+ return this._trustStoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setTrustStoreType(String trustStoreType)
+ {
+ this._trustStoreType = trustStoreType;
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
index 9633c7e9ec..9244314355 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.client;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
@@ -28,7 +29,6 @@ import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersions;
-import org.eclipse.jetty.http.ssl.SslSelectChannelEndPoint;
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
@@ -37,6 +37,7 @@ import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.Timeout;
@@ -214,23 +215,28 @@ public class HttpConnection implements Connection
if (!_generator.isComplete())
{
- InputStream in = _exchange.getRequestContentSource();
- if (in != null)
+ if (_exchange!=null)
{
- if (_requestContentChunk == null || _requestContentChunk.length() == 0)
+ InputStream in = _exchange.getRequestContentSource();
+ if (in != null)
{
- _requestContentChunk = _exchange.getRequestContentChunk();
- _destination.getHttpClient().schedule(_timeout);
+ if (_requestContentChunk == null || _requestContentChunk.length() == 0)
+ {
+ _requestContentChunk = _exchange.getRequestContentChunk();
+ _destination.getHttpClient().schedule(_timeout);
- if (_requestContentChunk != null)
- _generator.addContent(_requestContentChunk,false);
- else
- _generator.complete();
+ if (_requestContentChunk != null)
+ _generator.addContent(_requestContentChunk,false);
+ else
+ _generator.complete();
- flushed = _generator.flushBuffer();
- io += flushed;
+ flushed = _generator.flushBuffer();
+ io += flushed;
+ }
}
- }
+ else
+ _generator.complete();
+ }
else
_generator.complete();
}
@@ -333,16 +339,17 @@ public class HttpConnection implements Connection
no_progress = 0;
if (_exchange != null)
{
+ HttpExchange exchange=_exchange;
_exchange.disassociate();
_exchange = null;
if (_status==HttpStatus.SWITCHING_PROTOCOLS_101)
{
- HttpConnection switched=_exchange.onSwitchProtocol(_endp);
+ Connection switched=exchange.onSwitchProtocol(_endp);
if (switched!=null)
{
// switched protocol!
- HttpExchange exchange = _pipeline;
+ exchange = _pipeline;
_pipeline = null;
if (exchange!=null)
_destination.send(exchange);
@@ -351,7 +358,6 @@ public class HttpConnection implements Connection
}
}
-
if (_pipeline == null)
{
if (!isReserved())
@@ -364,13 +370,13 @@ public class HttpConnection implements Connection
if (!isReserved())
_destination.returnConnection(this,close);
- HttpExchange exchange = _pipeline;
+ exchange = _pipeline;
_pipeline = null;
_destination.send(exchange);
}
else
{
- HttpExchange exchange = _pipeline;
+ exchange = _pipeline;
_pipeline = null;
send(exchange);
}
@@ -388,6 +394,11 @@ public class HttpConnection implements Connection
{
_exchange.disassociate();
}
+
+ if (!_generator.isComplete() && _generator.getBytesBuffered()>0 && _endp instanceof AsyncEndPoint)
+ {
+ ((AsyncEndPoint)_endp).setWritable(false);
+ }
}
return this;
@@ -544,6 +555,8 @@ public class HttpConnection implements Connection
@Override
public void headerComplete() throws IOException
{
+ if (_endp instanceof AsyncEndPoint)
+ ((AsyncEndPoint)_endp).scheduleIdle();
HttpExchange exchange = _exchange;
if (exchange!=null)
exchange.setStatus(HttpExchange.STATUS_PARSING_CONTENT);
@@ -552,6 +565,8 @@ public class HttpConnection implements Connection
@Override
public void content(Buffer ref) throws IOException
{
+ if (_endp instanceof AsyncEndPoint)
+ ((AsyncEndPoint)_endp).scheduleIdle();
HttpExchange exchange = _exchange;
if (exchange!=null)
exchange.getEventListener().onResponseContent(ref);
@@ -579,6 +594,25 @@ public class HttpConnection implements Connection
public void close() throws IOException
{
+ //if there is a live, unfinished exchange, set its status to be
+ //excepted and wake up anyone waiting on waitForDone()
+
+ if (_exchange != null && !_exchange.isDone())
+ {
+ switch (_exchange.getStatus())
+ {
+ case HttpExchange.STATUS_CANCELLED:
+ case HttpExchange.STATUS_CANCELLING:
+ case HttpExchange.STATUS_COMPLETED:
+ case HttpExchange.STATUS_EXCEPTED:
+ case HttpExchange.STATUS_EXPIRED:
+ break;
+ default:
+ _exchange.setStatus(HttpExchange.STATUS_EXCEPTED);
+ _exchange.getEventListener().onException(new EOFException("local close"));
+ }
+ }
+
_endp.close();
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
index 09ab59e94d..b885828022 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
@@ -219,7 +219,7 @@ public class HttpDestination
if (connection!=null)
{
_connections.remove(connection);
- connection.getEndPoint().close();
+ connection.close();
connection=null;
}
if (_idle.size() > 0)
@@ -229,9 +229,10 @@ public class HttpDestination
if (connection==null)
return null;
- if (connection.cancelIdleTimeout() )
+ // Check if the connection was idle,
+ // but it expired just a moment ago
+ if (connection.cancelIdleTimeout())
return connection;
-
}
}
@@ -271,6 +272,11 @@ public class HttpDestination
HttpExchange ex = _queue.removeFirst();
ex.setStatus(HttpExchange.STATUS_EXCEPTED);
ex.getEventListener().onConnectionFailed(throwable);
+
+ // Since an existing connection had failed, we need to create a
+ // connection if the queue is not empty and client is running.
+ if (!_queue.isEmpty() && _client.isStarted())
+ startNewConnection();
}
}
@@ -323,7 +329,7 @@ public class HttpDestination
else
{
HttpExchange ex = _queue.removeFirst();
- connection.send(ex);
+ send(connection, ex);
}
}
@@ -372,7 +378,7 @@ public class HttpDestination
else
{
HttpExchange ex = _queue.removeFirst();
- connection.send(ex);
+ send(connection, ex);
}
this.notifyAll();
}
@@ -388,7 +394,7 @@ public class HttpDestination
}
}
- public void returnIdleConnection(HttpConnection connection) throws IOException
+ public void returnIdleConnection(HttpConnection connection)
{
try
{
@@ -403,10 +409,10 @@ public class HttpDestination
{
_idle.remove(connection);
_connections.remove(connection);
+
if (!_queue.isEmpty() && _client.isStarted())
startNewConnection();
}
-
}
public void send(HttpExchange ex) throws IOException
@@ -483,11 +489,9 @@ public class HttpDestination
HttpConnection connection = getIdleConnection();
if (connection != null)
{
- boolean sent = connection.send(ex);
- if (!sent) connection = null;
+ send(connection, ex);
}
-
- if (connection == null)
+ else
{
synchronized (this)
{
@@ -500,6 +504,20 @@ public class HttpDestination
}
}
+ protected void send(HttpConnection connection, HttpExchange exchange) throws IOException
+ {
+ synchronized (this)
+ {
+ // If server closes the connection, put the exchange back
+ // to the exchange queue and recycle the connection
+ if(!connection.send(exchange))
+ {
+ _queue.addFirst(exchange);
+ returnIdleConnection(connection);
+ }
+ }
+ }
+
@Override
public synchronized String toString()
{
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java
index eae8542cdc..cfe9b81051 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java
@@ -25,6 +25,7 @@ import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
@@ -53,8 +54,8 @@ import org.eclipse.jetty.util.log.Log;
* see {@link org.eclipse.jetty.client.ContentExchange} and {@link org.eclipse.jetty.client.CachedExchange}.</p>
*
* <p>Typically the HttpExchange is passed to the {@link HttpClient#send(HttpExchange)} method, which in
- * turn selects a {@link HttpDestination} and calls its {@link HttpDestination#send(HttpExchange), which
- * then creates or selects a {@link HttpConnection} and calls its {@link HttpConnection#send(HttpExchange).
+ * turn selects a {@link HttpDestination} and calls its {@link HttpDestination#send(HttpExchange)}, which
+ * then creates or selects a {@link HttpConnection} and calls its {@link HttpConnection#send(HttpExchange)}.
* A developer may wish to directly call send on the destination or connection if they wish to bypass
* some handling provided (eg Cookie handling in the HttpDestination).</p>
*
@@ -129,7 +130,7 @@ public class HttpExchange
* || onExpire
* || onRequestComplete && onResponseComplete
* </pre>
- * @return
+ * @return the done status
* @throws InterruptedException
*/
public int waitForDone () throws InterruptedException
@@ -172,6 +173,7 @@ public class HttpExchange
case STATUS_WAITING_FOR_CONNECTION:
case STATUS_WAITING_FOR_COMMIT:
case STATUS_CANCELLING:
+ case STATUS_EXCEPTED:
set=_status.compareAndSet(oldStatus,newStatus);
break;
}
@@ -282,6 +284,7 @@ public class HttpExchange
case STATUS_CANCELLING:
switch (newStatus)
{
+ case STATUS_EXCEPTED:
case STATUS_CANCELLED:
if (set=_status.compareAndSet(oldStatus,newStatus))
done();
@@ -300,6 +303,9 @@ public class HttpExchange
case STATUS_START:
set=_status.compareAndSet(oldStatus,newStatus);
break;
+ default:
+ set=true;
+ break;
}
break;
default:
@@ -324,6 +330,15 @@ public class HttpExchange
}
}
+ /**
+ * @deprecated
+ */
+ @Deprecated
+ public boolean isDone (int status)
+ {
+ return isDone();
+ }
+
public HttpEventListener getEventListener()
{
return _listener;
@@ -659,7 +674,7 @@ public class HttpExchange
/**
*/
- protected HttpConnection onSwitchProtocol(EndPoint enpd) throws IOException
+ protected Connection onSwitchProtocol(EndPoint endp) throws IOException
{
return null;
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java
index 6e0d47d0a2..d3de1e680a 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java
@@ -16,6 +16,7 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.Buffer;
@@ -26,8 +27,8 @@ import org.eclipse.jetty.io.Buffer;
*/
public class RedirectListener extends HttpEventListenerWrapper
{
+ private final HttpExchange _exchange;
private HttpDestination _destination;
- private HttpExchange _exchange;
private String _location;
private int _attempts;
private boolean _requestComplete;
@@ -44,6 +45,7 @@ public class RedirectListener extends HttpEventListenerWrapper
_exchange = ex;
}
+ @Override
public void onResponseStatus( Buffer version, int status, Buffer reason )
throws IOException
{
@@ -61,6 +63,7 @@ public class RedirectListener extends HttpEventListenerWrapper
}
+ @Override
public void onResponseHeader( Buffer name, Buffer value )
throws IOException
{
@@ -77,6 +80,7 @@ public class RedirectListener extends HttpEventListenerWrapper
super.onResponseHeader(name,value);
}
+ @Override
public void onRequestComplete() throws IOException
{
_requestComplete = true;
@@ -87,6 +91,7 @@ public class RedirectListener extends HttpEventListenerWrapper
}
}
+ @Override
public void onResponseComplete() throws IOException
{
_responseComplete = true;
@@ -109,7 +114,23 @@ public class RedirectListener extends HttpEventListenerWrapper
else
_exchange.setURI(_location);
- _destination.resend(_exchange);
+ // destination may have changed
+ HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme())));
+
+ if (_destination==destination)
+ _destination.resend(_exchange);
+ else
+ {
+ // unwrap to find ultimate listener.
+ HttpEventListener listener=this;
+ while(listener instanceof HttpEventListenerWrapper)
+ listener=((HttpEventListenerWrapper)listener).getEventListener();
+ //reset the listener
+ _exchange.getEventListener().onRetry();
+ _exchange.reset();
+ _exchange.setEventListener(listener);
+ destination.send(_exchange);
+ }
return false;
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
index aba10d0615..730a53a01a 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
@@ -25,7 +25,6 @@ import javax.net.ssl.SSLSession;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpVersions;
-import org.eclipse.jetty.http.ssl.SslSelectChannelEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ConnectedEndPoint;
@@ -35,6 +34,7 @@ import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.Timeout;
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java
index 87d37b9a7a..20902d4312 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java
@@ -58,7 +58,7 @@ public class SecurityListener extends HttpEventListenerWrapper
* scrapes an authentication type from the authString
*
* @param authString
- * @return
+ * @return the authentication type
*/
protected String scrapeAuthenticationType( String authString )
{
@@ -80,7 +80,7 @@ public class SecurityListener extends HttpEventListenerWrapper
* scrapes a set of authentication details from the authString
*
* @param authString
- * @return
+ * @return the authentication details
*/
protected Map<String, String> scrapeAuthenticationDetails( String authString )
{
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
index bc6c075e64..fff68bb5e5 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
@@ -15,6 +15,7 @@
package org.eclipse.jetty.client;
import java.io.IOException;
+import java.net.SocketTimeoutException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
@@ -281,10 +282,10 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
getHttpClient().send(exchange);
int status = exchange.waitForDone();
- assertEquals(HttpExchange.STATUS_COMPLETED, status);
assertTrue(exchange.isResponseCompleted());
assertFalse(exchange.isFailed());
assertFalse(exchange.isAssociated());
+ assertEquals(HttpExchange.STATUS_COMPLETED, status);
}
public void testHttpExchangeOnServerException() throws Exception
@@ -322,7 +323,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
httpClient.send(exchange);
int status = exchange.waitForDone();
- assertEquals(HttpExchange.STATUS_EXPIRED, status);
+
+ assertTrue(HttpExchange.STATUS_EXPIRED==status||HttpExchange.STATUS_EXCEPTED==status);
assertFalse(exchange.isResponseCompleted());
assertFalse(exchange.isFailed());
assertTrue(exchange.isExpired());
@@ -395,8 +397,11 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
@Override
protected void onException(Throwable ex)
{
- // ex.printStackTrace();
- this.failed = true;
+ if (ex instanceof SocketTimeoutException ||
+ ex.getCause() instanceof SocketTimeoutException)
+ expired=true;
+ else
+ failed = true;
}
public boolean isFailed()
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
index 7ed394dac0..48030d4cbd 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
@@ -21,6 +21,9 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
_scheme="https://";
startServer();
_httpClient=new HttpClient();
+ _httpClient.setIdleTimeout(2000);
+ _httpClient.setTimeout(2500);
+ _httpClient.setConnectTimeout(1000);
_httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
_httpClient.setMaxConnectionsPerAddress(2);
_httpClient.start();
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java
index d05b39ea7a..549144a9b1 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java
@@ -14,6 +14,8 @@
package org.eclipse.jetty.client;
+import org.eclipse.jetty.util.log.Log;
+
/**
* @version $Revision$ $Date$
*/
@@ -42,4 +44,5 @@ public class BlockingHttpExchangeCancelTest extends AbstractHttpExchangeCancelTe
{
return httpClient;
}
+
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionTest.java
index f282b82285..beed5f51b4 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionTest.java
@@ -14,49 +14,161 @@
package org.eclipse.jetty.client;
+import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import junit.framework.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* @version $Revision$ $Date$
*/
-public class ConnectionTest extends TestCase
+public class ConnectionTest
{
+ @Test
+ public void testServerClosedConnection() throws Exception
+ {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(null);
+ int port=serverSocket.getLocalPort();
+
+ HttpClient httpClient = new HttpClient();
+ httpClient.setMaxConnectionsPerAddress(1);
+ httpClient.start();
+ try
+ {
+ CountDownLatch latch = new CountDownLatch(1);
+ HttpExchange exchange = new ConnectionExchange(latch);
+ exchange.setAddress(new Address("localhost", port));
+ exchange.setURI("/");
+ httpClient.send(exchange);
+
+ Socket remote = serverSocket.accept();
+ OutputStream output = remote.getOutputStream();
+ output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
+ output.write("Content-Length: 0\r\n".getBytes("UTF-8"));
+ output.write("\r\n".getBytes("UTF-8"));
+ output.flush();
+
+ assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
+
+ remote.close();
+
+ // Need to wait a bit to allow the client to detect
+ // that the server has closed the connection
+ Thread.sleep(500);
+
+ // The server has closed the connection and another attempt to send
+ // with the same connection would fail because the connection has been
+ // closed by the client as well.
+ // The client must open a new connection in this case, and we check
+ // that the new request completes correctly
+ exchange.reset();
+ httpClient.send(exchange);
+
+ remote = serverSocket.accept();
+ output = remote.getOutputStream();
+ output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
+ output.write("Content-Length: 0\r\n".getBytes("UTF-8"));
+ output.write("\r\n".getBytes("UTF-8"));
+ output.flush();
+
+ assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
+ }
+ finally
+ {
+ httpClient.stop();
+ }
+ }
+
+ @Test
public void testConnectionFailed() throws Exception
{
- ServerSocket socket = new ServerSocket();
- socket.bind(null);
- int port=socket.getLocalPort();
- socket.close();
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(null);
+ int port=serverSocket.getLocalPort();
+ serverSocket.close();
HttpClient httpClient = new HttpClient();
httpClient.start();
+ try
+ {
+ CountDownLatch latch = new CountDownLatch(1);
+ HttpExchange exchange = new ConnectionExchange(latch);
+ exchange.setAddress(new Address("localhost", port));
+ exchange.setURI("/");
+ httpClient.send(exchange);
- CountDownLatch latch = new CountDownLatch(1);
- HttpExchange exchange = new ConnectionExchange(latch);
- exchange.setAddress(new Address("localhost", port));
- exchange.setURI("/");
- httpClient.send(exchange);
+ boolean passed = latch.await(4000, TimeUnit.MILLISECONDS);
+ assertTrue(passed);
- boolean passed = latch.await(4000, TimeUnit.MILLISECONDS);
- assertTrue(passed);
+ long wait = 100;
+ long maxWait = 10 * wait;
+ long curWait = wait;
+ while (curWait < maxWait && !exchange.isDone())
+ {
+ Thread.sleep(wait);
+ curWait += wait;
+ }
- long wait = 100;
- long maxWait = 10 * wait;
- long curWait = wait;
- while (curWait < maxWait && !exchange.isDone())
+ assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.getStatus());
+ }
+ finally
{
- Thread.sleep(wait);
- curWait += wait;
+ httpClient.stop();
}
+ }
+
+ @Test
+ public void testMultipleConnectionsFailed() throws Exception
+ {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(null);
+ int port=serverSocket.getLocalPort();
+ serverSocket.close();
- assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.getStatus());
+ HttpClient httpClient = new HttpClient();
+ httpClient.setMaxConnectionsPerAddress(1);
+ httpClient.start();
+ try
+ {
+ HttpExchange[] exchanges = new HttpExchange[20];
+ final CountDownLatch latch = new CountDownLatch(exchanges.length);
+ for (int i = 0; i < exchanges.length; ++i)
+ {
+ HttpExchange exchange = new HttpExchange()
+ {
+ @Override
+ protected void onConnectionFailed(Throwable x)
+ {
+ latch.countDown();
+ }
+ };
+ exchange.setAddress(new Address("localhost", port));
+ exchange.setURI("/");
+ exchanges[i] = exchange;
+ }
+
+ for (HttpExchange exchange : exchanges)
+ httpClient.send(exchange);
+
+ for (HttpExchange exchange : exchanges)
+ assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.waitForDone());
+
+ assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
+ }
+ finally
+ {
+ httpClient.stop();
+ }
}
+ @Test
public void testConnectionTimeoutWithSocketConnector() throws Exception
{
HttpClient httpClient = new HttpClient();
@@ -64,7 +176,6 @@ public class ConnectionTest extends TestCase
int connectTimeout = 5000;
httpClient.setConnectTimeout(connectTimeout);
httpClient.start();
-
try
{
CountDownLatch latch = new CountDownLatch(1);
@@ -86,6 +197,7 @@ public class ConnectionTest extends TestCase
}
}
+ @Test
public void testConnectionTimeoutWithSelectConnector() throws Exception
{
HttpClient httpClient = new HttpClient();
@@ -93,7 +205,6 @@ public class ConnectionTest extends TestCase
int connectTimeout = 5000;
httpClient.setConnectTimeout(connectTimeout);
httpClient.start();
-
try
{
CountDownLatch latch = new CountDownLatch(1);
@@ -115,56 +226,62 @@ public class ConnectionTest extends TestCase
}
}
+ @Test
public void testIdleConnection() throws Exception
{
- ServerSocket socket = new ServerSocket();
- socket.bind(null);
- int port=socket.getLocalPort();
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(null);
+ int port=serverSocket.getLocalPort();
HttpClient httpClient = new HttpClient();
httpClient.setIdleTimeout(700);
httpClient.start();
+ try
+ {
+ HttpExchange exchange = new ConnectionExchange();
+ exchange.setAddress(new Address("localhost", port));
+ exchange.setURI("/");
+ HttpDestination dest = httpClient.getDestination(new Address("localhost", port),false);
- HttpExchange exchange = new ConnectionExchange();
- exchange.setAddress(new Address("localhost", port));
- exchange.setURI("/");
- HttpDestination dest = httpClient.getDestination(new Address("localhost", port),false);
-
- httpClient.send(exchange);
- Socket s = socket.accept();
- byte[] buf = new byte[4096];
- s.getInputStream().read(buf);
- assertEquals(1,dest.getConnections());
- assertEquals(0,dest.getIdleConnections());
-
- s.getOutputStream().write("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n".getBytes());
+ httpClient.send(exchange);
+ Socket s = serverSocket.accept();
+ byte[] buf = new byte[4096];
+ s.getInputStream().read(buf);
+ assertEquals(1,dest.getConnections());
+ assertEquals(0,dest.getIdleConnections());
- Thread.sleep(300);
- assertEquals(1,dest.getConnections());
- assertEquals(1,dest.getIdleConnections());
+ s.getOutputStream().write("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n".getBytes());
- exchange = new ConnectionExchange();
- exchange.setAddress(new Address("localhost", port));
- exchange.setURI("/");
+ Thread.sleep(300);
+ assertEquals(1,dest.getConnections());
+ assertEquals(1,dest.getIdleConnections());
- httpClient.send(exchange);
- s.getInputStream().read(buf);
- assertEquals(1,dest.getConnections());
- assertEquals(0,dest.getIdleConnections());
- s.getOutputStream().write("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n".getBytes());
+ exchange = new ConnectionExchange();
+ exchange.setAddress(new Address("localhost", port));
+ exchange.setURI("/");
- Thread.sleep(500);
+ httpClient.send(exchange);
+ s.getInputStream().read(buf);
+ assertEquals(1,dest.getConnections());
+ assertEquals(0,dest.getIdleConnections());
+ s.getOutputStream().write("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n".getBytes());
- assertEquals(1,dest.getConnections());
- assertEquals(1,dest.getIdleConnections());
+ Thread.sleep(500);
- Thread.sleep(500);
+ assertEquals(1,dest.getConnections());
+ assertEquals(1,dest.getIdleConnections());
- assertEquals(0,dest.getConnections());
- assertEquals(0,dest.getIdleConnections());
+ Thread.sleep(500);
- socket.close();
+ assertEquals(0,dest.getConnections());
+ assertEquals(0,dest.getIdleConnections());
+ serverSocket.close();
+ }
+ finally
+ {
+ httpClient.stop();
+ }
}
private class ConnectionExchange extends HttpExchange
@@ -187,7 +304,7 @@ public class ConnectionTest extends TestCase
if (latch!=null)
latch.countDown();
}
-
+
@Override
protected void onException(Throwable x)
{
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java
index 71692727d8..e2daf2b485 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java
@@ -6,157 +6,108 @@ package org.eclipse.jetty.client;
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
-import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.log.Log;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
-/* Test expiring connections
- *
+/**
* Test contributed by: Michiel Thuys for JETTY-806
*/
-public class ExpireTest extends TestCase
+public class ExpireTest
{
- HttpClient client;
-
- Server server;
-
- AtomicInteger expireCount = new AtomicInteger();
+ private Server server;
+ private HttpClient client;
+ private int port;
- final String host = "localhost";
-
- int _port;
-
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- client = new HttpClient();
- client.setConnectorType( HttpClient.CONNECTOR_SELECT_CHANNEL );
- client.setTimeout( 200 );
- client.setMaxRetries( 0 );
- client.setMaxConnectionsPerAddress(100);
- try
- {
- client.start();
- }
- catch ( Exception e )
- {
- throw new Error( "Cannot start HTTP client: " + e );
- }
-
- // Create server
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
- connector.setHost( host );
- connector.setPort( 0 );
- server.setConnectors( new Connector[] { connector } );
- server.setHandler( new AbstractHandler()
+ connector.setHost("localhost");
+ connector.setPort(0);
+ server.addConnector(connector);
+ server.setHandler(new AbstractHandler()
{
- public void handle( String target, Request baseRequest, HttpServletRequest servletRequest, HttpServletResponse response ) throws IOException,
- ServletException
+ public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ throws IOException, ServletException
{
- Request request = (Request) servletRequest;
+ request.setHandled(true);
try
{
- Thread.sleep( 2000 );
+ Thread.sleep(2000);
}
- catch ( InterruptedException e )
+ catch (InterruptedException x)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ throw new ServletException(x);
}
- request.setHandled( true );
}
- } );
- try
- {
- server.start();
- _port = connector.getLocalPort();
- }
- catch ( Exception e )
- {
- Log.warn( "Cannot create server: " + e );
- }
+ });
+ server.start();
+ port = connector.getLocalPort();
+
+ client = new HttpClient();
+ client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+ client.setTimeout(200);
+ client.setMaxRetries(0);
+ client.setMaxConnectionsPerAddress(100);
+ client.start();
}
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
client.stop();
server.stop();
+ server.join();
}
- public void testExpire() throws IOException
+ @Test
+ public void testExpire() throws Exception
{
- String baseUrl = "http://" + host + ":" + _port + "/";
+ String baseUrl = "http://" + "localhost" + ":" + port + "/";
int count = 200;
- expireCount.set( 0 );
- Log.info( "Starting test on " + baseUrl );
+ final CountDownLatch expires = new CountDownLatch(count);
for (int i=0;i<count;i++)
{
- if (i%10==0)
- System.err.print('.');
- expireCount.incrementAndGet();
- final ContentExchange ex = new ContentExchange()
+ final ContentExchange exchange = new ContentExchange()
{
@Override
protected void onExpire()
{
- expireCount.decrementAndGet();
+ expires.countDown();
}
};
- ex.setMethod( "GET" );
- ex.setURL( baseUrl );
+ exchange.setMethod("GET");
+ exchange.setURL(baseUrl);
- client.send( ex );
- try
- {
- Thread.sleep( 50 );
- }
- catch ( InterruptedException e )
- {
- break;
- }
+ client.send(exchange);
+ Thread.sleep(50);
}
- // Log.info("Test done");
- // Wait to be sure that all exchanges have expired
- try
- {
- Thread.sleep( 2000 );
- int loops = 0;
- while ( expireCount.get()>0 && loops < 10 ) // max out at 30 seconds
- {
- Log.info( "waiting for test to complete: "+expireCount.get()+" of "+count );
- ++loops;
- Thread.sleep( 2000 );
- }
- Thread.sleep( 2000 );
- }
- catch ( InterruptedException e )
- {
- }
- System.err.println('!');
- assertEquals( 0, expireCount.get() );
+ // Wait to be sure that all exchanges have expired
+ assertTrue(expires.await(5, TimeUnit.SECONDS));
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
index a0dc69d08f..3ec2d764cb 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
@@ -13,12 +13,15 @@
package org.eclipse.jetty.client;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -30,11 +33,14 @@ import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
/**
* Functional testing for HttpExchange.
@@ -55,9 +61,9 @@ public class HttpExchangeTest extends TestCase
{
startServer();
_httpClient=new HttpClient();
- _httpClient.setIdleTimeout(2000);
- _httpClient.setTimeout(2500);
- _httpClient.setConnectTimeout(1000);
+ _httpClient.setIdleTimeout(3000);
+ _httpClient.setTimeout(3500);
+ _httpClient.setConnectTimeout(2000);
_httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
_httpClient.setMaxConnectionsPerAddress(_maxConnectionsPerAddress);
_httpClient.start();
@@ -94,8 +100,6 @@ public class HttpExchangeTest extends TestCase
sender(1,true);
sender(10,false);
sender(10,true);
- sender(20,false);
- sender(20,true);
}
}
@@ -123,7 +127,6 @@ public class HttpExchangeTest extends TestCase
protected void onRequestCommitted()
{
result="committed";
- // System.err.println(n+" Request committed: "+close);
}
@Override
@@ -136,13 +139,11 @@ public class HttpExchangeTest extends TestCase
protected void onResponseStatus(Buffer version, int status, Buffer reason)
{
result="status";
- // System.err.println(n+" Response Status: " + version+" "+status+" "+reason);
}
@Override
protected void onResponseHeader(Buffer name, Buffer value)
{
- // System.err.println(n+" Response header: " + name + " = " + value);
}
@Override
@@ -156,14 +157,12 @@ public class HttpExchangeTest extends TestCase
protected void onResponseContent(Buffer content)
{
len+=content.length();
- // System.err.println(n+" Response content:" + content.length());
}
@Override
protected void onResponseComplete()
{
result="complete";
- // System.err.println(n+" Response completed "+len);
if (len==2009)
latch.countDown();
else
@@ -216,16 +215,19 @@ public class HttpExchangeTest extends TestCase
assertTrue(complete.await(45,TimeUnit.SECONDS));
long elapsed=System.currentTimeMillis()-start;
+
// make windows-friendly ... System.currentTimeMillis() on windows is dope!
+ /*
if(elapsed>0)
System.err.println(nb+"/"+_count+" c="+close+" rate="+(nb*1000/elapsed));
+ */
assertEquals("nb="+nb+" close="+close,0,latch.getCount());
}
public void testPostWithContentExchange() throws Exception
{
- for (int i=0;i<200;i++)
+ for (int i=0;i<20;i++)
{
ContentExchange httpExchange=new ContentExchange();
//httpExchange.setURL(_scheme+"localhost:"+_port+"/");
@@ -243,7 +245,7 @@ public class HttpExchangeTest extends TestCase
public void testGetWithContentExchange() throws Exception
{
- for (int i=0;i<200;i++)
+ for (int i=0;i<10;i++)
{
ContentExchange httpExchange=new ContentExchange();
httpExchange.setURL(_scheme+"localhost:"+_port+"/?i="+i);
@@ -259,6 +261,84 @@ public class HttpExchangeTest extends TestCase
}
}
+ public void testShutdownWithExchange() throws Exception
+ {
+ final AtomicReference<Throwable> throwable=new AtomicReference<Throwable>();
+
+ HttpExchange httpExchange=new HttpExchange()
+ {
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.client.HttpExchange#onException(java.lang.Throwable)
+ */
+ @Override
+ protected void onException(Throwable x)
+ {
+ throwable.set(x);
+ }
+
+ };
+ httpExchange.setURL(_scheme+"localhost:"+_port+"/");
+ httpExchange.setMethod("SLEEP");
+ _httpClient.send(httpExchange);
+ new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try {
+ Thread.sleep(250);
+ _httpClient.stop();
+ } catch(Exception e) {e.printStackTrace();}
+ }
+ }.start();
+ int status = httpExchange.waitForDone();
+
+ assertTrue(throwable.get().toString().indexOf("local close")>=0);
+ assertEquals(HttpExchange.STATUS_EXCEPTED, status);
+ }
+
+ public void testBigPostWithContentExchange() throws Exception
+ {
+ int size =32;
+ ContentExchange httpExchange=new ContentExchange();
+
+ Buffer babuf = new ByteArrayBuffer(size*36*1024);
+ Buffer niobuf = new DirectNIOBuffer(size*36*1024);
+
+ byte[] bytes="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes();
+
+ for (int i=0;i<size*1024;i++)
+ {
+ babuf.put(bytes);
+ niobuf.put(bytes);
+ }
+
+ httpExchange.setURL(_scheme+"localhost:"+_port+"/");
+ httpExchange.setMethod(HttpMethods.POST);
+ httpExchange.setRequestContentType("application/data");
+ httpExchange.setRequestContent(babuf);
+
+ _httpClient.send(httpExchange);
+ int status = httpExchange.waitForDone();
+
+ assertEquals(HttpExchange.STATUS_COMPLETED,status);
+ String result=httpExchange.getResponseContent();
+ assertEquals(babuf.length(),result.length());
+
+ httpExchange.reset();
+ httpExchange.setURL(_scheme+"localhost:"+_port+"/");
+ httpExchange.setMethod(HttpMethods.POST);
+ httpExchange.setRequestContentType("application/data");
+ httpExchange.setRequestContent(niobuf);
+ _httpClient.send(httpExchange);
+ status = httpExchange.waitForDone();
+ result=httpExchange.getResponseContent();
+ assertEquals(niobuf.length(),result.length());
+ assertEquals(HttpExchange.STATUS_COMPLETED, status);
+ }
+
public void testSlowPost() throws Exception
{
ContentExchange httpExchange=new ContentExchange()
@@ -289,7 +369,6 @@ public class HttpExchangeTest extends TestCase
if (_index>=data.length())
return -1;
- //System.err.println("sleep "+_index);
try
{
Thread.sleep(250);
@@ -377,7 +456,7 @@ public class HttpExchangeTest extends TestCase
}
- public static void copyStream(InputStream in, OutputStream out)
+ public static void copyStrxeam(InputStream in, OutputStream out)
{
try
{
@@ -403,6 +482,8 @@ public class HttpExchangeTest extends TestCase
_server=new Server();
_server.setGracefulShutdown(500);
_connector=new SelectChannelConnector();
+
+ _connector.setMaxIdleTime(3000000);
_connector.setPort(0);
_server.setConnectors(new Connector[] { _connector });
@@ -424,13 +505,11 @@ public class HttpExchangeTest extends TestCase
if (request.getServerName().equals("jetty.eclipse.org"))
{
- // System.err.println("HANDLING Proxy");
response.getOutputStream().println("Proxy request: "+request.getRequestURL());
response.getOutputStream().println(request.getHeader(HttpHeaders.PROXY_AUTHORIZATION));
}
else if (request.getMethod().equalsIgnoreCase("GET"))
{
- // System.err.println("HANDLING Hello "+request.getRequestURI());
response.getOutputStream().println("<hello>");
for (; i<100; i++)
{
@@ -440,12 +519,24 @@ public class HttpExchangeTest extends TestCase
}
response.getOutputStream().println("</hello>");
}
+ else if (request.getMethod().equalsIgnoreCase("SLEEP"))
+ {
+ Thread.sleep(1000);
+ }
else
{
- // System.err.println("HANDLING "+request.getMethod());
- copyStream(request.getInputStream(),response.getOutputStream());
+ response.setContentType(request.getContentType());
+ int size=request.getContentLength();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream(size>0?size:32768);
+ IO.copy(request.getInputStream(),bout);
+ response.getOutputStream().write(bout.toByteArray());
}
}
+ catch(InterruptedException e)
+ {
+ System.err.println(e);
+ Log.debug(e);
+ }
catch(IOException e)
{
e.printStackTrace();
@@ -458,7 +549,6 @@ public class HttpExchangeTest extends TestCase
}
finally
{
- // System.err.println("HANDLED "+i);
}
}
});
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java
index af29296bdb..cb4b6738ed 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java
@@ -35,6 +35,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
@@ -63,6 +64,8 @@ public class HttpGetRedirectTest
private Realm _realm;
private String _protocol;
private String _requestUrl;
+ private String _requestUrl2;
+ private RedirectHandler _handler;
public void setUp()
throws Exception
@@ -73,10 +76,14 @@ public class HttpGetRedirectTest
_server = new Server();
configureServer(_server);
+ org.eclipse.jetty.server.bio.SocketConnector connector = new org.eclipse.jetty.server.bio.SocketConnector();
+ _server.addConnector(connector);
_server.start();
int port = _server.getConnectors()[0].getLocalPort();
_requestUrl = _protocol+"://localhost:"+port+ "/content.txt";
+
+ _handler._toURL=_protocol+"://localhost:"+connector.getLocalPort()+ "/moved.txt";
}
public void tearDown()
@@ -92,7 +99,7 @@ public class HttpGetRedirectTest
public void testGet() throws Exception
{
startClient(_realm);
-
+
ContentExchange getExchange = new ContentExchange();
getExchange.setURL(_requestUrl);
getExchange.setMethod(HttpMethods.GET);
@@ -107,10 +114,10 @@ public class HttpGetRedirectTest
content = getExchange.getResponseContent();
}
- stopClient();
-
assertEquals(HttpStatus.OK_200,responseStatus);
assertEquals(_content,content);
+
+ stopClient();
}
protected void configureServer(Server server)
@@ -121,8 +128,8 @@ public class HttpGetRedirectTest
SelectChannelConnector connector = new SelectChannelConnector();
server.addConnector(connector);
- Handler handler = new RedirectHandler(HttpStatus.MOVED_PERMANENTLY_301, "/content.txt", "/moved.txt", 1);
- server.setHandler( handler );
+ _handler = new RedirectHandler(HttpStatus.MOVED_PERMANENTLY_301, "/content.txt", "WAIT FOR IT", 2);
+ server.setHandler( _handler );
}
@@ -162,46 +169,26 @@ public class HttpGetRedirectTest
_realm = realm;
}
- public static void copyStream(InputStream in, OutputStream out)
- {
- try
- {
- byte[] buffer=new byte[1024];
- int len;
- while ((len=in.read(buffer))>=0)
- {
- out.write(buffer,0,len);
- }
- }
- catch (EofException e)
- {
- System.err.println(e);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
private static class RedirectHandler
extends AbstractHandler
{
- private final String origUrl;
-
- private final int code;
+ private final String _fromURI;
+ private final int _code;
+ private final int _maxRedirects;
+ private int _redirectCount = 0;
+ private String _toURL;
- private final int maxRedirects;
-
- private int redirectCount = 0;
-
- private final String currUrl;
-
- public RedirectHandler( final int code, final String currUrl, final String origUrl, final int maxRedirects )
+ public RedirectHandler( final int code, final String fromURI, final String toURL, final int maxRedirects )
{
- this.code = code;
- this.currUrl = currUrl;
- this.origUrl = origUrl;
- this.maxRedirects = maxRedirects;
+ this._code = code;
+ this._fromURI = fromURI;
+ this._toURL = toURL;
+ this._maxRedirects = maxRedirects;
+
+ if (_fromURI==null || _toURL==null)
+ throw new IllegalArgumentException();
+
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
@@ -212,23 +199,18 @@ public class HttpGetRedirectTest
return;
}
- if (request.getRequestURI().equals(currUrl))
+ if (request.getRequestURI().equals(_fromURI))
{
- redirectCount++;
-
- if ( maxRedirects < 0 || redirectCount <= maxRedirects )
- {
- response.setStatus( code );
- response.setHeader( "Location", currUrl );
- }
- else
- {
- response.setStatus( code );
- response.setHeader( "Location", origUrl );
- }
+ _redirectCount++;
+
+ String location = ( _redirectCount <= _maxRedirects )?_fromURI:_toURL;
+
+ response.setStatus( _code );
+ response.setHeader( "Location", location );
+
( (Request) request ).setHandled( true );
}
- else if (request.getRequestURI().equals(origUrl))
+ else
{
PrintWriter out = response.getWriter();
out.write(_content);
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java
index 0737c01f64..60ae2f9e43 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.client;
@@ -18,13 +18,10 @@ import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector;
@@ -32,10 +29,16 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-public class HttpHeadersTest extends TestCase
+public class HttpHeadersTest
{
- private static String _content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "
+ private static final String CONTENT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "
+ "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "
+ "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+ "Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "
@@ -48,75 +51,67 @@ public class HttpHeadersTest extends TestCase
+ "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "
+ "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
- private File _docRoot;
private Server _server;
- private Connector _connector;
private TestHeaderHandler _handler;
private int _port;
- public void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- _docRoot = new File("target/test-output/docroot/");
- _docRoot.mkdirs();
- _docRoot.deleteOnExit();
+ File docRoot = new File("target/test-output/docroot/");
+ if (!docRoot.exists())
+ assertTrue(docRoot.mkdirs());
+ docRoot.deleteOnExit();
+
+ _server = new Server();
+ Connector connector = new SelectChannelConnector();
+ _server.addConnector(connector);
+
+ _handler = new TestHeaderHandler();
+ _server.setHandler(_handler);
+
+ _server.start();
- startServer();
+ _port = connector.getLocalPort();
}
- public void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- stopServer();
+ _server.stop();
+ _server.join();
}
+ @Test
public void testHttpHeaders() throws Exception
{
- HttpClient client = new HttpClient();
- client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
- client.start();
-
- String requestUrl = "http://localhost:" + _port + "/header";
-
- ContentExchange exchange = new ContentExchange();
- exchange.setURL(requestUrl);
- exchange.setMethod(HttpMethods.GET);
- exchange.addRequestHeader("User-Agent","Jetty-Client/7.0");
-
- client.send(exchange);
- int state = exchange.waitForDone();
-
- String content = "";
- int responseStatus = exchange.getResponseStatus();
- if (responseStatus == HttpStatus.OK_200)
+ HttpClient httpClient = new HttpClient();
+ httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+ httpClient.start();
+ try
{
- content = exchange.getResponseContent();
- }
-
- assertEquals(HttpStatus.OK_200,responseStatus);
- assertEquals(_content,content);
- assertEquals("Jetty-Client/7.0",_handler.headers.get("User-Agent"));
- }
-
- protected void startServer() throws Exception
- {
- _server = new Server(0);
+ String requestUrl = "http://localhost:" + _port + "/header";
- _connector = new SelectChannelConnector();
- _server.addConnector(_connector);
+ ContentExchange exchange = new ContentExchange();
+ exchange.setURL(requestUrl);
+ exchange.setMethod(HttpMethods.GET);
+ exchange.addRequestHeader("User-Agent","Jetty-Client/7.0");
- _handler = new TestHeaderHandler();
- _server.setHandler(_handler);
+ httpClient.send(exchange);
- _server.start();
+ int state = exchange.waitForDone();
+ assertEquals(HttpExchange.STATUS_COMPLETED, state);
+ int responseStatus = exchange.getResponseStatus();
+ assertEquals(HttpStatus.OK_200,responseStatus);
- _port = _connector.getLocalPort();
- }
+ String content = exchange.getResponseContent();
- protected void stopServer() throws Exception
- {
- if (_server != null)
+ assertEquals(HttpHeadersTest.CONTENT,content);
+ assertEquals("Jetty-Client/7.0",_handler.headers.get("User-Agent"));
+ }
+ finally
{
- _server.stop();
- _server = null;
+ httpClient.stop();
}
}
@@ -138,7 +133,7 @@ public class HttpHeadersTest extends TestCase
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
- response.getWriter().print(_content);
+ response.getWriter().print(CONTENT);
baseRequest.setHandled(true);
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java
index 679b0e1a4f..fb2152e8be 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.client;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -78,7 +79,7 @@ public class SecuredContentExchangeTest
knownRoles.add("user");
knownRoles.add("admin");
- security.setConstraintMappings(new ConstraintMapping[] {mapping}, knownRoles);
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java
index 413ed1828c..5469ec072a 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.client;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -144,7 +145,7 @@ public class SecuredErrorStatusTest
knownRoles.add("user");
knownRoles.add("admin");
- security.setConstraintMappings(new ConstraintMapping[] {mapping}, knownRoles);
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java
index 9f72fbd046..b1cf3a82b6 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java
@@ -14,6 +14,7 @@
package org.eclipse.jetty.client;
import java.io.File;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -83,7 +84,7 @@ extends ContentExchangeTest
knownRoles.add("user");
knownRoles.add("admin");
- security.setConstraintMappings(new ConstraintMapping[] {mapping}, knownRoles);
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java
index 8647262be5..37eef2b271 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.client;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -144,7 +145,7 @@ public class SslSecuredErrorStatusTest
knownRoles.add("user");
knownRoles.add("admin");
- security.setConstraintMappings(new ConstraintMapping[] {mapping}, knownRoles);
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java
index 36646ff8ee..c7ee05bb54 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java
@@ -18,6 +18,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CyclicBarrier;
@@ -170,7 +171,7 @@ public class SslSecurityListenerTest extends TestCase
sh.setAuthenticator(authenticator);
Set<String> roles = new HashSet<String>(Arrays.asList(new String[]{"user", "admin"}));
- sh.setConstraintMappings(new ConstraintMapping[] { cm }, roles);
+ sh.setConstraintMappings(Collections.singletonList(cm), roles);
_server.setHandler(sh);
Handler testHandler = new AbstractHandler()
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java
new file mode 100644
index 0000000000..e1bdfc41e2
--- /dev/null
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java
@@ -0,0 +1,249 @@
+// ========================================================================
+// Copyright (c) 2006-2009 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.client;
+
+import java.io.IOException;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.TestCase;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketConnection;
+import org.eclipse.jetty.websocket.WebSocketHandler;
+
+/**
+ * Functional testing for HttpExchange.
+ */
+public class WebSocketUpgradeTest extends TestCase
+{
+ protected Server _server;
+ protected int _port;
+ protected HttpClient _httpClient;
+ protected Connector _connector;
+ protected ConcurrentLinkedQueue<TestWebSocket> _webSockets= new ConcurrentLinkedQueue<TestWebSocket>();
+ protected WebSocketHandler _handler;
+ protected TestWebSocket _websocket;
+ final BlockingQueue<Object> _results = new ArrayBlockingQueue<Object>(100);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ startServer();
+ _httpClient=new HttpClient();
+ _httpClient.setIdleTimeout(2000);
+ _httpClient.setTimeout(2500);
+ _httpClient.setConnectTimeout(1000);
+ _httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+ _httpClient.setMaxConnectionsPerAddress(10);
+ _httpClient.start();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ _httpClient.stop();
+ Thread.sleep(500);
+ stopServer();
+ }
+
+
+ public void testGetWithContentExchange() throws Exception
+ {
+ final WebSocket clientWS = new WebSocket()
+ {
+ Outbound _outbound;
+
+ public void onConnect(Outbound outbound)
+ {
+ _outbound=outbound;
+ _results.add("clientWS.onConnect");
+ _results.add(_outbound);
+ }
+
+ public void onDisconnect()
+ {
+ }
+
+ public void onMessage(byte frame, String data)
+ {
+ _results.add("clientWS.onMessage");
+ _results.add(data);
+ }
+
+ public void onMessage(byte frame, byte[] data, int offset, int length)
+ {
+ }
+ };
+
+
+ HttpExchange httpExchange=new HttpExchange()
+ {
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.client.HttpExchange#onResponseStatus(org.eclipse.jetty.io.Buffer, int, org.eclipse.jetty.io.Buffer)
+ */
+ @Override
+ protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+ {
+ waitFor(2);
+ _results.add(new Integer(status));
+ super.onResponseStatus(version,status,reason);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.client.HttpExchange#onSwitchProtocol(org.eclipse.jetty.io.EndPoint)
+ */
+ @Override
+ protected Connection onSwitchProtocol(EndPoint endp) throws IOException
+ {
+ waitFor(3);
+ WebSocketConnection connection = new WebSocketConnection(clientWS,endp);
+
+ _results.add("onSwitchProtocol");
+ _results.add(connection);
+ clientWS.onConnect(connection);
+ return connection;
+ }
+
+ private void waitFor(int results)
+ {
+ try
+ {
+ int c=10;
+ while(_results.size()<results && c-->0)
+ Thread.sleep(10);
+ }
+ catch(InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ httpExchange.setURL("http://localhost:"+_port+"/");
+ httpExchange.setMethod(HttpMethods.GET);
+
+ httpExchange.addRequestHeader("Upgrade","WebSocket");
+ httpExchange.addRequestHeader("Connection","Upgrade");
+
+ _httpClient.send(httpExchange);
+ int status = httpExchange.waitForDone();
+ assertEquals(HttpExchange.STATUS_COMPLETED, status);
+
+ System.err.println("results="+_results);
+
+ assertEquals("serverWS.onConnect", _results.poll(1,TimeUnit.SECONDS));
+ TestWebSocket serverWS = (TestWebSocket)_results.poll(1,TimeUnit.SECONDS);
+
+ assertEquals(new Integer(101), _results.poll(1,TimeUnit.SECONDS));
+
+ assertEquals("onSwitchProtocol", _results.poll(1,TimeUnit.SECONDS));
+ WebSocketConnection client_conn=(WebSocketConnection)_results.poll(1,TimeUnit.SECONDS);
+
+ assertEquals("clientWS.onConnect", _results.poll(1,TimeUnit.SECONDS));
+ assertEquals(client_conn, _results.poll(1,TimeUnit.SECONDS));
+
+ client_conn.sendMessage("hello world");
+
+ assertEquals("serverWS.onMessage", _results.poll(1,TimeUnit.SECONDS));
+ assertEquals("hello world", _results.poll(1,TimeUnit.SECONDS));
+
+ serverWS.sendMessage("buongiorno");
+
+ assertEquals("clientWS.onMessage", _results.poll(1,TimeUnit.SECONDS));
+ assertEquals("buongiorno", _results.poll(1,TimeUnit.SECONDS));
+
+ }
+
+ protected void newServer() throws Exception
+ {
+ _server=new Server();
+ _server.setGracefulShutdown(500);
+ _connector=new SelectChannelConnector();
+
+ _connector.setPort(0);
+ _server.setConnectors(new Connector[] { _connector });
+ }
+
+ protected void startServer() throws Exception
+ {
+ newServer();
+ _handler= new WebSocketHandler()
+ {
+ @Override
+ protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
+ {
+ _websocket = new TestWebSocket();
+ return _websocket;
+ }
+ };
+
+ _server.setHandler(_handler);
+ _server.start();
+ _port=_connector.getLocalPort();
+ }
+
+ private void stopServer() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
+
+ /* ------------------------------------------------------------ */
+ /* ------------------------------------------------------------ */
+ class TestWebSocket implements WebSocket
+ {
+ Outbound _outbound;
+
+ public void onConnect(Outbound outbound)
+ {
+ _outbound=outbound;
+ _webSockets.add(this);
+ _results.add("serverWS.onConnect");
+ _results.add(this);
+ }
+
+ public void onMessage(byte frame, byte[] data,int offset, int length)
+ {
+ }
+
+ public void onMessage(final byte frame, final String data)
+ {
+ _results.add("serverWS.onMessage");
+ _results.add(data);
+ }
+
+ public void onDisconnect()
+ {
+ _results.add("onDisconnect");
+ _webSockets.remove(this);
+ }
+
+ public void sendMessage(String msg) throws IOException
+ {
+ _outbound.sendMessage(msg);
+ }
+ }
+}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java
index 7c3386093b..9c70665e33 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java
@@ -4,35 +4,36 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.client.security;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class SecurityResolverTest extends TestCase
+public class SecurityResolverTest
{
+ @Test
public void testNothing()
{
-
}
+
/* TODO
public void testCredentialParsing() throws Exception
{
SecurityListener resolver = new SecurityListener();
Buffer value = new ByteArrayBuffer("basic a=b".getBytes());
-
+
assertEquals( "basic", resolver.scrapeAuthenticationType( value.toString() ) );
assertEquals( 1, resolver.scrapeAuthenticationDetails( value.toString() ).size() );
value = new ByteArrayBuffer("digest a=boo, c=\"doo\" , egg=foo".getBytes());
-
+
assertEquals( "digest", resolver.scrapeAuthenticationType( value.toString() ) );
Map<String,String> testMap = resolver.scrapeAuthenticationDetails( value.toString() );
assertEquals( 3, testMap.size() );
@@ -40,6 +41,6 @@ public class SecurityResolverTest extends TestCase
assertEquals( "doo", testMap.get("c") );
assertEquals( "foo", testMap.get("egg") );
}
-
+
*/
}
diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml
index 12f284228b..bbbf30da9f 100644
--- a/jetty-continuation/pom.xml
+++ b/jetty-continuation/pom.xml
@@ -54,10 +54,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.continuation.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java
index 7cc7bfa19f..e547f13d1d 100644
--- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java
+++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java
@@ -27,10 +27,10 @@ import javax.servlet.ServletResponseWrapper;
* A continuation is a mechanism by which a HTTP Request can be suspended and
* restarted after a timeout or an asynchronous event has occurred.
* <p>
- * The continuation mechanism is a portable mechansim that will work
- * asychronously without additional configuration of all jetty-7,
+ * The continuation mechanism is a portable mechanism that will work
+ * asynchronously without additional configuration of all jetty-7,
* jetty-8 and Servlet 3.0 containers. With the addition of
- * the {@link ContinuationFilter}, the mechansism will also work
+ * the {@link ContinuationFilter}, the mechanism will also work
* asynchronously on jetty-6 and non-asynchronously on any
* servlet 2.5 container.
* <p>
@@ -172,8 +172,8 @@ public interface Continuation
* the container with a suspended request, the thread is freed for other
* tasks and the request is held until either:
* <ul>
- * <li>a call to {@link ServletRequest#resume()}.</li>
- * <li>a call to {@link ServletRequest#complete()}.</li>
+ * <li>a call to {@link #resume()}.</li>
+ * <li>a call to {@link #complete()}.</li>
* <li>the timeout expires.</li>
* </ul>
* <p>
@@ -207,8 +207,8 @@ public interface Continuation
* the container with a suspended request, the thread is freed for other
* tasks and the request is held until either:
* <ul>
- * <li>a call to {@link ServletRequest#resume()}.</li>
- * <li>a call to {@link ServletRequest#complete()}.</li>
+ * <li>a call to {@link #resume()}.</li>
+ * <li>a call to {@link #complete()}.</li>
* <li>the timeout expires.</li>
* </ul>
* <p>
@@ -241,11 +241,11 @@ public interface Continuation
* </p>
* <p>
* If resume is called before a suspended request is returned to the
- * container (ie the thread that called {@link #suspend(long)} is still
+ * container (ie the thread that called {@link #suspend()} is still
* within the filter chain and/or servlet service method), then the resume
* does not take effect until the call to the filter chain and/or servlet
* returns to the container. In this case both {@link #isSuspended()} and
- * {@link isResumed()} return true. Multiple calls to resume are ignored.
+ * {@link #isResumed()} return true. Multiple calls to resume are ignored.
* </p>
* <p>
* Typically resume() is used after a call to {@link #suspend()} with
@@ -254,7 +254,7 @@ public interface Continuation
* had been passed a wrapped response.
* </p>
*
- * @see {@link #suspend()}
+ * @see #suspend()
* @exception IllegalStateException if the request is not suspended.
*
*/
@@ -267,16 +267,16 @@ public interface Continuation
* <p>
* This method can be called by any thread that has been passed a reference
* to a suspended request. When a request is completed, the associated
- * response object commited and flushed. The request is not redispatched.
+ * response object committed and flushed. The request is not redispatched.
* </p>
*
* <p>
* If complete is called before a suspended request is returned to the
- * container (ie the thread that called {@link #suspend(long)} is still
+ * container (ie the thread that called {@link #suspend()} is still
* within the filter chain and/or servlet service method), then the complete
* does not take effect until the call to the filter chain and/or servlet
* returns to the container. In this case both {@link #isSuspended()} and
- * {@link isResumed()} return true.
+ * {@link #isResumed()} return true.
* </p>
*
* <p>
@@ -295,7 +295,7 @@ public interface Continuation
* not valid hold a request or continuation reference after the end of the
* life cycle.
*
- * @see {@link #suspend()}
+ * @see #suspend()
* @exception IllegalStateException
* if the request is not suspended.
*
@@ -304,7 +304,7 @@ public interface Continuation
/* ------------------------------------------------------------ */
/**
- * @return true after {@link #suspend(long)} has been called and before the
+ * @return true after {@link #suspend()} has been called and before the
* request has been redispatched due to being resumed, completed or
* timed out.
*/
diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java
index 3b64778392..6a90a5ad3c 100644
--- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java
+++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java
@@ -96,8 +96,8 @@ public class ContinuationSupport
* vary depending on the container in which the application is
* deployed. It may be an implementation native to the container (eg
* org.eclipse.jetty.server.AsyncContinuation) or one of the utility
- * implementations provided such as {@link FauxContinuation} or
- * {@link Servlet3Continuation}.
+ * implementations provided such as an internal <code>FauxContinuation</code>
+ * or a real implementation like {@link org.eclipse.jetty.continuation.Servlet3Continuation}.
* @param request The request
* @return a Continuation instance
*/
@@ -147,10 +147,10 @@ public class ContinuationSupport
/* ------------------------------------------------------------ */
/**
- * @param request
- * @param response
+ * @param request the servlet request
+ * @param response the servlet response
* @deprecated use {@link #getContinuation(ServletRequest)}
- * @return
+ * @return the continuation
*/
@Deprecated
public static Continuation getContinuation(final ServletRequest request, final ServletResponse response)
diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java
index 3d15be2d0a..1e801ba468 100644
--- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java
+++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java
@@ -59,6 +59,7 @@ public class Servlet3Continuation implements Continuation
public void onTimeout(AsyncEvent event) throws IOException
{
_initial=false;
+ System.err.println("Doing dispatch on timed out continuation for "+_request.getAttribute("FOO"));
event.getAsyncContext().dispatch();
}
});
diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml
index 37f3ec8de4..07681758d2 100644
--- a/jetty-deploy/pom.xml
+++ b/jetty-deploy/pom.xml
@@ -27,6 +27,23 @@
</executions>
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>config.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<!--
Required for OSGI
-->
@@ -38,10 +55,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.deploy.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -59,7 +78,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.7</version>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-deploy/src/main/config/etc/jetty-deploy.xml b/jetty-deploy/src/main/config/etc/jetty-deploy.xml
new file mode 100644
index 0000000000..89fc9899e2
--- /dev/null
+++ b/jetty-deploy/src/main/config/etc/jetty-deploy.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Deployers -->
+<!-- =============================================================== -->
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Configure the deployment manager -->
+ <!-- -->
+ <!-- Sets up 2 monitored dir app providers that are configured -->
+ <!-- to behave in a similaraly to the legacy ContextDeployer -->
+ <!-- and WebAppDeployer from previous versions of Jetty. -->
+ <!-- =========================================================== -->
+ <Call name="addBean">
+ <Arg>
+ <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+ <Set name="contexts">
+ <Ref id="Contexts" />
+ </Set>
+ <Call name="setContextAttribute">
+ <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
+ <Arg>.*/servlet-api-[^/]*\.jar$</Arg>
+ </Call>
+ <!-- Providers of Apps via Context XML files.
+ Configured to behave similar to the legacy ContextDeployer -->
+ <Call name="addAppProvider">
+ <Arg>
+ <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
+ <Set name="monitoredDir"><Property name="jetty.home" default="." />/contexts</Set>
+ <Set name="scanInterval">5</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- Providers of Apps via WAR file existence.
+ Configured to behave similar to the legacy WebAppDeployer -->
+ <Call name="addAppProvider">
+ <Arg>
+ <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+ <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
+ <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+ <Set name="scanInterval">5</Set>
+ <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
+ </New>
+ </Arg>
+ </Call>
+ </New>
+ </Arg>
+ </Call>
+</Configure>
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
index c881985096..4dc1f5a370 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
@@ -15,20 +15,9 @@
// ========================================================================
package org.eclipse.jetty.deploy;
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.AttributesMap;
-import org.eclipse.jetty.util.URIUtil;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.xml.XmlConfiguration;
-import org.xml.sax.SAXException;
+import org.omg.CORBA.portable.ApplicationException;
/**
* The information about an App that is managed by the {@link DeploymentManager}
@@ -98,8 +87,8 @@ public class App
* Create it if needed.
*
* @return the {@link ContextHandler} to use for the App when fully started.
- * (Portions of which might be ignored when App is in the
- * {@link AppState#STAGED} state}
+ * (Portions of which might be ignored when App is not yet
+ * {@link AppLifeCycle#DEPLOYED} or {@link AppLifeCycle#STARTED})
* @throws Exception
*/
public ContextHandler getContextHandler() throws Exception
@@ -107,7 +96,15 @@ public class App
if (_context == null)
{
_context = getAppProvider().createContextHandler(this);
- this._context.setAttributes(new AttributesMap(_manager.getContextAttributes()));
+
+ AttributesMap attributes = _manager.getContextAttributes();
+ if (attributes!=null && attributes.size()>0)
+ {
+ // Merge the manager attributes under the existing attributes
+ attributes = new AttributesMap(attributes);
+ attributes.addAll(_context.getAttributes());
+ _context.setAttributes(attributes);
+ }
}
return _context;
}
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java
index ddc195bc1f..7738cecb32 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java
@@ -29,7 +29,7 @@ import org.eclipse.jetty.util.log.Log;
/**
* The lifecycle of an App in the {@link DeploymentManager}.
*
- * Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link DeployLifeCycleBinding}
+ * Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link AppLifeCycle.Binding}
* annotation.
* <p>
* <img src="doc-files/AppLifeCycle.png">
@@ -54,8 +54,6 @@ public class AppLifeCycle extends Graph
* the node being processed
* @param app
* the app being processed
- * @param deploymentManager
- * the {@link DeploymentManager} tracking the {@link AppLifeCycle} and {@link App}
* @throws Exception
* if any problem severe enough to halt the AppLifeCycle processing
*/
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ContextDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ContextDeployer.java
index 116e009728..0a7c6c29de 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ContextDeployer.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ContextDeployer.java
@@ -15,10 +15,10 @@ package org.eclipse.jetty.deploy;
import java.io.File;
import java.io.FilenameFilter;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
@@ -48,7 +48,7 @@ import org.eclipse.jetty.xml.XmlConfiguration;
*
* <p>
* The xml should configure the context and the instance is deployed to the {@link ContextHandlerCollection} specified
- * by {@link #setContexts(Server)}.
+ * by {@link Server#setHandler(org.eclipse.jetty.server.Handler)}.
*
* <p>
* Similarly, when one of these existing files is removed, the corresponding context is undeployed; when one of these
@@ -88,7 +88,7 @@ public class ContextDeployer extends AbstractLifeCycle
/**
* Handle a new deployment
*
- * @see org.eclipse.jetty.util.Scanner.FileAddedListener#fileAdded(java.lang.String)
+ * @see org.eclipse.jetty.util.Scanner.DiscreteListener#fileAdded(java.lang.String)
*/
public void fileAdded(String filename) throws Exception
{
@@ -98,7 +98,7 @@ public class ContextDeployer extends AbstractLifeCycle
/**
* Handle a change to an existing deployment. Undeploy then redeploy.
*
- * @see org.eclipse.jetty.util.Scanner.FileChangedListener#fileChanged(java.lang.String)
+ * @see org.eclipse.jetty.util.Scanner.DiscreteListener#fileChanged(java.lang.String)
*/
public void fileChanged(String filename) throws Exception
{
@@ -108,7 +108,7 @@ public class ContextDeployer extends AbstractLifeCycle
/**
* Handle an undeploy.
*
- * @see org.eclipse.jetty.util.Scanner.FileRemovedListener#fileRemoved(java.lang.String)
+ * @see org.eclipse.jetty.util.Scanner.DiscreteListener#fileRemoved(java.lang.String)
*/
public void fileRemoved(String filename) throws Exception
{
@@ -123,8 +123,6 @@ public class ContextDeployer extends AbstractLifeCycle
/**
* Constructor
- *
- * @throws Exception
*/
public ContextDeployer()
{
@@ -245,7 +243,7 @@ public class ContextDeployer extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the directory
* @deprecated use {@link #setContextsDir(String)}
*/
@Deprecated
@@ -256,7 +254,7 @@ public class ContextDeployer extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the configuration directory
* @deprecated use {@link #setContextsDir(String)}
*/
@Deprecated
@@ -276,7 +274,7 @@ public class ContextDeployer extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the configuration manager
*/
public ConfigurationManager getConfigurationManager()
{
@@ -319,7 +317,7 @@ public class ContextDeployer extends AbstractLifeCycle
/**
* Get a contextAttribute that will be set for every Context deployed by this deployer.
* @param name
- * @return
+ * @return the attribute value
*/
public Object getAttribute (String name)
{
@@ -450,7 +448,14 @@ public class ContextDeployer extends AbstractLifeCycle
xmlConfiguration.setProperties(properties);
ContextHandler context=(ContextHandler)xmlConfiguration.configure();
- context.setAttributes(new AttributesMap(_contextAttributes));
+
+ // merge attributes
+ if (_contextAttributes!=null && _contextAttributes.size()>0)
+ {
+ AttributesMap attributes = new AttributesMap(_contextAttributes);
+ attributes.addAll(context.getAttributes());
+ context.setAttributes(attributes);
+ }
return context;
}
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
index 381a496ef3..e138969663 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
@@ -24,7 +24,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.Set;
import org.eclipse.jetty.deploy.bindings.StandardDeployer;
import org.eclipse.jetty.deploy.bindings.StandardStarter;
@@ -305,9 +304,9 @@ public class DeploymentManager extends AbstractLifeCycle
/**
* Get Set of {@link App}s by {@link Node}
*
- * @param state
- * the state to look for.
- * @return
+ * @param node
+ * the node to look for.
+ * @return the collection of apps for the node
*/
public Collection<App> getApps(Node node)
{
@@ -358,7 +357,7 @@ public class DeploymentManager extends AbstractLifeCycle
* Get a contextAttribute that will be set for every Context deployed by this provider.
*
* @param name
- * @return
+ * @return the context attribute value
*/
public Object getContextAttribute(String name)
{
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/WebAppDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/WebAppDeployer.java
index a76e3491a1..b78c1d4641 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/WebAppDeployer.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/WebAppDeployer.java
@@ -15,6 +15,7 @@ package org.eclipse.jetty.deploy;
import java.util.ArrayList;
+import org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
@@ -40,7 +41,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
* by {@link #getContexts()}. {@link ContextHandlerCollection#getContextClass()}
*
* <p>
- * This deployer does not do hot deployment or undeployment. Nor does it support per webapplication configuration. For
+ * This deployer does not do hot deployment or undeployment. Nor does it support per web application configuration. For
* these features see {@link ContextDeployer}.
*
* @see DeploymentManager
@@ -149,7 +150,7 @@ public class WebAppDeployer extends AbstractLifeCycle
/**
* Get a contextAttribute that will be set for every Context deployed by this deployer.
* @param name
- * @return
+ * @return the attribute value
*/
public Object getAttribute (String name)
{
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java
index a07b33beda..91b8395c43 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java
@@ -19,7 +19,6 @@ import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.log.Log;
public class StandardStarter implements AppLifeCycle.Binding
{
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java
index 547bdb3519..02860e7b84 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java
@@ -138,7 +138,7 @@ public class Graph
/**
* Find all edges that are connected {@link Edge#getFrom()} the specific node.
*
- * @param node
+ * @param from
* the node with potential edges from it
* @return the set of edges from the node
*/
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java
index 8a92c45893..92940acee7 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java
@@ -16,7 +16,7 @@ import org.eclipse.jetty.xml.XmlConfiguration;
/* ------------------------------------------------------------ */
/** Context directory App Provider.
- * <p>This specialisation of {@link MonitoredDirAppProvider} is the
+ * <p>This specialization of {@link MonitoredDirAppProvider} is the
* replacement for {@link ContextDeployer} and it will scan a directory
* only for context.xml files.
* @see ContextDeployer
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
index e3cf85da61..36ea012de7 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
@@ -17,7 +17,6 @@ package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
-import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -40,10 +39,8 @@ import org.eclipse.jetty.xml.XmlConfiguration;
* AppProvider for Monitoring directories for contexts.
*
* A Context may either be a WAR, a directory or an XML descriptor.
- *
- * @deprecated - Use {@link ContextProvider} or {@link WebAppProvider}
*/
-public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider
+public abstract class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider
{
class MonitoredFilenameFilter implements FilenameFilter
{
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
index 6d648b22eb..417ff6cc33 100644
--- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
+++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
@@ -4,18 +4,15 @@ import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
-import java.util.HashMap;
-import java.util.Map;
import org.eclipse.jetty.deploy.App;
-import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.WebAppDeployer;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.xml.XmlConfiguration;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
/* ------------------------------------------------------------ */
@@ -31,6 +28,7 @@ public class WebAppProvider extends ScanningAppProvider
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
private Filter _filter;
+ private File _tempDirectory;
private String[] _configurationClasses;
private static class Filter implements FilenameFilter
@@ -40,13 +38,17 @@ public class WebAppProvider extends ScanningAppProvider
public boolean accept(File dir, String name)
{
if (!dir.exists())
+ {
return false;
+ }
String lowername = name.toLowerCase();
File file = new File(dir,name);
// is it not a directory and not a war ?
if (!file.isDirectory() && !lowername.endsWith(".war"))
+ {
return false;
+ }
// is it a directory for an existing war file?
if (file.isDirectory() &&
@@ -61,7 +63,9 @@ public class WebAppProvider extends ScanningAppProvider
{
String context=name;
if (!file.isDirectory())
+ {
context=context.substring(0,context.length()-4);
+ }
if (new File(_contexts,context+".xml").exists() ||
new File(_contexts,context+".XML").exists() )
{
@@ -116,7 +120,7 @@ public class WebAppProvider extends ScanningAppProvider
{
_parentLoaderPriority = parentLoaderPriority;
}
-
+
/* ------------------------------------------------------------ */
/** Get the defaultsDescriptor.
* @return the defaultsDescriptor
@@ -160,7 +164,7 @@ public class WebAppProvider extends ScanningAppProvider
}
catch (MalformedURLException e)
{
- e.printStackTrace();
+ throw new RuntimeException(e);
}
catch (IOException e)
{
@@ -187,6 +191,27 @@ public class WebAppProvider extends ScanningAppProvider
return _configurationClasses;
}
+ /**
+ * Set the Work directory where unpacked WAR files are managed from.
+ * <p>
+ * Default is the same as the <code>java.io.tmpdir</code> System Property.
+ *
+ * @param directory the new work directory
+ */
+ public void setTempDir(File directory)
+ {
+ _tempDirectory = directory;
+ }
+
+ /**
+ * Get the user supplied Work Directory.
+ *
+ * @return the user supplied work directory (null if user has not set Temp Directory yet)
+ */
+ public File getTempDir()
+ {
+ return _tempDirectory;
+ }
/* ------------------------------------------------------------ */
public ContextHandler createContextHandler(final App app) throws Exception
@@ -207,31 +232,54 @@ public class WebAppProvider extends ScanningAppProvider
// Context Path is the same as the archive.
context = context.substring(0,context.length() - 4);
}
- else
+ else
+ {
throw new IllegalStateException("unable to create ContextHandler for "+app);
+ }
// special case of archive (or dir) named "root" is / context
- if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
+ if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
+ {
context = URIUtil.SLASH;
+ }
// Ensure "/" is Prepended to all context paths.
- if (context.charAt(0) != '/')
+ if (context.charAt(0) != '/')
+ {
context = "/" + context;
+ }
// Ensure "/" is Not Trailing in context paths.
- if (context.endsWith("/") && context.length() > 0)
+ if (context.endsWith("/") && context.length() > 0)
+ {
context = context.substring(0,context.length() - 1);
+ }
WebAppContext wah = new WebAppContext();
wah.setContextPath(context);
wah.setWar(file.getAbsolutePath());
- if (_defaultsDescriptor != null)
+ if (_defaultsDescriptor != null)
+ {
wah.setDefaultsDescriptor(_defaultsDescriptor);
+ }
wah.setExtractWAR(_extractWars);
wah.setParentLoaderPriority(_parentLoaderPriority);
- if (_configurationClasses != null)
+ if (_configurationClasses != null)
+ {
wah.setConfigurationClasses(_configurationClasses);
+ }
+ if (_tempDirectory != null)
+ {
+ /* Since the Temp Dir is really a context base temp directory,
+ * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it,
+ * instead of setting the
+ * WebAppContext.setTempDirectory(File).
+ * If we used .setTempDirectory(File) all webapps will wind up in the
+ * same temp / work directory, overwriting each others work.
+ */
+ wah.setAttribute(WebAppContext.BASETEMPDIR,_tempDirectory);
+ }
return wah;
}
diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java
index 26acce7045..5caa04b68a 100644
--- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java
+++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java
@@ -159,7 +159,7 @@ public class AppLifeCycleTest
/**
* Request multiple lifecycle paths with a single lifecycle instance. Just to ensure that there is no state
- * maintained between {@link AppLifeCycle#findPath(Node, Node)} requests.
+ * maintained between {@link AppLifeCycle#getPath(Node, Node)} requests.
*
* @throws IOException
*/
diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java
index d2d74b0b21..cc284e1f4d 100644
--- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java
+++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java
@@ -1,9 +1,9 @@
package org.eclipse.jetty.deploy.graph;
-import org.junit.Test;
-
import junit.framework.Assert;
+import org.junit.Test;
+
public class GraphTest
{
diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java
new file mode 100644
index 0000000000..8fc7cb5930
--- /dev/null
+++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java
@@ -0,0 +1,76 @@
+package org.eclipse.jetty.deploy.providers;
+
+import java.io.File;
+
+import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class WebAppProviderTest
+{
+ private static XmlConfiguredJetty jetty;
+
+ @BeforeClass
+ public static void setupEnvironment() throws Exception
+ {
+ jetty = new XmlConfiguredJetty();
+ jetty.addConfiguration("jetty.xml");
+ jetty.addConfiguration("jetty-deploy-wars.xml");
+
+ // Setup initial context
+ jetty.copyContext("foo.xml","foo.xml");
+ jetty.copyWebapp("foo-webapp-1.war","foo.war");
+
+ // Should not throw an Exception
+ jetty.load();
+
+ // Start it
+ jetty.start();
+ }
+
+ @AfterClass
+ public static void teardownEnvironment() throws Exception
+ {
+ // Stop jetty.
+ jetty.stop();
+ }
+
+ @Test
+ public void testStartupContext()
+ {
+ // Check Server for Handlers
+ jetty.printHandlers(System.out);
+ jetty.assertWebAppContextsExists("/foo");
+
+ File workDir = jetty.getJettyDir("workish");
+
+ // Test for regressions
+ assertDirNotExists("root of work directory",workDir,"webinf");
+ assertDirNotExists("root of work directory",workDir,"jsp");
+
+ // Test for correct behavior
+ Assert.assertTrue("Should have generated directory in work directory: " + workDir,hasJettyGeneratedPath(workDir,"foo.war"));
+ }
+
+ private static boolean hasJettyGeneratedPath(File basedir, String expectedWarFilename)
+ {
+ for (File path : basedir.listFiles())
+ {
+ if (path.exists() && path.isDirectory() && path.getName().startsWith("Jetty_") && path.getName().contains(expectedWarFilename))
+ {
+ System.out.println("Found expected generated directory: " + path);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static void assertDirNotExists(String msg, File workDir, String subdir)
+ {
+ File dir = new File(workDir,subdir);
+ Assert.assertFalse("Should not have " + subdir + " in " + msg + " - " + workDir,dir.exists());
+ }
+}
diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/MavenTestingUtils.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/MavenTestingUtils.java
index e6f9e265a0..367d584aa2 100644
--- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/MavenTestingUtils.java
+++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/MavenTestingUtils.java
@@ -93,7 +93,8 @@ public class MavenTestingUtils
*
* @param test
* the junit 3.x testcase to base this new directory on.
- * @return
+ * @return the File path to the testcase specific testing directory underneath the
+ * <code>${basedir}/target</code> sub directory
*/
public static File getTargetTestingDir(TestCase test)
{
@@ -105,7 +106,8 @@ public class MavenTestingUtils
*
* @param testname
* the testname to create directory against.
- * @return
+ * @return the File path to the testname sepecific testing directory underneath the
+ * <code>${basedir}/target</code> sub directory
*/
public static File getTargetTestingDir(String testname)
{
diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
index e2e18f911e..89e03dd26f 100644
--- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
+++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
@@ -59,7 +59,7 @@ public class XmlConfiguredJetty
{
this(MavenTestingUtils.getTestID());
}
-
+
public XmlConfiguredJetty(String testname) throws IOException
{
xmlConfigurations = new ArrayList<URL>();
@@ -69,9 +69,10 @@ public class XmlConfiguredJetty
// Ensure we have a new (pristene) directory to work with.
int idx = 0;
jettyHome = new File(jettyHomeBase + "#" + idx);
- while(jettyHome.exists()) {
- idx++;
- jettyHome = new File(jettyHomeBase + "#" + idx);
+ while (jettyHome.exists())
+ {
+ idx++;
+ jettyHome = new File(jettyHomeBase + "#" + idx);
}
deleteContents(jettyHome);
// Prepare Jetty.Home (Test) dir
@@ -91,15 +92,28 @@ public class XmlConfiguredJetty
deleteContents(contextsDir);
}
contextsDir.mkdirs();
+
File webappsDir = new File(jettyHome,"webapps");
if (webappsDir.exists())
{
deleteContents(webappsDir);
}
webappsDir.mkdirs();
+
File tmpDir = new File(jettyHome,"tmp");
+ if (tmpDir.exists())
+ {
+ deleteContents(tmpDir);
+ }
tmpDir.mkdirs();
+ File workishDir = new File(jettyHome,"workish");
+ if (workishDir.exists())
+ {
+ deleteContents(workishDir);
+ }
+ workishDir.mkdirs();
+
// Setup properties
System.setProperty("java.io.tmpdir",tmpDir.getAbsolutePath());
properties.setProperty("jetty.home",jettyHome.getAbsolutePath());
@@ -108,6 +122,7 @@ public class XmlConfiguredJetty
properties.setProperty("test.resourcesdir",MavenTestingUtils.getTestResourcesDir().getAbsolutePath());
properties.setProperty("test.webapps",webappsDir.getAbsolutePath());
properties.setProperty("test.targetdir",MavenTestingUtils.getTargetDir().getAbsolutePath());
+ properties.setProperty("test.workdir",workishDir.getAbsolutePath());
// Write out configuration for use by ConfigurationManager.
File testConfig = MavenTestingUtils.getTargetFile("xml-configured-jetty.properties");
@@ -238,11 +253,11 @@ public class XmlConfiguredJetty
private void deleteContents(File dir)
{
System.out.printf("Delete (dir) %s/%n",dir);
- if(!dir.exists())
+ if (!dir.exists())
{
- return;
+ return;
}
-
+
for (File file : dir.listFiles())
{
// Safety measure. only recursively delete within target directory.
@@ -261,9 +276,7 @@ public class XmlConfiguredJetty
public DeploymentManager getActiveDeploymentManager()
{
- List<DeploymentManager> depmans = server.getBeans(DeploymentManager.class);
- Assert.assertEquals("DeploymentManager bean count",1,depmans.size());
- return depmans.get(0);
+ return server.getBean(DeploymentManager.class);
}
public File getJettyDir(String name)
diff --git a/jetty-deploy/src/test/resources/jetty-deploy-wars.xml b/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
new file mode 100644
index 0000000000..f336584c66
--- /dev/null
+++ b/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <Call name="addLifeCycle">
+ <Arg>
+ <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+ <Set name="contexts">
+ <Ref id="Contexts" />
+ </Set>
+
+ <!-- Providers of Apps -->
+ <Set name="appProviders">
+ <Array type="org.eclipse.jetty.deploy.AppProvider">
+ <Item>
+ <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+ <Set name="monitoredDir"><SystemProperty name="jetty.home" />/webapps</Set>
+ <Set name="scanInterval">1</Set>
+ <Set name="tempDir"><Property name="jetty.home" default="target" />/workish</Set>
+ </New>
+ </Item>
+ </Array>
+ </Set>
+ </New>
+ </Arg>
+ </Call>
+
+</Configure>
diff --git a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
index 841944926d..07cf8d2889 100644
--- a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
+++ b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
@@ -15,7 +15,7 @@
<Array type="org.eclipse.jetty.deploy.AppProvider">
<Item>
<New class="org.eclipse.jetty.deploy.providers.ContextProvider">
- <Set name="monitoredDir"><Property name="jetty.home" />/contexts</Set>
+ <Set name="monitoredDir"><SystemProperty name="jetty.home" />/contexts</Set>
<Set name="scanInterval">1</Set>
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
@@ -28,9 +28,9 @@
</Item>
<Item>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
- <Set name="monitoredDir"><Property name="jetty.home" />/webapps</Set>
+ <Set name="monitoredDir"><SystemProperty name="jetty.home" />/webapps</Set>
<Set name="scanInterval">1</Set>
- <Set name="contextXmlDir"><Property name="jetty.home" />/contexts</Set>
+ <Set name="contextXmlDir"><SystemProperty name="jetty.home" />/contexts</Set>
</New>
</Item>
</Array>
diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml
index de13ded520..f0ac036c19 100644
--- a/jetty-distribution/pom.xml
+++ b/jetty-distribution/pom.xml
@@ -9,28 +9,44 @@
<name>Jetty :: Distribution Assemblies</name>
<packaging>pom</packaging>
<properties>
- <assembly.directory>target/distribution</assembly.directory>
+ <eclipse-mirror>http://mirror.cc.vt.edu/pub/eclipse/eclipse/downloads/drops</eclipse-mirror>
+ <orbit-url>http://download.eclipse.org/tools/orbit/committers/drops/I20100628101947/bundles</orbit-url>
+ <assembly-directory>target/distribution</assembly-directory>
+ <eclipse-drop>R-3.6-201006080911</eclipse-drop>
+ <eclipse-ecj-version>3.6</eclipse-ecj-version>
+ <orbit-javax-activation-version>${javax-activation-version}.0.v201005080500</orbit-javax-activation-version>
+ <orbit-javax-el-version>2.1.0.v201004190952</orbit-javax-el-version>
+ <orbit-javax-mail-glassfish-version>${javax-mail-version}.v201005082020</orbit-javax-mail-glassfish-version>
</properties>
- <build>
+ <build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
- <configuration>
- <includeEmptyDirs>true</includeEmptyDirs>
- <outputDirectory>${assembly.directory}</outputDirectory>
- </configuration>
<executions>
<execution>
+ <id>copy-base-assembly-tree</id>
<phase>generate-resources</phase>
<goals>
- <goal>resources</goal>
+ <goal>copy-resources</goal>
</goals>
+ <configuration>
+ <useBuildFilters>false</useBuildFilters>
+ <includeEmptyDirs>true</includeEmptyDirs>
+ <outputDirectory>${assembly-directory}</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${basedir}/src/main/resources</directory>
+ </resource>
+ </resources>
+ </configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
+ <version>1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
@@ -39,16 +55,38 @@
</goals>
<configuration>
<tasks>
- <property name="orbit.base.url" value="http://download.eclipse.org/tools/orbit/downloads/drops/R20090529135407/bundles" />
- <mkdir dir="${assembly.directory}/lib" />
- <!--
- <get src="${orbit.base.url}/javax.servlet_2.5.0.v200806031605.jar" dest="${assembly.directory}/lib/servlet-api-2.5.jar" usetimestamp="true" verbose="true" />
- -->
- <mkdir dir="${assembly.directory}/lib/jndi" />
- <get src="${orbit.base.url}/javax.activation_1.1.0.v200905021805.jar" dest="${assembly.directory}/lib/jndi/activation-1.1.jar" usetimestamp="true" verbose="true" />
- <get src="${orbit.base.url}/javax.mail_1.4.0.v200905040518.jar" dest="${assembly.directory}/lib/jndi/mail-1.4.jar" usetimestamp="true" verbose="true" />
- <copy file="../VERSION.txt" todir="${assembly.directory}" />
- <chmod dir="${assembly.directory}/bin" perm="755" includes="**/*.sh" />
+ <!-- This is the Orbit Downloads Process -->
+
+ <!-- Step 1: download orbit artifact into orbit-cache (if not present) -->
+ <property name="orbit-cache" value="${user.home}/.m2/eclipse-orbit" />
+
+ <mkdir dir="${orbit-cache}" />
+ <get dest="${orbit-cache}" verbose="true" skipexisting="true">
+ <url url="${orbit-url}/javax.activation_${orbit-javax-activation-version}.jar" />
+ <url url="${orbit-url}/javax.mail.glassfish_${orbit-javax-mail-glassfish-version}.jar" />
+ </get>
+
+ <mkdir dir="${orbit-cache}/${eclipse-drop}" />
+ <get dest="${orbit-cache}/${eclipse-drop}" verbose="true" skipexisting="true">
+ <url url="${eclipse-mirror}/${eclipse-drop}/ecj-${eclipse-ecj-version}.jar" />
+ </get>
+
+ <!-- Step 2: copy the orbit artifact from orbit-cache to the appropriate lib directory -->
+
+ <!-- ${jetty.home}/lib/ -->
+ <mkdir dir="${assembly-directory}/lib" />
+
+ <!-- ${jetty.home}/lib/jndi/ -->
+ <mkdir dir="${assembly-directory}/lib/jndi" />
+ <copy todir="${assembly-directory}/lib/jndi">
+ <fileset dir="${orbit-cache}">
+ <include name="javax.activation_${orbit-javax-activation-version}.jar" />
+ <include name="javax.mail.glassfish_${orbit-javax-mail-glassfish-version}.jar" />
+ </fileset>
+ </copy>
+
+ <copy file="../VERSION.txt" todir="${assembly-directory}" />
+ <chmod dir="${assembly-directory}/bin" perm="755" includes="**/*.sh" />
</tasks>
</configuration>
</execution>
@@ -68,7 +106,7 @@
<resourceBundle>org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.0</resourceBundle>
<resourceBundle>org.eclipse.jetty.toolchain:jetty-distribution-remote-resources:1.1</resourceBundle>
</resourceBundles>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</configuration>
</execution>
</executions>
@@ -93,7 +131,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -103,7 +141,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -113,7 +151,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -123,7 +161,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -133,7 +171,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -143,7 +181,17 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-deploy</artifactId>
+ <version>${project.version}</version>
+ <classifier>config</classifier>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <includes>**</includes>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -153,7 +201,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -163,7 +211,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -173,7 +221,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
@@ -193,7 +241,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -202,7 +250,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -211,7 +259,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -220,7 +268,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -229,7 +277,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -238,7 +286,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -247,7 +295,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -256,7 +304,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -265,7 +313,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<!-- Jetty Deploy -->
<artifactItem>
@@ -275,7 +323,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -284,7 +332,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -293,7 +341,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -302,7 +350,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -311,7 +359,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -320,7 +368,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -329,7 +377,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -338,7 +386,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -347,7 +395,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -356,7 +404,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
@@ -365,7 +413,7 @@
<type>war</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/webapps</outputDirectory>
+ <outputDirectory>${assembly-directory}/webapps</outputDirectory>
<destFileName>test.war</destFileName>
</artifactItem>
<artifactItem>
@@ -375,7 +423,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}</outputDirectory>
+ <outputDirectory>${assembly-directory}</outputDirectory>
<destFileName>start.jar</destFileName>
</artifactItem>
<artifactItem>
@@ -385,7 +433,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
<destFileName>servlet-api-3.0.jar</destFileName>
</artifactItem>
<artifactItem>
@@ -395,47 +443,11 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${assembly.directory}/lib</outputDirectory>
+ <outputDirectory>${assembly-directory}/lib</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
- <!--
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-annotation_1.0_spec</artifactId>
- <version>1.1.1</version>
- <outputDirectory>${assembly.directory}/lib/annotations</outputDirectory>
- </artifactItem>
- <artifactItem>
- <groupId>asm</groupId>
- <artifactId>asm-commons</artifactId>
- <version>3.1</version>
- <outputDirectory>${assembly.directory}/lib/annotations</outputDirectory>
- </artifactItem>
- <artifactItem>
- <groupId>asm</groupId>
- <artifactId>asm</artifactId>
- <version>3.1</version>
- <outputDirectory>${assembly.directory}/lib/annotations</outputDirectory>
- </artifactItem>
- <artifactItem>
- <groupId>asm</groupId>
- <artifactId>asm-tree</artifactId>
- <version>3.1</version>
- <outputDirectory>${assembly.directory}/lib/annotations</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- -->
</executions>
</plugin>
<plugin>
@@ -456,6 +468,22 @@
</execution>
</executions>
</plugin>
+ <!-- No point performing PMD in assembly project -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <!-- No point performing Findbugs in assembly project -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
@@ -531,4 +559,35 @@
<version>${project.version}</version>
</dependency>
</dependencies>
+ <!-- profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.1</version>
+ <executions>
+ <execution>
+ <id>unpack-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <includes>**/*</includes>
+ <excludes>META-INF/**</excludes>
+ <includeGroupIds>org.eclipse.jetty</includeGroupIds>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles -->
</project>
diff --git a/jetty-distribution/src/main/assembly/jetty-assembly.xml b/jetty-distribution/src/main/assembly/jetty-assembly.xml
index 3c5a9cc881..eac183cc96 100644
--- a/jetty-distribution/src/main/assembly/jetty-assembly.xml
+++ b/jetty-distribution/src/main/assembly/jetty-assembly.xml
@@ -6,7 +6,7 @@
</formats>
<fileSets>
<fileSet>
- <directory>${assembly.directory}</directory>
+ <directory>${assembly-directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>**</include>
diff --git a/jetty-distribution/src/main/resources/README.txt b/jetty-distribution/src/main/resources/README.txt
index 5d41b2c813..2a094bd58e 100644
--- a/jetty-distribution/src/main/resources/README.txt
+++ b/jetty-distribution/src/main/resources/README.txt
@@ -3,88 +3,64 @@ JETTY
=====
The Jetty project is a 100% Java HTTP Server, HTTP Client
-and Servlet Container. The core project is hosted by
-the Eclipse Foundation at
+and Servlet Container.
- http://www.eclipse.org/jetty/
-The jetty integrations with 3rd party modules are hosted
-by the Codehaus at
+The Jetty @ eclipse project is based on the Jetty project at codehaus
http://jetty.codehaus.org
+Ongoing development is now at the eclipse foundation
-JETTY DISTRIBUTION
-==================
-
-This is the jetty-distribution module from Jetty @ eclipse
-project and is based on the Jetty modules from eclipse plus
-dependencies that have been through the eclipse IP
-process and conditioning.
+ http://www.eclipse.org/jetty/
-This distribution and its dependencies are provided under
-the terms and conditions of the Eclipse Foundation Software
-User Agreement unless otherwise specified.
-This distribution contains only the core functionality
-of a servlet server and the HTTP client.
+Jetty @ eclipse is open source and is dual licensed using the apache 2.0 and
+eclipse public license 1.0. You may choose either license when distributing
+jetty.
-Some modules (eg annotations) are missing dependencies
-which may be discovered by using the command
- mvn dependency:tree
-within the source module and placing them in the
-lib/ext directory. Alternately we recommend the jetty-hightide
-distribution for users that desire more third party integrations.
-JETTY HIGHTIDE
+BUILDING JETTY
==============
-The Jetty-hightide distribution is available for
-download via http://jetty.codehaus.org and contains
-the core jetty modules, plus the 3rd party dependencies
-and integrations needed to create a full featured
-application server.
-
+Jetty uses maven 2 as its build system. Maven will fetch
+the dependancies, build the server and assemble a runnable
+version:
-MAVEN
-=====
-All Jetty artifacts are available as maven dependencies
-under the org.eclipse.jetty and org.mortbay.hightide group IDs
+ mvn install
- http://repo1.maven.org/maven2/org/eclipse/jetty/
- http://repo2.maven.org/maven2/org/mortbay/jetty/
RUNNING JETTY
=============
-The run directory is either the top-level of a distribution
-or jetty-distribution/target/distribution directory when built from
+The run directory is either the top-level of a binary release
+or jetty-distribution/target/assembly-prep directory when built from
source.
To run with the default options:
java -jar start.jar
-To run with specific configuration file(s)
-
- java -jar start.jar etc/jetty.xml
-
-To see the available options
+To see the available options and the default arguments
+provided by the start.ini file:
java -jar start.jar --help
-To run with JSP support (if available)
+To run with extra configuration file(s) appended, eg SSL
+
+ java -jar start.jar etc/jetty-ssl.xml
- java -jar start.jar OPTIONS=Server,jsp
+To run with extra configuration file(s) prepended, eg logging & jmx
-To run with JMX support
+ java -jar start.jar --pre=etc/jetty-logging.xml --pre=etc/jetty-jmx.xml
- java -jar start.jar OPTIONS=Server,jmx etc/jetty-jmx.xml etc/jetty.xml
+To run without the args from start.ini
-To run with JSP & JMX support
+ java -jar start.jar --ini OPTIONS=Server,websocket etc/jetty.xml etc/jetty-deploy.xml etc/jetty-ssl.xml
- java -jar start.jar OPTIONS=Server,jsp,jmx etc/jetty-jmx.xml etc/jetty.xml
+to list the know OPTIONS:
+ java -jar start.jar --list-options
diff --git a/jetty-distribution/src/main/resources/bin/jetty.sh b/jetty-distribution/src/main/resources/bin/jetty.sh
index 5c3fda5f78..c0b1be6a7d 100755
--- a/jetty-distribution/src/main/resources/bin/jetty.sh
+++ b/jetty-distribution/src/main/resources/bin/jetty.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# Startup script for jetty under *nix systems (it works under NT/cygwin too).
@@ -37,12 +37,8 @@
#
# Configuration variables
#
-# JAVA_HOME
-# Home of Java installation.
-#
# JAVA
-# Command to invoke Java. If not set, $JAVA_HOME/bin/java will be
-# used.
+# Command to invoke Java. If not set, java (from the PATH) will be used.
#
# JAVA_OPTIONS
# Extra options to pass to the JVM
@@ -83,12 +79,10 @@
# JETTY_USER
# if set, then used as a username to run the server as
#
-# Set to 0 if you do not want to use start-stop-daemon (especially on SUSE boxes)
-START_STOP_DAEMON=1
usage()
{
- echo "Usage: $0 {start|stop|run|restart|check|supervise} [ CONFIGS ... ] "
+ echo "Usage: ${0##*/} [-d] {start|stop|run|restart|check|supervise} [ CONFIGS ... ] "
exit 1
}
@@ -100,70 +94,64 @@ usage()
##################################################
findDirectory()
{
- OP=$1
- shift
- for L in $* ; do
- [ $OP $L ] || continue
- echo $L
- break
- done
+ local L OP=$1
+ shift
+ for L in "$@"; do
+ [ "$OP" "$L" ] || continue
+ printf %s "$L"
+ break
+ done
}
running()
{
- [ -f $1 ] || return 1
- PID=$(cat $1)
- ps -p $PID >/dev/null 2>/dev/null || return 1
- return 0
+ local PID=$(cat "$1" 2>/dev/null) || return 1
+ kill -0 "$PID" 2>/dev/null
}
-
-
-
+readConfig()
+{
+ (( DEBUG )) && echo "Reading $1.."
+ source "$1"
+}
##################################################
# Get the action & configs
##################################################
-
+CONFIGS=()
+NO_START=0
+DEBUG=0
+
+while [[ $1 = -* ]]; do
+ case $1 in
+ -d) DEBUG=1 ;;
+ esac
+ shift
+done
ACTION=$1
shift
-ARGS="$*"
-CONFIGS=""
-NO_START=0
##################################################
-# See if there's a default configuration file
+# Read any configuration files
##################################################
-if [ -f /etc/default/jetty7 ] ; then
- . /etc/default/jetty7
-elif [ -f /etc/default/jetty ] ; then
- . /etc/default/jetty
-fi
-
+for CONFIG in /etc/default/jetty{,7} $HOME/.jettyrc; do
+ if [ -f "$CONFIG" ] ; then
+ readConfig "$CONFIG"
+ fi
+done
-##################################################
-# See if there's a user-specific configuration file
-##################################################
-if [ -f $HOME/.jettyrc ] ; then
- . $HOME/.jettyrc
-fi
##################################################
# Set tmp if not already set.
##################################################
-
-if [ -z "$TMP" ]
-then
- TMP=/tmp
-fi
+TMPDIR=${TMPDIR:-/tmp}
##################################################
# Jetty's hallmark
##################################################
JETTY_INSTALL_TRACE_FILE="etc/jetty.xml"
-TMPJ=$TMP/j$$
##################################################
@@ -171,11 +159,17 @@ TMPJ=$TMP/j$$
##################################################
if [ -z "$JETTY_HOME" ]
then
- JETTY_HOME_1=`dirname "$0"`
- JETTY_HOME_1=`dirname "$JETTY_HOME_1"`
- if [ -f "${JETTY_HOME_1}/${JETTY_INSTALL_TRACE_FILE}" ] ;
+ JETTY_SH=$0
+ case "$JETTY_SH" in
+ /*) ;;
+ ./*) ;;
+ *) JETTY_SH=./$JETTY_SH ;;
+ esac
+ JETTY_HOME=${JETTY_SH%/*/*}
+
+ if [ ! -f "${JETTY_SH%/*/*}/$JETTY_INSTALL_TRACE_FILE" ]
then
- JETTY_HOME=${JETTY_HOME_1}
+ JETTY_HOME=
fi
fi
@@ -183,42 +177,57 @@ fi
##################################################
# if no JETTY_HOME, search likely locations.
##################################################
-if [ "$JETTY_HOME" = "" ] ; then
- STANDARD_LOCATIONS=" \
- /usr/share \
- /usr/share/java \
- $HOME \
- $HOME/src \
- ${HOME}/opt/ \
- /opt \
- /java \
- /usr/local \
- /usr/local/share \
- /usr/local/share/java \
- /home \
- "
- JETTY_DIR_NAMES=" \
- jetty-7 \
- jetty7 \
- jetty-7.* \
- jetty \
- Jetty-7 \
- Jetty7 \
- Jetty-7.* \
- Jetty \
- "
+if [ -z "$JETTY_HOME" ] ; then
+ STANDARD_LOCATIONS=(
+ "/usr/share"
+ "/usr/share/java"
+ "${HOME}"
+ "${HOME}/src"
+ "${HOME}/opt"
+ "/opt"
+ "/java"
+ "/usr/local"
+ "/usr/local/share"
+ "/usr/local/share/java"
+ "/home"
+ )
+ JETTY_DIR_NAMES=(
+ "jetty-7"
+ "jetty7"
+ "jetty-7.*"
+ "jetty"
+ "Jetty-7"
+ "Jetty7"
+ "Jetty-7.*"
+ "Jetty"
+ )
- JETTY_HOME=
- for L in $STANDARD_LOCATIONS
+ for L in "${STANDARD_LOCATIONS[@]}"
do
- for N in $JETTY_DIR_NAMES
- do
- if [ -d $L/$N ] && [ -f "$L/${N}/${JETTY_INSTALL_TRACE_FILE}" ] ;
- then
- JETTY_HOME="$L/$N"
- fi
- done
- [ ! -z "$JETTY_HOME" ] && break
+ for N in "${JETTY_DIR_NAMES[@]}"
+ do
+ POSSIBLE_JETTY_HOME=("$L/"$N)
+ if [ ! -d "$POSSIBLE_JETTY_HOME" ]
+ then
+ # Not a directory. skip.
+ unset POSSIBLE_JETTY_HOME
+ elif [ ! -f "$POSSIBLE_JETTY_HOME/$JETTY_INSTALL_TRACE_FILE" ]
+ then
+ # Trace file not found. skip.
+ unset POSSIBLE_JETTY_HOME
+ else
+ # Good hit, Use it
+ JETTY_HOME=$POSSIBLE_JETTY_HOME
+ # Break out of JETTY_DIR_NAMES loop
+ break
+ fi
+ done
+ if [ -n "$POSSIBLE_JETTY_HOME" ]
+ then
+ # We have found our JETTY_HOME
+ # Break out of STANDARD_LOCATIONS loop
+ break
+ fi
done
fi
@@ -226,57 +235,25 @@ fi
##################################################
# No JETTY_HOME yet? We're out of luck!
##################################################
-if [ -z "$JETTY_HOME" ] ; then
- echo "** ERROR: JETTY_HOME not set, you need to set it or install in a standard location"
- exit 1
+if [ -z "$JETTY_HOME" ]; then
+ echo "** ERROR: JETTY_HOME not set, you need to set it or install in a standard location"
+ exit 1
fi
-cd $JETTY_HOME
-JETTY_HOME=`pwd`
+
+cd "$JETTY_HOME"
+JETTY_HOME=$PWD
+
#####################################################
# Check that jetty is where we think it is
#####################################################
-if [ ! -r $JETTY_HOME/$JETTY_INSTALL_TRACE_FILE ]
+if [ ! -r "$JETTY_HOME/$JETTY_INSTALL_TRACE_FILE" ]
then
- echo "** ERROR: Oops! Jetty doesn't appear to be installed in $JETTY_HOME"
- echo "** ERROR: $JETTY_HOME/$JETTY_INSTALL_TRACE_FILE is not readable!"
- exit 1
+ echo "** ERROR: Oops! Jetty doesn't appear to be installed in $JETTY_HOME"
+ echo "** ERROR: $JETTY_HOME/$JETTY_INSTALL_TRACE_FILE is not readable!"
+ exit 1
fi
-
-###########################################################
-# Get the list of config.xml files from the command line.
-###########################################################
-if [ ! -z "$ARGS" ]
-then
- for A in $ARGS
- do
- if [ -f $A ]
- then
- CONF="$A"
- elif [ -f $JETTY_HOME/etc/$A ]
- then
- CONF="$JETTY_HOME/etc/$A"
- elif [ -f ${A}.xml ]
- then
- CONF="${A}.xml"
- elif [ -f $JETTY_HOME/etc/${A}.xml ]
- then
- CONF="$JETTY_HOME/etc/${A}.xml"
- else
- echo "** ERROR: Cannot find configuration '$A' specified in the command line."
- exit 1
- fi
- if [ ! -r $CONF ]
- then
- echo "** ERROR: Cannot read configuration '$A' specified in the command line."
- exit 1
- fi
- CONFIGS="$CONFIGS $CONF"
- done
-fi
-
-
##################################################
# Try to find this script's configuration file,
# but only if no configurations were given on the
@@ -286,170 +263,89 @@ if [ -z "$JETTY_CONF" ]
then
if [ -f /etc/jetty.conf ]
then
- JETTY_CONF=/etc/jetty.conf
- elif [ -f "${JETTY_HOME}/etc/jetty.conf" ]
+ JETTY_CONF=/etc/jetty.conf
+ elif [ -f "$JETTY_HOME/etc/jetty.conf" ]
then
- JETTY_CONF="${JETTY_HOME}/etc/jetty.conf"
+ JETTY_CONF=$JETTY_HOME/etc/jetty.conf
fi
fi
##################################################
-# Read the configuration file if one exists
-##################################################
-CONFIG_LINES=
-if [ -z "$CONFIGS" ] && [ -f "$JETTY_CONF" ] && [ -r "$JETTY_CONF" ]
-then
- CONFIG_LINES=`cat $JETTY_CONF | grep -v "^[:space:]*#" | tr "\n" " "`
-fi
-
-##################################################
# Get the list of config.xml files from jetty.conf
##################################################
-if [ ! -z "${CONFIG_LINES}" ]
+if [ -z "$CONFIGS" ] && [ -f "$JETTY_CONF" ] && [ -r "$JETTY_CONF" ]
then
- for CONF in ${CONFIG_LINES}
+ while read -r CONF
do
- if [ ! -r "$CONF" ]
- then
- echo "** WARNING: Cannot read '$CONF' specified in '$JETTY_CONF'"
- elif [ -f "$CONF" ]
- then
- # assume it's a configure.xml file
- CONFIGS="$CONFIGS $CONF"
- elif [ -d "$CONF" ]
+ if expr "$CONF" : '#' >/dev/null ; then
+ continue
+ fi
+
+ if [ -d "$CONF" ]
then
# assume it's a directory with configure.xml files
# for example: /etc/jetty.d/
# sort the files before adding them to the list of CONFIGS
- XML_FILES=`ls ${CONF}/*.xml | sort | tr "\n" " "`
- for FILE in ${XML_FILES}
+ for file in "$CONF/"*.xml
do
- if [ -r "$FILE" ] && [ -f "$FILE" ]
- then
- CONFIGS="$CONFIGS $FILE"
- else
- echo "** WARNING: Cannot read '$FILE' specified in '$JETTY_CONF'"
- fi
+ if [ -r "$FILE" ] && [ -f "$FILE" ]
+ then
+ CONFIGS+=("$FILE")
+ else
+ echo "** WARNING: Cannot read '$FILE' specified in '$JETTY_CONF'"
+ fi
done
else
- echo "** WARNING: Don''t know what to do with '$CONF' specified in '$JETTY_CONF'"
+ # assume it's a command line parameter (let start.jar deal with its validity)
+ CONFIGS+=("$CONF")
fi
- done
+ done < "$JETTY_CONF"
fi
#####################################################
-# Run the standard server if there's nothing else to run
-#####################################################
-if [ -z "$CONFIGS" ]
-then
- CONFIGS="${JETTY_HOME}/etc/jetty-logging.xml ${JETTY_HOME}/etc/jetty.xml"
-fi
-
-
-#####################################################
# Find a location for the pid file
#####################################################
-if [ -z "$JETTY_RUN" ]
+if [ -z "$JETTY_RUN" ]
then
- JETTY_RUN=`findDirectory -w /var/run /usr/var/run /tmp`
+ JETTY_RUN=$(findDirectory -w /var/run /usr/var/run /tmp)
fi
#####################################################
# Find a PID for the pid file
#####################################################
-if [ -z "$JETTY_PID" ]
+if [ -z "$JETTY_PID" ]
then
JETTY_PID="$JETTY_RUN/jetty.pid"
fi
-
-##################################################
-# Check for JAVA_HOME
-##################################################
-if [ -z "$JAVA_HOME" ]
-then
- # If a java runtime is not defined, search the following
- # directories for a JVM and sort by version. Use the highest
- # version number.
-
- # Java search path
- JAVA_LOCATIONS="\
- /usr/java \
- /usr/bin \
- /usr/local/bin \
- /usr/local/java \
- /usr/local/jdk \
- /usr/local/jre \
- /usr/lib/jvm \
- /opt/java \
- /opt/jdk \
- /opt/jre \
- "
- JAVA_NAMES="java jdk jre"
- for N in $JAVA_NAMES ; do
- for L in $JAVA_LOCATIONS ; do
- [ -d $L ] || continue
- find $L -name "$N" ! -type d | grep -v threads | while read J ; do
- [ -x $J ] || continue
- VERSION=`eval $J -version 2>&1`
- [ $? = 0 ] || continue
- VERSION=`expr "$VERSION" : '.*"\(1.[0-9\.]*\)["_]'`
- [ "$VERSION" = "" ] && continue
- expr $VERSION \< 1.2 >/dev/null && continue
- echo $VERSION:$J
- done
- done
- done | sort | tail -1 > $TMPJ
- JAVA=`cat $TMPJ | cut -d: -f2`
- JVERSION=`cat $TMPJ | cut -d: -f1`
-
- JAVA_HOME=`dirname $JAVA`
- while [ ! -z "$JAVA_HOME" -a "$JAVA_HOME" != "/" -a ! -f "$JAVA_HOME/lib/tools.jar" ] ; do
- JAVA_HOME=`dirname $JAVA_HOME`
- done
- [ "$JAVA_HOME" = "" ] && JAVA_HOME=
-
- echo "Found JAVA=$JAVA in JAVA_HOME=$JAVA_HOME"
-fi
-
-
##################################################
-# Determine which JVM of version >1.2
-# Try to use JAVA_HOME
+# Setup JAVA if unset
##################################################
-if [ "$JAVA" = "" -a "$JAVA_HOME" != "" ]
+if [ -z "$JAVA" ]
then
- if [ ! -z "$JAVACMD" ]
- then
- JAVA="$JAVACMD"
- else
- [ -x $JAVA_HOME/bin/jre -a ! -d $JAVA_HOME/bin/jre ] && JAVA=$JAVA_HOME/bin/jre
- [ -x $JAVA_HOME/bin/java -a ! -d $JAVA_HOME/bin/java ] && JAVA=$JAVA_HOME/bin/java
- fi
+ JAVA=$(which java)
fi
-if [ "$JAVA" = "" ]
+if [ -z "$JAVA" ]
then
- echo "Cannot find a JRE or JDK. Please set JAVA_HOME to a >=1.2 JRE" 2>&2
- exit 1
+ echo "Cannot find a Java JDK. Please set either set JAVA or put java (>=1.5) in your PATH." 2>&2
+ exit 1
fi
-JAVA_VERSION=`expr "$($JAVA -version 2>&1 | head -1)" : '.*1\.\([0-9]\)'`
-
#####################################################
# See if JETTY_PORT is defined
#####################################################
-if [ "$JETTY_PORT" != "" ]
+if [ "$JETTY_PORT" ]
then
- JAVA_OPTIONS="$JAVA_OPTIONS -Djetty.port=$JETTY_PORT"
+ JAVA_OPTIONS+=("-Djetty.port=$JETTY_PORT")
fi
#####################################################
# See if JETTY_LOGS is defined
#####################################################
-if [ "$JETTY_LOGS" != "" ]
+if [ "$JETTY_LOGS" ]
then
- JAVA_OPTIONS="$JAVA_OPTIONS -Djetty.logs=$JETTY_LOGS"
+ JAVA_OPTIONS+=("-Djetty.logs=$JETTY_LOGS")
fi
#####################################################
@@ -464,203 +360,211 @@ esac
#####################################################
# Add jetty properties to Java VM options.
#####################################################
-JAVA_OPTIONS="$JAVA_OPTIONS -Djetty.home=$JETTY_HOME -Djava.io.tmpdir=$TMP"
+JAVA_OPTIONS+=("-Djetty.home=$JETTY_HOME" "-Djava.io.tmpdir=$TMPDIR")
-[ -f $JETTY_HOME/etc/start.config ] && JAVA_OPTIONS="-DSTART=$JETTY_HOME/etc/start.config $JAVA_OPTIONS"
+[ -f "$JETTY_HOME/etc/start.config" ] && JAVA_OPTIONS=("-DSTART=$JETTY_HOME/etc/start.config" "${JAVA_OPTIONS[@]}")
#####################################################
# This is how the Jetty server will be started
#####################################################
JETTY_START=$JETTY_HOME/start.jar
-[ ! -f $JETTY_START ] && JETTY_START=$JETTY_HOME/lib/start.jar
+[ ! -f "$JETTY_START" ] && JETTY_START=$JETTY_HOME/lib/start.jar
+
+START_INI=$(dirname $JETTY_START)/start.ini
+[ -r "$START_INI" ] || START_INI=""
-RUN_ARGS="$JAVA_OPTIONS -jar $JETTY_START $JETTY_ARGS $CONFIGS"
-RUN_CMD="$JAVA $RUN_ARGS"
+RUN_ARGS=(${JAVA_OPTIONS[@]} -jar "$JETTY_START" $JETTY_ARGS "${CONFIGS[@]}")
+RUN_CMD=("$JAVA" ${RUN_ARGS[@]})
#####################################################
# Comment these out after you're happy with what
# the script is doing.
#####################################################
-#echo "JETTY_HOME = $JETTY_HOME"
-#echo "JETTY_CONF = $JETTY_CONF"
-#echo "JETTY_RUN = $JETTY_RUN"
-#echo "JETTY_PID = $JETTY_PID"
-#echo "JETTY_ARGS = $JETTY_ARGS"
-#echo "CONFIGS = $CONFIGS"
-#echo "JAVA_OPTIONS = $JAVA_OPTIONS"
-#echo "JAVA = $JAVA"
-
+if (( DEBUG ))
+then
+ echo "JETTY_HOME = $JETTY_HOME"
+ echo "JETTY_CONF = $JETTY_CONF"
+ echo "JETTY_RUN = $JETTY_RUN"
+ echo "JETTY_PID = $JETTY_PID"
+ echo "JETTY_ARGS = $JETTY_ARGS"
+ echo "CONFIGS = ${CONFIGS[*]}"
+ echo "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
+ echo "JAVA = $JAVA"
+ echo "RUN_CMD = ${RUN_CMD}"
+fi
##################################################
# Do the action
##################################################
case "$ACTION" in
start)
- echo -n "Starting Jetty: "
-
- if [ "$NO_START" = "1" ]; then
- echo "Not starting jetty - NO_START=1 in /etc/default/jetty7";
- exit 0;
- fi
-
-
- if [ "$START_STOP_DAEMON" = "1" ] && type start-stop-daemon > /dev/null 2>&1
- then
- [ x$JETTY_USER = x ] && JETTY_USER=$(whoami)
- [ $UID = 0 ] && CH_USER="-c $JETTY_USER"
- if start-stop-daemon -S -p$JETTY_PID $CH_USER -d $JETTY_HOME -b -m -a $JAVA -- $RUN_ARGS
- then
- sleep 1
- if running $JETTY_PID
- then
- echo OK
- else
- echo FAILED
- fi
- fi
-
- else
-
- if [ -f $JETTY_PID ]
- then
- if running $JETTY_PID
- then
- echo "Already Running!!"
- exit 1
- else
- # dead pid file - remove
- rm -f $JETTY_PID
- fi
- fi
-
- if [ x$JETTY_USER != x ]
- then
- touch $JETTY_PID
- chown $JETTY_USER $JETTY_PID
- su - $JETTY_USER -c "
- $RUN_CMD &
- PID=\$!
- disown \$PID
- echo \$PID > $JETTY_PID"
- else
- $RUN_CMD &
- PID=$!
- disown $PID
- echo $PID > $JETTY_PID
- fi
-
- echo "STARTED Jetty `date`"
+ echo -n "Starting Jetty: "
+
+ if (( NO_START )); then
+ echo "Not starting jetty - NO_START=1";
+ exit
+ fi
+
+ if type start-stop-daemon > /dev/null 2>&1
+ then
+ unset CH_USER
+ if [ -n "$JETTY_USER" ]
+ then
+ CH_USER="-c$JETTY_USER"
+ fi
+ if start-stop-daemon -S -p"$JETTY_PID" $CH_USER -d"$JETTY_HOME" -b -m -a "$JAVA" -- "${RUN_ARGS[@]}" --daemon
+ then
+ sleep 1
+ if running "$JETTY_PID"
+ then
+ echo "OK"
+ else
+ echo "FAILED"
+ fi
+ fi
+
+ else
+
+ if [ -f "$JETTY_PID" ]
+ then
+ if running $JETTY_PID
+ then
+ echo "Already Running!"
+ exit 1
+ else
+ # dead pid file - remove
+ rm -f "$JETTY_PID"
fi
+ fi
+
+ if [ "$JETTY_USER" ]
+ then
+ touch "$JETTY_PID"
+ chown "$JETTY_USER" "$JETTY_PID"
+ # FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc.
+ su - "$JETTY_USER" -c "
+ ${RUN_CMD[*]} --daemon &
+ disown \$!
+ echo \$! > '$JETTY_PID'"
+ else
+ "${RUN_CMD[@]}" &
+ disown $!
+ echo $! > "$JETTY_PID"
+ fi
+
+ echo "STARTED Jetty `date`"
+ fi
- ;;
+ ;;
stop)
- echo -n "Stopping Jetty: "
- if [ "$START_STOP_DAEMON" = "1" ] && type start-stop-daemon > /dev/null 2>&1; then
- start-stop-daemon -K -p $JETTY_PID -d $JETTY_HOME -a $JAVA -s HUP
- sleep 1
- if running $JETTY_PID
- then
- sleep 3
- if running $JETTY_PID
- then
- sleep 30
- if running $JETTY_PID
- then
- start-stop-daemon -K -p $JETTY_PID -d $JETTY_HOME -a $JAVA -s KILL
- fi
- fi
- fi
-
- rm -f $JETTY_PID
- echo OK
- else
- PID=`cat $JETTY_PID 2>/dev/null`
- TIMEOUT=30
- while running $JETTY_PID && [ $TIMEOUT -gt 0 ]
- do
- kill $PID 2>/dev/null
- sleep 1
- let TIMEOUT=$TIMEOUT-1
- done
-
- [ $TIMEOUT -gt 0 ] || kill -9 $PID 2>/dev/null
-
- rm -f $JETTY_PID
- echo OK
- fi
- ;;
+ echo -n "Stopping Jetty: "
+ if type start-stop-daemon > /dev/null 2>&1; then
+ start-stop-daemon -K -p"$JETTY_PID" -d"$JETTY_HOME" -a "$JAVA" -s HUP
+
+ TIMEOUT=30
+ while running "$JETTY_PID"; do
+ if (( TIMEOUT-- == 0 )); then
+ start-stop-daemon -K -p"$JETTY_PID" -d"$JETTY_HOME" -a "$JAVA" -s KILL
+ fi
- restart)
- JETTY_SH=$0
- if [ ! -f $JETTY_SH ]; then
- if [ ! -f $JETTY_HOME/bin/jetty.sh ]; then
- echo "$JETTY_HOME/bin/jetty.sh does not exist."
- exit 1
- fi
- JETTY_SH=$JETTY_HOME/bin/jetty.sh
+ sleep 1
+ done
+
+ rm -f "$JETTY_PID"
+ echo OK
+ else
+ PID=$(cat "$JETTY_PID" 2>/dev/null)
+ kill "$PID" 2>/dev/null
+
+ TIMEOUT=30
+ while running $JETTY_PID; do
+ if (( TIMEOUT-- == 0 )); then
+ kill -KILL "$PID" 2>/dev/null
fi
- $JETTY_SH stop $*
- sleep 5
- $JETTY_SH start $*
- ;;
+
+ sleep 1
+ done
+
+ rm -f "$JETTY_PID"
+ echo OK
+ fi
+
+ ;;
+
+ restart)
+ JETTY_SH=$0
+ if [ ! -f $JETTY_SH ]; then
+ if [ ! -f $JETTY_HOME/bin/jetty.sh ]; then
+ echo "$JETTY_HOME/bin/jetty.sh does not exist."
+ exit 1
+ fi
+ JETTY_SH=$JETTY_HOME/bin/jetty.sh
+ fi
+
+ "$JETTY_SH" stop "$@"
+ "$JETTY_SH" start "$@"
+
+ ;;
supervise)
- #
- # Under control of daemontools supervise monitor which
- # handles restarts and shutdowns via the svc program.
- #
- exec $RUN_CMD
- ;;
+ #
+ # Under control of daemontools supervise monitor which
+ # handles restarts and shutdowns via the svc program.
+ #
+ exec "${RUN_CMD[@]}"
+
+ ;;
run|demo)
- echo "Running Jetty: "
+ echo "Running Jetty: "
- if [ -f $JETTY_PID ]
- then
- if running $JETTY_PID
- then
- echo "Already Running!!"
- exit 1
- else
- # dead pid file - remove
- rm -f $JETTY_PID
- fi
- fi
+ if [ -f "$JETTY_PID" ]
+ then
+ if running "$JETTY_PID"
+ then
+ echo "Already Running!"
+ exit 1
+ else
+ # dead pid file - remove
+ rm -f "$JETTY_PID"
+ fi
+ fi
- exec $RUN_CMD
- ;;
+ exec "${RUN_CMD[@]}"
- check)
- echo "Checking arguments to Jetty: "
- echo "JETTY_HOME = $JETTY_HOME"
- echo "JETTY_CONF = $JETTY_CONF"
- echo "JETTY_RUN = $JETTY_RUN"
- echo "JETTY_PID = $JETTY_PID"
- echo "JETTY_PORT = $JETTY_PORT"
- echo "JETTY_LOGS = $JETTY_LOGS"
- echo "CONFIGS = $CONFIGS"
- echo "JAVA_OPTIONS = $JAVA_OPTIONS"
- echo "JAVA = $JAVA"
- echo "CLASSPATH = $CLASSPATH"
- echo "RUN_CMD = $RUN_CMD"
- echo
-
- if [ -f $JETTY_RUN/jetty.pid ]
- then
- echo "Jetty running pid="`cat $JETTY_RUN/jetty.pid`
- exit 0
- fi
- exit 1
- ;;
+ ;;
-*)
- usage
- ;;
-esac
+ check)
+ echo "Checking arguments to Jetty: "
+ echo "JETTY_HOME = $JETTY_HOME"
+ echo "JETTY_CONF = $JETTY_CONF"
+ echo "JETTY_RUN = $JETTY_RUN"
+ echo "JETTY_PID = $JETTY_PID"
+ echo "JETTY_PORT = $JETTY_PORT"
+ echo "JETTY_LOGS = $JETTY_LOGS"
+ echo "START_INI = $START_INI"
+ echo "CONFIGS = ${CONFIGS[*]}"
+ echo "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
+ echo "JAVA = $JAVA"
+ echo "CLASSPATH = $CLASSPATH"
+ echo "RUN_CMD = ${RUN_CMD[*]}"
+ echo
+
+ if [ -f "$JETTY_RUN/jetty.pid" ]
+ then
+ echo "Jetty running pid=$(< "$JETTY_RUN/jetty.pid")"
+ exit 0
+ fi
+ exit 1
-exit 0
+ ;;
+ *)
+ usage
+ ;;
+esac
+exit 0
diff --git a/jetty-distribution/src/main/resources/contexts/javadoc.xml b/jetty-distribution/src/main/resources/contexts-available/resources.xml
index 342e6b9957..87a8d32770 100644
--- a/jetty-distribution/src/main/resources/contexts/javadoc.xml
+++ b/jetty-distribution/src/main/resources/contexts-available/resources.xml
@@ -2,22 +2,21 @@
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.eclipse.org/configure.dtd">
<!--
-Configure a custom context for the javadoc.
+Configure a custom context for serving static resources
-This context contains only a ServletHandler with a default servlet
+This context contains only a ResourceHandler
to serve static html files and images.
-->
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Call class="org.eclipse.jetty.util.log.Log" name="debug"><Arg>Configure javadoc.xml</Arg></Call>
- <Set name="contextPath">/javadoc</Set>
- <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/javadoc/</Set>
+ <Set name="contextPath">/resources</Set>
+ <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/resources/</Set>
<Set name="handler">
<New class="org.eclipse.jetty.server.handler.ResourceHandler">
<Set name="welcomeFiles">
<Array type="String">
<Item>index.html</Item>
- <Item>contents.html</Item> <!-- the index if javadoc not generated -->
</Array>
</Set>
<Set name="cacheControl">max-age=3600,public</Set>
diff --git a/jetty-distribution/src/main/resources/etc/jetty.conf b/jetty-distribution/src/main/resources/etc/jetty.conf
new file mode 100644
index 0000000000..b79f3169fb
--- /dev/null
+++ b/jetty-distribution/src/main/resources/etc/jetty.conf
@@ -0,0 +1,13 @@
+# ========================================================
+# jetty.conf Configuration for jetty.sh script
+# --------------------------------------------------------
+# This file is used by the jetty.sh script to provide
+# extra configuration arguments for the start.jar command
+# created by that script.
+#
+# Each line in this file becomes an arguement to start.jar
+# unless this file contains an --ini option, then these
+# arguments will be in addition to those found in the
+# start.ini file
+# =======================================================
+--pre=etc/jetty-logging.xml
diff --git a/jetty-distribution/src/main/resources/javadoc/README.txt b/jetty-distribution/src/main/resources/javadoc/README.txt
deleted file mode 100644
index f6b026ed8a..0000000000
--- a/jetty-distribution/src/main/resources/javadoc/README.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-Javadocs are available at:
-
-http://download.eclipse.org/jetty/stable-7/apidocs/
-
-
-Jxr is available at:
-
-http://download.eclipse.org/jetty/stable-7/xref/
-
-
-For specific versions replace 'stable-7' with the version, for example the javadocs for jetty-7.0.0.RC5 would be at
-
-http://download.eclipse.org/jetty/7.0.0.RC5/apidocs/
-
diff --git a/jetty-distribution/src/main/resources/javadoc/contents.html b/jetty-distribution/src/main/resources/javadoc/contents.html
deleted file mode 100644
index 7cca04ae17..0000000000
--- a/jetty-distribution/src/main/resources/javadoc/contents.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<h1>Javadoc not generated</h1>
-See the online version at <a
-href="http://download.eclipse.org/jetty/">http://download.eclipse.org/jetty/</a>.
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/RunningStatsTest.java b/jetty-distribution/src/main/resources/lib/ext/.donotdelete
index e69de29bb2..e69de29bb2 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/RunningStatsTest.java
+++ b/jetty-distribution/src/main/resources/lib/ext/.donotdelete
diff --git a/jetty-distribution/src/main/resources/logs/.donotdelete b/jetty-distribution/src/main/resources/logs/.donotdelete
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/jetty-distribution/src/main/resources/logs/.donotdelete
diff --git a/jetty-distribution/src/main/resources/start.ini b/jetty-distribution/src/main/resources/start.ini
index 5ae24f5d0b..a20537b258 100644
--- a/jetty-distribution/src/main/resources/start.ini
+++ b/jetty-distribution/src/main/resources/start.ini
@@ -1,10 +1,13 @@
#===========================================================
# Jetty start.jar arguments
-#-----------------------------------------------------------
# Each line of this file is prepended to the command line
# arguments # of a call to:
# java -jar start.jar [arg...]
-#
+#===========================================================
+
+
+
+#===========================================================
# If the arguements in this file include JVM arguments
# (eg -Xmx512m) or JVM System properties (eg com.sun.???),
# then these will not take affect unless the --exec
@@ -12,20 +15,46 @@
# is executed like:
# eval $(java -jar start.jar --dry-run)
#
-#===========================================================
+# Below are some recommended options for Sun's JRE
+#-----------------------------------------------------------
+# --exec
+# -Dcom.sun.management.jmxremote
+# -Xmx2000m
+# -Xmn512m
+# -verbose:gc
+# -XX:+PrintGCDateStamps
+# -XX:+PrintGCTimeStamps
+# -XX:+PrintGCDetails
+# -XX:+PrintTenuringDistribution
+# -XX:+PrintCommandLineFlags
+# -XX:+DisableExplicitGC
+# -XX:+UseConcMarkSweepGC
+# -XX:ParallelCMSThreads=2
+# -XX:+CMSClassUnloadingEnabled
+# -XX:+UseCMSCompactAtFullCollection
+# -XX:CMSInitiatingOccupancyFraction=80
+#-----------------------------------------------------------
+
+#===========================================================
+# Start classpath OPTIONS.
+# These control what classes are on the classpath
+# for a full listing do
+# java -jar start.jar --list-options
+#-----------------------------------------------------------
OPTIONS=Server,jmx,resources,websocket,ext
+#-----------------------------------------------------------
+
#===========================================================
-# The following is an example of the ini args to run the
-# server with a heap size, JMX remote enabled, JMX mbeans
-# and ssl
+# Configuration files.
+# For a full list of available configuration files do
+# java -jar start.jar --help
#-----------------------------------------------------------
-# --exec
-# -Xmx512m
-# -Dcom.sun.management.jmxremote
-# OPTIONS=Server,jmx,resources
-# etc/jetty-jmx.xml
-# etc/jetty.xml
+#etc/jetty-jmx.xml
+etc/jetty.xml
# etc/jetty-ssl.xml
+# etc/jetty-requestlog.xml
+etc/jetty-deploy.xml
+etc/jetty-testrealm.xml
#===========================================================
diff --git a/jetty-distribution/src/main/resources/webapps/.donotdelete b/jetty-distribution/src/main/resources/webapps/.donotdelete
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/jetty-distribution/src/main/resources/webapps/.donotdelete
diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml
index b3cf361820..a40111ad68 100644
--- a/jetty-http/pom.xml
+++ b/jetty-http/pom.xml
@@ -20,6 +20,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -35,6 +36,11 @@
<goals>
<goal>manifest</goal>
</goals>
+ <configuration>
+ <instructions>
+ <Import-Package>javax.net.*,*</Import-Package>
+ </instructions>
+ </configuration>
</execution>
</executions>
</plugin>
@@ -56,16 +62,17 @@
</execution>
</executions>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.http.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/AbstractGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/AbstractGenerator.java
index 560543218d..db0db7902f 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/AbstractGenerator.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/AbstractGenerator.java
@@ -62,8 +62,7 @@ public abstract class AbstractGenerator implements Generator
protected boolean _last = false;
protected boolean _head = false;
protected boolean _noContent = false;
- protected boolean _close = false;
-
+ protected Boolean _persistent = null;
protected Buffer _header; // Buffer for HTTP header (and maybe small _content)
protected Buffer _buffer; // Buffer for copy of passed _content
@@ -79,8 +78,7 @@ public abstract class AbstractGenerator implements Generator
* Constructor.
*
* @param buffers buffer pool
- * @param headerBufferSize Size of the buffer to allocate for HTTP header
- * @param contentBufferSize Size of the buffer to allocate for HTTP content
+ * @param io the end point
*/
public AbstractGenerator(Buffers buffers, EndPoint io)
{
@@ -89,6 +87,12 @@ public abstract class AbstractGenerator implements Generator
}
/* ------------------------------------------------------------------------------- */
+ public abstract boolean isRequest();
+
+ /* ------------------------------------------------------------------------------- */
+ public abstract boolean isResponse();
+
+ /* ------------------------------------------------------------------------------- */
public boolean isOpen()
{
return _endp.isOpen();
@@ -104,7 +108,7 @@ public abstract class AbstractGenerator implements Generator
_last = false;
_head = false;
_noContent=false;
- _close = false;
+ _persistent = null;
_contentWritten = 0;
_contentLength = HttpTokens.UNKNOWN_CONTENT;
_date = null;
@@ -134,7 +138,7 @@ public abstract class AbstractGenerator implements Generator
throw new IllegalStateException("Flushed");
_last = false;
- _close = false;
+ _persistent=null;
_contentWritten = 0;
_contentLength = HttpTokens.UNKNOWN_CONTENT;
_content=null;
@@ -252,13 +256,15 @@ public abstract class AbstractGenerator implements Generator
*/
public boolean isPersistent()
{
- return !_close;
+ return _persistent!=null
+ ?_persistent.booleanValue()
+ :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL);
}
/* ------------------------------------------------------------ */
public void setPersistent(boolean persistent)
{
- _close=!persistent;
+ _persistent=persistent;
}
/* ------------------------------------------------------------ */
@@ -402,7 +408,7 @@ public abstract class AbstractGenerator implements Generator
{
if (Log.isDebugEnabled())
Log.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength);
- _close = true;
+ _persistent = false;
}
}
@@ -428,23 +434,30 @@ public abstract class AbstractGenerator implements Generator
/* ------------------------------------------------------------ */
/**
* Utility method to send an error response. If the builder is not committed, this call is
- * equivalent to a setResponse, addcontent and complete call.
+ * equivalent to a setResponse, addContent and complete call.
*
- * @param code
- * @param reason
- * @param content
- * @param close
- * @throws IOException
+ * @param code The error code
+ * @param reason The error reason
+ * @param content Contents of the error page
+ * @param close True if the connection should be closed
+ * @throws IOException if there is a problem flushing the response
*/
public void sendError(int code, String reason, String content, boolean close) throws IOException
{
+ if (close)
+ _persistent=false;
if (!isCommitted())
{
setResponse(code, reason);
- _close = close;
- completeHeader(null, false);
if (content != null)
+ {
+ completeHeader(null, false);
addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
+ }
+ else
+ {
+ completeHeader(null, true);
+ }
complete();
}
}
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
index 95bcdf84ab..351ef15938 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
@@ -115,7 +115,7 @@ public abstract class HttpBuffers extends AbstractLifeCycle
public Buffers getResponseBuffers()
{
- return _requestBuffers;
+ return _responseBuffers;
}
/**
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
index e6813d6f5a..e98db730ac 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
@@ -285,17 +285,15 @@ public class HttpFields
};
-
-
-
-
public final static String __01Jan1970=formatCookieDate(0);
public final static Buffer __01Jan1970_BUFFER=new ByteArrayBuffer(__01Jan1970);
/* -------------------------------------------------------------- */
- protected final ArrayList<Field> _fields = new ArrayList<Field>(20);
- protected final HashMap<Buffer,Field> _bufferMap = new HashMap<Buffer,Field>(32);
- protected int _revision;
+ private final ArrayList<Field> _fields = new ArrayList<Field>(20);
+ private final HashMap<Buffer,Field> _bufferMap = new HashMap<Buffer,Field>(32);
+ private final int _maxCookieVersion;
+ private int _revision;
+
@@ -305,8 +303,18 @@ public class HttpFields
*/
public HttpFields()
{
+ _maxCookieVersion=1;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Constructor.
+ */
+ public HttpFields(int maxCookieVersion)
+ {
+ _maxCookieVersion=maxCookieVersion;
+ }
+
/* -------------------------------------------------------------- */
/**
* Get Collection of header names.
@@ -981,7 +989,6 @@ public class HttpFields
* Format a set cookie value
*
* @param cookie The cookie.
- * @param cookie2 If true, use the alternate cookie 2 header
*/
public void addSetCookie(HttpCookie cookie)
{
@@ -996,12 +1003,19 @@ public class HttpFields
cookie.isHttpOnly(),
cookie.getVersion());
}
-
- /* ------------------------------------------------------------ */
+
/**
* Format a set cookie value
- * @param cookie The cookie.
- * @param cookie2 If true, use the alternate cookie 2 header
+ *
+ * @param name the name
+ * @param value the value
+ * @param domain the domain
+ * @param path the path
+ * @param maxAge the maximum age
+ * @param comment the comment (only present on versions > 0)
+ * @param isSecure true if secure cookie
+ * @param isHttpOnly true if for http only
+ * @param version version of cookie logic to use (0 == default behavior)
*/
public void addSetCookie(
final String name,
@@ -1012,19 +1026,29 @@ public class HttpFields
final String comment,
final boolean isSecure,
final boolean isHttpOnly,
- final int version)
+ int version)
{
+ String delim=_maxCookieVersion==0?"":"\"\\\n\r\t\f\b%+ ;=";
+
// Check arguments
if (name == null || name.length() == 0) throw new IllegalArgumentException("Bad cookie name");
// Format value and params
StringBuilder buf = new StringBuilder(128);
String name_value_params;
- QuotedStringTokenizer.quoteIfNeeded(buf, name);
+ boolean quoted = QuotedStringTokenizer.quoteIfNeeded(buf, name, delim);
buf.append('=');
+ String start=buf.toString();
if (value != null && value.length() > 0)
- QuotedStringTokenizer.quoteIfNeeded(buf, value);
+ quoted|=QuotedStringTokenizer.quoteIfNeeded(buf, value, delim);
+
+ // upgrade to version 1 cookies if quoted.
+ if (quoted&&version==0 && _maxCookieVersion>=1)
+ version=1;
+ if (version>_maxCookieVersion)
+ version=_maxCookieVersion;
+
if (version > 0)
{
buf.append(";Version=");
@@ -1032,7 +1056,7 @@ public class HttpFields
if (comment != null && comment.length() > 0)
{
buf.append(";Comment=");
- QuotedStringTokenizer.quoteIfNeeded(buf, comment);
+ QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim);
}
}
if (path != null && path.length() > 0)
@@ -1041,25 +1065,24 @@ public class HttpFields
if (path.trim().startsWith("\""))
buf.append(path);
else
- QuotedStringTokenizer.quoteIfNeeded(buf,path);
+ QuotedStringTokenizer.quoteIfNeeded(buf,path,delim);
}
if (domain != null && domain.length() > 0)
{
buf.append(";Domain=");
- QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase());
+ QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(),delim);
}
if (maxAge >= 0)
{
- if (version == 0)
- {
- buf.append(";Expires=");
- if (maxAge == 0)
- buf.append(__01Jan1970);
- else
- formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge);
- }
- else
+ // Always add the expires param as some browsers still don't handle max-age
+ buf.append(";Expires=");
+ if (maxAge == 0)
+ buf.append(__01Jan1970);
+ else
+ formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge);
+
+ if (version >0)
{
buf.append(";Max-Age=");
buf.append(maxAge);
@@ -1077,8 +1100,28 @@ public class HttpFields
// TODO - straight to Buffer?
name_value_params = buf.toString();
- put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER);
+
+ // look for existing cookie
+ Field field = getField(HttpHeaders.SET_COOKIE_BUFFER);
+ if (field != null)
+ {
+ final int revision=_revision;
+
+ while (field!=null)
+ {
+ if (field._revision!=revision || field._value!=null && field._value.toString().startsWith(start))
+ {
+ field.reset(new ByteArrayBuffer(name_value_params),-1,revision);
+ return;
+ }
+ field=field._next;
+ }
+ }
+
add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params));
+
+ // Expire responses with set-cookie headers so they do not get cached.
+ put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER);
}
/* -------------------------------------------------------------- */
@@ -1281,7 +1324,7 @@ public class HttpFields
/**
* List values in quality order.
*
- * @param enum Enumeration of values with quality parameters
+ * @param e Enumeration of values with quality parameters
* @return values in quality order.
*/
public static List qualityList(Enumeration e)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
index d70e689687..6e6149d7b8 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
@@ -17,21 +17,21 @@ import java.io.IOException;
import java.io.InterruptedIOException;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
-import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
/**
* HttpGenerator. Builds HTTP Messages.
- *
- *
- *
+ *
+ *
+ *
*/
public class HttpGenerator extends AbstractGenerator
{
@@ -46,7 +46,7 @@ public class HttpGenerator extends AbstractGenerator
static
{
int versionLength=HttpVersions.HTTP_1_1_BUFFER.length();
-
+
for (int i=0;i<__status.length;i++)
{
HttpStatus.Code code = HttpStatus.getCode(i);
@@ -64,7 +64,7 @@ public class HttpGenerator extends AbstractGenerator
bytes[versionLength+5+j]=(byte)reason.charAt(j);
bytes[versionLength+5+reason.length()]=HttpTokens.CARRIAGE_RETURN;
bytes[versionLength+6+reason.length()]=HttpTokens.LINE_FEED;
-
+
__status[i] = new Status();
__status[i]._reason=new ByteArrayBuffer(bytes,versionLength+5,bytes.length-versionLength-7,Buffer.IMMUTABLE);
__status[i]._schemeCode=new ByteArrayBuffer(bytes,0,versionLength+5,Buffer.IMMUTABLE);
@@ -80,8 +80,8 @@ public class HttpGenerator extends AbstractGenerator
return status._reason;
return null;
}
-
-
+
+
// common _content
private static final byte[] LAST_CHUNK =
{ (byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'};
@@ -95,7 +95,7 @@ public class HttpGenerator extends AbstractGenerator
// other statics
private static final int CHUNK_SPACE = 12;
-
+
public static void setServerVersion(String version)
{
SERVER=StringUtil.getBytes("Server: Jetty("+version+")\015\012");
@@ -107,14 +107,13 @@ public class HttpGenerator extends AbstractGenerator
private boolean _needEOC = false;
private boolean _bufferChunked = false;
-
+
/* ------------------------------------------------------------------------------- */
/**
* Constructor.
- *
+ *
* @param buffers buffer pool
- * @param headerBufferSize Size of the buffer to allocate for HTTP header
- * @param contentBufferSize Size of the buffer to allocate for HTTP content
+ * @param io the end point to use
*/
public HttpGenerator(Buffers buffers, EndPoint io)
{
@@ -140,7 +139,7 @@ public class HttpGenerator extends AbstractGenerator
/* ------------------------------------------------------------ */
/**
* Add content.
- *
+ *
* @param content
* @param last
* @throws IllegalArgumentException if <code>content</code> is {@link Buffer#isImmutable immutable}.
@@ -153,7 +152,7 @@ public class HttpGenerator extends AbstractGenerator
if (_noContent)
throw new IllegalStateException("NO CONTENT");
- if (_last || _state==STATE_END)
+ if (_last || _state==STATE_END)
{
Log.debug("Ignoring extra content {}",content);
content.clear();
@@ -167,7 +166,7 @@ public class HttpGenerator extends AbstractGenerator
if (!_endp.isOpen())
throw new EofException();
flushBuffer();
- if (_content != null && _content.length()>0)
+ if (_content != null && _content.length()>0)
{
Buffer nc=_buffers.getBuffer(_content.length()+content.length());
nc.put(_content);
@@ -194,13 +193,13 @@ public class HttpGenerator extends AbstractGenerator
else if (!_bufferChunked)
{
// Yes - so we better check we have a buffer
- if (_buffer == null)
+ if (_buffer == null)
_buffer = _buffers.getBuffer();
// Copy _content to buffer;
int len=_buffer.put(_content);
_content.skip(len);
- if (_content.length() == 0)
+ if (_content.length() == 0)
_content = null;
}
}
@@ -208,7 +207,7 @@ public class HttpGenerator extends AbstractGenerator
/* ------------------------------------------------------------ */
/**
* send complete response.
- *
+ *
* @param response
*/
public void sendResponse(Buffer response) throws IOException
@@ -224,13 +223,13 @@ public class HttpGenerator extends AbstractGenerator
// TODO this is not exactly right, but should do.
_contentLength =_contentWritten = response.length();
-
+
}
-
+
/* ------------------------------------------------------------ */
/**
* Add content.
- *
+ *
* @param b byte
* @return true if the buffers are full
* @throws IOException
@@ -239,8 +238,8 @@ public class HttpGenerator extends AbstractGenerator
{
if (_noContent)
throw new IllegalStateException("NO CONTENT");
-
- if (_last || _state==STATE_END)
+
+ if (_last || _state==STATE_END)
{
Log.debug("Ignoring extra content {}",Byte.valueOf(b));
return false;
@@ -250,23 +249,23 @@ public class HttpGenerator extends AbstractGenerator
if (_content != null && _content.length()>0 || _bufferChunked)
{
flushBuffer();
- if (_content != null && _content.length()>0 || _bufferChunked)
+ if (_content != null && _content.length()>0 || _bufferChunked)
throw new IllegalStateException("FULL");
}
_contentWritten++;
-
+
// Handle the _content
if (_head)
return false;
-
+
// we better check we have a buffer
- if (_buffer == null)
+ if (_buffer == null)
_buffer = _buffers.getBuffer();
-
+
// Copy _content to buffer;
_buffer.put(b);
-
+
return _buffer.space()<=(_contentLength == HttpTokens.CHUNKED_CONTENT?CHUNK_SPACE:0);
}
@@ -281,8 +280,8 @@ public class HttpGenerator extends AbstractGenerator
{
if (_noContent)
return -1;
-
- if (_last || _state==STATE_END)
+
+ if (_last || _state==STATE_END)
return -1;
// Handle any unfinished business?
@@ -290,23 +289,23 @@ public class HttpGenerator extends AbstractGenerator
if (content != null && content.length()>0 || _bufferChunked)
{
flushBuffer();
- if (content != null && content.length()>0 || _bufferChunked)
+ if (content != null && content.length()>0 || _bufferChunked)
throw new IllegalStateException("FULL");
}
// we better check we have a buffer
- if (_buffer == null)
+ if (_buffer == null)
_buffer = _buffers.getBuffer();
_contentWritten-=_buffer.length();
-
+
// Handle the _content
if (_head)
return Integer.MAX_VALUE;
-
+
return _buffer.space()-(_contentLength == HttpTokens.CHUNKED_CONTENT?CHUNK_SPACE:0);
}
-
+
/* ------------------------------------------------------------ */
@Override
public boolean isBufferFull()
@@ -318,22 +317,22 @@ public class HttpGenerator extends AbstractGenerator
/* ------------------------------------------------------------ */
public void send1xx(int code) throws IOException
{
- if (_state != STATE_HEADER)
+ if (_state != STATE_HEADER)
return;
-
+
if (code<100||code>199)
throw new IllegalArgumentException("!1xx");
Status status=__status[code];
if (status==null)
throw new IllegalArgumentException(code+"?");
-
+
// get a header buffer
- if (_header == null)
+ if (_header == null)
_header = _buffers.getHeader();
-
+
_header.put(status._responseLine);
_header.put(HttpTokens.CRLF);
-
+
try
{
// nasty semi busy flush!
@@ -351,34 +350,47 @@ public class HttpGenerator extends AbstractGenerator
Log.debug(e);
throw new InterruptedIOException(e.toString());
}
-
}
-
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public boolean isRequest()
+ {
+ return _method!=null;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public boolean isResponse()
+ {
+ return _method==null;
+ }
+
/* ------------------------------------------------------------ */
@Override
public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
{
- if (_state != STATE_HEADER)
+ if (_state != STATE_HEADER)
return;
-
- // handle a reset
- if (_method==null && _status==0)
+
+ // handle a reset
+ if (isResponse() && _status==0)
throw new EofException();
- if (_last && !allContentAdded)
+ if (_last && !allContentAdded)
throw new IllegalStateException("last?");
_last = _last | allContentAdded;
// get a header buffer
- if (_header == null)
+ if (_header == null)
_header = _buffers.getHeader();
-
+
boolean has_server = false;
-
- if (_method!=null)
+
+ if (isRequest())
{
- _close = false;
- // Request
+ _persistent=true;
+
if (_version == HttpVersions.HTTP_0_9_ORDINAL)
{
_contentLength = HttpTokens.NO_CONTENT;
@@ -402,22 +414,23 @@ public class HttpGenerator extends AbstractGenerator
}
else
{
- // Response
+ // Responses
+
if (_version == HttpVersions.HTTP_0_9_ORDINAL)
{
- _close = true;
+ _persistent = false;
_contentLength = HttpTokens.EOF_CONTENT;
_state = STATE_CONTENT;
return;
}
else
{
- if (_version == HttpVersions.HTTP_1_0_ORDINAL)
- _close = true;
+ if (_persistent==null)
+ _persistent= (_version > HttpVersions.HTTP_1_0_ORDINAL);
// add response line
Status status = _status<__status.length?__status[_status]:null;
-
+
if (status==null)
{
_header.put(HttpVersions.HTTP_1_1_BUFFER);
@@ -472,7 +485,7 @@ public class HttpGenerator extends AbstractGenerator
}
}
}
-
+
// Add headers
if (_status>=200 && _date!=null)
{
@@ -522,20 +535,20 @@ public class HttpGenerator extends AbstractGenerator
break;
case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
- if (_version == HttpVersions.HTTP_1_1_ORDINAL)
+ if (_version == HttpVersions.HTTP_1_1_ORDINAL)
transfer_encoding = field;
// Do NOT add yet!
break;
case HttpHeaders.CONNECTION_ORDINAL:
- if (_method!=null)
+ if (isRequest())
field.put(_header);
-
+
int connection_value = field.getValueOrdinal();
switch (connection_value)
{
case -1:
- {
+ {
String[] values = field.getValue().split(",");
for (int i=0;values!=null && i<values.length;i++)
{
@@ -547,10 +560,10 @@ public class HttpGenerator extends AbstractGenerator
{
case HttpHeaderValues.CLOSE_ORDINAL:
close=true;
- if (_method==null)
- _close=true;
+ if (isResponse())
+ _persistent=false;
keep_alive=false;
- if (_close && _method==null && _contentLength == HttpTokens.UNKNOWN_CONTENT)
+ if (!_persistent && isResponse() && _contentLength == HttpTokens.UNKNOWN_CONTENT)
_contentLength = HttpTokens.EOF_CONTENT;
break;
@@ -558,11 +571,11 @@ public class HttpGenerator extends AbstractGenerator
if (_version == HttpVersions.HTTP_1_0_ORDINAL)
{
keep_alive = true;
- if (_method==null)
- _close = false;
+ if (isResponse())
+ _persistent = true;
}
break;
-
+
default:
if (connection==null)
connection=new StringBuilder();
@@ -580,13 +593,13 @@ public class HttpGenerator extends AbstractGenerator
connection.append(values[i]);
}
}
-
+
break;
}
case HttpHeaderValues.UPGRADE_ORDINAL:
{
// special case for websocket connection ordering
- if (_method==null)
+ if (isResponse())
{
field.put(_header);
continue;
@@ -595,9 +608,9 @@ public class HttpGenerator extends AbstractGenerator
case HttpHeaderValues.CLOSE_ORDINAL:
{
close=true;
- if (_method==null)
- _close=true;
- if (_close && _method==null && _contentLength == HttpTokens.UNKNOWN_CONTENT)
+ if (isResponse())
+ _persistent=false;
+ if (!_persistent && isResponse() && _contentLength == HttpTokens.UNKNOWN_CONTENT)
_contentLength = HttpTokens.EOF_CONTENT;
break;
}
@@ -606,8 +619,8 @@ public class HttpGenerator extends AbstractGenerator
if (_version == HttpVersions.HTTP_1_0_ORDINAL)
{
keep_alive = true;
- if (_method==null)
- _close = false;
+ if (isResponse())
+ _persistent=true;
}
break;
}
@@ -625,7 +638,7 @@ public class HttpGenerator extends AbstractGenerator
break;
case HttpHeaders.SERVER_ORDINAL:
- if (getSendServerVersion())
+ if (getSendServerVersion())
{
has_server=true;
field.put(_header);
@@ -655,13 +668,13 @@ public class HttpGenerator extends AbstractGenerator
// written yet?
// Response known not to have a body
- if (_contentWritten == 0 && _method==null && (_status < 200 || _status == 204 || _status == 304))
+ if (_contentWritten == 0 && isResponse() && (_status < 200 || _status == 204 || _status == 304))
_contentLength = HttpTokens.NO_CONTENT;
else if (_last)
{
// we have seen all the _content there is
_contentLength = _contentWritten;
- if (content_length == null && (_method==null || _contentLength>0 || content_type ))
+ if (content_length == null && (isResponse() || _contentLength>0 || content_type ))
{
// known length but not actually set.
_header.put(HttpHeaders.CONTENT_LENGTH_BUFFER);
@@ -674,8 +687,8 @@ public class HttpGenerator extends AbstractGenerator
else
{
// No idea, so we must assume that a body is coming
- _contentLength = (_close || _version < HttpVersions.HTTP_1_1_ORDINAL ) ? HttpTokens.EOF_CONTENT : HttpTokens.CHUNKED_CONTENT;
- if (_method!=null && _contentLength==HttpTokens.EOF_CONTENT)
+ _contentLength = (!_persistent || _version < HttpVersions.HTTP_1_1_ORDINAL ) ? HttpTokens.EOF_CONTENT : HttpTokens.CHUNKED_CONTENT;
+ if (isRequest() && _contentLength==HttpTokens.EOF_CONTENT)
{
_contentLength=HttpTokens.NO_CONTENT;
_noContent=true;
@@ -684,12 +697,12 @@ public class HttpGenerator extends AbstractGenerator
break;
case HttpTokens.NO_CONTENT:
- if (content_length == null && _method==null && _status >= 200 && _status != 204 && _status != 304)
+ if (content_length == null && isResponse() && _status >= 200 && _status != 204 && _status != 304)
_header.put(CONTENT_LENGTH_0);
break;
case HttpTokens.EOF_CONTENT:
- _close = _method==null;
+ _persistent = isRequest();
break;
case HttpTokens.CHUNKED_CONTENT:
@@ -720,12 +733,12 @@ public class HttpGenerator extends AbstractGenerator
if (_contentLength==HttpTokens.EOF_CONTENT)
{
keep_alive=false;
- _close=true;
+ _persistent=false;
}
-
- if (_method==null)
+
+ if (isResponse())
{
- if (_close && (close || _version > HttpVersions.HTTP_1_0_ORDINAL))
+ if (!_persistent && (close || _version > HttpVersions.HTTP_1_0_ORDINAL))
{
_header.put(CONNECTION_CLOSE);
if (connection!=null)
@@ -754,7 +767,7 @@ public class HttpGenerator extends AbstractGenerator
_header.put(CRLF);
}
}
-
+
if (!has_server && _status>199 && getSendServerVersion())
_header.put(SERVER);
@@ -764,30 +777,30 @@ public class HttpGenerator extends AbstractGenerator
_state = STATE_CONTENT;
}
-
+
/* ------------------------------------------------------------ */
/**
* Complete the message.
- *
+ *
* @throws IOException
*/
@Override
public void complete() throws IOException
{
- if (_state == STATE_END)
+ if (_state == STATE_END)
return;
-
+
super.complete();
-
+
if (_state < STATE_FLUSHING)
{
_state = STATE_FLUSHING;
- if (_contentLength == HttpTokens.CHUNKED_CONTENT)
+ if (_contentLength == HttpTokens.CHUNKED_CONTENT)
_needEOC = true;
}
-
+
flushBuffer();
}
@@ -796,17 +809,17 @@ public class HttpGenerator extends AbstractGenerator
public long flushBuffer() throws IOException
{
try
- {
- if (_state == STATE_HEADER)
+ {
+ if (_state == STATE_HEADER)
throw new IllegalStateException("State==HEADER");
-
+
prepareBuffers();
-
+
if (_endp == null)
{
- if (_needCRLF && _buffer!=null)
+ if (_needCRLF && _buffer!=null)
_buffer.put(HttpTokens.CRLF);
- if (_needEOC && _buffer!=null && !_head)
+ if (_needEOC && _buffer!=null && !_head)
_buffer.put(LAST_CHUNK);
_needCRLF=false;
_needEOC=false;
@@ -841,7 +854,7 @@ public class HttpGenerator extends AbstractGenerator
case 0:
{
// Nothing more we can write now.
- if (_header != null)
+ if (_header != null)
_header.clear();
_bypass = false;
@@ -872,8 +885,8 @@ public class HttpGenerator extends AbstractGenerator
{
if (_state == STATE_FLUSHING)
_state = STATE_END;
- if (_state==STATE_END && _close && _status!=100)
- _endp.close();
+ if (_state==STATE_END && _persistent != null && !_persistent && _status!=100 && _method==null)
+ _endp.shutdownOutput();
}
else
// Try to prepare more to write.
@@ -904,7 +917,7 @@ public class HttpGenerator extends AbstractGenerator
{
int len = _buffer.put(_content);
_content.skip(len);
- if (_content.length() == 0)
+ if (_content.length() == 0)
_content = null;
}
@@ -995,7 +1008,7 @@ public class HttpGenerator extends AbstractGenerator
}
}
- if (_content != null && _content.length() == 0)
+ if (_content != null && _content.length() == 0)
_content = null;
}
@@ -1013,7 +1026,7 @@ public class HttpGenerator extends AbstractGenerator
(_buffer==null||_buffer.length()==0) &&
(_content==null||_content.length()==0);
}
-
+
@Override
public String toString()
{
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index 3d660700f5..b3ccf79002 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -26,18 +26,6 @@ import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
-/* ------------------------------------------------------------------------------- */
-/**
- *
- */
-
-/* ------------------------------------------------------------ */
-/**
- */
-
-/* ------------------------------------------------------------ */
-/**
- */
public class HttpParser implements Parser
{
// States
@@ -110,8 +98,9 @@ public class HttpParser implements Parser
/* ------------------------------------------------------------------------------- */
/**
* Constructor.
- * @param headerBufferSize size in bytes of header buffer
- * @param contentBufferSize size in bytes of content buffer
+ * @param buffers the buffers to use
+ * @param endp the endpoint
+ * @param handler the even handler
*/
public HttpParser(Buffers buffers, EndPoint endp, EventHandler handler)
{
@@ -237,7 +226,7 @@ public class HttpParser implements Parser
/* ------------------------------------------------------------------------------- */
/**
* Parse until next Event.
- * @returns number of bytes filled from endpoint or -1 if fill never called.
+ * @return number of bytes filled from endpoint or -1 if fill never called.
*/
public long parseNext() throws IOException
{
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java
index 84cafc46b4..e0dcba4b5f 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java
@@ -4,23 +4,21 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
-import org.eclipse.jetty.util.TypeUtil;
-
/**
* <p>
* HttpStatusCode enum class, for status codes based on various HTTP RFCs. (see
* table below)
* </p>
- *
+ *
* <table border="1" cellpadding="5">
* <tr>
* <th>Enum</th>
@@ -33,14 +31,14 @@ import org.eclipse.jetty.util.TypeUtil;
* <th>
* <a href="http://tools.ietf.org/html/rfc2518">RFC 2518 - WEBDAV</a></th>
* </tr>
- *
+ *
* <tr>
* <td><strong><code>Informational - 1xx</code></strong></td>
* <td colspan="5">{@link #isInformational(int)}</td>
* </tr>
- *
+ *
* <tr>
- * <td>{@link #CONTINUE}</td>
+ * <td>{@link #CONTINUE_100}</td>
* <td>100</td>
* <td>Continue</td>
* <td>&nbsp;</td>
@@ -49,7 +47,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #SWITCHING_PROTOCOLS}</td>
+ * <td>{@link #SWITCHING_PROTOCOLS_101}</td>
* <td>101</td>
* <td>Switching Protocols</td>
* <td>&nbsp;</td>
@@ -58,7 +56,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #PROCESSING}</td>
+ * <td>{@link #PROCESSING_102}</td>
* <td>102</td>
* <td>Processing</td>
* <td>&nbsp;</td>
@@ -66,14 +64,14 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>
* <a href="http://tools.ietf.org/html/rfc2518#section-10.1">Sec. 10.1</a></td>
* </tr>
- *
+ *
* <tr>
* <td><strong><code>Success - 2xx</code></strong></td>
* <td colspan="5">{@link #isSuccess(int)}</td>
* </tr>
- *
+ *
* <tr>
- * <td>{@link #OK}</td>
+ * <td>{@link #OK_200}</td>
* <td>200</td>
* <td>OK</td>
* <td>
@@ -83,7 +81,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #CREATED}</td>
+ * <td>{@link #CREATED_201}</td>
* <td>201</td>
* <td>Created</td>
* <td>
@@ -93,7 +91,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #ACCEPTED}</td>
+ * <td>{@link #ACCEPTED_202}</td>
* <td>202</td>
* <td>Accepted</td>
* <td>
@@ -103,7 +101,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NON_AUTHORITATIVE_INFORMATION}</td>
+ * <td>{@link #NON_AUTHORITATIVE_INFORMATION_203}</td>
* <td>203</td>
* <td>Non Authoritative Information</td>
* <td>&nbsp;</td>
@@ -112,7 +110,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NO_CONTENT}</td>
+ * <td>{@link #NO_CONTENT_204}</td>
* <td>204</td>
* <td>No Content</td>
* <td>
@@ -122,7 +120,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #RESET_CONTENT}</td>
+ * <td>{@link #RESET_CONTENT_205}</td>
* <td>205</td>
* <td>Reset Content</td>
* <td>&nbsp;</td>
@@ -131,7 +129,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #PARTIAL_CONTENT}</td>
+ * <td>{@link #PARTIAL_CONTENT_206}</td>
* <td>206</td>
* <td>Partial Content</td>
* <td>&nbsp;</td>
@@ -140,7 +138,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #MULTI_STATUS}</td>
+ * <td>{@link #MULTI_STATUS_207}</td>
* <td>207</td>
* <td>Multi-Status</td>
* <td>&nbsp;</td>
@@ -159,14 +157,14 @@ import org.eclipse.jetty.util.TypeUtil;
* >draft/01</a></td>
* <td>&nbsp;</td>
* </tr>
- *
+ *
* <tr>
* <td><strong><code>Redirection - 3xx</code></strong></td>
* <td colspan="5">{@link #isRedirection(int)}</td>
* </tr>
- *
+ *
* <tr>
- * <td>{@link #MULTIPLE_CHOICES}</td>
+ * <td>{@link #MULTIPLE_CHOICES_300}</td>
* <td>300</td>
* <td>Multiple Choices</td>
* <td>
@@ -176,7 +174,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #MOVED_PERMANENTLY}</td>
+ * <td>{@link #MOVED_PERMANENTLY_301}</td>
* <td>301</td>
* <td>Moved Permanently</td>
* <td>
@@ -186,7 +184,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #MOVED_TEMPORARILY}</td>
+ * <td>{@link #MOVED_TEMPORARILY_302}</td>
* <td>302</td>
* <td>Moved Temporarily</td>
* <td>
@@ -195,7 +193,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #FOUND}</td>
+ * <td>{@link #FOUND_302}</td>
* <td>302</td>
* <td>Found</td>
* <td>(was "<code>302 Moved Temporarily</code>")</td>
@@ -204,7 +202,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #SEE_OTHER}</td>
+ * <td>{@link #SEE_OTHER_303}</td>
* <td>303</td>
* <td>See Other</td>
* <td>&nbsp;</td>
@@ -213,7 +211,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NOT_MODIFIED}</td>
+ * <td>{@link #NOT_MODIFIED_304}</td>
* <td>304</td>
* <td>Not Modified</td>
* <td>
@@ -223,7 +221,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #USE_PROXY}</td>
+ * <td>{@link #USE_PROXY_305}</td>
* <td>305</td>
* <td>Use Proxy</td>
* <td>&nbsp;</td>
@@ -241,7 +239,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #TEMPORARY_REDIRECT}</td>
+ * <td>{@link #TEMPORARY_REDIRECT_307}</td>
* <td>307</td>
* <td>Temporary Redirect</td>
* <td>&nbsp;</td>
@@ -249,14 +247,14 @@ import org.eclipse.jetty.util.TypeUtil;
* <a href="http://tools.ietf.org/html/rfc2616#section-10.3.8">Sec. 10.3.8</a></td>
* <td>&nbsp;</td>
* </tr>
- *
+ *
* <tr>
* <td><strong><code>Client Error - 4xx</code></strong></td>
* <td colspan="5">{@link #isClientError(int)}</td>
* </tr>
- *
+ *
* <tr>
- * <td>{@link #BAD_REQUEST}</td>
+ * <td>{@link #BAD_REQUEST_400}</td>
* <td>400</td>
* <td>Bad Request</td>
* <td>
@@ -266,7 +264,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #UNAUTHORIZED}</td>
+ * <td>{@link #UNAUTHORIZED_401}</td>
* <td>401</td>
* <td>Unauthorized</td>
* <td>
@@ -276,7 +274,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #PAYMENT_REQUIRED}</td>
+ * <td>{@link #PAYMENT_REQUIRED_402}</td>
* <td>402</td>
* <td>Payment Required</td>
* <td>
@@ -286,7 +284,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #FORBIDDEN}</td>
+ * <td>{@link #FORBIDDEN_403}</td>
* <td>403</td>
* <td>Forbidden</td>
* <td>
@@ -296,7 +294,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NOT_FOUND}</td>
+ * <td>{@link #NOT_FOUND_404}</td>
* <td>404</td>
* <td>Not Found</td>
* <td>
@@ -306,7 +304,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #METHOD_NOT_ALLOWED}</td>
+ * <td>{@link #METHOD_NOT_ALLOWED_405}</td>
* <td>405</td>
* <td>Method Not Allowed</td>
* <td>&nbsp;</td>
@@ -315,7 +313,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NOT_ACCEPTABLE}</td>
+ * <td>{@link #NOT_ACCEPTABLE_406}</td>
* <td>406</td>
* <td>Not Acceptable</td>
* <td>&nbsp;</td>
@@ -324,7 +322,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #PROXY_AUTHENTICATION_REQUIRED}</td>
+ * <td>{@link #PROXY_AUTHENTICATION_REQUIRED_407}</td>
* <td>407</td>
* <td>Proxy Authentication Required</td>
* <td>&nbsp;</td>
@@ -333,7 +331,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #REQUEST_TIMEOUT}</td>
+ * <td>{@link #REQUEST_TIMEOUT_408}</td>
* <td>408</td>
* <td>Request Timeout</td>
* <td>&nbsp;</td>
@@ -342,7 +340,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #CONFLICT}</td>
+ * <td>{@link #CONFLICT_409}</td>
* <td>409</td>
* <td>Conflict</td>
* <td>&nbsp;</td>
@@ -352,7 +350,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #GONE}</td>
+ * <td>{@link #GONE_410}</td>
* <td>410</td>
* <td>Gone</td>
* <td>&nbsp;</td>
@@ -362,7 +360,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #LENGTH_REQUIRED}</td>
+ * <td>{@link #LENGTH_REQUIRED_411}</td>
* <td>411</td>
* <td>Length Required</td>
* <td>&nbsp;</td>
@@ -372,7 +370,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #PRECONDITION_FAILED}</td>
+ * <td>{@link #PRECONDITION_FAILED_412}</td>
* <td>412</td>
* <td>Precondition Failed</td>
* <td>&nbsp;</td>
@@ -382,7 +380,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #REQUEST_ENTITY_TOO_LARGE}</td>
+ * <td>{@link #REQUEST_ENTITY_TOO_LARGE_413}</td>
* <td>413</td>
* <td>Request Entity Too Large</td>
* <td>&nbsp;</td>
@@ -392,7 +390,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #REQUEST_URI_TOO_LONG}</td>
+ * <td>{@link #REQUEST_URI_TOO_LONG_414}</td>
* <td>414</td>
* <td>Request-URI Too Long</td>
* <td>&nbsp;</td>
@@ -402,7 +400,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #UNSUPPORTED_MEDIA_TYPE}</td>
+ * <td>{@link #UNSUPPORTED_MEDIA_TYPE_415}</td>
* <td>415</td>
* <td>Unsupported Media Type</td>
* <td>&nbsp;</td>
@@ -412,7 +410,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #REQUESTED_RANGE_NOT_SATISFIABLE}</td>
+ * <td>{@link #REQUESTED_RANGE_NOT_SATISFIABLE_416}</td>
* <td>416</td>
* <td>Requested Range Not Satisfiable</td>
* <td>&nbsp;</td>
@@ -422,7 +420,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #EXPECTATION_FAILED}</td>
+ * <td>{@link #EXPECTATION_FAILED_417}</td>
* <td>417</td>
* <td>Expectation Failed</td>
* <td>&nbsp;</td>
@@ -495,7 +493,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #UNPROCESSABLE_ENTITY}</td>
+ * <td>{@link #UNPROCESSABLE_ENTITY_422}</td>
* <td>422</td>
* <td>Unprocessable Entity</td>
* <td>&nbsp;</td>
@@ -504,7 +502,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <a href="http://tools.ietf.org/html/rfc2518#section-10.3">Sec. 10.3</a></td>
* </tr>
* <tr>
- * <td>{@link #LOCKED}</td>
+ * <td>{@link #LOCKED_423}</td>
* <td>423</td>
* <td>Locked</td>
* <td>&nbsp;</td>
@@ -513,7 +511,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <a href="http://tools.ietf.org/html/rfc2518#section-10.4">Sec. 10.4</a></td>
* </tr>
* <tr>
- * <td>{@link #FAILED_DEPENDENCY}</td>
+ * <td>{@link #FAILED_DEPENDENCY_424}</td>
* <td>424</td>
* <td>Failed Dependency</td>
* <td>&nbsp;</td>
@@ -521,14 +519,14 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>
* <a href="http://tools.ietf.org/html/rfc2518#section-10.5">Sec. 10.5</a></td>
* </tr>
- *
+ *
* <tr>
* <td><strong><code>Server Error - 5xx</code></strong></td>
* <td colspan="5">{@link #isServerError(int)}</td>
* </tr>
- *
+ *
* <tr>
- * <td>{@link #INTERNAL_SERVER_ERROR}</td>
+ * <td>{@link #INTERNAL_SERVER_ERROR_500}</td>
* <td>500</td>
* <td>Internal Server Error</td>
* <td>
@@ -538,7 +536,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #NOT_IMPLEMENTED}</td>
+ * <td>{@link #NOT_IMPLEMENTED_501}</td>
* <td>501</td>
* <td>Not Implemented</td>
* <td>
@@ -548,7 +546,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #BAD_GATEWAY}</td>
+ * <td>{@link #BAD_GATEWAY_502}</td>
* <td>502</td>
* <td>Bad Gateway</td>
* <td>
@@ -558,7 +556,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #SERVICE_UNAVAILABLE}</td>
+ * <td>{@link #SERVICE_UNAVAILABLE_503}</td>
* <td>503</td>
* <td>Service Unavailable</td>
* <td>
@@ -568,7 +566,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #GATEWAY_TIMEOUT}</td>
+ * <td>{@link #GATEWAY_TIMEOUT_504}</td>
* <td>504</td>
* <td>Gateway Timeout</td>
* <td>&nbsp;</td>
@@ -577,7 +575,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #HTTP_VERSION_NOT_SUPPORTED}</td>
+ * <td>{@link #HTTP_VERSION_NOT_SUPPORTED_505}</td>
* <td>505</td>
* <td>HTTP Version Not Supported</td>
* <td>&nbsp;</td>
@@ -594,7 +592,7 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>&nbsp;</td>
* </tr>
* <tr>
- * <td>{@link #INSUFFICIENT_STORAGE}</td>
+ * <td>{@link #INSUFFICIENT_STORAGE_507}</td>
* <td>507</td>
* <td>Insufficient Storage</td>
* <td>&nbsp;</td>
@@ -602,9 +600,9 @@ import org.eclipse.jetty.util.TypeUtil;
* <td>
* <a href="http://tools.ietf.org/html/rfc2518#section-10.6">Sec. 10.6</a></td>
* </tr>
- *
+ *
* </table>
- *
+ *
* @version $Id$
*/
public class HttpStatus
@@ -612,7 +610,7 @@ public class HttpStatus
public final static int CONTINUE_100 = 100;
public final static int SWITCHING_PROTOCOLS_101 = 101;
public final static int PROCESSING_102 = 102;
-
+
public final static int OK_200 = 200;
public final static int CREATED_201 = 201;
public final static int ACCEPTED_202 = 202;
@@ -621,7 +619,7 @@ public class HttpStatus
public final static int RESET_CONTENT_205 = 205;
public final static int PARTIAL_CONTENT_206 = 206;
public final static int MULTI_STATUS_207 = 207;
-
+
public final static int MULTIPLE_CHOICES_300 = 300;
public final static int MOVED_PERMANENTLY_301 = 301;
public final static int MOVED_TEMPORARILY_302 = 302;
@@ -630,7 +628,7 @@ public class HttpStatus
public final static int NOT_MODIFIED_304 = 304;
public final static int USE_PROXY_305 = 305;
public final static int TEMPORARY_REDIRECT_307 = 307;
-
+
public final static int BAD_REQUEST_400 = 400;
public final static int UNAUTHORIZED_401 = 401;
public final static int PAYMENT_REQUIRED_402 = 402;
@@ -652,7 +650,7 @@ public class HttpStatus
public final static int UNPROCESSABLE_ENTITY_422 = 422;
public final static int LOCKED_423 = 423;
public final static int FAILED_DEPENDENCY_424 = 424;
-
+
public final static int INTERNAL_SERVER_ERROR_500 = 500;
public final static int NOT_IMPLEMENTED_501 = 501;
public final static int BAD_GATEWAY_502 = 502;
@@ -660,9 +658,9 @@ public class HttpStatus
public final static int GATEWAY_TIMEOUT_504 = 504;
public final static int HTTP_VERSION_NOT_SUPPORTED_505 = 505;
public final static int INSUFFICIENT_STORAGE_507 = 507;
-
+
public static final int MAX_CODE = 507;
-
+
private static final Code[] codeMap = new Code[MAX_CODE+1];
@@ -673,7 +671,7 @@ public class HttpStatus
codeMap[code._code] = code;
}
}
-
+
public enum Code
{
@@ -843,7 +841,7 @@ public class HttpStatus
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
* and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
* HTTP/1.1</a>.
- *
+ *
* @return true if within range of codes that belongs to
* <code>Informational</code> messages.
*/
@@ -858,7 +856,7 @@ public class HttpStatus
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
* and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
* HTTP/1.1</a>.
- *
+ *
* @return true if within range of codes that belongs to
* <code>Success</code> messages.
*/
@@ -873,7 +871,7 @@ public class HttpStatus
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
* and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
* HTTP/1.1</a>.
- *
+ *
* @return true if within range of codes that belongs to
* <code>Redirection</code> messages.
*/
@@ -888,7 +886,7 @@ public class HttpStatus
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
* and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
* HTTP/1.1</a>.
- *
+ *
* @return true if within range of codes that belongs to
* <code>Client Error</code> messages.
*/
@@ -903,7 +901,7 @@ public class HttpStatus
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
* and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
* HTTP/1.1</a>.
- *
+ *
* @return true if within range of codes that belongs to
* <code>Server Error</code> messages.
*/
@@ -916,7 +914,7 @@ public class HttpStatus
/**
* Get the HttpStatusCode for a specific code
- *
+ *
* @param code
* the code to lookup.
* @return the {@link HttpStatus} if found, or null if not found.
@@ -929,10 +927,10 @@ public class HttpStatus
}
return null;
}
-
+
/**
* Get the status message for a specific code.
- *
+ *
* @param code
* the code to look up
* @return the specific message, or the code number itself if code
@@ -947,7 +945,7 @@ public class HttpStatus
}
else
{
- return TypeUtil.toString(code);
+ return Integer.toString(code);
}
}
@@ -956,7 +954,7 @@ public class HttpStatus
* <code>Informational</code> message category as defined in the <a
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
* href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
- *
+ *
* @param code
* the code to test.
* @return true if within range of codes that belongs to
@@ -972,7 +970,7 @@ public class HttpStatus
* <code>Success</code> message category as defined in the <a
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
* href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
- *
+ *
* @param code
* the code to test.
* @return true if within range of codes that belongs to
@@ -988,7 +986,7 @@ public class HttpStatus
* <code>Redirection</code> message category as defined in the <a
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
* href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
- *
+ *
* @param code
* the code to test.
* @return true if within range of codes that belongs to
@@ -1004,7 +1002,7 @@ public class HttpStatus
* <code>Client Error</code> message category as defined in the <a
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
* href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
- *
+ *
* @param code
* the code to test.
* @return true if within range of codes that belongs to
@@ -1020,7 +1018,7 @@ public class HttpStatus
* <code>Server Error</code> message category as defined in the <a
* href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
* href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
- *
+ *
* @param code
* the code to test.
* @return true if within range of codes that belongs to
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
index 47c67c1a48..6612b7d124 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
@@ -37,12 +37,12 @@ import org.eclipse.jetty.util.Utf8StringBuilder;
* <li>{@link #getQuery()} - query</li>
* <li>{@link #getFragment()} - fragment</li>
* </ul>
- *
+ *
*/
public class HttpURI
{
- private static final byte[] __empty={};
- private final static int
+ private static final byte[] __empty={};
+ private final static int
START=0,
AUTH_OR_PATH=1,
SCHEME_OR_PATH=2,
@@ -53,7 +53,7 @@ public class HttpURI
PARAM=8,
QUERY=9,
ASTERISK=10;
-
+
boolean _partial=false;
byte[] _raw=__empty;
String _rawString;
@@ -68,14 +68,14 @@ public class HttpURI
int _fragment;
int _end;
boolean _encoded=false;
-
+
final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64);
-
+
public HttpURI()
{
-
- }
-
+
+ }
+
/* ------------------------------------------------------------ */
/**
* @param parsePartialAuth If True, parse auth without prior scheme, else treat all URIs starting with / as paths
@@ -84,32 +84,106 @@ public class HttpURI
{
_partial=parsePartialAuth;
}
-
+
public HttpURI(String raw)
{
_rawString=raw;
byte[] b = raw.getBytes();
parse(b,0,b.length);
}
-
+
public HttpURI(byte[] raw,int offset, int length)
{
parse2(raw,offset,length);
}
-
+
public void parse(String raw)
{
byte[] b = raw.getBytes();
parse2(b,0,b.length);
_rawString=raw;
}
-
+
public void parse(byte[] raw,int offset, int length)
{
_rawString=null;
parse2(raw,offset,length);
}
-
+
+
+ public void parseConnect(byte[] raw,int offset, int length)
+ {
+ _rawString=null;
+ _encoded=false;
+ _raw=raw;
+ int i=offset;
+ int e=offset+length;
+ int state=AUTH;
+ int m=offset;
+ _end=offset+length;
+ _scheme=offset;
+ _authority=offset;
+ _host=offset;
+ _port=_end;
+ _portValue=-1;
+ _path=_end;
+ _param=_end;
+ _query=_end;
+ _fragment=_end;
+
+ loop: while (i<e)
+ {
+ char c=(char)(0xff&_raw[i]);
+ int s=i++;
+
+ switch (state)
+ {
+ case AUTH:
+ {
+ switch (c)
+ {
+ case ':':
+ {
+ _port = s;
+ break loop;
+ }
+ case '[':
+ {
+ state = IPV6;
+ break;
+ }
+ }
+ continue;
+ }
+
+ case IPV6:
+ {
+ switch (c)
+ {
+ case '/':
+ {
+ throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
+ }
+ case ']':
+ {
+ state = AUTH;
+ break;
+ }
+ }
+
+ continue;
+ }
+ }
+ }
+
+ if (_port<_path)
+ _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
+ else
+ throw new IllegalArgumentException("No port");
+ _path=offset;
+ }
+
+
private void parse2(byte[] raw,int offset, int length)
{
_encoded=false;
@@ -132,7 +206,7 @@ public class HttpURI
{
char c=(char)(0xff&_raw[i]);
int s=i++;
-
+
state: switch (state)
{
case START:
@@ -161,14 +235,14 @@ public class HttpURI
_path=s;
state=ASTERISK;
break;
-
+
default:
if (Character.isLetterOrDigit(c))
state=SCHEME_OR_PATH;
else
throw new IllegalArgumentException("!(SCHEME|PATH|AUTH):"+StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
}
-
+
continue;
}
@@ -185,16 +259,16 @@ public class HttpURI
{
i--;
state=PATH;
- }
+ }
else
{
_host=m;
_port=m;
state=PATH;
- }
+ }
continue;
}
-
+
case SCHEME_OR_PATH:
{
// short cut for http and https
@@ -219,7 +293,7 @@ public class HttpURI
c=':';
}
}
-
+
switch (c)
{
case ':':
@@ -238,20 +312,20 @@ public class HttpURI
}
break;
}
-
+
case '/':
{
state = PATH;
break;
}
-
+
case ';':
{
_param = s;
state = PARAM;
break;
}
-
+
case '?':
{
_param = s;
@@ -259,7 +333,7 @@ public class HttpURI
state = QUERY;
break;
}
-
+
case '#':
{
_param = s;
@@ -270,7 +344,7 @@ public class HttpURI
}
continue;
}
-
+
case AUTH:
{
switch (c)
@@ -321,7 +395,7 @@ public class HttpURI
continue;
}
-
+
case PORT:
{
if (c=='/')
@@ -334,7 +408,7 @@ public class HttpURI
}
continue;
}
-
+
case PATH:
{
switch (c)
@@ -366,7 +440,7 @@ public class HttpURI
}
continue;
}
-
+
case PARAM:
{
switch (c)
@@ -386,7 +460,7 @@ public class HttpURI
}
continue;
}
-
+
case QUERY:
{
if (c=='#')
@@ -396,7 +470,7 @@ public class HttpURI
}
continue;
}
-
+
case ASTERISK:
{
throw new IllegalArgumentException("only '*'");
@@ -407,62 +481,62 @@ public class HttpURI
if (_port<_path)
_portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
}
-
+
private String toUtf8String(int offset,int length)
{
_utf8b.reset();
_utf8b.append(_raw,offset,length);
return _utf8b.toString();
}
-
+
public String getScheme()
{
if (_scheme==_authority)
return null;
int l=_authority-_scheme;
- if (l==5 &&
- _raw[_scheme]=='h' &&
- _raw[_scheme+1]=='t' &&
- _raw[_scheme+2]=='t' &&
+ if (l==5 &&
+ _raw[_scheme]=='h' &&
+ _raw[_scheme+1]=='t' &&
+ _raw[_scheme+2]=='t' &&
_raw[_scheme+3]=='p' )
return HttpSchemes.HTTP;
- if (l==6 &&
- _raw[_scheme]=='h' &&
- _raw[_scheme+1]=='t' &&
- _raw[_scheme+2]=='t' &&
- _raw[_scheme+3]=='p' &&
+ if (l==6 &&
+ _raw[_scheme]=='h' &&
+ _raw[_scheme+1]=='t' &&
+ _raw[_scheme+2]=='t' &&
+ _raw[_scheme+3]=='p' &&
_raw[_scheme+4]=='s' )
return HttpSchemes.HTTPS;
-
+
return toUtf8String(_scheme,_authority-_scheme-1);
}
-
+
public String getAuthority()
{
if (_authority==_path)
return null;
return toUtf8String(_authority,_path-_authority);
}
-
+
public String getHost()
{
if (_host==_port)
return null;
return toUtf8String(_host,_port-_host);
}
-
+
public int getPort()
{
return _portValue;
}
-
+
public String getPath()
{
if (_path==_param)
return null;
return toUtf8String(_path,_param-_path);
}
-
+
public String getDecodedPath()
{
if (_path==_param)
@@ -475,7 +549,7 @@ public class HttpURI
for (int i=_path;i<_param;i++)
{
byte b = _raw[i];
-
+
if (b=='%')
{
if ((i+2)>=_param)
@@ -488,13 +562,13 @@ public class HttpURI
n++;
continue;
}
-
+
if (bytes==null)
{
bytes=new byte[length];
System.arraycopy(_raw,_path,bytes,0,n);
}
-
+
bytes[n++]=b;
}
@@ -505,47 +579,47 @@ public class HttpURI
_utf8b.append(bytes,0,n);
return _utf8b.toString();
}
-
+
public String getPathAndParam()
{
if (_path==_query)
return null;
return toUtf8String(_path,_query-_path);
}
-
+
public String getCompletePath()
{
if (_path==_end)
return null;
return toUtf8String(_path,_end-_path);
}
-
+
public String getParam()
{
if (_param==_query)
return null;
return toUtf8String(_param+1,_query-_param-1);
}
-
+
public String getQuery()
{
if (_query==_fragment)
return null;
return toUtf8String(_query+1,_fragment-_query-1);
}
-
+
public String getQuery(String encoding)
{
if (_query==_fragment)
return null;
return StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding);
}
-
+
public boolean hasQuery()
{
return (_fragment>_query);
}
-
+
public String getFragment()
{
if (_fragment==_end)
@@ -553,7 +627,7 @@ public class HttpURI
return toUtf8String(_fragment+1,_end-_fragment-1);
}
- public void decodeQueryTo(MultiMap parameters)
+ public void decodeQueryTo(MultiMap parameters)
{
if (_query==_fragment)
return;
@@ -561,12 +635,12 @@ public class HttpURI
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
}
- public void decodeQueryTo(MultiMap parameters, String encoding)
+ public void decodeQueryTo(MultiMap parameters, String encoding)
throws UnsupportedEncodingException
{
if (_query==_fragment)
return;
-
+
if (encoding==null || StringUtil.isUTF8(encoding))
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters);
else
@@ -580,7 +654,7 @@ public class HttpURI
_rawString="";
_encoded=false;
}
-
+
@Override
public String toString()
{
@@ -588,10 +662,10 @@ public class HttpURI
_rawString=toUtf8String(_scheme,_end-_scheme);
return _rawString;
}
-
+
public void writeTo(Utf8StringBuilder buf)
{
buf.append(_raw,_scheme,_end-_scheme);
}
-
+
}
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
index 146db9d433..8086084198 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
@@ -4,44 +4,48 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
+import java.net.CookieHandler;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.View;
-import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
-/* ------------------------------------------------------------------------------- */
/**
- *
+ *
*/
-public class HttpFieldsTest extends TestCase
+public class HttpFieldsTest
{
- public void testPut()
- throws Exception
+ @Test
+ public void testPut() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put("name0", "value0");
header.put("name1", "value1");
-
+
assertEquals("value0",header.getStringField("name0"));
assertEquals("value1",header.getStringField("name1"));
assertNull(header.getStringField("name2"));
-
+
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
@@ -53,35 +57,34 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(2, matches);
-
- matches=0;
+
e = header.getValues("name0");
assertEquals(true, e.hasMoreElements());
assertEquals(e.nextElement(), "value0");
assertEquals(false, e.hasMoreElements());
}
-
- public void testCRLF()
- throws Exception
+
+ @Test
+ public void testCRLF() throws Exception
{
HttpFields header = new HttpFields();
header.put("name0", "value\r\n0");
header.put("name\r\n1", "value1");
header.put("name:2", "value:\r\n2");
-
+
ByteArrayBuffer buffer = new ByteArrayBuffer(1024);
header.put(buffer);
assertTrue(buffer.toString().contains("name0: value0"));
assertTrue(buffer.toString().contains("name1: value1"));
- assertTrue(buffer.toString().contains("name2: value:2"));
+ assertTrue(buffer.toString().contains("name2: value:2"));
}
-
- public void testCachedPut()
- throws Exception
+
+ @Test
+ public void testCachedPut() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put("Connection", "keep-alive");
assertEquals(HttpHeaderValues.KEEP_ALIVE, header.getStringField(HttpHeaders.CONNECTION));
@@ -96,15 +99,13 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(1, matches);
-
-
}
-
- public void testRePut()
- throws Exception
+
+ @Test
+ public void testRePut() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put("name0", "value0");
header.put("name1", "xxxxxx");
header.put("name2", "value2");
@@ -112,14 +113,14 @@ public class HttpFieldsTest extends TestCase
assertEquals("value0",header.getStringField("name0"));
assertEquals("xxxxxx",header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
-
+
header.put("name1", "value1");
-
+
assertEquals("value0",header.getStringField("name0"));
assertEquals("value1",header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
assertNull(header.getStringField("name3"));
-
+
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
@@ -133,19 +134,18 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(3, matches);
-
- matches=0;
+
e = header.getValues("name1");
assertEquals(true, e.hasMoreElements());
assertEquals(e.nextElement(), "value1");
assertEquals(false, e.hasMoreElements());
}
-
- public void testRemovePut()
- throws Exception
+
+ @Test
+ public void testRemovePut() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put("name0", "value0");
header.put("name1", "value1");
header.put("name2", "value2");
@@ -153,14 +153,14 @@ public class HttpFieldsTest extends TestCase
assertEquals("value0",header.getStringField("name0"));
assertEquals("value1",header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
-
+
header.remove("name1");
-
+
assertEquals("value0",header.getStringField("name0"));
assertNull(header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
assertNull(header.getStringField("name3"));
-
+
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
@@ -174,18 +174,16 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(2, matches);
-
- matches=0;
+
e = header.getValues("name1");
assertEquals(false, e.hasMoreElements());
}
-
- public void testAdd()
- throws Exception
+ @Test
+ public void testAdd() throws Exception
{
HttpFields fields = new HttpFields();
-
+
fields.add("name0", "value0");
fields.add("name1", "valueA");
fields.add("name2", "value2");
@@ -193,14 +191,14 @@ public class HttpFieldsTest extends TestCase
assertEquals("value0",fields.getStringField("name0"));
assertEquals("valueA",fields.getStringField("name1"));
assertEquals("value2",fields.getStringField("name2"));
-
+
fields.add("name1", "valueB");
-
+
assertEquals("value0",fields.getStringField("name0"));
assertEquals("valueA",fields.getStringField("name1"));
assertEquals("value2",fields.getStringField("name2"));
assertNull(fields.getStringField("name3"));
-
+
int matches=0;
Enumeration e = fields.getFieldNames();
while (e.hasMoreElements())
@@ -214,8 +212,7 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(3, matches);
-
- matches=0;
+
e = fields.getValues("name1");
assertEquals(true, e.hasMoreElements());
assertEquals(e.nextElement(), "valueA");
@@ -223,9 +220,9 @@ public class HttpFieldsTest extends TestCase
assertEquals(e.nextElement(), "valueB");
assertEquals(false, e.hasMoreElements());
}
-
- public void testReuse()
- throws Exception
+
+ @Test
+ public void testReuse() throws Exception
{
HttpFields header = new HttpFields();
Buffer n1=new ByteArrayBuffer("name1");
@@ -237,21 +234,21 @@ public class HttpFieldsTest extends TestCase
vb.put((byte)'u');
vb.put((byte)'e');
vb.put((byte)'1');
-
+
header.put("name0", "value0");
header.put(n1,va);
header.put("name2", "value2");
-
+
assertEquals("value0",header.getStringField("name0"));
assertEquals("value1",header.getStringField("name1"));
assertEquals("value2",header.getStringField("name2"));
assertNull(header.getStringField("name3"));
-
+
header.remove(n1);
assertNull(header.getStringField("name1"));
header.put(n1,vb);
assertEquals("value1",header.getStringField("name1"));
-
+
int matches=0;
Enumeration e = header.getFieldNames();
while (e.hasMoreElements())
@@ -265,40 +262,38 @@ public class HttpFieldsTest extends TestCase
matches++;
}
assertEquals(3, matches);
-
- matches=0;
+
e = header.getValues("name1");
assertEquals(true, e.hasMoreElements());
assertEquals(e.nextElement(), "value1");
assertEquals(false, e.hasMoreElements());
}
-
- public void testDestroy()
- throws Exception
+
+ @Test
+ public void testDestroy() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put(new ByteArrayBuffer("name0"), new View(new ByteArrayBuffer("value0")));
assertTrue(header.getFieldNames().hasMoreElements());
assertNotNull(header.getStringField("name0"));
assertNull(header.getStringField("name1"));
-
+
header.destroy();
-
+
assertNull(header.getStringField("name0"));
}
- public void testCase()
- throws Exception
+ @Test
+ public void testCase() throws Exception
{
HttpFields fields= new HttpFields();
- Enumeration e;
Set s;
// 0123456789012345678901234567890
byte[] b ="Message-IDmessage-idvalueVALUE".getBytes();
ByteArrayBuffer buf= new ByteArrayBuffer(512);
buf.put(b);
-
+
View headUC= new View.CaseInsensitive(buf);
View headLC= new View.CaseInsensitive(buf);
View valUC = new View(buf);
@@ -327,7 +322,7 @@ public class HttpFieldsTest extends TestCase
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
assertEquals("value",fields.getStringField("message-id").toLowerCase());
-
+
fields.clear();
fields.add("header","value");
@@ -349,19 +344,19 @@ public class HttpFieldsTest extends TestCase
assertTrue(s.contains("message-id"));
assertEquals("value",fields.getStringField("Message-ID").toLowerCase());
assertEquals("value",fields.getStringField("message-id").toLowerCase());
-
+
}
-
- public void testHttpHeaderValues()
- throws Exception
+
+ @Test
+ public void testHttpHeaderValues() throws Exception
{
assertTrue(((CachedBuffer)HttpHeaderValues.CACHE.lookup("unknown value")).getOrdinal()<0);
assertTrue(((CachedBuffer)HttpHeaderValues.CACHE.lookup("close")).getOrdinal()>=0);
assertTrue(((CachedBuffer)HttpHeaderValues.CACHE.lookup("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)")).getOrdinal()>=0);
}
- public void testSetCookie()
- throws Exception
+ @Test
+ public void testSetCookie() throws Exception
{
HttpFields fields = new HttpFields();
fields.addSetCookie("minimal","value",null,null,-1,null,false,false,-1);
@@ -370,27 +365,57 @@ public class HttpFieldsTest extends TestCase
fields.clear();
fields.addSetCookie("everything","value","domain","path",0,"comment",true,true,0);
assertEquals("everything=value;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie"));
-
+
fields.clear();
fields.addSetCookie("ev erything","va lue","do main","pa th",1,"co mment",true,true,2);
- assertEquals("\"ev erything\"=\"va lue\";Version=2;Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Max-Age=1;Secure;HttpOnly",fields.getStringField("Set-Cookie"));
+ String setCookie=fields.getStringField("Set-Cookie");
+ assertTrue(setCookie.startsWith("\"ev erything\"=\"va lue\";Version=1;Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Expires="));
+ assertTrue(setCookie.endsWith("GMT;Max-Age=1;Secure;HttpOnly"));
fields.clear();
+ fields.addSetCookie("name","value",null,null,-1,null,false,false,0);
+ setCookie=fields.getStringField("Set-Cookie");
+ assertEquals(-1,setCookie.indexOf("Version="));
+ fields.clear();
+ fields.addSetCookie("name","v a l u e",null,null,-1,null,false,false,0);
+ setCookie=fields.getStringField("Set-Cookie");
+ assertEquals(17,setCookie.indexOf("Version=1"));
+
+ fields.clear();
fields.addSetCookie("json","{\"services\":[\"cwa\", \"aa\"]}",null,null,-1,null,false,false,-1);
assertEquals("json=\"{\\\"services\\\":[\\\"cwa\\\", \\\"aa\\\"]}\"",fields.getStringField("Set-Cookie"));
-
+
+ fields.clear();
+ fields.addSetCookie("name","value","domain",null,-1,null,false,false,-1);
+ fields.addSetCookie("name","other","domain",null,-1,null,false,false,-1);
+ assertEquals("name=other;Domain=domain",fields.getStringField("Set-Cookie"));
+ fields.addSetCookie("name","more","domain",null,-1,null,false,false,-1);
+ assertEquals("name=more;Domain=domain",fields.getStringField("Set-Cookie"));
+ fields.addSetCookie("foo","bar","domain",null,-1,null,false,false,-1);
+ fields.addSetCookie("foo","bob","domain",null,-1,null,false,false,-1);
+ assertEquals("name=more;Domain=domain",fields.getStringField("Set-Cookie"));
+
+ Enumeration e=fields.getValues("Set-Cookie");
+ assertEquals("name=more;Domain=domain",e.nextElement());
+ assertEquals("foo=bob;Domain=domain",e.nextElement());
+
+ fields=new HttpFields(0);
+ fields.addSetCookie("name","value==",null,null,-1,null,false,false,0);
+ setCookie=fields.getStringField("Set-Cookie");
+ assertEquals("name=value==",setCookie);
+
}
-
- private Set enum2set(Enumeration e)
+
+ private Set<String> enum2set(Enumeration<String> e)
{
- HashSet s=new HashSet();
+ Set<String> s=new HashSet<String>();
while(e.hasMoreElements())
- s.add(e.nextElement().toString().toLowerCase());
+ s.add(e.nextElement().toLowerCase());
return s;
}
-
- public void testDateFields()
- throws Exception
+
+ @Test
+ public void testDateFields() throws Exception
{
HttpFields fields = new HttpFields();
@@ -414,7 +439,7 @@ public class HttpFieldsTest extends TestCase
assertEquals(d2,d3);
assertEquals(d3+2000,d4);
assertEquals(951825600000L,d5);
-
+
d1 = fields.getDateField("D1");
d2 = fields.getDateField("D2");
d3 = fields.getDateField("D3");
@@ -426,28 +451,28 @@ public class HttpFieldsTest extends TestCase
assertEquals(d2,d3);
assertEquals(d3+2000,d4);
assertEquals(951825600000L,d5);
-
+
fields.putDateField("D2",d1);
assertEquals("Fri, 31 Dec 1999 23:59:59 GMT",fields.getStringField("D2"));
}
-
- public void testLongFields()
- throws Exception
+
+ @Test
+ public void testLongFields() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put("I1", "42");
header.put("I2", " 43 99");
header.put("I3", "-44;");
header.put("I4", " - 45abc");
header.put("N1", " - ");
header.put("N2", "xx");
-
+
long i1=header.getLongField("I1");
long i2=header.getLongField("I2");
long i3=header.getLongField("I3");
long i4=header.getLongField("I4");
-
+
try{
header.getLongField("N1");
assertTrue(false);
@@ -456,7 +481,7 @@ public class HttpFieldsTest extends TestCase
{
assertTrue(true);
}
-
+
try{
header.getLongField("N2");
assertTrue(false);
@@ -465,24 +490,24 @@ public class HttpFieldsTest extends TestCase
{
assertTrue(true);
}
-
+
assertEquals(42,i1);
assertEquals(43,i2);
assertEquals(-44,i3);
assertEquals(-45,i4);
-
+
header.putLongField("I5", 46);
header.putLongField("I6",-47);
assertEquals("46",header.getStringField("I5"));
assertEquals("-47",header.getStringField("I6"));
-
+
}
- public void testToString()
- throws Exception
+ @Test
+ public void testToString() throws Exception
{
HttpFields header = new HttpFields();
-
+
header.put(new ByteArrayBuffer("name0"), new View(new ByteArrayBuffer("value0")));
header.put(new ByteArrayBuffer("name1"), new View(new ByteArrayBuffer("value1".getBytes())));
String s1=header.toString();
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
index e08612fd85..56d97cef67 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
@@ -4,119 +4,116 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
import java.io.IOException;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.View;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-public class HttpGeneratorClientTest extends TestCase
+public class HttpGeneratorClientTest
{
public final static String CONTENT="The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n";
public final static String[] connect={null,"keep-alive","close"};
- public HttpGeneratorClientTest(String arg0)
- {
- super(arg0);
- }
-
- public void testContentLength()
- throws Exception
+ @Test
+ public void testContentLength() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
-
+
generator.setRequest("GET","/usr");
-
+
HttpFields fields = new HttpFields();
fields.add("Header","Value");
fields.add("Content-Type","text/plain");
-
+
String content = "The quick brown fox jumped over the lazy dog";
fields.addLongField("Content-Length",content.length());
-
+
generator.completeHeader(fields,false);
-
+
generator.addContent(new ByteArrayBuffer(content),true);
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
-
+
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Content-Length: 44||"+content,result);
}
- public void testAutoContentLength()
- throws Exception
+ @Test
+ public void testAutoContentLength() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
-
+
generator.setRequest("GET","/usr");
-
+
HttpFields fields = new HttpFields();
fields.add("Header","Value");
fields.add("Content-Type","text/plain");
-
+
String content = "The quick brown fox jumped over the lazy dog";
generator.addContent(new ByteArrayBuffer(content),true);
generator.completeHeader(fields,true);
-
+
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
-
+
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Content-Length: 44||"+content,result);
}
- public void testChunked()
- throws Exception
+ @Test
+ public void testChunked() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
-
+
generator.setRequest("GET","/usr");
-
+
HttpFields fields = new HttpFields();
fields.add("Header","Value");
fields.add("Content-Type","text/plain");
-
+
String content = "The quick brown fox jumped over the lazy dog";
generator.completeHeader(fields,false);
-
+
generator.addContent(new ByteArrayBuffer(content),false);
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
-
+
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Transfer-Encoding: chunked||2C|"+content+"|0||",result);
}
-
- public void testHTTP()
- throws Exception
+
+ @Test
+ public void testHTTP() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
@@ -125,7 +122,7 @@ public class HttpGeneratorClientTest extends TestCase
HttpGenerator hb = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
Handler handler = new Handler();
HttpParser parser=null;
-
+
// For HTTP version
for (int v=9;v<=11;v++)
{
@@ -140,13 +137,13 @@ public class HttpGeneratorClientTest extends TestCase
{
String t="v="+v+",r="+r+",chunks="+chunks+",c="+c+",tr="+tr[r];
// System.err.println(t);
-
+
hb.reset(true);
endp.reset();
fields.clear();
// System.out.println("TEST: "+t);
-
+
try
{
tr[r].build(v,hb,connect[c],null,chunks, fields);
@@ -160,15 +157,15 @@ public class HttpGeneratorClientTest extends TestCase
}
String request=endp.getOut().toString();
// System.out.println(request+(hb.isPersistent()?"...\n":"---\n"));
-
+
assertTrue(t,hb.isPersistent());
-
+
if (v==9)
{
assertEquals(t,"GET /context/path/info\r\n", request);
continue;
}
-
+
parser=new HttpParser(new ByteArrayBuffer(request.getBytes()), handler);
try
{
@@ -180,14 +177,14 @@ public class HttpGeneratorClientTest extends TestCase
throw e;
continue;
}
-
+
if (tr[r].body!=null)
assertEquals(t,tr[r].body, this.content);
if (v==10)
assertTrue(t,hb.isPersistent() || tr[r].values[1]==null || c==2 || c==0);
else
assertTrue(t,hb.isPersistent() || c==2);
-
+
assertTrue(t,tr[r].values[1]==null || content.length()==Integer.parseInt(tr[r].values[1]));
}
}
@@ -195,23 +192,21 @@ public class HttpGeneratorClientTest extends TestCase
}
}
-
-
- static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
- class TR
+ private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
+ private class TR
{
- String[] values=new String[headers.length];
- String body;
-
- TR(String ct, String cl ,String content)
+ private String[] values=new String[headers.length];
+ private String body;
+
+ private TR(String ct, String cl ,String content)
{
values[0]=ct;
values[1]=cl;
values[4]="value";
this.body=content;
}
-
- void build(int version,HttpGenerator hb, String connection, String te, int chunks, HttpFields fields)
+
+ private void build(int version,HttpGenerator hb, String connection, String te, int chunks, HttpFields fields)
throws Exception
{
values[2]=connection;
@@ -219,14 +214,14 @@ public class HttpGeneratorClientTest extends TestCase
hb.setRequest(HttpMethods.GET,"/context/path/info");
hb.setVersion(version);
-
+
for (int i=0;i<headers.length;i++)
{
- if (values[i]==null)
+ if (values[i]==null)
continue;
fields.put(new ByteArrayBuffer(headers[i]),new ByteArrayBuffer(values[i]));
}
-
+
if (body!=null)
{
int inc=1+body.length()/chunks;
@@ -262,15 +257,15 @@ public class HttpGeneratorClientTest extends TestCase
}
hb.complete();
}
-
+
@Override
public String toString()
{
return "["+values[0]+","+values[1]+","+(body==null?"none":"_content")+"]";
}
}
-
- private TR[] tr =
+
+ private final TR[] tr =
{
/* 0 */ new TR(null,null,null),
/* 1 */ new TR(null,null,CONTENT),
@@ -279,20 +274,20 @@ public class HttpGeneratorClientTest extends TestCase
/* 5 */ new TR("text/html",null,CONTENT),
/* 7 */ new TR("text/html",""+CONTENT.length(),CONTENT),
};
-
-
- String content;
- String f0;
- String f1;
- String f2;
- String[] hdr;
- String[] val;
- int h;
-
- class Handler extends HttpParser.EventHandler
- {
- int index=0;
-
+
+
+ private String content;
+ private String f0;
+ private String f1;
+ private String f2;
+ private String[] hdr;
+ private String[] val;
+ private int h;
+
+ private class Handler extends HttpParser.EventHandler
+ {
+ private int index=0;
+
@Override
public void content(Buffer ref)
{
@@ -302,7 +297,6 @@ public class HttpGeneratorClientTest extends TestCase
index+=ref.length();
}
-
@Override
public void startRequest(Buffer tok0, Buffer tok1, Buffer tok2)
{
@@ -319,7 +313,6 @@ public class HttpGeneratorClientTest extends TestCase
// System.out.println(f0+" "+f1+" "+f2);
}
-
/* (non-Javadoc)
* @see org.eclipse.jetty.EventHandler#startResponse(org.eclipse.io.Buffer, int, org.eclipse.io.Buffer)
*/
@@ -355,8 +348,5 @@ public class HttpGeneratorClientTest extends TestCase
public void messageComplete(long contentLength)
{
}
-
-
}
-
}
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
index fcf5195acd..56a1c786d1 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
@@ -4,66 +4,62 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
-
import java.io.IOException;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.View;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
- *
+ *
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
-public class HttpGeneratorTest extends TestCase
+public class HttpGeneratorTest
{
public final static String CONTENT="The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n";
public final static String[] connect={null,"keep-alive","close","TE, close"};
- public HttpGeneratorTest(String arg0)
- {
- super(arg0);
- }
-
- public void testRequest()
- throws Exception
+ @Test
+ public void testRequest() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
HttpFields fields = new HttpFields();
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
HttpGenerator hg = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
-
+
fields.add("Host","something");
fields.add("User-Agent","test");
-
+
hg.setRequest("GET","/index.html");
hg.setVersion(11);
hg.completeHeader(fields,true);
hg.complete();
-
+
assertTrue(endp.getOut().toString().indexOf("GET /index.html HTTP/1.1")==0);
assertTrue(endp.getOut().toString().indexOf("Content-Length")==-1);
-
}
-
- public void testHTTP()
- throws Exception
+
+ @Test
+ public void testHTTP() throws Exception
{
Buffer bb=new ByteArrayBuffer(8096);
Buffer sb=new ByteArrayBuffer(1500);
@@ -72,7 +68,7 @@ public class HttpGeneratorTest extends TestCase
HttpGenerator hb = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
Handler handler = new Handler();
HttpParser parser=null;
-
+
// For HTTP version
for (int v=9;v<=11;v++)
{
@@ -85,18 +81,18 @@ public class HttpGeneratorTest extends TestCase
// For none, keep-alive, close
for (int c=0;c<(v==11?connect.length:(connect.length-1));c++)
{
-
+
String t="v="+v+",r="+r+",chunks="+chunks+",connect="+connect[c]+",tr="+tr[r];
// System.err.println(t);
-
+
hb.reset(true);
endp.reset();
fields.clear();
-
+
tr[r].build(v,hb,"OK\r\nTest",connect[c],null,chunks, fields);
String response=endp.getOut().toString();
// System.out.println("RESPONSE: "+t+"\n"+response+(hb.isPersistent()?"...\n":"---\n"));
-
+
if (v==9)
{
assertFalse(t,hb.isPersistent());
@@ -104,7 +100,7 @@ public class HttpGeneratorTest extends TestCase
assertEquals(t,tr[r].body, response);
continue;
}
-
+
parser=new HttpParser(new ByteArrayBuffer(response.getBytes()), handler);
try
{
@@ -116,17 +112,17 @@ public class HttpGeneratorTest extends TestCase
throw e;
continue;
}
-
+
if (tr[r].body!=null)
assertEquals(t,tr[r].body, this.content);
if (v==10)
assertTrue(t,hb.isPersistent() || tr[r].values[1]==null || c==2 || c==0);
else
assertTrue(t,hb.isPersistent() || c==2 || c==3);
-
+
if (v>9)
assertEquals("OK Test",f2);
-
+
assertTrue(t,tr[r].values[1]==null || content.length()==Integer.parseInt(tr[r].values[1]));
}
}
@@ -134,16 +130,14 @@ public class HttpGeneratorTest extends TestCase
}
}
-
-
- static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
- class TR
+ private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
+ private class TR
{
- int code;
- String[] values=new String[headers.length];
- String body;
-
- TR(int code,String ct, String cl ,String content)
+ private int code;
+ private String[] values=new String[headers.length];
+ private String body;
+
+ private TR(int code,String ct, String cl ,String content)
{
this.code=code;
values[0]=ct;
@@ -151,22 +145,21 @@ public class HttpGeneratorTest extends TestCase
values[4]="value";
this.body=content;
}
-
- void build(int version,HttpGenerator hb,String reason, String connection, String te, int chunks, HttpFields fields)
- throws Exception
+
+ private void build(int version,HttpGenerator hb,String reason, String connection, String te, int chunks, HttpFields fields) throws Exception
{
values[2]=connection;
values[3]=te;
hb.setVersion(version);
hb.setResponse(code,reason);
-
+
for (int i=0;i<headers.length;i++)
{
- if (values[i]==null)
+ if (values[i]==null)
continue;
fields.put(new ByteArrayBuffer(headers[i]),new ByteArrayBuffer(values[i]));
}
-
+
if (body!=null)
{
int inc=1+body.length()/chunks;
@@ -198,15 +191,15 @@ public class HttpGeneratorTest extends TestCase
}
hb.complete();
}
-
+
@Override
public String toString()
{
return "["+code+","+values[0]+","+values[1]+","+(body==null?"none":"_content")+"]";
}
}
-
- private TR[] tr =
+
+ private final TR[] tr =
{
/* 0 */ new TR(200,null,null,null),
/* 1 */ new TR(200,null,null,CONTENT),
@@ -217,19 +210,19 @@ public class HttpGeneratorTest extends TestCase
/* 6 */ new TR(200,"text/html",""+CONTENT.length(),null),
/* 7 */ new TR(200,"text/html",""+CONTENT.length(),CONTENT),
};
-
- String content;
- String f0;
- String f1;
- String f2;
- String[] hdr;
- String[] val;
- int h;
-
- class Handler extends HttpParser.EventHandler
- {
- int index=0;
-
+
+ private String content;
+ private String f0;
+ private String f1;
+ private String f2;
+ private String[] hdr;
+ private String[] val;
+ private int h;
+
+ private class Handler extends HttpParser.EventHandler
+ {
+ private int index=0;
+
@Override
public void content(Buffer ref)
{
@@ -239,7 +232,6 @@ public class HttpGeneratorTest extends TestCase
index+=ref.length();
}
-
@Override
public void startRequest(Buffer tok0, Buffer tok1, Buffer tok2)
{
@@ -256,7 +248,6 @@ public class HttpGeneratorTest extends TestCase
// System.out.println(f0+" "+f1+" "+f2);
}
-
/* (non-Javadoc)
* @see org.eclipse.jetty.EventHandler#startResponse(org.eclipse.io.Buffer, int, org.eclipse.io.Buffer)
*/
@@ -292,8 +283,5 @@ public class HttpGeneratorTest extends TestCase
public void messageComplete(long contentLength)
{
}
-
-
}
-
}
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 6069ea59c7..70a2462115 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
@@ -4,67 +4,34 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
import java.io.UnsupportedEncodingException;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.bio.StringEndPoint;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
- *
*
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
*/
-public class HttpParserTest extends TestCase
+public class HttpParserTest
{
- /**
- * Constructor for HttpParserTest.
- * @param arg0
- */
- public HttpParserTest(String arg0)
- {
- super(arg0);
- }
-
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(HttpParserTest.class);
- }
-
- /**
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- /**
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- public void testLineParse0()
- throws Exception
+ @Test
+ public void testLineParse0() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /foo HTTP/1.0\015\012" + "\015\012");
@@ -80,8 +47,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testLineParse1()
- throws Exception
+ @Test
+ public void testLineParse1() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("GET /999\015\012");
@@ -98,8 +65,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testLineParse2()
- throws Exception
+ @Test
+ public void testLineParse2() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /222 \015\012");
@@ -116,8 +83,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testLineParse3()
- throws Exception
+ @Test
+ public void testLineParse3() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /fo\u0690 HTTP/1.0\015\012" + "\015\012");
@@ -133,8 +100,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testLineParse4()
- throws Exception
+ @Test
+ public void testLineParse4() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("POST /foo?param=\u0690 HTTP/1.0\015\012" + "\015\012");
@@ -150,8 +117,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testConnect()
- throws Exception
+ @Test
+ public void testConnect() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput("CONNECT 192.168.1.2:80 HTTP/1.1\015\012" + "\015\012");
@@ -168,8 +135,8 @@ public class HttpParserTest extends TestCase
assertEquals(-1, h);
}
- public void testHeaderParse()
- throws Exception
+ @Test
+ public void testHeaderParse() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
@@ -207,14 +174,14 @@ public class HttpParserTest extends TestCase
assertEquals(5, h);
}
- public void testChunkParse()
- throws Exception
+ @Test
+ public void testChunkParse() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
"GET /chunk HTTP/1.0\015\012"
+ "Header1: value1\015\012"
- + "Transfer-Encoding: chunked\015\012"
+ + "Transfer-Encoding: chunked\015\012"
+ "\015\012"
+ "a;\015\012"
+ "0123456789\015\012"
@@ -237,14 +204,14 @@ public class HttpParserTest extends TestCase
assertEquals("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content);
}
- public void testMultiParse()
- throws Exception
+ @Test
+ public void testMultiParse() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
"GET /mp HTTP/1.0\015\012"
+ "Header1: value1\015\012"
- + "Transfer-Encoding: chunked\015\012"
+ + "Transfer-Encoding: chunked\015\012"
+ "\015\012"
+ "a;\015\012"
+ "0123456789\015\012"
@@ -253,11 +220,11 @@ public class HttpParserTest extends TestCase
+ "0\015\012"
+ "POST /foo HTTP/1.0\015\012"
+ "Header2: value2\015\012"
- + "Content-Length: 0\015\012"
+ + "Content-Length: 0\015\012"
+ "\015\012"
+ "PUT /doodle HTTP/1.0\015\012"
+ "Header3: value3\015\012"
- + "Content-Length: 10\015\012"
+ + "Content-Length: 10\015\012"
+ "\015\012"
+ "0123456789\015\012");
@@ -293,15 +260,15 @@ public class HttpParserTest extends TestCase
assertEquals("Header3", hdr[0]);
assertEquals("value3", val[0]);
assertEquals("0123456789", _content);
-
}
+ @Test
public void testStreamParse() throws Exception
{
StringEndPoint io=new StringEndPoint();
String http="GET / HTTP/1.0\015\012"
+ "Header1: value1\015\012"
- + "Transfer-Encoding: chunked\015\012"
+ + "Transfer-Encoding: chunked\015\012"
+ "\015\012"
+ "a;\015\012"
+ "0123456789\015\012"
@@ -314,11 +281,10 @@ public class HttpParserTest extends TestCase
+ "\015\012"
+ "PUT /doodle HTTP/1.0\015\012"
+ "Header3: value3\015\012"
- + "Content-Length: 10\015\012"
+ + "Content-Length: 10\015\012"
+ "\015\012"
+ "0123456789\015\012";
-
int[] tests=
{
1024,
@@ -333,7 +299,7 @@ public class HttpParserTest extends TestCase
64,
32
};
-
+
for (int t= 0; t < tests.length; t++)
{
String tst="t"+tests[t];
@@ -345,10 +311,9 @@ public class HttpParserTest extends TestCase
Handler handler = new Handler();
HttpParser parser= new HttpParser(buffers,io, handler);
-
-
+
io.setInput(http);
-
+
parser.parse();
assertEquals(tst,"GET", f0);
assertEquals(tst,"/", f1);
@@ -357,7 +322,7 @@ public class HttpParserTest extends TestCase
assertEquals(tst,"Header1", hdr[0]);
assertEquals(tst,"value1", val[0]);
assertEquals(tst,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content);
-
+
parser.parse();
assertEquals(tst,"POST", f0);
assertEquals(tst,"/foo", f1);
@@ -366,7 +331,7 @@ public class HttpParserTest extends TestCase
assertEquals(tst,"Header2", hdr[0]);
assertEquals(tst,"value2", val[0]);
assertEquals(tst,null, _content);
-
+
parser.parse();
assertEquals(tst,"PUT", f0);
assertEquals(tst,"/doodle", f1);
@@ -385,16 +350,16 @@ public class HttpParserTest extends TestCase
}
}
- public void testResponseParse0()
- throws Exception
+ @Test
+ public void testResponseParse0() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
- "HTTP/1.1 200 Correct\015\012"
- + "Content-Length: 10\015\012"
- + "Content-Type: text/plain\015\012"
- + "\015\012"
- + "0123456789\015\012");
+ "HTTP/1.1 200 Correct\015\012"
+ + "Content-Length: 10\015\012"
+ + "Content-Type: text/plain\015\012"
+ + "\015\012"
+ + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
@@ -404,19 +369,19 @@ public class HttpParserTest extends TestCase
assertEquals("HTTP/1.1", f0);
assertEquals("200", f1);
assertEquals("Correct", f2);
- assertEquals(_content.length(), 10);
- assertTrue(headerCompleted);
- assertTrue(messageCompleted);
+ assertEquals(_content.length(), 10);
+ assertTrue(headerCompleted);
+ assertTrue(messageCompleted);
}
- public void testResponseParse1()
- throws Exception
+ @Test
+ public void testResponseParse1() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
- "HTTP/1.1 304 Not-Modified\015\012"
- + "Connection: close\015\012"
- + "\015\012");
+ "HTTP/1.1 304 Not-Modified\015\012"
+ + "Connection: close\015\012"
+ + "\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
@@ -426,23 +391,23 @@ public class HttpParserTest extends TestCase
assertEquals("HTTP/1.1", f0);
assertEquals("304", f1);
assertEquals("Not-Modified", f2);
- assertTrue(headerCompleted);
- assertTrue(messageCompleted);
+ assertTrue(headerCompleted);
+ assertTrue(messageCompleted);
}
- public void testResponseParse2()
- throws Exception
+ @Test
+ public void testResponseParse2() throws Exception
{
StringEndPoint io=new StringEndPoint();
io.setInput(
- "HTTP/1.1 204 No-Content\015\012"
- + "Connection: close\015\012"
- + "\015\012"
- + "HTTP/1.1 200 Correct\015\012"
- + "Content-Length: 10\015\012"
- + "Content-Type: text/plain\015\012"
- + "\015\012"
- + "0123456789\015\012");
+ "HTTP/1.1 204 No-Content\015\012"
+ + "Connection: close\015\012"
+ + "\015\012"
+ + "HTTP/1.1 200 Correct\015\012"
+ + "Content-Length: 10\015\012"
+ + "Content-Type: text/plain\015\012"
+ + "\015\012"
+ + "0123456789\015\012");
ByteArrayBuffer buffer= new ByteArrayBuffer(4096);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
@@ -452,34 +417,34 @@ public class HttpParserTest extends TestCase
assertEquals("HTTP/1.1", f0);
assertEquals("204", f1);
assertEquals("No-Content", f2);
- assertTrue(headerCompleted);
- assertTrue(messageCompleted);
+ assertTrue(headerCompleted);
+ assertTrue(messageCompleted);
parser.parse();
assertEquals("HTTP/1.1", f0);
assertEquals("200", f1);
assertEquals("Correct", f2);
- assertEquals(_content.length(), 10);
- assertTrue(headerCompleted);
- assertTrue(messageCompleted);
+ assertEquals(_content.length(), 10);
+ assertTrue(headerCompleted);
+ assertTrue(messageCompleted);
}
- String _content;
- String f0;
- String f1;
- String f2;
- String[] hdr;
- String[] val;
- int h;
-
- boolean headerCompleted;
- boolean messageCompleted;
-
- class Handler extends HttpParser.EventHandler
- {
- HttpFields fields;
- boolean request;
-
+ private String _content;
+ private String f0;
+ private String f1;
+ private String f2;
+ private String[] hdr;
+ private String[] val;
+ private int h;
+
+ private boolean headerCompleted;
+ private boolean messageCompleted;
+
+ private class Handler extends HttpParser.EventHandler
+ {
+ private HttpFields fields;
+ private boolean request;
+
public void content(Buffer ref)
{
if (_content==null)
@@ -487,7 +452,6 @@ public class HttpParserTest extends TestCase
_content= _content + ref;
}
-
public void startRequest(Buffer tok0, Buffer tok1, Buffer tok2)
{
try
@@ -507,12 +471,11 @@ public class HttpParserTest extends TestCase
}
catch (UnsupportedEncodingException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ throw new RuntimeException(e);
}
- messageCompleted = false;
- headerCompleted = false;
+ messageCompleted = false;
+ headerCompleted = false;
}
public void parsedHeader(Buffer name, Buffer value)
@@ -533,28 +496,27 @@ public class HttpParserTest extends TestCase
throw new IllegalStateException();
}
- headerCompleted = true;
+ headerCompleted = true;
}
public void messageComplete(long contentLength)
{
- messageCompleted = true;
+ messageCompleted = true;
}
-
public void startResponse(Buffer version, int status, Buffer reason)
{
request=false;
f0 = version.toString();
- f1 = Integer.toString(status);
- f2 = reason.toString();
+ f1 = Integer.toString(status);
+ f2 = reason.toString();
fields=new HttpFields();
hdr= new String[9];
val= new String[9];
- messageCompleted = false;
- headerCompleted = false;
+ messageCompleted = false;
+ headerCompleted = false;
}
}
}
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java
index 55c0b5d0fe..b0b5a282de 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java
@@ -4,19 +4,22 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
-import junit.framework.TestCase;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
-public class HttpStatusCodeTest extends TestCase
+public class HttpStatusCodeTest
{
+ @Test
public void testInvalidGetCode()
{
assertNull("Invalid code: 800", HttpStatus.getCode(800));
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/PathMapTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/PathMapTest.java
index dffa6f2cd5..4bb7a15255 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/PathMapTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/PathMapTest.java
@@ -4,53 +4,24 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
import junit.framework.TestCase;
+import org.junit.Test;
-
-/* ------------------------------------------------------------ */
/**
- * Top level test harness.
- *
- *
+ *
*/
public class PathMapTest extends TestCase
{
- /**
- * Constructor for HttpParserTest.
- *
- * @param arg0
- */
- public PathMapTest(String arg0)
- {
- super(arg0);
- }
-
- /**
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- /**
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- /* --------------------------------------------------------------- */
+ @Test
public void testPathMap() throws Exception
{
PathMap p = new PathMap();
@@ -65,28 +36,28 @@ public class PathMapTest extends TestCase
p.put("/", "8");
p.put("/XXX:/YYY", "9");
- String[][] tests = {
- { "/abs/path", "1"},
- { "/abs/path/xxx", "8"},
+ String[][] tests = {
+ { "/abs/path", "1"},
+ { "/abs/path/xxx", "8"},
{ "/abs/pith", "8"},
- { "/abs/path/longer", "2"},
- { "/abs/path/", "8"},
+ { "/abs/path/longer", "2"},
+ { "/abs/path/", "8"},
{ "/abs/path/xxx", "8"},
- { "/animal/bird/eagle/bald", "3"},
+ { "/animal/bird/eagle/bald", "3"},
{ "/animal/fish/shark/grey", "4"},
- { "/animal/insect/bug", "5"},
- { "/animal", "5"},
+ { "/animal/insect/bug", "5"},
+ { "/animal", "5"},
{ "/animal/", "5"},
{ "/animal/x", "5"},
{ "/animal/*", "5"},
- { "/suffix/path.tar.gz", "6"},
+ { "/suffix/path.tar.gz", "6"},
{ "/suffix/path.gz", "7"},
- { "/animal/path.gz", "5"},
+ { "/animal/path.gz", "5"},
{ "/Other/path", "8"},};
- for (int i = 0; i < tests.length; i++)
+ for (String[] test : tests)
{
- assertEquals(tests[i][0], tests[i][1], p.getMatch(tests[i][0]).getValue());
+ assertEquals(test[0], test[1], p.getMatch(test[0]).getValue());
}
assertEquals("Get absolute path", "1", p.get("/abs/path"));
@@ -158,10 +129,11 @@ public class PathMapTest extends TestCase
/**
* See JIRA issue: JETTY-88.
*/
+ @Test
public void testPathMappingsOnlyMatchOnDirectoryNames() throws Exception
{
String spec = "/xyz/*";
-
+
assertMatch(spec, "/xyz");
assertMatch(spec, "/xyz/");
assertMatch(spec, "/xyz/123");
diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml
index 83704ee2ad..9255af14b4 100644
--- a/jetty-io/pom.xml
+++ b/jetty-io/pom.xml
@@ -20,6 +20,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -50,16 +51,17 @@
</execution>
</executions>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.io.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
index 753b8b54b6..f7167b4d91 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
@@ -45,4 +45,15 @@ public interface AsyncEndPoint extends EndPoint
* it becomes writable.
*/
public void scheduleWrite();
+
+ /* ------------------------------------------------------------ */
+ /** Schedule a call to the idle timeout
+ */
+ public void scheduleIdle();
+
+ /* ------------------------------------------------------------ */
+ /** Cancel a call to the idle timeout
+ */
+ public void cancelIdle();
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferUtil.java b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferUtil.java
index 11e6e65036..0cc471143b 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferUtil.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferUtil.java
@@ -254,9 +254,9 @@ public class BufferUtil
{
boolean started= false;
// This assumes constant time int arithmatic
- for (int i= 0; i < decDivisors.length; i++)
+ for (int i= 0; i < decDivisorsL.length; i++)
{
- if (n < decDivisors[i])
+ if (n < decDivisorsL[i])
{
if (started)
buffer.put((byte)'0');
@@ -264,25 +264,68 @@ public class BufferUtil
}
started= true;
- long d= n / decDivisors[i];
+ long d= n / decDivisorsL[i];
buffer.put(DIGIT[(int)d]);
- n= n - d * decDivisors[i];
+ n= n - d * decDivisorsL[i];
}
}
}
public static Buffer toBuffer(long value)
{
- ByteArrayBuffer buf=new ByteArrayBuffer(16);
+ ByteArrayBuffer buf=new ByteArrayBuffer(32);
putDecLong(buf, value);
return buf;
}
private final static int[] decDivisors=
- { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 };
+ {
+ 1000000000,
+ 100000000,
+ 10000000,
+ 1000000,
+ 100000,
+ 10000,
+ 1000,
+ 100,
+ 10,
+ 1
+ };
private final static int[] hexDivisors=
- { 0x10000000, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 1 };
+ {
+ 0x10000000,
+ 0x1000000,
+ 0x100000,
+ 0x10000,
+ 0x1000,
+ 0x100,
+ 0x10,
+ 0x1
+ };
+
+ private final static long[] decDivisorsL=
+ {
+ 1000000000000000000L,
+ 100000000000000000L,
+ 10000000000000000L,
+ 1000000000000000L,
+ 100000000000000L,
+ 10000000000000L,
+ 1000000000000L,
+ 100000000000L,
+ 10000000000L,
+ 1000000000L,
+ 100000000L,
+ 10000000L,
+ 1000000L,
+ 100000L,
+ 10000L,
+ 1000L,
+ 100L,
+ 10L,
+ 1L
+ };
public static void putCRLF(Buffer buffer)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
index 484e3660b5..1c89fb0059 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
@@ -24,13 +24,15 @@ import java.io.IOException;
*/
public class ByteArrayEndPoint implements ConnectedEndPoint
{
- byte[] _inBytes;
- ByteArrayBuffer _in;
- ByteArrayBuffer _out;
- boolean _closed;
- boolean _nonBlocking;
- boolean _growOutput;
- Connection _connection;
+ protected byte[] _inBytes;
+ protected ByteArrayBuffer _in;
+ protected ByteArrayBuffer _out;
+ protected boolean _closed;
+ protected boolean _nonBlocking;
+ protected boolean _growOutput;
+ protected Connection _connection;
+ protected int _maxIdleTime;
+
/* ------------------------------------------------------------ */
/**
@@ -151,6 +153,14 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
/* ------------------------------------------------------------ */
/*
+ * @see org.eclipse.io.EndPoint#shutdownOutput()
+ */
+ public void shutdownOutput() throws IOException
+ {
+ }
+
+ /* ------------------------------------------------------------ */
+ /*
* @see org.eclipse.io.EndPoint#close()
*/
public void close() throws IOException
@@ -353,5 +363,23 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
_growOutput=growOutput;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.io.EndPoint#getMaxIdleTime()
+ */
+ public int getMaxIdleTime()
+ {
+ return _maxIdleTime;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.io.EndPoint#setMaxIdleTime(int)
+ */
+ public void setMaxIdleTime(int timeMs) throws IOException
+ {
+ _maxIdleTime=timeMs;
+ }
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
index 24e7fb9fc6..95a33e242c 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
@@ -16,16 +16,19 @@ package org.eclipse.jetty.io;
import java.io.IOException;
-
/**
*
* A transport EndPoint
*/
public interface EndPoint
{
+ /**
+ * Shutdown any backing output stream associated with the endpoint
+ */
+ void shutdownOutput() throws IOException;
/**
- * Close any backing stream associated with the buffer
+ * Close any backing stream associated with the endpoint
*/
void close() throws IOException;
@@ -149,4 +152,25 @@ public interface EndPoint
*/
public void flush() throws IOException;
+
+ /* ------------------------------------------------------------ */
+ /** Get the max idle time in ms.
+ * <p>The max idle time is the time the endpoint can be idle before
+ * extraordinary handling takes place. This loosely corresponds to
+ * the {@link java.net.Socket#getSoTimeout()} for blocking connections,
+ * but {@link AsyncEndPoint} implementations must use other mechanisms
+ * to implement the max idle time.
+ * @return the max idle time in ms.
+ */
+ public int getMaxIdleTime();
+
+ /* ------------------------------------------------------------ */
+ /** Set the max idle time.
+ * @param timeMs the max idle time in MS.
+ * @throws IOException if the timeout cannot be set.
+ */
+ public void setMaxIdleTime(int timeMs) throws IOException;
+
+
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java b/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
index 03a2e72f0d..7be12a17d1 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
@@ -11,7 +11,6 @@
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-
package org.eclipse.jetty.io;
import java.io.BufferedWriter;
@@ -28,74 +27,106 @@ import org.eclipse.jetty.util.log.Log;
/**
* A wrapper for the {@link java.io.PrintWriter} that re-throws the instances of
* {@link java.io.IOException} thrown by the underlying implementation of
- * {@link java.io.Writer} as {@link RunimeIOException} instances.
+ * {@link java.io.Writer} as {@link RuntimeIOException} instances.
*/
public class UncheckedPrintWriter extends PrintWriter
-{
- private boolean autoFlush = false;
-
+{
+ private boolean _autoFlush = false;
+ private boolean _throwUnchecked=true;
+
/* ------------------------------------------------------------ */
/**
- * Line separator string. This is the value of the line.separator
- * property at the moment that the stream was created.
+ * Line separator string. This is the value of the line.separator property
+ * at the moment that the stream was created.
*/
- private String lineSeparator;
-
- public UncheckedPrintWriter (Writer out)
+ private String _lineSeparator;
+
+ public UncheckedPrintWriter(Writer out)
{
- this(out, false);
+ this(out,false);
}
/* ------------------------------------------------------------ */
- /**
+ /**
* Create a new PrintWriter.
- *
- * @param out A character-output stream
- * @param autoFlush A boolean; if true, the println() methods will flush
- * the output buffer
+ *
+ * @param out
+ * A character-output stream
+ * @param autoFlush
+ * A boolean; if true, the println() methods will flush the
+ * output buffer
*/
public UncheckedPrintWriter(Writer out, boolean autoFlush)
{
- super(out, autoFlush);
- this.autoFlush = autoFlush;
- this.lineSeparator = System.getProperty("line.separator");
+ super(out,autoFlush);
+ this._autoFlush = autoFlush;
+ this._lineSeparator = System.getProperty("line.separator");
}
/* ------------------------------------------------------------ */
/**
* Create a new PrintWriter, without automatic line flushing, from an
- * existing OutputStream. This convenience constructor creates the
- * necessary intermediate OutputStreamWriter, which will convert characters
- * into bytes using the default character encoding.
- *
- * @param out An output stream
- *
+ * existing OutputStream. This convenience constructor creates the necessary
+ * intermediate OutputStreamWriter, which will convert characters into bytes
+ * using the default character encoding.
+ *
+ * @param out
+ * An output stream
+ *
* @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
*/
public UncheckedPrintWriter(OutputStream out)
{
- this(out, false);
+ this(out,false);
}
/* ------------------------------------------------------------ */
/**
- * Create a new PrintWriter from an existing OutputStream. This
- * convenience constructor creates the necessary intermediate
- * OutputStreamWriter, which will convert characters into bytes using the
- * default character encoding.
- *
- * @param out An output stream
- * @param autoFlush A boolean; if true, the println() methods will flush
- * the output buffer
- *
+ * Create a new PrintWriter from an existing OutputStream. This convenience
+ * constructor creates the necessary intermediate OutputStreamWriter, which
+ * will convert characters into bytes using the default character encoding.
+ *
+ * @param out
+ * An output stream
+ * @param autoFlush
+ * A boolean; if true, the println() methods will flush the
+ * output buffer
+ *
* @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
*/
public UncheckedPrintWriter(OutputStream out, boolean autoFlush)
{
- this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
+ this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush);
+ }
+
+ /* ------------------------------------------------------------ */
+ private void setError(Throwable th)
+ {
+ setError();
+ if (_throwUnchecked)
+ throw new RuntimeIOException(th);
+ Log.debug(th);
}
/* ------------------------------------------------------------ */
+ /** Are unchecked exceptions thrown.
+ * @return True if {@link RuntimeIOException}s are thrown
+ */
+ public boolean isUncheckedPrintWriter()
+ {
+ return _throwUnchecked;
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Set if unchecked exceptions are thrown
+ * @param uncheckedPrintWriter True if {@link RuntimeIOException}s are to be thrown
+ */
+ public void setUncheckedPrintWriter(boolean uncheckedPrintWriter)
+ {
+ _throwUnchecked = uncheckedPrintWriter;
+ }
+
+ /* ------------------------------------------------------------ */
/** Check to make sure that the stream has not been closed */
private void isOpen() throws IOException
{
@@ -104,281 +135,326 @@ public class UncheckedPrintWriter extends PrintWriter
}
/* ------------------------------------------------------------ */
- /**
- * Flush the stream.
+ /**
+ * Flush the stream.
*/
@Override
- public void flush() {
- try {
- synchronized (lock) {
+ public void flush()
+ {
+ try
+ {
+ synchronized (lock)
+ {
isOpen();
out.flush();
}
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
/* ------------------------------------------------------------ */
- /**
- * Close the stream.
+ /**
+ * Close the stream.
*/
@Override
- public void close() {
- try {
- synchronized (lock) {
+ public void close()
+ {
+ try
+ {
+ synchronized (lock)
+ {
out.close();
}
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
/* ------------------------------------------------------------ */
- /**
+ /**
* Write a single character.
- * @param c int specifying a character to be written.
+ *
+ * @param c
+ * int specifying a character to be written.
*/
@Override
- public void write(int c) {
- try {
- synchronized (lock) {
+ public void write(int c)
+ {
+ try
+ {
+ synchronized (lock)
+ {
isOpen();
out.write(c);
}
}
- catch (InterruptedIOException x) {
+ catch (InterruptedIOException x)
+ {
Thread.currentThread().interrupt();
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
/* ------------------------------------------------------------ */
- /**
- * Write a portion of an array of characters.
- * @param buf Array of characters
- * @param off Offset from which to start writing characters
- * @param len Number of characters to write
+ /**
+ * Write a portion of an array of characters.
+ *
+ * @param buf
+ * Array of characters
+ * @param off
+ * Offset from which to start writing characters
+ * @param len
+ * Number of characters to write
*/
@Override
- public void write(char buf[], int off, int len) {
- try {
- synchronized (lock) {
+ public void write(char buf[], int off, int len)
+ {
+ try
+ {
+ synchronized (lock)
+ {
isOpen();
- out.write(buf, off, len);
+ out.write(buf,off,len);
}
}
- catch (InterruptedIOException x) {
+ catch (InterruptedIOException x)
+ {
Thread.currentThread().interrupt();
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
/* ------------------------------------------------------------ */
/**
- * Write an array of characters. This method cannot be inherited from the
+ * Write an array of characters. This method cannot be inherited from the
* Writer class because it must suppress I/O exceptions.
- * @param buf Array of characters to be written
+ *
+ * @param buf
+ * Array of characters to be written
*/
@Override
- public void write(char buf[]) {
- this.write(buf, 0, buf.length);
+ public void write(char buf[])
+ {
+ this.write(buf,0,buf.length);
}
/* ------------------------------------------------------------ */
- /**
- * Write a portion of a string.
- * @param s A String
- * @param off Offset from which to start writing characters
- * @param len Number of characters to write
+ /**
+ * Write a portion of a string.
+ *
+ * @param s
+ * A String
+ * @param off
+ * Offset from which to start writing characters
+ * @param len
+ * Number of characters to write
*/
@Override
- public void write(String s, int off, int len) {
- try {
- synchronized (lock) {
+ public void write(String s, int off, int len)
+ {
+ try
+ {
+ synchronized (lock)
+ {
isOpen();
- out.write(s, off, len);
+ out.write(s,off,len);
}
}
- catch (InterruptedIOException x) {
+ catch (InterruptedIOException x)
+ {
Thread.currentThread().interrupt();
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
/* ------------------------------------------------------------ */
/**
- * Write a string. This method cannot be inherited from the Writer class
+ * Write a string. This method cannot be inherited from the Writer class
* because it must suppress I/O exceptions.
- * @param s String to be written
+ *
+ * @param s
+ * String to be written
*/
@Override
- public void write(String s) {
- this.write(s, 0, s.length());
+ public void write(String s)
+ {
+ this.write(s,0,s.length());
}
- private void newLine() {
- try {
- synchronized (lock) {
+ private void newLine()
+ {
+ try
+ {
+ synchronized (lock)
+ {
isOpen();
- out.write(lineSeparator);
- if (autoFlush)
+ out.write(_lineSeparator);
+ if (_autoFlush)
out.flush();
}
}
- catch (InterruptedIOException x) {
+ catch (InterruptedIOException x)
+ {
Thread.currentThread().interrupt();
}
- catch (IOException ex) {
- Log.debug(ex);
- setError();
- throw new UncheckedIOException(ex);
+ catch (IOException ex)
+ {
+ setError(ex);
}
}
-
- /* Methods that do not terminate lines */
-
/* ------------------------------------------------------------ */
- /**
- * Print a boolean value. The string produced by <code>{@link
+ /**
+ * Print a boolean value. The string produced by <code>{@link
* java.lang.String#valueOf(boolean)}</code> is translated into bytes
* according to the platform's default character encoding, and these bytes
* are written in exactly the manner of the <code>{@link
* #write(int)}</code> method.
- *
- * @param b The <code>boolean</code> to be printed
+ *
+ * @param b
+ * The <code>boolean</code> to be printed
*/
@Override
- public void print(boolean b) {
- this.write(b ? "true" : "false");
+ public void print(boolean b)
+ {
+ this.write(b?"true":"false");
}
/* ------------------------------------------------------------ */
/**
- * Print a character. The character is translated into one or more bytes
+ * Print a character. The character is translated into one or more bytes
* according to the platform's default character encoding, and these bytes
* are written in exactly the manner of the <code>{@link
* #write(int)}</code> method.
- *
- * @param c The <code>char</code> to be printed
+ *
+ * @param c
+ * The <code>char</code> to be printed
*/
@Override
- public void print(char c) {
+ public void print(char c)
+ {
this.write(c);
}
/* ------------------------------------------------------------ */
/**
- * Print an integer. The string produced by <code>{@link
+ * Print an integer. The string produced by <code>{@link
* java.lang.String#valueOf(int)}</code> is translated into bytes according
- * to the platform's default character encoding, and these bytes are
- * written in exactly the manner of the <code>{@link #write(int)}</code>
- * method.
- *
- * @param i The <code>int</code> to be printed
- * @see java.lang.Integer#toString(int)
+ * to the platform's default character encoding, and these bytes are written
+ * in exactly the manner of the <code>{@link #write(int)}</code> method.
+ *
+ * @param i
+ * The <code>int</code> to be printed
+ * @see java.lang.Integer#toString(int)
*/
@Override
- public void print(int i) {
+ public void print(int i)
+ {
this.write(String.valueOf(i));
}
/* ------------------------------------------------------------ */
/**
- * Print a long integer. The string produced by <code>{@link
- * java.lang.String#valueOf(long)}</code> is translated into bytes
- * according to the platform's default character encoding, and these bytes
- * are written in exactly the manner of the <code>{@link #write(int)}</code>
- * method.
- *
- * @param l The <code>long</code> to be printed
- * @see java.lang.Long#toString(long)
+ * Print a long integer. The string produced by <code>{@link
+ * java.lang.String#valueOf(long)}</code> is translated into bytes according
+ * to the platform's default character encoding, and these bytes are written
+ * in exactly the manner of the <code>{@link #write(int)}</code> method.
+ *
+ * @param l
+ * The <code>long</code> to be printed
+ * @see java.lang.Long#toString(long)
*/
@Override
- public void print(long l) {
+ public void print(long l)
+ {
this.write(String.valueOf(l));
}
/* ------------------------------------------------------------ */
/**
- * Print a floating-point number. The string produced by <code>{@link
+ * Print a floating-point number. The string produced by <code>{@link
* java.lang.String#valueOf(float)}</code> is translated into bytes
* according to the platform's default character encoding, and these bytes
* are written in exactly the manner of the <code>{@link #write(int)}</code>
* method.
- *
- * @param f The <code>float</code> to be printed
- * @see java.lang.Float#toString(float)
+ *
+ * @param f
+ * The <code>float</code> to be printed
+ * @see java.lang.Float#toString(float)
*/
@Override
- public void print(float f) {
+ public void print(float f)
+ {
this.write(String.valueOf(f));
}
/* ------------------------------------------------------------ */
/**
- * Print a double-precision floating-point number. The string produced by
+ * Print a double-precision floating-point number. The string produced by
* <code>{@link java.lang.String#valueOf(double)}</code> is translated into
* bytes according to the platform's default character encoding, and these
* bytes are written in exactly the manner of the <code>{@link
* #write(int)}</code> method.
- *
- * @param d The <code>double</code> to be printed
- * @see java.lang.Double#toString(double)
+ *
+ * @param d
+ * The <code>double</code> to be printed
+ * @see java.lang.Double#toString(double)
*/
@Override
- public void print(double d) {
+ public void print(double d)
+ {
this.write(String.valueOf(d));
}
/* ------------------------------------------------------------ */
/**
- * Print an array of characters. The characters are converted into bytes
+ * Print an array of characters. The characters are converted into bytes
* according to the platform's default character encoding, and these bytes
* are written in exactly the manner of the <code>{@link #write(int)}</code>
* method.
- *
- * @param s The array of chars to be printed
- *
- * @throws NullPointerException If <code>s</code> is <code>null</code>
+ *
+ * @param s
+ * The array of chars to be printed
+ *
+ * @throws NullPointerException
+ * If <code>s</code> is <code>null</code>
*/
@Override
- public void print(char s[]) {
+ public void print(char s[])
+ {
this.write(s);
}
/* ------------------------------------------------------------ */
/**
- * Print a string. If the argument is <code>null</code> then the string
- * <code>"null"</code> is printed. Otherwise, the string's characters are
+ * Print a string. If the argument is <code>null</code> then the string
+ * <code>"null"</code> is printed. Otherwise, the string's characters are
* converted into bytes according to the platform's default character
* encoding, and these bytes are written in exactly the manner of the
* <code>{@link #write(int)}</code> method.
- *
- * @param s The <code>String</code> to be printed
+ *
+ * @param s
+ * The <code>String</code> to be printed
*/
@Override
- public void print(String s) {
- if (s == null) {
+ public void print(String s)
+ {
+ if (s == null)
+ {
s = "null";
}
this.write(s);
@@ -386,46 +462,49 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print an object. The string produced by the <code>{@link
+ * Print an object. The string produced by the <code>{@link
* java.lang.String#valueOf(Object)}</code> method is translated into bytes
* according to the platform's default character encoding, and these bytes
* are written in exactly the manner of the <code>{@link #write(int)}</code>
* method.
- *
- * @param obj The <code>Object</code> to be printed
- * @see java.lang.Object#toString()
+ *
+ * @param obj
+ * The <code>Object</code> to be printed
+ * @see java.lang.Object#toString()
*/
@Override
- public void print(Object obj) {
+ public void print(Object obj)
+ {
this.write(String.valueOf(obj));
}
-
- /* Methods that do terminate lines */
-
/* ------------------------------------------------------------ */
/**
- * Terminate the current line by writing the line separator string. The
- * line separator string is defined by the system property
+ * Terminate the current line by writing the line separator string. The line
+ * separator string is defined by the system property
* <code>line.separator</code>, and is not necessarily a single newline
* character (<code>'\n'</code>).
*/
@Override
- public void println() {
+ public void println()
+ {
this.newLine();
}
/* ------------------------------------------------------------ */
/**
- * Print a boolean value and then terminate the line. This method behaves
- * as though it invokes <code>{@link #print(boolean)}</code> and then
+ * Print a boolean value and then terminate the line. This method behaves as
+ * though it invokes <code>{@link #print(boolean)}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the <code>boolean</code> value to be printed
+ *
+ * @param x
+ * the <code>boolean</code> value to be printed
*/
@Override
- public void println(boolean x) {
- synchronized (lock) {
+ public void println(boolean x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -433,15 +512,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print a character and then terminate the line. This method behaves as
+ * Print a character and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(char)}</code> and then <code>{@link
* #println()}</code>.
- *
- * @param x the <code>char</code> value to be printed
+ *
+ * @param x
+ * the <code>char</code> value to be printed
*/
@Override
- public void println(char x) {
- synchronized (lock) {
+ public void println(char x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -449,15 +531,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print an integer and then terminate the line. This method behaves as
+ * Print an integer and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(int)}</code> and then <code>{@link
* #println()}</code>.
- *
- * @param x the <code>int</code> value to be printed
+ *
+ * @param x
+ * the <code>int</code> value to be printed
*/
@Override
- public void println(int x) {
- synchronized (lock) {
+ public void println(int x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -465,15 +550,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print a long integer and then terminate the line. This method behaves
- * as though it invokes <code>{@link #print(long)}</code> and then
+ * Print a long integer and then terminate the line. This method behaves as
+ * though it invokes <code>{@link #print(long)}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the <code>long</code> value to be printed
+ *
+ * @param x
+ * the <code>long</code> value to be printed
*/
@Override
- public void println(long x) {
- synchronized (lock) {
+ public void println(long x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -481,15 +569,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print a floating-point number and then terminate the line. This method
+ * Print a floating-point number and then terminate the line. This method
* behaves as though it invokes <code>{@link #print(float)}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the <code>float</code> value to be printed
+ *
+ * @param x
+ * the <code>float</code> value to be printed
*/
@Override
- public void println(float x) {
- synchronized (lock) {
+ public void println(float x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -498,15 +589,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
* Print a double-precision floating-point number and then terminate the
- * line. This method behaves as though it invokes <code>{@link
+ * line. This method behaves as though it invokes <code>{@link
* #print(double)}</code> and then <code>{@link #println()}</code>.
- *
- * @param x the <code>double</code> value to be printed
+ *
+ * @param x
+ * the <code>double</code> value to be printed
*/
/* ------------------------------------------------------------ */
@Override
- public void println(double x) {
- synchronized (lock) {
+ public void println(double x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -514,15 +608,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print an array of characters and then terminate the line. This method
+ * Print an array of characters and then terminate the line. This method
* behaves as though it invokes <code>{@link #print(char[])}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the array of <code>char</code> values to be printed
+ *
+ * @param x
+ * the array of <code>char</code> values to be printed
*/
@Override
- public void println(char x[]) {
- synchronized (lock) {
+ public void println(char x[])
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -530,15 +627,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print a String and then terminate the line. This method behaves as
- * though it invokes <code>{@link #print(String)}</code> and then
+ * Print a String and then terminate the line. This method behaves as though
+ * it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the <code>String</code> value to be printed
+ *
+ * @param x
+ * the <code>String</code> value to be printed
*/
@Override
- public void println(String x) {
- synchronized (lock) {
+ public void println(String x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
@@ -546,15 +646,18 @@ public class UncheckedPrintWriter extends PrintWriter
/* ------------------------------------------------------------ */
/**
- * Print an Object and then terminate the line. This method behaves as
+ * Print an Object and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(Object)}</code> and then
* <code>{@link #println()}</code>.
- *
- * @param x the <code>Object</code> value to be printed
+ *
+ * @param x
+ * the <code>Object</code> value to be printed
*/
@Override
- public void println(Object x) {
- synchronized (lock) {
+ public void println(Object x)
+ {
+ synchronized (lock)
+ {
this.print(x);
this.println();
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
index 35dc953312..9f45293647 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 2004-2010 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
@@ -29,9 +29,9 @@ import org.eclipse.jetty.util.log.Log;
*/
public class SocketEndPoint extends StreamEndPoint
{
- Socket _socket;
- InetSocketAddress _local;
- InetSocketAddress _remote;
+ final Socket _socket;
+ final InetSocketAddress _local;
+ final InetSocketAddress _remote;
/**
*
@@ -41,6 +41,23 @@ public class SocketEndPoint extends StreamEndPoint
{
super(socket.getInputStream(),socket.getOutputStream());
_socket=socket;
+ _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+ _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+ super.setMaxIdleTime(_socket.getSoTimeout());
+ }
+
+ /**
+ *
+ */
+ protected SocketEndPoint(Socket socket, int maxIdleTime)
+ throws IOException
+ {
+ super(socket.getInputStream(),socket.getOutputStream());
+ _socket=socket;
+ _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+ _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+ _socket.setSoTimeout(maxIdleTime>0?maxIdleTime:0);
+ super.setMaxIdleTime(maxIdleTime);
}
/* (non-Javadoc)
@@ -52,27 +69,25 @@ public class SocketEndPoint extends StreamEndPoint
return super.isOpen() && _socket!=null && !_socket.isClosed() && !_socket.isInputShutdown() && !_socket.isOutputShutdown();
}
+
+
+ /* ------------------------------------------------------------ */
+ /*
+ * @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
+ */
+ @Override
+ public void shutdownOutput() throws IOException
+ {
+ if (!_socket.isClosed() && !_socket.isOutputShutdown())
+ _socket.shutdownOutput();
+ }
+
/* (non-Javadoc)
* @see org.eclipse.io.BufferIO#close()
*/
@Override
public void close() throws IOException
{
- if (!_socket.isClosed() && !_socket.isOutputShutdown())
- {
- try
- {
- _socket.shutdownOutput();
- }
- catch(IOException e)
- {
- Log.ignore(e);
- }
- catch(UnsupportedOperationException e)
- {
- Log.ignore(e);
- }
- }
_socket.close();
_in=null;
_out=null;
@@ -86,9 +101,6 @@ public class SocketEndPoint extends StreamEndPoint
@Override
public String getLocalAddr()
{
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
-
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
return StringUtil.ALL_INTERFACES;
@@ -102,9 +114,6 @@ public class SocketEndPoint extends StreamEndPoint
@Override
public String getLocalHost()
{
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
-
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
return StringUtil.ALL_INTERFACES;
@@ -119,8 +128,6 @@ public class SocketEndPoint extends StreamEndPoint
public int getLocalPort()
{
if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
- if (_local==null)
return -1;
return _local.getPort();
}
@@ -133,8 +140,6 @@ public class SocketEndPoint extends StreamEndPoint
public String getRemoteAddr()
{
if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- if (_remote==null)
return null;
InetAddress addr = _remote.getAddress();
return ( addr == null ? null : addr.getHostAddress() );
@@ -148,8 +153,6 @@ public class SocketEndPoint extends StreamEndPoint
public String getRemoteHost()
{
if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- if (_remote==null)
return null;
return _remote.getAddress().getCanonicalHostName();
}
@@ -162,8 +165,6 @@ public class SocketEndPoint extends StreamEndPoint
public int getRemotePort()
{
if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- if (_remote==null)
return -1;
return _remote.getPort();
}
@@ -177,4 +178,18 @@ public class SocketEndPoint extends StreamEndPoint
{
return _socket;
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
+ */
+ @Override
+ public void setMaxIdleTime(int timeMs) throws IOException
+ {
+ if (timeMs!=getMaxIdleTime())
+ _socket.setSoTimeout(timeMs>0?timeMs:0);
+ super.setMaxIdleTime(timeMs);
+ }
+
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
index 355ac3bd81..24e1b9e0ab 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
@@ -31,6 +31,7 @@ public class StreamEndPoint implements EndPoint
{
InputStream _in;
OutputStream _out;
+ int _maxIdleTime;
/**
*
@@ -72,6 +73,10 @@ public class StreamEndPoint implements EndPoint
return !isOpen();
}
+ public void shutdownOutput() throws IOException
+ {
+ }
+
/*
* @see org.eclipse.io.BufferIO#close()
*/
@@ -280,5 +285,17 @@ public class StreamEndPoint implements EndPoint
{
return false;
}
+
+ /* ------------------------------------------------------------ */
+ public int getMaxIdleTime()
+ {
+ return _maxIdleTime;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setMaxIdleTime(int timeMs) throws IOException
+ {
+ _maxIdleTime=timeMs;
+ }
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
index 762e9380df..c9628b86ab 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
@@ -29,27 +29,58 @@ import org.eclipse.jetty.util.log.Log;
/**
+ * Channel End Point.
+ * <p>Holds the channel and socket for an NIO endpoint.
*
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
*/
public class ChannelEndPoint implements EndPoint
{
protected final ByteChannel _channel;
protected final ByteBuffer[] _gather2=new ByteBuffer[2];
protected final Socket _socket;
- protected InetSocketAddress _local;
- protected InetSocketAddress _remote;
+ protected final InetSocketAddress _local;
+ protected final InetSocketAddress _remote;
+ protected int _maxIdleTime;
/**
*
*/
- public ChannelEndPoint(ByteChannel channel)
+ public ChannelEndPoint(ByteChannel channel) throws IOException
{
super();
this._channel = channel;
_socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+ if (_socket!=null)
+ {
+ _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+ _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+ _maxIdleTime=_socket.getSoTimeout();
+ }
+ else
+ {
+ _local=_remote=null;
+ }
+ }
+
+ /**
+ *
+ */
+ protected ChannelEndPoint(ByteChannel channel, int maxIdleTime) throws IOException
+ {
+ this._channel = channel;
+ _maxIdleTime=maxIdleTime;
+ _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+ if (_socket!=null)
+ {
+ _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+ _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+ _socket.setSoTimeout(_maxIdleTime);
+ }
+ else
+ {
+ _local=_remote=null;
+ }
+
}
public boolean isBlocking()
@@ -78,34 +109,23 @@ public class ChannelEndPoint implements EndPoint
/* (non-Javadoc)
* @see org.eclipse.io.EndPoint#close()
*/
- public void close() throws IOException
+ public void shutdownOutput() throws IOException
{
- if (_channel.isOpen())
+ if (_channel.isOpen() && _channel instanceof SocketChannel)
{
- try
- {
- if (_channel instanceof SocketChannel)
- {
- // TODO - is this really required?
- Socket socket= ((SocketChannel)_channel).socket();
- if (!socket.isClosed()&&!socket.isOutputShutdown())
- socket.shutdownOutput();
- }
- }
- catch(IOException e)
- {
- Log.ignore(e);
- }
- catch(UnsupportedOperationException e)
- {
- Log.ignore(e);
- }
- finally
- {
- _channel.close();
- }
+ Socket socket= ((SocketChannel)_channel).socket();
+ if (!socket.isClosed()&&!socket.isOutputShutdown())
+ socket.shutdownOutput();
}
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.io.EndPoint#close()
+ */
+ public void close() throws IOException
+ {
+ _channel.close();
+ }
/* (non-Javadoc)
* @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
@@ -317,13 +337,8 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return null;
-
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
-
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
return StringUtil.ALL_INTERFACES;
-
return _local.getAddress().getHostAddress();
}
@@ -335,13 +350,8 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return null;
-
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
-
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
return StringUtil.ALL_INTERFACES;
-
return _local.getAddress().getCanonicalHostName();
}
@@ -353,9 +363,6 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return 0;
-
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
if (_local==null)
return -1;
return _local.getPort();
@@ -369,10 +376,6 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return null;
-
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
-
if (_remote==null)
return null;
return _remote.getAddress().getHostAddress();
@@ -386,10 +389,6 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return null;
-
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
-
if (_remote==null)
return null;
return _remote.getAddress().getCanonicalHostName();
@@ -403,10 +402,6 @@ public class ChannelEndPoint implements EndPoint
{
if (_socket==null)
return 0;
-
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
-
return _remote==null?-1:_remote.getPort();
}
@@ -442,4 +437,21 @@ public class ChannelEndPoint implements EndPoint
{
return false;
}
+
+ /* ------------------------------------------------------------ */
+ public int getMaxIdleTime()
+ {
+ return _maxIdleTime;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
+ */
+ public void setMaxIdleTime(int timeMs) throws IOException
+ {
+ if (_socket!=null && timeMs!=_maxIdleTime)
+ _socket.setSoTimeout(timeMs>0?timeMs:0);
+ _maxIdleTime=timeMs;
+ }
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
index 87c97a84ed..7f5f2afc79 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
@@ -46,10 +46,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
private boolean _readBlocked;
private boolean _writeBlocked;
private boolean _open;
- private final Timeout.Task _idleTask = new IdleTask();
+ private volatile long _idleTimestamp;
/* ------------------------------------------------------------ */
public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key)
+ throws IOException
{
super(channel);
@@ -61,7 +62,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
_key = key;
_connection = _manager.newConnection(channel,this);
- _manager.endPointOpened(this);
scheduleIdle();
}
@@ -198,13 +198,22 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
/* ------------------------------------------------------------ */
public void scheduleIdle()
{
- _selectSet.scheduleIdle(_idleTask);
+ _idleTimestamp=System.currentTimeMillis();
}
/* ------------------------------------------------------------ */
public void cancelIdle()
{
- _selectSet.cancelIdle(_idleTask);
+ _idleTimestamp=0;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void checkIdleTimestamp(long now)
+ {
+ if (_idleTimestamp!=0 && _maxIdleTime!=0 && now>(_idleTimestamp+_maxIdleTime))
+ {
+ idleExpired();
+ }
}
/* ------------------------------------------------------------ */
@@ -336,6 +345,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
finally
{
_writeBlocked=false;
+ if (_idleTimestamp!=-1)
+ scheduleIdle();
}
}
return true;
@@ -424,7 +435,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
cancelIdle();
if (_open)
- _manager.endPointClosed(this);
+ {
+ _selectSet.destroyEndPoint(this);
+ }
_open=false;
_key = null;
}
@@ -437,7 +450,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
}
else
{
- if (_key.isValid())
+ if (_key!=null && _key.isValid())
_key.interestOps(0);
else
_key=null;
@@ -450,7 +463,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
cancelIdle();
if (_open)
- _manager.endPointClosed(this);
+ {
+ _selectSet.destroyEndPoint(this);
+ }
_open=false;
_key = null;
}
@@ -548,41 +563,27 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Runnable,
synchronized(this)
{
return "SCEP@" + hashCode() + "\t[d=" + _dispatched + ",io=" + _interestOps+
- ",w=" + _writable + ",b=" + _readBlocked + "|" + _writeBlocked + "]";
+ ",w=" + _writable + ",rb=" + _readBlocked + ",wb=" + _writeBlocked + "]";
}
}
/* ------------------------------------------------------------ */
- public Timeout.Task getTimeoutTask()
- {
- return _idleTask;
- }
-
- /* ------------------------------------------------------------ */
public SelectSet getSelectSet()
{
return _selectSet;
}
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- private class IdleTask extends Timeout.Task
+ /**
+ * Don't set the SoTimeout
+ * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int)
+ */
+ @Override
+ public void setMaxIdleTime(int timeMs) throws IOException
{
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.thread.Timeout.Task#expire()
- */
- @Override
- public void expired()
- {
- idleExpired();
- }
-
- @Override
- public String toString()
- {
- return "TimeoutTask:" + SelectChannelEndPoint.this.toString();
- }
+ _maxIdleTime=timeMs;
}
+
+
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
index 1c30409a02..52d47e0d1e 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -21,7 +21,11 @@ import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.Connection;
@@ -39,32 +43,31 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
* <p>
* This class works around a number of know JVM bugs. For details
* see http://wiki.eclipse.org/Jetty/Feature/JVM_NIO_Bug
- *
*/
public abstract class SelectorManager extends AbstractLifeCycle
{
// TODO Tune these by approx system speed.
private static final int __JVMBUG_THRESHHOLD=Integer.getInteger("org.mortbay.io.nio.JVMBUG_THRESHHOLD",512).intValue();
private static final int __MONITOR_PERIOD=Integer.getInteger("org.mortbay.io.nio.MONITOR_PERIOD",1000).intValue();
- private static final int __MAX_SELECTS=Integer.getInteger("org.mortbay.io.nio.MAX_SELECTS",15000).intValue();
+ private static final int __MAX_SELECTS=Integer.getInteger("org.mortbay.io.nio.MAX_SELECTS",25000).intValue();
private static final int __BUSY_PAUSE=Integer.getInteger("org.mortbay.io.nio.BUSY_PAUSE",50).intValue();
private static final int __BUSY_KEY=Integer.getInteger("org.mortbay.io.nio.BUSY_KEY",-1).intValue();
- private long _maxIdleTime;
+ private int _maxIdleTime;
+ private int _lowResourcesMaxIdleTime;
private long _lowResourcesConnections;
- private long _lowResourcesMaxIdleTime;
- private transient SelectSet[] _selectSet;
+ private SelectSet[] _selectSet;
private int _selectSets=1;
private volatile int _set;
/* ------------------------------------------------------------ */
/**
* @param maxIdleTime The maximum period in milli seconds that a connection may be idle before it is closed.
- * @see {@link #setLowResourcesMaxIdleTime(long)}
+ * @see #setLowResourcesMaxIdleTime(long)
*/
public void setMaxIdleTime(long maxIdleTime)
{
- _maxIdleTime=maxIdleTime;
+ _maxIdleTime=(int)maxIdleTime;
}
/* ------------------------------------------------------------ */
@@ -80,7 +83,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the max idle time
*/
public long getMaxIdleTime()
{
@@ -89,21 +92,33 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the number of select sets in use
*/
public int getSelectSets()
{
return _selectSets;
}
-
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param i
+ * @return The select set
+ */
+ public SelectSet getSelectSet(int i)
+ {
+ return _selectSet[i];
+ }
/* ------------------------------------------------------------ */
/** Register a channel
* @param channel
* @param att Attached Object
- * @throws IOException
*/
public void register(SocketChannel channel, Object att)
{
+ // The ++ increment here is not atomic, but it does not matter.
+ // so long as the value changes sometimes, then connections will
+ // be distributed over the available sets.
+
int s=_set++;
s=s%_selectSets;
SelectSet[] sets=_selectSet;
@@ -116,10 +131,8 @@ public abstract class SelectorManager extends AbstractLifeCycle
}
/* ------------------------------------------------------------ */
- /** Register a serverchannel
+ /** Register a {@link ServerSocketChannel}
* @param acceptChannel
- * @return
- * @throws IOException
*/
public void register(ServerSocketChannel acceptChannel)
{
@@ -144,7 +157,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
* Set the number of connections, which if exceeded places this manager in low resources state.
* This is not an exact measure as the connection count is averaged over the select sets.
* @param lowResourcesConnections the number of connections
- * @see {@link #setLowResourcesMaxIdleTime(long)}
+ * @see #setLowResourcesMaxIdleTime(long)
*/
public void setLowResourcesConnections(long lowResourcesConnections)
{
@@ -163,11 +176,11 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
* @param lowResourcesMaxIdleTime the period in ms that a connection is allowed to be idle when this SelectSet has more connections than {@link #getLowResourcesConnections()}
- * @see {@link #setMaxIdleTime(long)}
+ * @see #setMaxIdleTime(long)
*/
public void setLowResourcesMaxIdleTime(long lowResourcesMaxIdleTime)
{
- _lowResourcesMaxIdleTime=lowResourcesMaxIdleTime;
+ _lowResourcesMaxIdleTime=(int)lowResourcesMaxIdleTime;
}
/* ------------------------------------------------------------ */
@@ -184,8 +197,8 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @param key
- * @return
+ * @param key the selection key
+ * @return the SocketChannel created on accept
* @throws IOException
*/
protected abstract SocketChannel acceptChannel(SelectionKey key) throws IOException;
@@ -245,10 +258,11 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
+ * Create a new end point
* @param channel
* @param selectSet
- * @param sKey
- * @return
+ * @param sKey the selection key
+ * @return the new endpoint {@link SelectChannelEndPoint}
* @throws IOException
*/
protected abstract SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey sKey) throws IOException;
@@ -295,13 +309,13 @@ public abstract class SelectorManager extends AbstractLifeCycle
public class SelectSet
{
private final int _setID;
- private final Timeout _idleTimeout;
private final Timeout _timeout;
- private final List<Object>[] _changes;
-
- private int _change;
- private int _nextSet;
+
+ private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>();
+
private Selector _selector;
+
+ private int _nextSet;
private volatile Thread _selecting;
private int _jvmBug;
private int _selects;
@@ -315,21 +329,20 @@ public abstract class SelectorManager extends AbstractLifeCycle
private int _jvmFix0;
private int _jvmFix1;
private int _jvmFix2;
+ private volatile long _idleTick;
+ private ConcurrentMap<SelectChannelEndPoint,Object> _endPoints = new ConcurrentHashMap<SelectChannelEndPoint, Object>();
/* ------------------------------------------------------------ */
SelectSet(int acceptorID) throws Exception
{
_setID=acceptorID;
- _idleTimeout = new Timeout(this);
- _idleTimeout.setDuration(getMaxIdleTime());
+ _idleTick = System.currentTimeMillis();
_timeout = new Timeout(this);
_timeout.setDuration(0L);
- _changes = new List[] {new ArrayList(),new ArrayList()};
// create a selector;
_selector = Selector.open();
- _change=0;
_monitorStart=System.currentTimeMillis();
_monitorNext=_monitorStart+__MONITOR_PERIOD;
_log=_monitorStart+60000;
@@ -338,10 +351,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
public void addChange(Object point)
{
- synchronized (_changes)
- {
- _changes[_change].add(point);
- }
+ _changes.add(point);
}
/* ------------------------------------------------------------ */
@@ -356,12 +366,6 @@ public abstract class SelectorManager extends AbstractLifeCycle
}
/* ------------------------------------------------------------ */
- public void cancelIdle(Timeout.Task task)
- {
- task.cancel();
- }
-
- /* ------------------------------------------------------------ */
/**
* Select and dispatch tasks found from changes and the selector.
*
@@ -372,44 +376,36 @@ public abstract class SelectorManager extends AbstractLifeCycle
try
{
_selecting=Thread.currentThread();
- List<?> changes;
- final Selector selector;
- synchronized (_changes)
- {
- changes=_changes[_change];
- _change=_change==0?1:0;
- selector=_selector;
- }
+ final Selector selector=_selector;
// Make any key changes required
- final int size=changes.size();
- for (int i = 0; i < size; i++)
+ Object change;
+ int changes=_changes.size();
+ while (changes-->0 && (change=_changes.poll())!=null)
{
try
{
- Object o = changes.get(i);
-
- if (o instanceof EndPoint)
+ if (change instanceof EndPoint)
{
// Update the operations for a key.
- SelectChannelEndPoint endpoint = (SelectChannelEndPoint)o;
+ SelectChannelEndPoint endpoint = (SelectChannelEndPoint)change;
endpoint.doUpdateKey();
}
- else if (o instanceof Runnable)
+ else if (change instanceof Runnable)
{
- dispatch((Runnable)o);
+ dispatch((Runnable)change);
}
- else if (o instanceof ChangeSelectableChannel)
+ else if (change instanceof ChangeSelectableChannel)
{
// finish accepting/connecting this connection
- final ChangeSelectableChannel asc = (ChangeSelectableChannel)o;
+ final ChangeSelectableChannel asc = (ChangeSelectableChannel)change;
final SelectableChannel channel=asc._channel;
final Object att = asc._attachment;
if ((channel instanceof SocketChannel) && ((SocketChannel)channel).isConnected())
{
SelectionKey key = channel.register(selector,SelectionKey.OP_READ,att);
- SelectChannelEndPoint endpoint = newEndPoint((SocketChannel)channel,this,key);
+ SelectChannelEndPoint endpoint = createEndPoint((SocketChannel)channel,key);
key.attach(endpoint);
endpoint.schedule();
}
@@ -418,14 +414,14 @@ public abstract class SelectorManager extends AbstractLifeCycle
channel.register(selector,SelectionKey.OP_CONNECT,att);
}
}
- else if (o instanceof SocketChannel)
+ else if (change instanceof SocketChannel)
{
- final SocketChannel channel=(SocketChannel)o;
+ final SocketChannel channel=(SocketChannel)change;
if (channel.isConnected())
{
SelectionKey key = channel.register(selector,SelectionKey.OP_READ,null);
- SelectChannelEndPoint endpoint = newEndPoint(channel,this,key);
+ SelectChannelEndPoint endpoint = createEndPoint(channel,key);
key.attach(endpoint);
endpoint.schedule();
}
@@ -434,17 +430,17 @@ public abstract class SelectorManager extends AbstractLifeCycle
channel.register(selector,SelectionKey.OP_CONNECT,null);
}
}
- else if (o instanceof ServerSocketChannel)
+ else if (change instanceof ServerSocketChannel)
{
- ServerSocketChannel channel = (ServerSocketChannel)o;
+ ServerSocketChannel channel = (ServerSocketChannel)change;
channel.register(getSelector(),SelectionKey.OP_ACCEPT);
}
- else if (o instanceof ChangeTask)
+ else if (change instanceof ChangeTask)
{
- ((ChangeTask)o).run();
+ ((ChangeTask)change).run();
}
else
- throw new IllegalArgumentException(o.toString());
+ throw new IllegalArgumentException(change.toString());
}
catch (Exception e)
{
@@ -454,28 +450,15 @@ public abstract class SelectorManager extends AbstractLifeCycle
Log.debug(e);
}
}
- changes.clear();
- long idle_next;
long retry_next;
long now=System.currentTimeMillis();
- synchronized (this)
- {
- _idleTimeout.setNow(now);
- _timeout.setNow(now);
-
- if (_lowResourcesConnections>0 && selector.keys().size()>_lowResourcesConnections)
- _idleTimeout.setDuration(_lowResourcesMaxIdleTime);
- else
- _idleTimeout.setDuration(_maxIdleTime);
- idle_next=_idleTimeout.getTimeToNext();
- retry_next=_timeout.getTimeToNext();
- }
+ _timeout.setNow(now);
+
+ retry_next=_timeout.getTimeToNext();
// workout how low to wait in select
- long wait = 1000L; // not getMaxIdleTime() as the now value of the idle timers needs to be updated.
- if (idle_next >= 0 && wait > idle_next)
- wait = idle_next;
+ long wait = 1000L;
if (wait > 0 && retry_next >= 0 && wait > retry_next)
wait = retry_next;
@@ -498,7 +481,6 @@ public abstract class SelectorManager extends AbstractLifeCycle
long before=now;
int selected=selector.select(wait);
now = System.currentTimeMillis();
- _idleTimeout.setNow(now);
_timeout.setNow(now);
_selects++;
@@ -521,16 +503,16 @@ public abstract class SelectorManager extends AbstractLifeCycle
if (now>_log)
{
if (_paused>0)
- Log.info(this+" Busy selector - injecting delay "+_paused+" times");
+ Log.debug(this+" Busy selector - injecting delay "+_paused+" times");
if (_jvmFix2>0)
- Log.info(this+" JVM BUG(s) - injecting delay"+_jvmFix2+" times");
+ Log.debug(this+" JVM BUG(s) - injecting delay"+_jvmFix2+" times");
if (_jvmFix1>0)
- Log.info(this+" JVM BUG(s) - recreating selector "+_jvmFix1+" times, cancelled keys "+_jvmFix0+" times");
+ Log.debug(this+" JVM BUG(s) - recreating selector "+_jvmFix1+" times, cancelled keys "+_jvmFix0+" times");
else if(Log.isDebugEnabled() && _jvmFix0>0)
- Log.info(this+" JVM BUG(s) - cancelled keys "+_jvmFix0+" times");
+ Log.debug(this+" JVM BUG(s) - cancelled keys "+_jvmFix0+" times");
_paused=0;
_jvmFix2=0;
_jvmFix1=0;
@@ -679,7 +661,8 @@ public abstract class SelectorManager extends AbstractLifeCycle
{
// bind connections to this select set.
SelectionKey cKey = channel.register(_selectSet[_nextSet].getSelector(), SelectionKey.OP_READ);
- SelectChannelEndPoint endpoint=newEndPoint(channel,_selectSet[_nextSet],cKey);
+
+ SelectChannelEndPoint endpoint=_selectSet[_nextSet].createEndPoint(channel,cKey);
cKey.attach(endpoint);
if (endpoint != null)
endpoint.schedule();
@@ -709,7 +692,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
if (connected)
{
key.interestOps(SelectionKey.OP_READ);
- SelectChannelEndPoint endpoint = newEndPoint(channel,this,key);
+ SelectChannelEndPoint endpoint = createEndPoint(channel,key);
key.attach(endpoint);
endpoint.schedule();
}
@@ -723,7 +706,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
{
// Wrap readable registered channel in an endpoint
SocketChannel channel = (SocketChannel)key.channel();
- SelectChannelEndPoint endpoint = newEndPoint(channel,this,key);
+ SelectChannelEndPoint endpoint = createEndPoint(channel,key);
key.attach(endpoint);
if (key.isReadable())
endpoint.schedule();
@@ -749,9 +732,6 @@ public abstract class SelectorManager extends AbstractLifeCycle
// Everything always handled
selector.selectedKeys().clear();
- // tick over the timers
- _idleTimeout.tick(now);
-
_timeout.setNow(now);
Task task = _timeout.expired();
while (task!=null)
@@ -763,6 +743,27 @@ public abstract class SelectorManager extends AbstractLifeCycle
task = _timeout.expired();
}
+
+ // Idle tick
+ if (now-_idleTick>1000)
+ {
+ _idleTick=now;
+
+ final long idle_now=((_lowResourcesConnections>0 && selector.keys().size()>_lowResourcesConnections))
+ ?(now+_maxIdleTime-_lowResourcesMaxIdleTime)
+ :now;
+
+ dispatch(new Runnable()
+ {
+ public void run()
+ {
+ for (SelectChannelEndPoint endp:_endPoints.keySet())
+ {
+ endp.checkIdleTimestamp(idle_now);
+ }
+ }
+ });
+ }
}
catch (CancelledKeyException e)
{
@@ -783,15 +784,7 @@ public abstract class SelectorManager extends AbstractLifeCycle
/* ------------------------------------------------------------ */
public long getNow()
{
- return _idleTimeout.getNow();
- }
-
- /* ------------------------------------------------------------ */
- public void scheduleIdle(Timeout.Task task)
- {
- if (_idleTimeout.getDuration() <= 0)
- return;
- _idleTimeout.schedule(task);
+ return _timeout.getNow();
}
/* ------------------------------------------------------------ */
@@ -819,6 +812,22 @@ public abstract class SelectorManager extends AbstractLifeCycle
if (selector!=null)
selector.wakeup();
}
+
+ /* ------------------------------------------------------------ */
+ private SelectChannelEndPoint createEndPoint(SocketChannel channel, SelectionKey sKey) throws IOException
+ {
+ SelectChannelEndPoint endp = newEndPoint(channel,this,sKey);
+ endPointOpened(endp);
+ _endPoints.put(endp,this);
+ return endp;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void destroyEndPoint(SelectChannelEndPoint endp)
+ {
+ _endPoints.remove(endp);
+ endPointClosed(endp);
+ }
/* ------------------------------------------------------------ */
Selector getSelector()
@@ -864,7 +873,6 @@ public abstract class SelectorManager extends AbstractLifeCycle
selecting=_selecting!=null;
}
- _idleTimeout.cancelAll();
_timeout.cancelAll();
try
{
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/ssl/SslSelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslSelectChannelEndPoint.java
index 04c9c21225..0133c62920 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/ssl/SslSelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslSelectChannelEndPoint.java
@@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-package org.eclipse.jetty.http.ssl;
+package org.eclipse.jetty.io.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -24,13 +24,9 @@ import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.EofException;
-import org.eclipse.jetty.io.nio.NIOBuffer;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
-import org.eclipse.jetty.io.nio.SelectorManager;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -54,12 +50,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
private final SSLEngine _engine;
private final SSLSession _session;
- private final ByteBuffer _inBuffer;
- private final NIOBuffer _inNIOBuffer;
- private final ByteBuffer _outBuffer;
- private final NIOBuffer _outNIOBuffer;
+ private volatile NIOBuffer _inNIOBuffer;
+ private volatile NIOBuffer _outNIOBuffer;
- private final NIOBuffer[] _reuseBuffer=new NIOBuffer[2];
private final ByteBuffer[] _gather=new ByteBuffer[2];
private boolean _closing=false;
@@ -70,7 +63,6 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
private final boolean _debug = __log.isDebugEnabled(); // snapshot debug status for optimizer
-
/* ------------------------------------------------------------ */
public SslSelectChannelEndPoint(Buffers buffers,SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, SSLEngine engine)
throws IOException
@@ -82,15 +74,46 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
_engine=engine;
_session=engine.getSession();
- // TODO pool buffers and use only when needed.
- _outNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
- _outBuffer=_outNIOBuffer.getByteBuffer();
- _inNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
- _inBuffer=_inNIOBuffer.getByteBuffer();
-
if (_debug) __log.debug(_session+" channel="+channel);
}
-
+
+ /* ------------------------------------------------------------ */
+ private void needOutBuffer()
+ {
+ if (_outNIOBuffer==null)
+ {
+ _outNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private void needInBuffer()
+ {
+ if (_inNIOBuffer==null)
+ {
+ _inNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private void freeOutBuffer()
+ {
+ if (_outNIOBuffer.length()==0)
+ {
+ _buffers.returnBuffer(_outNIOBuffer);
+ _outNIOBuffer=null;
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private void freeInBuffer()
+ {
+ if (_inNIOBuffer.length()==0)
+ {
+ _buffers.returnBuffer(_inNIOBuffer);
+ _inNIOBuffer=null;
+ }
+ }
/* ------------------------------------------------------------ */
/**
@@ -120,43 +143,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
{
Log.info(""+_result);
}
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see org.eclipse.io.nio.SelectChannelEndPoint#idleExpired()
- */
- @Override
- protected void idleExpired()
- {
- try
- {
- getSelectManager().dispatch(new Runnable()
- {
- public void run()
- {
- doIdleExpired();
- }
- });
- }
- catch(Exception e)
- {
- Log.ignore(e);
- }
- }
-
- /* ------------------------------------------------------------ */
- protected void doIdleExpired()
- {
- super.idleExpired();
- }
-
/* ------------------------------------------------------------ */
@Override
- public void close() throws IOException
+ public void shutdownOutput() throws IOException
{
// TODO - this really should not be done in a loop here - but with async callbacks.
-
- _closing=true;
long end=System.currentTimeMillis()+((SocketChannel)_channel).socket().getSoTimeout();
try
{
@@ -224,19 +215,22 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
case NEED_WRAP:
{
+ needOutBuffer();
+ ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
try
- {
+ {
_outNIOBuffer.compact();
int put=_outNIOBuffer.putIndex();
- _outBuffer.position(put);
+ out_buffer.position(put);
_result=null;
- _result=_engine.wrap(__NO_BUFFERS,_outBuffer);
+ _result=_engine.wrap(__NO_BUFFERS,out_buffer);
if (_debug) __log.debug(_session+" close wrap "+_result);
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
}
finally
{
- _outBuffer.position(0);
+ out_buffer.position(0);
+ freeOutBuffer();
}
break;
@@ -244,26 +238,33 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
}
}
- catch(IOException e)
+ catch (InterruptedException e)
{
Log.ignore(e);
}
- catch (InterruptedException e)
+ }
+
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void close() throws IOException
+ {
+ try
+ {
+ _closing=true;
+ shutdownOutput();
+ }
+ catch(IOException e)
{
Log.ignore(e);
}
finally
{
super.close();
-
if (_inNIOBuffer!=null)
_buffers.returnBuffer(_inNIOBuffer);
if (_outNIOBuffer!=null)
_buffers.returnBuffer(_outNIOBuffer);
- if (_reuseBuffer[0]!=null)
- _buffers.returnBuffer(_reuseBuffer[0]);
- if (_reuseBuffer[1]!=null)
- _buffers.returnBuffer(_reuseBuffer[1]);
}
}
@@ -271,7 +272,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
/* ------------------------------------------------------------ */
/** Fill the buffer with unencrypted bytes.
- * Called by a {@link Parser} instance when more data is
+ * Called by a Http Parser when more data is
* needed to continue parsing a request or a response.
*/
@Override
@@ -373,7 +374,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
// The SSL needs to send some handshake data to the other side,
// so let fill become a flush for a little bit.
wraps++;
- synchronized(_outBuffer)
+ needOutBuffer();
+ ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
+ synchronized(out_buffer)
{
try
{
@@ -381,9 +384,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
// generate required handshake messages into _outNIOBuffer
_outNIOBuffer.compact();
int put=_outNIOBuffer.putIndex();
- _outBuffer.position();
+ out_buffer.position();
_result=null;
- _result=_engine.wrap(__NO_BUFFERS,_outBuffer);
+ _result=_engine.wrap(__NO_BUFFERS,out_buffer);
if (_debug) __log.debug(_session+" fill wrap "+_result);
switch(_result.getStatus())
{
@@ -398,13 +401,14 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
finally
{
- _outBuffer.position(0);
+ out_buffer.position(0);
}
}
// flush the encrypted outNIOBuffer
flush();
-
+ freeOutBuffer();
+
break;
}
}
@@ -450,7 +454,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
if (buffer!=null)
available+=buffer.length();
- int tries=0;
+ needOutBuffer();
+ ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
loop: while (true)
{
if (_outNIOBuffer.length()>0)
@@ -529,15 +534,15 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
case NEED_WRAP:
{
checkRenegotiate();
- synchronized(_outBuffer)
+ synchronized(out_buffer)
{
try
{
_outNIOBuffer.compact();
int put=_outNIOBuffer.putIndex();
- _outBuffer.position();
+ out_buffer.position();
_result=null;
- _result=_engine.wrap(__NO_BUFFERS,_outBuffer);
+ _result=_engine.wrap(__NO_BUFFERS,out_buffer);
if (_debug) __log.debug(_session+" flush wrap "+_result);
switch(_result.getStatus())
{
@@ -551,7 +556,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
finally
{
- _outBuffer.position(0);
+ out_buffer.position(0);
}
}
@@ -563,7 +568,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
}
}
-
+
+ freeOutBuffer();
return consumed;
}
@@ -571,6 +577,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
@Override
public void flush() throws IOException
{
+ if (_outNIOBuffer==null)
+ return;
+
int len=_outNIOBuffer.length();
if (isBufferingOutput())
{
@@ -612,6 +621,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
*/
private boolean unwrap(ByteBuffer buffer) throws IOException
{
+ needInBuffer();
+ ByteBuffer in_buffer=_inNIOBuffer.getByteBuffer();
+
if (_inNIOBuffer.hasContent())
_inNIOBuffer.compact();
else
@@ -636,7 +648,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
{
if (_inNIOBuffer.length()==0)
{
- _outNIOBuffer.clear();
+ if (_outNIOBuffer!=null)
+ {
+ _outNIOBuffer.clear();
+ freeOutBuffer();
+ }
throw e;
}
break;
@@ -648,7 +664,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
{
if(!isOpen())
{
- _outNIOBuffer.clear();
+ if (_outNIOBuffer!=null)
+ _outNIOBuffer.clear();
throw new EofException();
}
return false;
@@ -659,12 +676,12 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
{
// inBuffer is the NIO buffer inside the _inNIOBuffer,
// so update its position and limit from the inNIOBuffer.
- _inBuffer.position(_inNIOBuffer.getIndex());
- _inBuffer.limit(_inNIOBuffer.putIndex());
+ in_buffer.position(_inNIOBuffer.getIndex());
+ in_buffer.limit(_inNIOBuffer.putIndex());
_result=null;
// Do the unwrap
- _result=_engine.unwrap(_inBuffer,buffer);
+ _result=_engine.unwrap(in_buffer,buffer);
if (_debug) __log.debug(_session+" unwrap unwrap "+_result);
// skip the bytes consumed
@@ -673,8 +690,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
finally
{
// reset the buffer so it can be managed by the _inNIOBuffer again.
- _inBuffer.position(0);
- _inBuffer.limit(_inBuffer.capacity());
+ in_buffer.position(0);
+ in_buffer.limit(in_buffer.capacity());
+ freeInBuffer();
}
// handle the unwrap results
@@ -692,7 +710,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
if(!isOpen())
{
_inNIOBuffer.clear();
- _outNIOBuffer.clear();
+ if (_outNIOBuffer!=null)
+ _outNIOBuffer.clear();
throw new EofException();
}
return (total_filled > 0);
@@ -712,51 +731,44 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
/* ------------------------------------------------------------ */
- private ByteBuffer extractOutputBuffer(Buffer buffer,int n)
+ private ByteBuffer extractOutputBuffer(Buffer buffer)
{
if (buffer.buffer() instanceof NIOBuffer)
- {
- NIOBuffer nBuf=(NIOBuffer)buffer.buffer();
- return nBuf.getByteBuffer();
- }
- else
- {
- if (_reuseBuffer[n]==null)
- _reuseBuffer[n] = (NIOBuffer)_buffers.getBuffer(_session.getApplicationBufferSize());
- NIOBuffer buf = _reuseBuffer[n];
- buf.clear();
- buf.put(buffer);
- return buf.getByteBuffer();
- }
+ return ((NIOBuffer)buffer.buffer()).getByteBuffer();
+
+ return ByteBuffer.wrap(buffer.array());
}
/* ------------------------------------------------------------ */
private int wrap(final Buffer header, final Buffer buffer) throws IOException
{
- _gather[0]=extractOutputBuffer(header,0);
+ _gather[0]=extractOutputBuffer(header);
+
synchronized(_gather[0])
{
_gather[0].position(header.getIndex());
_gather[0].limit(header.putIndex());
- _gather[1]=extractOutputBuffer(buffer,1);
+ _gather[1]=extractOutputBuffer(buffer);
synchronized(_gather[1])
{
_gather[1].position(buffer.getIndex());
_gather[1].limit(buffer.putIndex());
- synchronized(_outBuffer)
+ needOutBuffer();
+ ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
+ synchronized(out_buffer)
{
int consumed=0;
try
{
_outNIOBuffer.clear();
- _outBuffer.position(0);
- _outBuffer.limit(_outBuffer.capacity());
+ out_buffer.position(0);
+ out_buffer.limit(out_buffer.capacity());
_result=null;
- _result=_engine.wrap(_gather,_outBuffer);
+ _result=_engine.wrap(_gather,out_buffer);
if (_debug) __log.debug(_session+" wrap wrap "+_result);
_outNIOBuffer.setGetIndex(0);
_outNIOBuffer.setPutIndex(_result.bytesProduced());
@@ -764,7 +776,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
finally
{
- _outBuffer.position(0);
+ out_buffer.position(0);
if (consumed>0)
{
@@ -783,6 +795,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
_gather[1].limit(_gather[1].capacity());
}
assert consumed==0;
+
+ freeOutBuffer();
}
}
}
@@ -810,22 +824,26 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
/* ------------------------------------------------------------ */
private int wrap(final Buffer buffer) throws IOException
{
- _gather[0]=extractOutputBuffer(buffer,0);
+ _gather[0]=extractOutputBuffer(buffer);
synchronized(_gather[0])
{
+ ByteBuffer bb;
+
_gather[0].position(buffer.getIndex());
_gather[0].limit(buffer.putIndex());
int consumed=0;
- synchronized(_outBuffer)
+ needOutBuffer();
+ ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
+ synchronized(out_buffer)
{
try
{
_outNIOBuffer.clear();
- _outBuffer.position(0);
- _outBuffer.limit(_outBuffer.capacity());
+ out_buffer.position(0);
+ out_buffer.limit(out_buffer.capacity());
_result=null;
- _result=_engine.wrap(_gather[0],_outBuffer);
+ _result=_engine.wrap(_gather[0],out_buffer);
if (_debug) __log.debug(_session+" wrap wrap "+_result);
_outNIOBuffer.setGetIndex(0);
_outNIOBuffer.setPutIndex(_result.bytesProduced());
@@ -833,7 +851,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
finally
{
- _outBuffer.position(0);
+ out_buffer.position(0);
if (consumed>0)
{
@@ -844,6 +862,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
_gather[0].limit(_gather[0].capacity());
}
assert consumed==0;
+
+ freeOutBuffer();
}
}
}
@@ -869,14 +889,16 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
@Override
public boolean isBufferingInput()
{
- return _inNIOBuffer.hasContent();
+ final Buffer in = _inNIOBuffer;
+ return in==null?false:_inNIOBuffer.hasContent();
}
/* ------------------------------------------------------------ */
@Override
public boolean isBufferingOutput()
{
- return _outNIOBuffer.hasContent();
+ final NIOBuffer b=_outNIOBuffer;
+ return b==null?false:b.hasContent();
}
/* ------------------------------------------------------------ */
@@ -896,6 +918,9 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
@Override
public String toString()
{
- return super.toString()+","+_engine.getHandshakeStatus()+", in/out="+_inNIOBuffer.length()+"/"+_outNIOBuffer.length()+" "+_result;
+ final NIOBuffer i=_inNIOBuffer;
+ final NIOBuffer o=_outNIOBuffer;
+ return super.toString()+","+_engine.getHandshakeStatus()+", in/out="+
+ (i==null?0:_inNIOBuffer.length())+"/"+(o==null?0:o.length())+" "+_result;
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferCacheTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferCacheTest.java
index 542c9b7ef0..3d7d6e8a79 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferCacheTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferCacheTest.java
@@ -4,61 +4,42 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.io;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
-/* ------------------------------------------------------------------------------- */
/**
- *
- *
+ *
*/
-public class BufferCacheTest extends TestCase
+public class BufferCacheTest
{
- final static String[] S=
- { "S0", "S1", "s2", "s3" };
-
- BufferCache cache;
-
- public BufferCacheTest(String arg0)
- {
- super(arg0);
- }
+ private final static String[] S = {"S0", "S1", "s2", "s3" };
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(BufferCacheTest.class);
- }
+ private BufferCache cache;
- /**
- * @see TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- super.setUp();
cache=new BufferCache();
cache.add(S[1],1);
cache.add(S[2],2);
cache.add(S[3],3);
}
- /**
- * @see TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
+ @Test
public void testLookupIndex()
{
for (int i=0; i<S.length; i++)
@@ -75,6 +56,7 @@ public class BufferCacheTest extends TestCase
}
}
+ @Test
public void testGetBuffer()
{
for (int i=0; i<S.length; i++)
@@ -90,6 +72,7 @@ public class BufferCacheTest extends TestCase
}
}
+ @Test
public void testLookupBuffer()
{
for (int i=0; i<S.length; i++)
@@ -100,35 +83,37 @@ public class BufferCacheTest extends TestCase
assertEquals(S[i],b.toString());
if (i>0)
- assertTrue(""+i,S[i]==b.toString());
+ assertSame(""+i, S[i], b.toString());
else
{
- assertTrue(""+i,S[i]!=b.toString());
- assertEquals(""+i,S[i],b.toString());
+ assertNotSame(""+i, S[i], b.toString());
+ assertEquals(""+i, S[i], b.toString());
}
}
}
+ @Test
public void testLookupPartialBuffer()
{
cache.add("44444",4);
-
+
ByteArrayBuffer buf=new ByteArrayBuffer("44444");
Buffer b=cache.lookup(buf);
assertEquals("44444",b.toString());
assertEquals(4,cache.getOrdinal(b));
-
+
buf=new ByteArrayBuffer("4444");
b=cache.lookup(buf);
assertEquals(-1,cache.getOrdinal(b));
-
+
buf=new ByteArrayBuffer("44444x");
b=cache.lookup(buf);
assertEquals(-1,cache.getOrdinal(b));
-
+
}
+ @Test
public void testInsensitiveLookupBuffer()
{
for (int i=0; i<S.length; i++)
@@ -139,12 +124,13 @@ public class BufferCacheTest extends TestCase
assertTrue("test"+i,S[i].equalsIgnoreCase(b.toString()));
if (i>0)
- assertTrue("test"+i,S[i]==b.toString());
+ assertSame("test"+i, S[i], b.toString());
else
- assertTrue("test"+i,S[i]!=b.toString());
+ assertNotSame("test"+i, S[i], b.toString());
}
}
+ @Test
public void testToString()
{
for (int i=0; i<S.length; i++)
@@ -155,10 +141,9 @@ public class BufferCacheTest extends TestCase
assertEquals(S[i],b);
if (i>0)
- assertTrue(S[i]==b);
+ assertSame(S[i], b);
else
- assertTrue(S[i]!=b);
+ assertNotSame(S[i], b);
}
}
-
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferTest.java
index c335c27a92..fc96d189bb 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferTest.java
@@ -4,49 +4,40 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.io;
import java.io.File;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.RandomAccessFileBuffer;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
- *
*
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
*/
-public class BufferTest extends TestCase
+public class BufferTest
{
- Buffer[] buffer;
-
- public static void main(String[] args)
- {
- }
+ private Buffer[] buffer;
- /*
- * @see TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- super.setUp();
File file = File.createTempFile("test",".buf");
file.deleteOnExit();
- file.createNewFile();
-
+
buffer=new Buffer[]{
new RandomAccessFileBuffer(file,10),
new ByteArrayBuffer(10),
@@ -55,37 +46,25 @@ public class BufferTest extends TestCase
};
}
- /*
- * @see TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- /*
- *
- */
- public void testBuffer()
- throws Exception
+ @Test
+ public void testBuffer() throws Exception
{
for (int i=0;i<buffer.length;i++)
{
String t="t"+i;
Buffer b = buffer[i];
-
+
assertEquals(t,0,b.length());
assertEquals(t,10,b.capacity());
assertEquals(t,10,b.space());
-
+
b.put((byte)0);
b.put((byte)1);
b.put((byte)2);
assertEquals(t,3,b.length());
assertEquals(t,10,b.capacity());
assertEquals(t,7,b.space());
-
+
assertEquals(t,0,b.get());
assertEquals(t,1,b.get());
assertEquals(t,1,b.length());
@@ -93,34 +72,34 @@ public class BufferTest extends TestCase
assertEquals(t,7,b.space());
b.compact();
assertEquals(t,9,b.space());
-
+
byte[] ba = { (byte)-1, (byte)3,(byte)4,(byte)5,(byte)6 };
-
+
b.put(ba,1,3);
assertEquals(t,4,b.length());
assertEquals(t,6,b.space());
-
+
byte[] bg = new byte[4];
b.get(bg,1,2);
assertEquals(t,2,bg[1]);
assertEquals(t,3,bg[2]);
-
+
//test getting 0 bytes returns 0
int count = b.get(bg,0,0);
assertEquals(t,0, count);
-
+
//read up to end
count = b.get(bg,0,2);
assertEquals(t, 2, count);
-
+
//test reading past end returns -1
count = b.get(bg,0,1);
assertEquals(t, -1, count);
}
}
-
- public void testHash()
- throws Exception
+
+ @Test
+ public void testHash() throws Exception
{
Buffer[] b=
{
@@ -129,42 +108,43 @@ public class BufferTest extends TestCase
new DirectNIOBuffer(4096),
};
b[2].put("TeSt1234 ".getBytes(StringUtil.__UTF8));
-
+
for (int i=0;i<b.length;i++)
- assertEquals("t"+i,b[0].hashCode(),b[i].hashCode());
+ assertEquals("t"+i,b[0].hashCode(),b[i].hashCode());
}
-
- public void testGet ()
- throws Exception
+
+ @Test
+ public void testGet () throws Exception
{
Buffer buff = new ByteArrayBuffer(new byte[]{(byte)0,(byte)1,(byte)2,(byte)3,(byte)4,(byte)5});
-
+
byte[] readbuff = new byte[2];
-
+
int count = buff.get(readbuff, 0, 2);
assertEquals(2, count);
assertEquals(readbuff[0], (byte)0);
assertEquals(readbuff[1], (byte)1);
-
+
count = buff.get(readbuff, 0, 2);
assertEquals(2, count);
assertEquals(readbuff[0], (byte)2);
assertEquals(readbuff[1], (byte)3);
-
+
count = buff.get(readbuff, 0, 0);
assertEquals(0, count);
-
+
readbuff[0]=(byte)9;
readbuff[1]=(byte)9;
-
+
count = buff.get(readbuff, 0, 2);
assertEquals(2, count);
-
+
count = buff.get(readbuff, 0, 2);
assertEquals(-1, count);
-
+
}
-
+
+ @Test
public void testInsensitive()
{
Buffer cs0 = new ByteArrayBuffer("Test 1234");
@@ -184,7 +164,7 @@ public class BufferTest extends TestCase
assertTrue( cs0.equals(ci1));
assertTrue( cs0.equals(ci2));
assertTrue(!cs0.equals(ci3));
-
+
assertTrue( cs1.equals(cs0));
assertTrue( cs1.equals(cs1));
assertTrue(!cs1.equals(cs2));
@@ -193,7 +173,7 @@ public class BufferTest extends TestCase
assertTrue( cs1.equals(ci1));
assertTrue( cs1.equals(ci2));
assertTrue(!cs1.equals(ci3));
-
+
assertTrue(!cs2.equals(cs0));
assertTrue(!cs2.equals(cs1));
assertTrue( cs2.equals(cs2));
@@ -211,8 +191,8 @@ public class BufferTest extends TestCase
assertTrue(!cs3.equals(ci1));
assertTrue(!cs3.equals(ci2));
assertTrue( cs3.equals(ci3));
-
-
+
+
assertTrue( ci0.equals(cs0));
assertTrue( ci0.equals(cs1));
assertTrue( ci0.equals(cs2));
@@ -221,7 +201,7 @@ public class BufferTest extends TestCase
assertTrue( ci0.equals(ci1));
assertTrue( ci0.equals(ci2));
assertTrue(!ci0.equals(ci3));
-
+
assertTrue( ci1.equals(cs0));
assertTrue( ci1.equals(cs1));
assertTrue( ci1.equals(cs2));
@@ -230,7 +210,7 @@ public class BufferTest extends TestCase
assertTrue( ci1.equals(ci1));
assertTrue( ci1.equals(ci2));
assertTrue(!ci1.equals(ci3));
-
+
assertTrue( ci2.equals(cs0));
assertTrue( ci2.equals(cs1));
assertTrue( ci2.equals(cs2));
@@ -251,6 +231,7 @@ public class BufferTest extends TestCase
}
+ @Test
public void testView()
{
Buffer b = new ByteArrayBuffer(" Test 1234 ".getBytes());
@@ -259,7 +240,7 @@ public class BufferTest extends TestCase
View v0 = new View(b);
View v1 = new View(b);
View v2 = new View(v0);
-
+
String s=b.toString();
String s0=v0.toString();
String s1=v1.toString();
@@ -267,15 +248,13 @@ public class BufferTest extends TestCase
String s3=v0.toString();
String s4=v1.toString();
String s5=v2.toString();
-
+
assertEquals(s, s0);
assertEquals(s0, s1);
assertEquals(s1, s2);
assertEquals(s2, s3);
assertEquals(s3, s4);
assertEquals(s4, s5);
-
- }
-
+ }
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferUtilTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferUtilTest.java
index 1db375bee5..ce053e789e 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/BufferUtilTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/BufferUtilTest.java
@@ -4,43 +4,29 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.io;
-import junit.framework.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
-/* ------------------------------------------------------------------------------- */
/**
- *
+ *
*/
-public class BufferUtilTest extends TestCase
+public class BufferUtilTest
{
-
- /**
- * Constructor for BufferUtilTest.
- * @param arg0
- */
- public BufferUtilTest(String arg0)
- {
- super(arg0);
- }
-
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(BufferUtilTest.class);
- }
-
- public void testToInt()
- throws Exception
+ @Test
+ public void testToInt() throws Exception
{
- Buffer buf[] =
+ Buffer buf[] =
{
new ByteArrayBuffer("0"),
new ByteArrayBuffer(" 42 "),
@@ -50,29 +36,29 @@ public class BufferUtilTest extends TestCase
new ByteArrayBuffer("-2147483648"),
new ByteArrayBuffer("2147483647"),
};
-
+
int val[] =
{
0,42,43,-44,-45,-2147483648,2147483647
};
-
+
for (int i=0;i<buf.length;i++)
assertEquals("t"+i, val[i], BufferUtil.toInt(buf[i]));
}
- public void testPutInt()
- throws Exception
+ @Test
+ public void testPutInt() throws Exception
{
int val[] =
{
- 0,42,43,-44,-45,-2147483648,2147483647
+ 0,42,43,-44,-45,Integer.MIN_VALUE,Integer.MAX_VALUE
};
-
+
String str[] =
{
- "0","42","43","-44","-45","-2147483648","2147483647"
+ "0","42","43","-44","-45",""+Integer.MIN_VALUE,""+Integer.MAX_VALUE
};
-
+
Buffer buffer = new ByteArrayBuffer(12);
for (int i=0;i<val.length;i++)
@@ -80,22 +66,45 @@ public class BufferUtilTest extends TestCase
buffer.clear();
BufferUtil.putDecInt(buffer,val[i]);
assertEquals("t"+i,str[i],BufferUtil.to8859_1_String(buffer));
- }
+ }
+ }
+
+ @Test
+ public void testPutLong() throws Exception
+ {
+ long val[] =
+ {
+ 0L,42L,43L,-44L,-45L,Long.MIN_VALUE,Long.MAX_VALUE
+ };
+
+ String str[] =
+ {
+ "0","42","43","-44","-45",""+Long.MIN_VALUE,""+Long.MAX_VALUE
+ };
+
+ Buffer buffer = new ByteArrayBuffer(50);
+
+ for (int i=0;i<val.length;i++)
+ {
+ buffer.clear();
+ BufferUtil.putDecLong(buffer,val[i]);
+ assertEquals("t"+i,str[i],BufferUtil.to8859_1_String(buffer));
+ }
}
- public void testPutHexInt()
- throws Exception
+ @Test
+ public void testPutHexInt() throws Exception
{
int val[] =
{
0,42,43,-44,-45,-2147483648,2147483647
};
-
+
String str[] =
{
"0","2A","2B","-2C","-2D","-80000000","7FFFFFFF"
};
-
+
Buffer buffer = new ByteArrayBuffer(12);
for (int i=0;i<val.length;i++)
@@ -103,6 +112,6 @@ public class BufferUtilTest extends TestCase
buffer.clear();
BufferUtil.putHexInt(buffer,val[i]);
assertEquals("t"+i,str[i],BufferUtil.to8859_1_String(buffer));
- }
+ }
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java
new file mode 100644
index 0000000000..c0a7d1a9dd
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java
@@ -0,0 +1,75 @@
+package org.eclipse.jetty.io;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.rmi.server.ServerCloneException;
+import java.util.concurrent.Exchanger;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ServerSocketFactory;
+
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EndPointTest
+{
+ @Test
+ public void testSocketEndPoints() throws Exception
+ {
+ final ServerSocket server = new ServerSocket();
+ server.bind(null);
+
+ final Exchanger<Socket> accepted = new Exchanger<Socket>();
+ new Thread(){
+ public void run()
+ {
+ try
+ {
+ accepted.exchange(server.accept());
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+
+ Socket s0 = new Socket(server.getInetAddress(),server.getLocalPort());
+ Socket s1 = accepted.exchange(null,5,TimeUnit.SECONDS);
+
+ SocketEndPoint in = new SocketEndPoint(s0);
+ SocketEndPoint out = new SocketEndPoint(s1);
+
+ check(in,out);
+ }
+
+
+ private void check(EndPoint in, EndPoint out) throws Exception
+ {
+ String data="Now is the time for all good men to come to the aid of the party";
+ Buffer send = new ByteArrayBuffer(data);
+ Buffer receive = new IndirectNIOBuffer(4096);
+
+ int lo=out.flush(send);
+ int li=in.fill(receive);
+
+ Assert.assertEquals(data.length(),lo);
+ Assert.assertEquals(data.length(),li);
+ Assert.assertEquals(data,receive.toString());
+
+ in.close();
+ out.close();
+ }
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
index 3d72037d2a..6b22b7d5d2 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.io;
@@ -16,38 +16,17 @@ package org.eclipse.jetty.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import junit.framework.TestSuite;
-
import org.eclipse.jetty.util.IO;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
-/* ------------------------------------------------------------ */
-/** Util meta Tests.
- *
+/**
+ *
*/
-public class IOTest extends junit.framework.TestCase
+public class IOTest
{
- public IOTest(String name)
- {
- super(name);
- }
-
- public static junit.framework.Test suite() {
- TestSuite suite = new TestSuite(IOTest.class);
- return suite;
- }
-
- /* ------------------------------------------------------------ */
- /** main.
- */
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
-
-
- /* ------------------------------------------------------------ */
+ @Test
public void testIO() throws InterruptedException
{
// Only a little test
@@ -64,15 +43,13 @@ public class IOTest extends junit.framework.TestCase
"The quick brown fox jumped over the lazy dog");
}
-
-
- /* ------------------------------------------------------------ */
+ @Test
public void testStringSpeed()
{
String s="012345678901234567890000000000000000000000000";
char[] ca = new char[s.length()];
int loops=1000000;
-
+
long start=System.currentTimeMillis();
long result=0;
for (int loop=0;loop<loops;loop++)
@@ -82,7 +59,7 @@ public class IOTest extends junit.framework.TestCase
}
long end=System.currentTimeMillis();
System.err.println("charAt "+(end-start)+" "+result);
-
+
start=System.currentTimeMillis();
result=0;
for (int loop=0;loop<loops;loop++)
@@ -93,6 +70,5 @@ public class IOTest extends junit.framework.TestCase
}
end=System.currentTimeMillis();
System.err.println("getChars "+(end-start)+" "+result);
-
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ThreadLocalBuffersTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ThreadLocalBuffersTest.java
index 86b99325ab..fcf773b583 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ThreadLocalBuffersTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ThreadLocalBuffersTest.java
@@ -4,56 +4,34 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.io;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
-import junit.framework.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
public class ThreadLocalBuffersTest
- extends TestCase
{
public boolean _stress = Boolean.getBoolean("STRESS");
- private int _headerBufferSize = 6 * 1024;
-
- InnerBuffers httpBuffers;
-
- List<Thread> threadList = new ArrayList<Thread>();
-
- int numThreads = _stress?100:10;
-
- int runTestLength = _stress?5000:1000;
-
- boolean runTest = false;
-
- AtomicLong buffersRetrieved;
-
- @Override
- protected void setUp()
- throws Exception
- {
- super.setUp();
- }
-
- @Override
- protected void tearDown()
- throws Exception
- {
- super.tearDown();
- }
-
- public void execAbstractBuffer()
- throws Exception
+ private InnerBuffers httpBuffers;
+ private List<Thread> threadList = new ArrayList<Thread>();
+ private int numThreads = _stress?100:10;
+ private int runTestLength = _stress?5000:1000;
+ private boolean runTest = false;
+ private AtomicLong buffersRetrieved;
+
+ private void execAbstractBuffer() throws Exception
{
threadList.clear();
buffersRetrieved = new AtomicLong( 0 );
@@ -94,54 +72,50 @@ public class ThreadLocalBuffersTest
System.out.println( "Buffers Retrieved: " + totalBuffersRetrieved );
System.out.println( "Memory Used: " + ( mem1 - mem0 ) );
- for ( Iterator<Thread> i = threadList.iterator(); i.hasNext(); )
- {
- Thread t = i.next();
+ for (Thread t : threadList)
t.stop();
- }
}
- public void testAbstractBuffers()
- throws Exception
+ @Test
+ public void testAbstractBuffers() throws Exception
{
execAbstractBuffer( );
}
- public void testDifferentSizes()
- throws Exception
+ @Test
+ public void testDifferentSizes() throws Exception
{
InnerBuffers buffers = new InnerBuffers();
buffers.setHeaderSize(128);
buffers.setBufferSize(256);
-
+
Buffer h1 = buffers.getHeader();
Buffer h2 = buffers.getHeader();
Buffer b1 = buffers.getBuffer();
Buffer b2 = buffers.getBuffer();
Buffer b3 = buffers.getBuffer(512);
-
+
buffers.returnBuffer(h1);
buffers.returnBuffer(h2);
buffers.returnBuffer(b1);
buffers.returnBuffer(b2);
buffers.returnBuffer(b3);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
assertTrue(h2!=buffers.getHeader()); // b2 replaced h2 in other slot
assertTrue(b1==buffers.getBuffer()); // pooled buffer
assertTrue(b2!=buffers.getBuffer()); // b3 replaced b2 in other slot
assertTrue(b3==buffers.getBuffer(512)); // b2 from other slot
-
+
buffers.returnBuffer(h1);
buffers.returnBuffer(h2);
buffers.returnBuffer(b1);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
assertTrue(h2==buffers.getHeader()); // h2 in other slot
assertTrue(b1==buffers.getBuffer()); // pooled buffer
assertTrue(b2!=buffers.getBuffer()); // new buffer
assertTrue(b3!=buffers.getBuffer(512)); // new buffer
-
// check that sizes are respected
buffers.returnBuffer(b3);
@@ -149,22 +123,21 @@ public class ThreadLocalBuffersTest
buffers.returnBuffer(b2);
buffers.returnBuffer(h1);
buffers.returnBuffer(h2);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
assertTrue(h2==buffers.getHeader()); // h2 in other slot
assertTrue(b1==buffers.getBuffer()); // pooled buffer
assertTrue(b2!=buffers.getBuffer()); // new buffer
assertTrue(b3!=buffers.getBuffer(512)); // new buffer
}
-
- public void testSameSizes()
- throws Exception
+
+ @Test
+ public void testSameSizes() throws Exception
{
- Buffer buffer=null;
InnerBuffers buffers = new InnerBuffers();
buffers.setHeaderSize(128);
buffers.setBufferSize(128);
-
+
Buffer h1 = buffers.getHeader();
Buffer h2 = buffers.getHeader();
Buffer b1 = buffers.getBuffer();
@@ -176,26 +149,25 @@ public class ThreadLocalBuffersTest
known.add(b1);
known.add(b2);
known.add(h1);
-
+
buffers.returnBuffer(h1);
buffers.returnBuffer(h2);
buffers.returnBuffer(b1);
buffers.returnBuffer(b2);
buffers.returnBuffer(b3);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
- buffer=buffers.getHeader();
+ Buffer buffer = buffers.getHeader();
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
assertTrue(h2==buffers.getBuffer()); // h2 used from buffer slot
assertTrue(b3==buffers.getBuffer()); // b1 from other slot
buffer=buffers.getBuffer(128);
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
-
buffers.returnBuffer(h1);
buffers.returnBuffer(h2);
buffers.returnBuffer(b1);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
buffer=buffers.getHeader();
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
@@ -205,7 +177,7 @@ public class ThreadLocalBuffersTest
buffers.returnBuffer(h1);
buffers.returnBuffer(b1);
buffers.returnBuffer(h2);
-
+
assertTrue(h1==buffers.getHeader()); // pooled header
assertTrue(h2==buffers.getHeader()); // h2 from other slot
buffer=buffers.getHeader();
@@ -213,19 +185,17 @@ public class ThreadLocalBuffersTest
assertTrue(b1==buffers.getBuffer()); // b1 used from buffer slot
buffer=buffers.getBuffer();
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
-
-
}
- static class HeaderBuffer extends ByteArrayBuffer
+ private static class HeaderBuffer extends ByteArrayBuffer
{
public HeaderBuffer(int size)
{
super(size);
}
}
-
- static class InnerBuffers extends ThreadLocalBuffers
+
+ private static class InnerBuffers extends ThreadLocalBuffers
{
@Override
protected Buffer newBuffer(int size)
@@ -244,21 +214,13 @@ public class ThreadLocalBuffersTest
}
}
-
- /**
- * generic buffer peeper
- *
- *
- */
- class BufferPeeper
- extends Thread
+ private class BufferPeeper extends Thread
{
- private String _bufferName;
+ private final String _bufferName;
public BufferPeeper( String bufferName )
{
_bufferName = bufferName;
-
start();
}
@@ -269,15 +231,12 @@ public class ThreadLocalBuffersTest
{
try
{
-
if ( runTest )
{
Buffer buf = httpBuffers.getHeader();
-
buffersRetrieved.getAndIncrement();
-
- buf.put( new Byte( "2" ).byteValue() );
+ buf.put(new Byte("2"));
// sleep( threadWaitTime );
@@ -296,5 +255,4 @@ public class ThreadLocalBuffersTest
}
}
}
-
}
diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml
index 8b13df9370..563ee66196 100644
--- a/jetty-jaspi/pom.xml
+++ b/jetty-jaspi/pom.xml
@@ -38,10 +38,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.jaspi.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java
index e640e376ac..70764bd872 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java
@@ -115,12 +115,15 @@ public class JaspiAuthenticator implements Authenticator
{
Set<UserIdentity> ids = clientSubject.getPrivateCredentials(UserIdentity.class);
UserIdentity userIdentity;
- if (ids.size() > 0) {
+ if (ids.size() > 0)
+ {
userIdentity = ids.iterator().next();
-// return new FormAuthenticator.FormAuthentication(this,ids.iterator().next());
} else {
CallerPrincipalCallback principalCallback = _callbackHandler.getThreadCallerPrincipalCallback();
- if (principalCallback == null) throw new NullPointerException("No CallerPrincipalCallback");
+ if (principalCallback == null)
+ {
+ return Authentication.UNAUTHENTICATED;
+ }
Principal principal = principalCallback.getPrincipal();
if (principal == null) {
String principalName = principalCallback.getName();
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java
index 15caef790f..d11a8d9bc8 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java
@@ -37,7 +37,6 @@ import org.eclipse.jetty.server.UserIdentity;
*
* Idiot class required by jaspi stupidity
*
- * @#*($)#@&^)$@#&*$@
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
*/
public class ServletCallbackHandler implements CallbackHandler
diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml
index 818fc1a077..f10980de95 100644
--- a/jetty-jmx/pom.xml
+++ b/jetty-jmx/pom.xml
@@ -23,6 +23,11 @@
<goals>
<goal>manifest</goal>
</goals>
+ <configuration>
+ <instructions>
+ <Import-Package>javax.management.*,*</Import-Package>
+ </instructions>
+ </configuration>
</execution>
</executions>
</plugin>
@@ -33,7 +38,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
@@ -55,11 +60,12 @@
</execution>
</executions>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.jmx.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -67,6 +73,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml
index 4df07109f3..bdce9d4298 100644
--- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml
+++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml
@@ -1,12 +1,12 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-<!-- =============================================================== -->
-<!-- Configure the JVM JMX Server -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -DOPTIONS=jmx -jar start.jar etc/jetty-jmx.xml etc/jetty.xml -->
-<!-- =============================================================== -->
+<!-- ============================================================================ -->
+<!-- To correctly start Jetty with JMX module enabled, this configuration -->
+<!-- file must appear first in the list of the configuration files. -->
+<!-- The simplest way to achieve this is to add etc/jetty-jmx.xml as the -->
+<!-- first file in configuration file list at the end of start.ini file. -->
+<!-- ============================================================================ -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
@@ -50,8 +50,37 @@
</Arg>
</Call>
</Ref>
+
+ <!-- In order to connect to the JMX server remotely from a different
+ process, possibly running on a different host, Jetty JMX module
+ can create a remote JMX connector. It requires RMI registry to
+ be started prior to creating the connector server because the
+ JMX specification uses RMI to facilitate connections.
+ -->
- <!-- optionally add a remote JMX connector
+ <!-- Optionally start the RMI registry. Normally RMI registry runs on
+ port 1099. The argument below can be changed in order to comply
+ with the firewall requirements.
+ -->
+ <!--
+ <Call name="createRegistry" class="java.rmi.registry.LocateRegistry">
+ <Arg type="java.lang.Integer">1099</Arg>
+ <Call name="sleep" class="java.lang.Thread">
+ <Arg type="java.lang.Integer">1000</Arg>
+ </Call>
+ </Call>
+ -->
+
+ <!-- Optionally add a remote JMX connector. The parameters of the constructor
+ below specify the JMX service URL, and the object name string for the
+ connector server bean. The parameters of the JMXServiceURL constructor
+ specify the protocol that clients will use to connect to the remote JMX
+ connector (RMI), the hostname of the server (local hostname), port number
+ (automatically assigned), and the URL path. Note that URL path contains
+ the RMI registry hostname and port number, that may need to be modified
+ in order to comply with the firewall requirements.
+ -->
+ <!--
<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
@@ -65,6 +94,5 @@
<Call name="start" />
</New>
-->
-
</Configure>
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index cbf35f6dfb..8311374d56 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.jmx;
@@ -20,13 +20,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
-
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import org.eclipse.jetty.util.MultiMap;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.Container;
import org.eclipse.jetty.util.component.Container.Relationship;
@@ -36,7 +34,7 @@ import org.eclipse.jetty.util.thread.ShutdownThread;
/* ------------------------------------------------------------ */
/**
- * Container class for the MBean instances
+ * Container class for the MBean instances
*/
public class MBeanContainer extends AbstractLifeCycle implements Container.Listener
{
@@ -49,21 +47,21 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
/* ------------------------------------------------------------ */
/**
* Lookup an object name by instance
- *
+ *
* @param object instance for which object name is looked up
* @return object name associated with specified instance, or null if not found
*/
public synchronized ObjectName findMBean(Object object)
{
ObjectName bean = (ObjectName)_beans.get(object);
- return bean==null?null:bean;
+ return bean==null?null:bean;
}
/* ------------------------------------------------------------ */
/**
* Lookup an instance by object name
- *
- * @param oname object name of instance
+ *
+ * @param oname object name of instance
* @return instance associated with specified object name, or null if not found
*/
public synchronized Object findBean(ObjectName oname)
@@ -80,7 +78,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
/* ------------------------------------------------------------ */
/**
* Constructs MBeanContainer
- *
+ *
* @param server instance of MBeanServer for use by container
*/
public MBeanContainer(MBeanServer server)
@@ -96,62 +94,62 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
Log.ignore(e);
}
}
-
+
/* ------------------------------------------------------------ */
/**
* Retrieve instance of MBeanServer used by container
- *
+ *
* @return instance of MBeanServer
*/
public MBeanServer getMBeanServer()
{
return _server;
}
-
+
/* ------------------------------------------------------------ */
/**
* Set domain to be used to add MBeans
- *
+ *
* @param domain domain name
*/
public void setDomain (String domain)
{
_domain = domain;
}
-
+
/* ------------------------------------------------------------ */
/**
* Retrieve domain name used to add MBeans
- *
+ *
* @return domain name
*/
public String getDomain()
{
return _domain;
}
-
+
/* ------------------------------------------------------------ */
/**
* Implementation of Container.Listener interface
- *
+ *
* @see org.eclipse.jetty.util.component.Container.Listener#add(org.eclipse.jetty.util.component.Container.Relationship)
*/
public synchronized void add(Relationship relationship)
- {
+ {
ObjectName parent=(ObjectName)_beans.get(relationship.getParent());
if (parent==null)
{
addBean(relationship.getParent());
parent=(ObjectName)_beans.get(relationship.getParent());
}
-
+
ObjectName child=(ObjectName)_beans.get(relationship.getChild());
if (child==null)
{
addBean(relationship.getChild());
child=(ObjectName)_beans.get(relationship.getChild());
}
-
+
if (parent!=null && child!=null)
_relations.add(parent,relationship);
}
@@ -159,7 +157,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
/* ------------------------------------------------------------ */
/**
* Implementation of Container.Listener interface
- *
+ *
* @see org.eclipse.jetty.util.component.Container.Listener#remove(org.eclipse.jetty.util.component.Container.Relationship)
*/
public synchronized void remove(Relationship relationship)
@@ -173,7 +171,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
/* ------------------------------------------------------------ */
/**
* Implementation of Container.Listener interface
- *
+ *
* @see org.eclipse.jetty.util.component.Container.Listener#removeBean(java.lang.Object)
*/
public synchronized void removeBean(Object obj)
@@ -192,7 +190,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
relation.getContainer().update(relation.getParent(),relation.getChild(),null,relation.getRelationship(),true);
}
}
-
+
try
{
_server.unregisterMBean(bean);
@@ -208,11 +206,11 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
}
}
}
-
+
/* ------------------------------------------------------------ */
/**
* Implementation of Container.Listener interface
- *
+ *
* @see org.eclipse.jetty.util.component.Container.Listener#addBean(java.lang.Object)
*/
public synchronized void addBean(Object obj)
@@ -221,7 +219,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
{
if (obj == null || _beans.containsKey(obj))
return;
-
+
Object mbean = ObjectMBean.mbeanFor(obj);
if (mbean == null)
return;
@@ -232,7 +230,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
((ObjectMBean) mbean).setMBeanContainer(this);
oname = ((ObjectMBean)mbean).getObjectName();
}
-
+
//no override mbean object name, so make a generic one
if (oname == null)
{
@@ -240,7 +238,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
int dot = type.lastIndexOf('.');
if (dot >= 0)
type = type.substring(dot + 1);
-
+
String name=null;
if (mbean instanceof ObjectMBean)
{
@@ -261,11 +259,11 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
name=name.replace(':','_').replace('*','_').replace('?','_').replace('=','_').replace(',','_').replace(' ','_');
}
}
-
+
String basis=(name!=null&&name.length()>1)?("type="+type+",name="+name):("type="+type);
-
+
Integer count = (Integer) _unique.get(basis);
- count = TypeUtil.newInteger(count == null ? 0 : (1 + count.intValue()));
+ count = count == null ? 0 : 1 + count;
_unique.put(basis, count);
//if no explicit domain, create one
@@ -275,7 +273,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
oname = ObjectName.getInstance(domain+":"+basis+",id="+count);
}
-
+
ObjectInstance oinstance = _server.registerMBean(mbean, oname);
Log.debug("Registered {}" , oinstance.getObjectName());
_beans.put(obj, oinstance.getObjectName());
@@ -286,7 +284,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
Log.warn("bean: "+obj,e);
}
}
-
+
/* ------------------------------------------------------------ */
/**
* Perform actions needed to start lifecycle
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
index 6cba39de59..7ab8ebde5d 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
@@ -337,7 +337,7 @@ public class ObjectMBean implements DynamicMBean
catch (InvocationTargetException e)
{
Log.warn(Log.EXCEPTION, e);
- throw new ReflectionException((Exception) e.getTargetException());
+ throw new ReflectionException(new Exception(e.getCause()));
}
}
@@ -405,7 +405,7 @@ public class ObjectMBean implements DynamicMBean
catch (InvocationTargetException e)
{
Log.warn(Log.EXCEPTION, e);
- throw new ReflectionException((Exception) e.getTargetException());
+ throw new ReflectionException(new Exception(e.getCause()));
}
}
@@ -470,7 +470,7 @@ public class ObjectMBean implements DynamicMBean
catch (InvocationTargetException e)
{
Log.warn(Log.EXCEPTION, e);
- throw new ReflectionException((Exception) e.getTargetException());
+ throw new ReflectionException(new Exception(e.getCause()));
}
finally
{
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties
index e2d97a4860..fd7667217d 100644
--- a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties
+++ b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties
@@ -16,5 +16,4 @@ confidentialPort: Port to use for confidential redirections.
confidentialScheme: Scheme to use for confidential redirections.
integralPort: Port to use for integral redirections.
integralScheme: Scheme to use for integral redirections.
-lowResourcesConnections: The number of connections, which if exceeded represents low resources
lowResourcesMaxIdleTime: The period in ms that a connection may be idle when the connector has low resources, before it is closed.
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties
index 096a4b4aad..dbe718d5b0 100644
--- a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties
+++ b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties
@@ -1 +1,2 @@
SelectChannelConnector: HTTP connector using NIO ByteChannels and Selectors
+lowResourcesConnections: The number of connections, which if exceeded represents low resources
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties
index 2bc03eb42a..385f28a420 100644
--- a/jetty-jmx/src/main/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties
+++ b/jetty-jmx/src/main/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties
@@ -9,15 +9,10 @@ sessionCookie: The set session cookie
sessionDomain: The domain of the session cookie or null for the default
sessionPath: The path of the session cookie or null for the default
sessionsTotal: The total number of sessions
-sessionsMax: The maximum number of simultaneous sessions
-sessionTimeMax: The maximum session lifetime in seconds
-sessionTimeMean: The mean session lifetime in seconds
-sessionTimeStdDev: The standard deviation of session lifetime in seconds
sessionIdPathParameterName: The name to use for URL session tracking
statsReset(): Reset statistics
sessions: Current instantaneous number of sessions
sessionsMax: Maximum number of simultaneous sessions since statsReset() was called
-sessionsMin: Minimum number of simultaneous sessions since statsReset() was called
sessionTimeMax: Maximum amount of time in seconds session remained valid since statsReset() was called
sessionTimeTotal: Total amount of time in seconds sessions remained valid since statsReset() was called
sessionTimeMean: Mean amount of time in seconds a session remained valid since statsReset() was called
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties
new file mode 100644
index 0000000000..6a1f31aa49
--- /dev/null
+++ b/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties
@@ -0,0 +1,12 @@
+DoSFilter: Limit exposure to abuse from request flooding, whether malicious, or as a result of a misconfigured client.
+maxRequestsPerSec: maximum number of requests from a connection per second. Requests in excess of this are first delayed, then throttled.
+delayMs: delay (in milliseconds) that is applied to all requests over the rate limit, before they are considered at all, 0 - no delay, -1 - reject request.
+maxWaitMs: maximum amount of time (in milliseconds) the filter will blocking wait for the throttle semaphore.
+throttledRequests: number of requests over the rate limit able to be considered at once.
+throttleMs: amount of time (in milliseconds) to async wait for semaphore.
+maxRequestMs: maximum amount of time (in milliseconds) to allow the request to process.
+maxIdleTrackerMs: maximum amount of time (in milliseconds) to keep track of request rates for a connection, before deciding that the user has gone away, and discarding it.
+insertHeaders: insert the DoSFilter headers into the response.
+trackSessions: usage rate is tracked by session if a session exists.
+remotePort: usage rate is tracked by IP+port (effectively connection) if session tracking is not used.
+ipWhitelist: list of IP addresses that will not be rate limited. \ No newline at end of file
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties
new file mode 100644
index 0000000000..c781d638aa
--- /dev/null
+++ b/jetty-jmx/src/main/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties
@@ -0,0 +1,4 @@
+QoSFilter: Quality of Service Filter.
+maxRequests: maximum number of requests allowed to be processedat the same time.
+waitMs: (short) amount of time (in milliseconds) that the filter would wait for the semaphore to become available before suspending a request.
+suspendMs: amount of time (in milliseconds) that the filter would suspend a request for while waiting for the semaphore to become available.
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
index 28b52a60e8..132ff3b06a 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
@@ -4,51 +4,32 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.jmx;
-
-import junit.framework.TestCase;
-
+import com.acme.Derived;
import org.eclipse.jetty.server.Server;
+import org.junit.Test;
-import com.acme.Derived;
+import static org.junit.Assert.assertTrue;
-public class ObjectMBeanTest extends TestCase
+public class ObjectMBeanTest
{
- public ObjectMBeanTest(String arg0)
- {
- super(arg0);
- }
-
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(ObjectMBeanTest.class);
- }
-
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
+ @Test
public void testMbeanInfo()
{
Derived derived = new Derived();
ObjectMBean mbean = new ObjectMBean(derived);
assertTrue(mbean.getMBeanInfo()!=null); // TODO do more than just run it
}
-
+
+ @Test
public void testMbeanFor()
{
Derived derived = new Derived();
diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml
index fccb29330e..b7b8ad561a 100644
--- a/jetty-jndi/pom.xml
+++ b/jetty-jndi/pom.xml
@@ -23,6 +23,11 @@
<goals>
<goal>manifest</goal>
</goals>
+ <configuration>
+ <instructions>
+ <Import-Package>javax.naming.*,*</Import-Package>
+ </instructions>
+ </configuration>
</execution>
</executions>
</plugin>
@@ -33,16 +38,17 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.jndi.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -50,6 +56,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -61,7 +68,7 @@
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
- <version>${mail-version}</version>
+ <version>${javax-mail-version}</version>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
@@ -80,9 +87,9 @@
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
- <version>${activation-version}</version>
- </dependency>
+ <version>${javax-activation-version}</version>
+ </dependency>
</dependencies>
</profile>
- </profiles>
+ </profiles>
</project>
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java
index ca00153e1b..75e626a72c 100644
--- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java
+++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java
@@ -151,7 +151,7 @@ public class ContextFactory implements ObjectFactory
* Keep trying ancestors of the given classloader to find one to which
* the context is bound.
* @param loader
- * @return
+ * @return the context from the parent class loader
*/
public Context getParentClassLoaderContext (ClassLoader loader)
{
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java
index df635a6eab..0f2cf7bb18 100644
--- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java
+++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java
@@ -41,11 +41,11 @@ public class NamingUtil
/* ------------------------------------------------------------ */
/**
- * Bind an object to a context ensuring all subcontexts
+ * Bind an object to a context ensuring all sub-contexts
* are created if necessary
*
* @param ctx the context into which to bind
- * @param name the name relative to context to bind
+ * @param nameStr the name relative to context to bind
* @param obj the object to be bound
* @exception NamingException if an error occurs
*/
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
index 80e95d677b..e6ff384f54 100644
--- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
+++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
@@ -111,7 +111,7 @@ public class MailSessionReference extends Reference implements ObjectFactory
* @param arg1 not used
* @param arg2 not used
* @param arg3 not used
- * @return
+ * @return the object found
* @throws Exception
*/
public Object getObjectInstance(Object ref, Name arg1, Context arg2, Hashtable arg3) throws Exception
diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java
index 6933005225..f76fb42aa5 100644
--- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java
+++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java
@@ -4,17 +4,16 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.jndi.factories;
import java.util.Properties;
-
import javax.mail.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
@@ -22,19 +21,20 @@ import javax.naming.LinkRef;
import javax.naming.Name;
import javax.naming.NameParser;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.jndi.NamingUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
/**
- * TestMailSessionReference
- *
*
*/
-public class TestMailSessionReference extends TestCase
+public class TestMailSessionReference
{
- public void testMailSessionReference ()
- throws Exception
+ @Test
+ public void testMailSessionReference () throws Exception
{
InitialContext icontext = new InitialContext();
MailSessionReference sref = new MailSessionReference();
@@ -52,20 +52,20 @@ public class TestMailSessionReference extends TestCase
Properties sessionProps = session.getProperties();
assertEquals(props, sessionProps);
assertTrue (session.getDebug());
-
+
Context foo = icontext.createSubcontext("foo");
NameParser parser = icontext.getNameParser("");
Name objectNameInNamespace = parser.parse(icontext.getNameInNamespace());
objectNameInNamespace.addAll(parser.parse("mail/Session"));
-
+
NamingUtil.bind(foo, "mail/Session", new LinkRef(objectNameInNamespace.toString()));
-
+
Object o = foo.lookup("mail/Session");
assertNotNull(o);
Session fooSession = (Session)o;
assertEquals(props, fooSession.getProperties());
assertTrue(fooSession.getDebug());
-
+
icontext.destroySubcontext("mail");
icontext.destroySubcontext("foo");
}
diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
index 614a0ac3f4..c4bc048078 100644
--- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
+++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
@@ -4,21 +4,19 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.jndi.java;
-
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Hashtable;
-
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.LinkRef;
@@ -32,57 +30,31 @@ import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
import org.eclipse.jetty.jndi.NamingContext;
import org.eclipse.jetty.util.log.Log;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-
-public class TestJNDI extends TestCase
+/**
+ *
+ */
+public class TestJNDI
{
-
-
public static class MyObjectFactory implements ObjectFactory
{
public static String myString = "xxx";
- public Object getObjectInstance(Object obj,
- Name name,
- Context nameCtx,
- Hashtable environment)
- throws Exception
- {
- return myString;
- }
- }
-
- public TestJNDI (String name)
- {
- super (name);
- }
-
-
- public static Test suite ()
- {
- return new TestSuite (TestJNDI.class);
- }
-
- public void setUp ()
- throws Exception
- {
- }
-
-
- public void tearDown ()
- throws Exception
- {
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception
+ {
+ return myString;
+ }
}
- public void testIt ()
- throws Exception
+ @Test
+ public void testIt() throws Exception
{
try
{
@@ -99,9 +71,6 @@ public class TestJNDI extends TestCase
initCtxA.bind ("blah", "123");
assertEquals ("123", initCtxA.lookup("blah"));
-
-
-
InitialContext initCtx = new InitialContext();
Context sub0 = (Context)initCtx.lookup("java:");
@@ -109,7 +78,6 @@ public class TestJNDI extends TestCase
Name n = sub0.getNameParser("").parse("/red/green/");
-
if(Log.isDebugEnabled())Log.debug("get(0)="+n.get(0));
if(Log.isDebugEnabled())Log.debug("getPrefix(1)="+n.getPrefix(1));
n = n.getSuffix(1);
@@ -166,42 +134,35 @@ public class TestJNDI extends TestCase
//expected exception
}
-
-
//check bindings at comp
Context sub1 = (Context)initCtx.lookup("java:comp");
Context sub2 = sub1.createSubcontext ("env");
initCtx.bind ("java:comp/env/rubbish", "abc");
- assertEquals ("abc", (String)initCtx.lookup("java:comp/env/rubbish"));
-
-
+ assertEquals ("abc", initCtx.lookup("java:comp/env/rubbish"));
//check binding LinkRefs
LinkRef link = new LinkRef ("java:comp/env/rubbish");
initCtx.bind ("java:comp/env/poubelle", link);
- assertEquals ("abc", (String)initCtx.lookup("java:comp/env/poubelle"));
+ assertEquals ("abc", initCtx.lookup("java:comp/env/poubelle"));
//check binding References
StringRefAddr addr = new StringRefAddr("blah", "myReferenceable");
Reference ref = new Reference (java.lang.String.class.getName(),
addr,
MyObjectFactory.class.getName(),
- (String)null);
+ null);
initCtx.bind ("java:comp/env/quatsch", ref);
- assertEquals (MyObjectFactory.myString, (String)initCtx.lookup("java:comp/env/quatsch"));
+ assertEquals (MyObjectFactory.myString, initCtx.lookup("java:comp/env/quatsch"));
//test binding something at java:
Context sub3 = initCtx.createSubcontext("java:zero");
initCtx.bind ("java:zero/one", "ONE");
assertEquals ("ONE", initCtx.lookup("java:zero/one"));
-
-
-
- //change the current thread's classloader to check distinct naming
+ //change the current thread's classloader to check distinct naming
currentThread.setContextClassLoader(childLoader2);
Context otherSub1 = (Context)initCtx.lookup("java:comp");
@@ -215,7 +176,6 @@ public class TestJNDI extends TestCase
//expected
}
-
//put the thread's classloader back
currentThread.setContextClassLoader(childLoader1);
@@ -227,11 +187,11 @@ public class TestJNDI extends TestCase
initCtx.rebind ("java:comp/env/mullheim", "hij");
assertEquals ("hij", initCtx.lookup("java:comp/env/mullheim"));
- //test that the other bindings are already there
- assertEquals ("xyz", (String)initCtx.lookup("java:comp/env/poubelle"));
+ //test that the other bindings are already there
+ assertEquals ("xyz", initCtx.lookup("java:comp/env/poubelle"));
//test java:/comp/env/stuff
- assertEquals ("xyz", (String)initCtx.lookup("java:/comp/env/poubelle/"));
+ assertEquals ("xyz", initCtx.lookup("java:/comp/env/poubelle/"));
//test list Names
NamingEnumeration nenum = initCtx.list ("java:comp/env");
@@ -244,10 +204,10 @@ public class TestJNDI extends TestCase
assertEquals (4, results.size());
- assertEquals ("java.lang.String", (String)results.get("rubbish"));
- assertEquals ("javax.naming.LinkRef", (String)results.get("poubelle"));
- assertEquals ("java.lang.String", (String)results.get("mullheim"));
- assertEquals ("javax.naming.Reference", (String)results.get("quatsch"));
+ assertEquals ("java.lang.String", results.get("rubbish"));
+ assertEquals ("javax.naming.LinkRef", results.get("poubelle"));
+ assertEquals ("java.lang.String", results.get("mullheim"));
+ assertEquals ("javax.naming.Reference", results.get("quatsch"));
//test list Bindings
NamingEnumeration benum = initCtx.list("java:comp/env");
@@ -265,13 +225,11 @@ public class TestJNDI extends TestCase
InitialContext closeInit = new InitialContext();
closeInit.close();
-
-
//check locking the context
Context ectx = (Context)initCtx.lookup("java:comp");
ectx.bind("crud", "xxx");
ectx.addToEnvironment("org.eclipse.jndi.immutable", "TRUE");
- assertEquals ("xxx", (String)initCtx.lookup("java:comp/crud"));
+ assertEquals ("xxx", initCtx.lookup("java:comp/crud"));
try
{
ectx.bind("crud2", "xxx2");
@@ -282,7 +240,7 @@ public class TestJNDI extends TestCase
}
//test what happens when you close an initial context that was used
- initCtx.close();
+ initCtx.close();
}
finally
{
@@ -290,6 +248,5 @@ public class TestJNDI extends TestCase
Context comp = (Context)ic.lookup("java:comp");
comp.destroySubcontext("env");
}
- }
-
+ }
}
diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java
index 23a9955c43..0caa18fcef 100644
--- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java
+++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.jndi.java;
@@ -18,41 +18,37 @@ import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.jndi.NamingUtil;
+import org.junit.After;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
-public class TestLocalJNDI extends TestCase
+/**
+ *
+ */
+public class TestLocalJNDI
{
-
-
- public void setUp ()
- throws Exception
- {
- }
-
-
- public void tearDown ()
- throws Exception
+ @After
+ public void tearDown() throws Exception
{
InitialContext ic = new InitialContext();
ic.destroySubcontext("a");
}
-
-
- public void testLocal ()
- throws Exception
+
+ @Test
+ public void testLocal () throws Exception
{
-
InitialContext ic = new InitialContext();
NameParser parser = ic.getNameParser("");
ic.bind("foo", "xxx");
-
+
Object o = ic.lookup("foo");
assertNotNull(o);
assertEquals("xxx", (String)o);
-
+
ic.unbind("foo");
try
{
@@ -72,17 +68,16 @@ public class TestLocalJNDI extends TestCase
Context c = (Context)ic.lookup("a/b/c");
o = c.lookup("d");
assertNotNull(o);
- assertEquals("333", (String)o);
+ assertEquals("333", (String)o);
assertEquals("333", ic.lookup(name));
ic.destroySubcontext("a");
-
+
name = parser.parse("");
name.add("x");
Name suffix = parser.parse("y/z");
name.addAll(suffix);
- NamingUtil.bind(ic, name.toString(), "555");
+ NamingUtil.bind(ic, name.toString(), "555");
assertEquals("555", ic.lookup(name));
ic.destroySubcontext("x");
}
-
}
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF
index 50b1a5c580..6fc66ebd32 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF
+++ b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Jetty-OSGi-Jasper integration
Fragment-Host: org.eclipse.jetty.osgi.boot
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.jsp;singleton:=true
-Bundle-Version: 8.0.0.M0.qualifier
+Bundle-Version: 8.0.0.qualifier
Bundle-Vendor: Mort Bay Consulting
Bundle-RequiredExecutionEnvironment: J2SE-1.6
Import-Package: javax.el;version="2.2",
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
index abf6876280..575fb5a1c1 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>8.0.0.M0-SNAPSHOT</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -96,11 +96,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.osgi.boot.jasper.*,org.eclipse.jetty.osgi.boot.jsp.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml.tycho b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml.tycho
deleted file mode 100644
index 3f4c536781..0000000000
--- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml.tycho
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>jetty-osgi</artifactId>
- <version>8.0.0.M0-SNAPSHOT</version>
- <groupId>org.eclipse.jetty.osgi</groupId>
- </parent>
- <artifactId>org.eclipse.jetty.osgi.boot.jsp</artifactId>
- <packaging>eclipse-plugin</packaging>
-
-</project>
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java
index 084fac8b49..d1ea7b8122 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java
@@ -118,7 +118,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
* Support only 2 types of packaging for the bundle: - the bundle is a jar (recommended for runtime.) - the bundle is a folder and contain jars in the root
* and/or in the lib folder (nice for PDE developement situations) Unsupported: the bundle is a jar that embeds more jars.
*
- * @return
+ * @return array of URLs
* @throws Exception
*/
public URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper locatorHelper) throws Exception
@@ -148,7 +148,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
{
Bundle tldBundle = FrameworkUtil.getBundle(cl);
File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle);
- if (tldBundleLocation.isDirectory())
+ if (tldBundleLocation != null && tldBundleLocation.isDirectory())
{
// try to find the jar files inside this folder
for (File f : tldBundleLocation.listFiles())
@@ -170,7 +170,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
}
}
- else
+ else if (tldBundleLocation != null)
{
urls.add(tldBundleLocation.toURI().toURL());
}
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
index 8e84cbdf11..46a9ce31bc 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
@@ -12,7 +12,7 @@
// ========================================================================
package org.eclipse.jetty.osgi.boot.jsp;
-import org.eclipse.jetty.osgi.boot.internal.webapp.WebappRegistrationHelper;
+import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleDeployerHelper;
import org.eclipse.jetty.osgi.boot.jasper.PluggableWebAppRegistrationCustomizerImpl;
import org.eclipse.jetty.osgi.boot.jasper.WebappRegistrationCustomizerImpl;
import org.osgi.framework.BundleActivator;
@@ -36,13 +36,8 @@ public class FragmentActivator implements BundleActivator
*
*/
public void start(BundleContext context) throws Exception {
- WebappRegistrationHelper.JSP_REGISTRATION_HELPERS.add(new WebappRegistrationCustomizerImpl());
- WebappRegistrationHelper.JSP_REGISTRATION_HELPERS.add(new PluggableWebAppRegistrationCustomizerImpl());
-// try {
-// FragmentActivator.class.getClassLoader().loadClass("does.not.exist");
-// } catch (Throwable t) {
-// t.printStackTrace();
-// }
+ WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new WebappRegistrationCustomizerImpl());
+ WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new PluggableWebAppRegistrationCustomizerImpl());
}
/**
diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml b/jetty-osgi/jetty-osgi-boot-logback/pom.xml
index fc30d33975..262aa86f5e 100644
--- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>8.0.0.M1</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -95,11 +95,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.osgi.boot.logback.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml.tycho b/jetty-osgi/jetty-osgi-boot-logback/pom.xml.tycho
index 6f8277e581..b09cf8d687 100644
--- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml.tycho
+++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml.tycho
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>jetty-osgi</artifactId>
- <version>7.0.1-SNAPSHOT</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<groupId>org.eclipse.jetty.osgi</groupId>
</parent>
<artifactId>org.eclipse.jetty.osgi.boot.logback</artifactId>
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
index b21be87966..f37149d358 100644
--- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>8.0.0.M1</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -65,11 +65,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.osgi.boot.warurl.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml.tycho b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml.tycho
deleted file mode 100644
index b30ae7a464..0000000000
--- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml.tycho
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>jetty-osgi</artifactId>
- <version>7.0.1-SNAPSHOT</version>
- <groupId>org.eclipse.jetty.osgi</groupId>
- </parent>
- <groupId>org.eclipse.jetty.osgi</groupId>
- <artifactId>org.eclipse.jetty.osgi.boot.warurl</artifactId>
- <version>7.0.1.qualifier</version>
- <packaging>eclipse-plugin</packaging>
-</project>
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java
index ec31f3c24a..744a43c2ec 100644
--- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java
+++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java
@@ -99,7 +99,7 @@ public class WarURLConnection extends URLConnection
/**
* @param url The file url (for example)
- * @param The manifest to use as a replacement to the jar file inside
+ * @param mf The manifest to use as a replacement to the jar file inside
* the file url.
*/
public WarURLConnection(URL url, Manifest mf) throws IOException
diff --git a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF
index 861d73ad82..e302c3dd48 100644
--- a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF
+++ b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF
@@ -2,66 +2,16 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Jetty OSGi bootstrap
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot;singleton:=true
+Bundle-Vendor: Mort Bay Consulting
Bundle-Version: 8.0.0.qualifier
Bundle-Activator: org.eclipse.jetty.osgi.boot.JettyBootstrapActivator
-Bundle-Vendor: Mort Bay Consulting
-Export-Package: org,
- org.eclipse,
- org.eclipse.jetty,
- org.eclipse.jetty.osgi,
- org.eclipse.jetty.osgi.boot,
- org.eclipse.jetty.osgi.boot.internal,
- org.eclipse.jetty.osgi.boot.internal.jsp,
- org.eclipse.jetty.osgi.boot.internal.serverfactory,
- org.eclipse.jetty.osgi.boot.internal.webapp,
- org.eclipse.jetty.osgi.boot.utils,
- org.eclipse.jetty.osgi.boot.utils.internal
-Require-Bundle: org.eclipse.jetty.ajp;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.annotations;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.client;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.continuation;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.deploy;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.http;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.io;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.jmx;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.jndi;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.plus;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.rewrite;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.security;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.server;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.servlet;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.servlets;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.util;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.webapp;bundle-version="[8.0,
- 9)",
- org.eclipse.jetty.websocket;bundle-version="[8.0,
- 9)";resolution:=optional,
- org.eclipse.jetty.xml;bundle-version="[8.0,
- 9)"
-Bundle-RequiredExecutionEnvironment: J2SE-1.6
Import-Package: javax.mail;version="1.4.0";resolution:=optional,
javax.mail.event;version="1.4.0";resolution:=optional,
javax.mail.internet;version="1.4.0";resolution:=optional,
javax.mail.search;version="1.4.0";resolution:=optional,
javax.mail.util;version="1.4.0";resolution:=optional,
- javax.servlet;version="2.5.0",
- javax.servlet.http;version="2.5.0",
+ javax.servlet;version="3.0",
+ javax.servlet.http;version="3.0",
javax.transaction;version="1.1.0";resolution:=optional,
javax.transaction.xa;version="1.1.0";resolution:=optional,
org.osgi.framework,
@@ -73,4 +23,29 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
org.slf4j;resolution:=optional,
org.slf4j.spi;resolution:=optional,
org.slf4j.helpers;resolution:=optional
+ org.xml.sax,
+ org.xml.sax.helpers
+Bundle-RequiredExecutionEnvironment: J2SE-1.6
+Bundle-Classpath: .
+Require-Bundle: org.eclipse.jetty.ajp;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.annotations;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.client;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.continuation;bundle-version="[7.0,9)";resolution:=optional,
+ org.eclipse.jetty.deploy;bundle-version="[8.0,9)",
+ org.eclipse.jetty.http;bundle-version="[8.0,9)",
+ org.eclipse.jetty.io;bundle-version="[8.0,9)",
+ org.eclipse.jetty.jmx;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.jndi;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.plus;bundle-version="[8.0,9.0)";resolution:=optional,
+ org.eclipse.jetty.rewrite;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.security;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.server;bundle-version="[8.0,9)",
+ org.eclipse.jetty.servlet;bundle-version="[8.0,9)",
+ org.eclipse.jetty.servlets;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.util;bundle-version="[8.0,9)",
+ org.eclipse.jetty.webapp;bundle-version="[8.0,9)",
+ org.eclipse.jetty.websocket;bundle-version="[8.0,9)";resolution:=optional,
+ org.eclipse.jetty.xml;bundle-version="[8.0,9)"
+Export-Package: org.eclipse.jetty.osgi.boot,
+ org.eclipse.jetty.osgi.boot.utils
Bundle-ActivationPolicy: lazy
diff --git a/jetty-osgi/jetty-osgi-boot/build.properties b/jetty-osgi/jetty-osgi-boot/build.properties
index d9a9ce1f7f..ba1366d090 100644
--- a/jetty-osgi/jetty-osgi-boot/build.properties
+++ b/jetty-osgi/jetty-osgi-boot/build.properties
@@ -3,13 +3,6 @@ output.. = target/classes/
bin.includes = META-INF/,\
.,\
jettyhome/
-bin.excludes = jettyhome/logs/2009_09_21.request.log,\
- jettyhome/lib/atomikos-util-3.5.8.jar,\
- jettyhome/lib/transactions-3.5.8.jar,\
- jettyhome/lib/transactions-api-3.5.8.jar,\
- jettyhome/lib/transactions-jdbc-3.5.8.jar,\
- jettyhome/lib/transactions-jta-3.5.8.jar,\
- jettyhome/lib/ext/derby-10.4.1.3.jar,\
- jettyhome/lib/ext/derbytools-10.4.1.3.jar
-src.includes = META-INF/,\
- jettyhome/
+bin.excludes = jettyhome/logs/*.log,\
+ jettyhome/lib/*
+src.includes = jettyhome/
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/README b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/README
deleted file mode 100644
index dbc9fa7156..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This folder contains the default jetty configurations file for the server.
-In production, it is likely to be a different folder outside of the jetty's bootstrap plugin. \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jdbcRealm.properties b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jdbcRealm.properties
deleted file mode 100644
index 48104d88ad..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jdbcRealm.properties
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# This is a sample properties file for the org.eclipse.jetty.security.JDBCLoginService
-# implemtation of the UserRealm interface. This allows Jetty users authentication
-# to work from a database.
-#
-# +-------+ +------------+ +-------+
-# | users | | user_roles | | roles |
-# +-------+ +------------+ +-------+
-# | id | /| user_id |\ | id |
-# | user -------| role_id |------- role |
-# | pwd | \| |/ | |
-# +-------+ +------------+ +-------+
-#
-#
-# 'cachetime' is a time in seconds to cache positive database
-# lookups in internal hash table. Set to 0 to disable caching.
-#
-#
-# For MySQL:
-# create a MYSQL user called "jetty" with password "jetty"
-#
-# Create the tables:
-# create table users
-# (
-# id integer primary key,
-# username varchar(100) not null unique key,
-# pwd varchar(20) not null
-# );
-#
-# create table roles
-# (
-# id integer primary key,
-# role varchar(100) not null unique key
-# );
-#
-# create table user_roles
-# (
-# user_id integer not null,
-# role_id integer not null,
-# unique key (user_id, role_id),
-# index(user_id)
-# );
-#
-# I'm not sure unique key with a first component of user_id will be
-# user by MySQL in query, so additional index wouldn't hurt.
-#
-# To test JDBC implementation:
-#
-# mysql> insert into users values (1, 'admin', 'password');
-# mysql> insert into roles values (1, 'server-administrator');
-# mysql> insert into roles values (2, 'content-administrator');
-# mysql> insert into user_roles values (1, 1);
-# mysql> insert into user_roles values (1, 2);
-#
-# Replace HashUserRealm in etc/admin.xml with JDBCUserRealm and
-# set path to properties file.
-#
-jdbcdriver = org.gjt.mm.mysql.Driver
-url = jdbc:mysql://localhost/jetty
-username = jetty
-password = jetty
-usertable = users
-usertablekey = id
-usertableuserfield = username
-usertablepasswordfield = pwd
-roletable = roles
-roletablekey = id
-roletablerolefield = role
-userroletable = user_roles
-userroletableuserkey = user_id
-userroletablerolekey = role_id
-cachetime = 300
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ajp.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ajp.xml
deleted file mode 100644
index 04a775ec3e..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ajp.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- Add a AJP listener on port 8009 -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
- <Set name="port">8009</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio-ssl.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio-ssl.xml
deleted file mode 100644
index 0b0c6fc16f..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio-ssl.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure SSL for the Jetty Server -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ssl.SslSocketConnector">
- <Set name="Port">9443</Set>
- <Set name="maxIdleTime">30000</Set>
- <Set name="Keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- <Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- </New>
- </Arg>
- </Call>
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio.xml
deleted file mode 100644
index 3c4c8a6b80..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-bio.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Mixin configuration for Block socket connector -->
-<!-- -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- Use this connector if NIO is not available. -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.bio.SocketConnector">
- <Set name="port"><SystemProperty name="jetty.bio.port" default="8081"/></Set>
- <Set name="maxIdleTime">50000</Set>
- <Set name="lowResourceMaxIdleTime">1500</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-debug.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-debug.xml
deleted file mode 100644
index afc972e5ab..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-debug.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Mixin the DebugHandler -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
- <Get id="oldhandler" name="handler"/>
- <Set name="handler">
- <New id="DebugHandler" class="org.eclipse.jetty.server.handler.DebugHandler">
- <Set name="handler"><Ref id="oldhandler"/></Set>
- <Set name="outputStream">
- <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
- <Arg type="String"><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg>
- <Arg type="boolean">true</Arg> <!-- append -->
- <Arg type="int">90</Arg> <!-- retain days -->
- </New>
- </Set>
- </New>
- </Set>
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-fileserver.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-fileserver.xml
deleted file mode 100644
index de15b38724..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-fileserver.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-
-<Configure id="FileServer" class="org.eclipse.jetty.server.Server">
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="port">8080</Set>
- </New>
- </Arg>
- </Call>
-
- <Set name="handler">
- <New class="org.eclipse.jetty.server.handler.HandlerList">
- <Set name="handlers">
- <Array type="org.eclipse.jetty.server.Handler">
- <Item>
- <New class="org.eclipse.jetty.server.handler.ResourceHandler">
- <Set name="directoriesListed">true</Set>
- <Set name="welcomeFiles">
- <Array type="String"><Item>index.html</Item></Array>
- </Set>
- <Set name="resourceBase">.</Set>
- </New>
- </Item>
- <Item>
- <New class="org.eclipse.jetty.server.handler.DefaultHandler">
- </New>
- </Item>
- </Array>
- </Set>
- </New>
- </Set>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jaas.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jaas.xml
deleted file mode 100644
index e5bab94b5f..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jaas.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-<Configure id="Server" class="org.mortbay.jetty.Server">
-
-
- <!-- ======================================================== -->
- <!-- java.security.auth.login.config System property -->
- <!-- This is usually a runtime parameter to the jvm, but -->
- <!-- it is placed here for convenience. -->
- <!-- ======================================================== -->
- <Call class="java.lang.System" name="setProperty">
- <Arg>java.security.auth.login.config</Arg>
- <Arg><SystemProperty name="jetty.home" default="." />/etc/login.conf</Arg>
- </Call>
-
-
- <!-- ======================================================== -->
- <!-- An example JAAS realm setup -->
- <!-- For more information see the jetty wiki at -->
- <!-- http://http://docs.codehaus.org/display/JETTY/JAAS -->
- <!-- ======================================================== -->
- <Set name="UserRealms">
- <Array type="org.mortbay.jetty.security.UserRealm">
- <Item>
- <New class="org.mortbay.jetty.plus.jaas.JAASUserRealm">
- <Set name="Name">Test JAAS Realm</Set>
- <Set name="LoginModuleName">xyz</Set>
- </New>
- </Item>
- </Array>
- </Set>
-
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jmx.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jmx.xml
deleted file mode 100644
index 2d48b6ca20..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-jmx.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure the JVM JMX Server -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -DOPTIONS=jmx -jar start.jar etc/jetty-jmx.xml etc/jetty.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Initialize an mbean server -->
- <!-- =========================================================== -->
- <Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/>
-
- <!-- =========================================================== -->
- <!-- Initialize the Jetty MBean container -->
- <!-- =========================================================== -->
- <New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
- <Arg><Ref id="MBeanServer"/></Arg>
- </New>
-
- <!-- Add to the Server to listen for object events -->
- <Get id="Container" name="container">
- <Call name="addEventListener">
- <Arg><Ref id="MBeanContainer"/></Arg>
- </Call>
- </Get>
-
- <!-- Add to the Server as a lifecycle -->
- <!-- Only do this if you know you will only have a single jetty server -->
- <Call name="addBean">
- <Arg><Ref id="MBeanContainer"/></Arg>
- </Call>
-
- <!-- Add the static log -->
- <Get id="Logger" class="org.eclipse.jetty.util.log.Log" name="log"/>
- <Ref id="MBeanContainer">
- <Call name="addBean">
- <Arg><Ref id="Logger"/></Arg>
- </Call>
- </Ref>
-
- <!-- optionally add a remote JMX connector
- <Call id="jmxConnector" class="javax.management.remote.JMXConnectorServerFactory" name="newJMXConnectorServer">
- <Arg>
- <New class="javax.management.remote.JMXServiceURL">
- <Arg>service:jmx:rmi:///jndi/rmi:///jettymbeanserver</Arg>
- </New>
- </Arg>
- <Arg/>
- <Arg><Ref id="MBeanServer"/></Arg>
- <Call name="start"/>
- </Call>
- -->
-
-</Configure>
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-logging.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-logging.xml
deleted file mode 100644
index 09b590abe6..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-logging.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-
-<!-- =============================================================== -->
-<!-- Configure stderr and stdout to a Jetty rollover log file -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -jar start.jar etc/jetty-logging.xml etc/jetty.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <New id="ServerLog" class="java.io.PrintStream">
- <Arg>
- <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
- <Arg><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.stderrout.log</Arg>
- <Arg type="boolean">false</Arg>
- <Arg type="int">90</Arg>
- <Arg><Call class="java.util.TimeZone" name="getTimeZone"><Arg>GMT</Arg></Call></Arg>
- <Get id="ServerLogName" name="datedFilename"/>
- </New>
- </Arg>
- </New>
-
- <Call class="org.eclipse.jetty.util.log.Log" name="info"><Arg>Redirecting stderr/stdout to <Ref id="ServerLogName"/></Arg></Call>
- <Call class="java.lang.System" name="setErr"><Arg><Ref id="ServerLog"/></Arg></Call>
- <Call class="java.lang.System" name="setOut"><Arg><Ref id="ServerLog"/></Arg></Call>
-
-</Configure>
-
-
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml
new file mode 100644
index 0000000000..dc7b48fb67
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server -->
+<!-- -->
+<!-- Documentation of this file format can be found at: -->
+<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
+<!-- -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Server Thread Pool -->
+ <!-- =========================================================== -->
+ <Set name="ThreadPool">
+ <!-- Default queued blocking threadpool
+ -->
+ <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+ <Set name="minThreads">10</Set>
+ <Set name="maxThreads">200</Set>
+ </New>
+
+ <!-- Optional Java 5 bounded threadpool with job queue
+ <New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
+ <Arg name="coreSize" type="int">25</Arg>
+ <Arg name="maxSize" type="int">50</Arg>
+ <Arg name="maxIdleMs" type="long">30000</Arg>
+ </New>
+ -->
+ </Set>
+
+
+
+ <!-- =========================================================== -->
+ <!-- Set connectors -->
+ <!-- =========================================================== -->
+
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+ <Set name="host"><Property name="jetty.host" /></Set>
+ <Set name="port"><Property name="jetty.port" default="8080"/></Set>
+ <Set name="maxIdleTime">300000</Set>
+ <Set name="Acceptors">2</Set>
+ <Set name="statsOn">false</Set>
+ <Set name="confidentialPort">8443</Set>
+ <Set name="lowResourcesConnections">20000</Set>
+ <Set name="lowResourcesMaxIdleTime">5000</Set>
+ </New>
+ </Arg>
+ </Call>
+
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- To add a HTTP blocking connector -->
+ <!-- mixin jetty-bio.xml: -->
+ <!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- To allow Jetty to be started from xinetd -->
+ <!-- mixin jetty-xinetd.xml: -->
+ <!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
+ <!-- -->
+ <!-- See jetty-xinetd.xml for further instructions. -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <!-- =========================================================== -->
+ <!-- Set handler Collection Structure -->
+ <!-- =========================================================== -->
+ <Set name="handler">
+ <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+ <Set name="handlers">
+ <Array type="org.eclipse.jetty.server.Handler">
+ <Item>
+ <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
+ </Item>
+ <Item>
+ <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
+ </Item>
+ <Item>
+ <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
+ </Item>
+ </Array>
+ </Set>
+ </New>
+ </Set>
+
+ <!-- =========================================================== -->
+ <!-- Configure the deployment manager -->
+ <!-- -->
+ <!-- Sets up 2 monitored dir app providers that are configured -->
+ <!-- to behave in a similaraly to the legacy ContextDeployer -->
+ <!-- and WebAppDeployer from previous versions of Jetty. -->
+ <!-- =========================================================== -->
+ <Call name="addBean">
+ <Arg>
+ <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+ <Set name="contexts">
+ <Ref id="Contexts" />
+ </Set>
+ <Call name="setContextAttribute">
+ <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
+ <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
+ </Call>
+ <!-- Providers of OSGi Apps -->
+ <Call name="addAppProvider">
+ <Arg>
+ <New class="org.eclipse.jetty.osgi.boot.OSGiAppProvider">
+ <!--
+ <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+ -->
+ <Set name="scanInterval">5</Set>
+ <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
+ <!-- comma separated list of bundle symbolic names that
+ contain custom tag libraries (*.tld files)
+ if those bundles don't exist or can't be loaded no errors or warning will be issued!
+ this default value is to plug the tld files of the reference implementation of JSF -->
+ <Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" default="javax.faces.jsf-impl" /></Set>
+ </New>
+ </Arg>
+ </Call>
+
+ </New>
+ </Arg>
+ </Call>
+
+ <!-- =========================================================== -->
+ <!-- extra options -->
+ <!-- =========================================================== -->
+ <Set name="stopAtShutdown">true</Set>
+ <Set name="sendServerVersion">true</Set>
+ <Set name="sendDateHeader">true</Set>
+ <Set name="gracefulShutdown">1000</Set>
+
+ <!-- jetty-jndi by default -->
+ <Call class="java.lang.System" name="setProperty">
+ <Arg>java.naming.factory.initial</Arg>
+ <Arg><Property name="java.naming.factory.initial" default="org.eclipse.jetty.jndi.InitialContextFactory"/></Arg>
+ </Call>
+ <Call class="java.lang.System" name="setProperty">
+ <Arg>java.naming.factory.url.pkgs</Arg>
+ <Arg><Property name="java.naming.factory.url.pkgs" default="org.eclipse.jetty.jndi"/></Arg>
+ </Call>
+
+</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-plus.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-plus.xml
deleted file mode 100644
index 3a9375f314..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-plus.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure Jetty Plus features -->
-<!-- -->
-<!-- This file sets up a WebAppDeployer to automatically deploy all -->
-<!-- webapps in $jetty.home/webapps-plus at startup time, and to -->
-<!-- enable all of them with Plus features (jndi etc). -->
-<!-- -->
-<!-- You can instead configure individual webapps with Jetty Plus -->
-<!-- features by using the ContextDeployer (configured in -->
-<!-- $jetty.home/etc/jetty.xml), and ensuring that you set the -->
-<!-- same set of classes listed below in the "plusConfig" as the -->
-<!-- webapp's configurationClasses. -->
-<!-- -->
-<!-- For more information about Jetty Plus, see the Jetty wiki at -->
-<!-- http://docs.codehaus.org/display/JETTY/Jetty+Wiki -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Example JAAS realm setup. -->
- <!-- The LoginModuleName must be exactly the same as in the -->
- <!-- login.conf file, and the realm Name must be the same as in -->
- <!-- the web.xml file. -->
- <!-- =========================================================== -->
- <!--
- <Call name="addLoginService">
- <Arg>
- <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
- <Set name="name">xyzrealm</Set>
- <Set name="LoginModuleName">xyz</Set>
- </New>
- </Arg>
- </Call>
- -->
-
- <!-- =========================================================== -->
- <!-- Configurations for WebAppContexts -->
- <!-- Sequence of configurations to enable Plus features. -->
- <!-- =========================================================== -->
- <Array id="plusConfig" type="java.lang.String">
- <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
- <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
- <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
- <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
- <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
- <Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
- <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
- <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
- </Array>
-
- <!-- =========================================================== -->
- <!-- Deploy all webapps in webapps-plus -->
- <!-- =========================================================== -->
- <!-- Uncomment the following to set up a WebAppDeployer that will -->
- <!-- deploy webapps from a directory called webapps-plus. Note -->
- <!-- that you will need to create this directory first! -->
- <!--
- <Call name="addLifeCycle">
- <Arg>
- <New class="org.eclipse.jetty.deploy.WebAppDeployer">
- <Set name="contexts"><Ref id="Contexts"/></Set>
- <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps-plus</Set>
- <Set name="parentLoaderPriority">false</Set>
- <Set name="extract">true</Set>
- <Set name="allowDuplicates">false</Set>
- <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Set name="configurationClasses"><Ref id="plusConfig"/></Set>
- <Call name="setAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- </New>
- </Arg>
- </Call>
- -->
-
-</Configure>
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-proxy.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-proxy.xml
deleted file mode 100644
index 9fe82f1429..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-proxy.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure the Jetty Server -->
-<!-- -->
-<!-- Documentation of this file format can be found at: -->
-<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
-<!-- -->
-<!-- =============================================================== -->
-
-
-<Configure id="Proxy" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Server Thread Pool -->
- <!-- =========================================================== -->
- <Set name="ThreadPool">
- <!-- Default queued blocking threadpool
- -->
- <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
- <Set name="minThreads">10</Set>
- <Set name="maxThreads">50</Set>
- </New>
- </Set>
-
-
- <!-- =========================================================== -->
- <!-- Set connectors -->
- <!-- =========================================================== -->
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host"><SystemProperty name="jetty.host" /></Set>
- <Set name="port"><SystemProperty name="jetty.port" default="8888"/></Set>
- <Set name="maxIdleTime">300000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="statsOn">false</Set>
- <Set name="lowResourcesConnections">20000</Set>
- <Set name="lowResourcesMaxIdleTime">5000</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <Set name="handler">
- <New id="Servlets" class="org.eclipse.jetty.servlet.ServletHandler">
- <Call name="addServletWithMapping">
- <Arg>org.eclipse.jetty.servlets.ProxyServlet</Arg>
- <Arg>/</Arg>
- </Call>
- </New>
- </Set>
-
- <!-- =========================================================== -->
- <!-- extra options -->
- <!-- =========================================================== -->
- <Set name="stopAtShutdown">true</Set>
- <Set name="sendServerVersion">true</Set>
- <Set name="sendDateHeader">true</Set>
- <Set name="gracefulShutdown">1000</Set>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-rewrite.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-rewrite.xml
deleted file mode 100644
index da0eb7b2cd..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-rewrite.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Mixin the RewriteHandler -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- configure rewrite handler -->
- <!-- =========================================================== -->
- <Get id="oldhandler" name="handler"/>
-
- <Set name="handler">
- <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
- <Set name="handler"><Ref id="oldhandler"/></Set>
- <Set name="rewriteRequestURI">true</Set>
- <Set name="rewritePathInfo">false</Set>
- <Set name="originalPathAttribute">requestedPath</Set>
-
- <!-- Add rule to protect against IE ssl bug -->
- <Call name="addRule">
- <Arg>
- <New class="org.eclipse.jetty.rewrite.handler.MsieSslRule"/>
- </Arg>
- </Call>
-
- <!-- protect favicon handling -->
- <Call name="addRule">
- <Arg>
- <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
- <Set name="pattern">/favicon.ico</Set>
- <Set name="name">Cache-Control</Set>
- <Set name="value">Max-Age=3600,public</Set>
- <Set name="terminating">true</Set>
- </New>
- </Arg>
- </Call>
-
-
- <!-- use legacy API for some rewrites -->
- <Call name="addRewriteRule">
- <Arg>/some/old/context/*</Arg>
- <Arg>/test/dump/newcontext</Arg>
- </Call>
- <Call name="addRewriteRule">
- <Arg>/test/dump/rewrite/*</Arg>
- <Arg>/test/dump/rewritten</Arg>
- </Call>
- <Call name="addRewriteRule">
- <Arg>/test/dump/rewrite/protect/*</Arg>
- <Arg/>
- </Call>
- <Call name="addRewriteRule">
- <Arg>/test/*</Arg>
- <Arg/>
- </Call>
- <Call name="addRewriteRule">
- <Arg>/*</Arg>
- <Arg>/test</Arg>
- </Call>
-
- <!-- add a regex rule -->
- <Call name="addRule">
- <Arg>
- <New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">
- <Set name="regex">/test/dump/regex/([^/]*)/(.*)</Set>
- <Set name="replacement">/test/dump/$2/$1</Set>
- </New>
- </Arg>
- </Call>
- </New>
- </Set>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-setuid.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-setuid.xml
deleted file mode 100644
index 9a30af7450..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-setuid.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-
-<!-- =============================================================== -->
-<!-- Configure the Jetty SetUIDServer -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -jar start.jar etc/jetty-setuid.xml etc/jetty.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.mortbay.setuid.SetUIDServer">
- <Set name="startServerAsPrivileged">false</Set>
- <Set name="umask">2</Set>
- <Set name="uid">jetty</Set>
- <Set name="gid">jetty</Set>
-</Configure>
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ssl.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ssl.xml
deleted file mode 100644
index f2ec1a4085..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-ssl.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure SSL for the Jetty Server -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- if NIO is not available, use org.eclipse.jetty.server.ssl.SslSocketConnector -->
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
- <Set name="Port"><Property name="jetty.port.ssl" default="8443" /></Set>
- <Set name="maxIdleTime">30000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="AcceptQueueSize">100</Set>
- <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- <Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="truststore"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- </New>
- </Arg>
- </Call>
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-sslengine.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-sslengine.xml
deleted file mode 100644
index d908abbc93..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-sslengine.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure SSL for the Jetty Server -->
-<!-- this configuration file should be used in combination with -->
-<!-- other configuration files. e.g. -->
-<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
-<!-- =============================================================== -->
-<Configure id="Server" class="org.mortbay.jetty.Server">
- <Call name="addConnector">
- <Arg>
- <New class="org.mortbay.jetty.security.SslSelectChannelConnector">
- <Set name="Port">8444</Set>
- <Set name="maxIdleTime">30000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="AcceptQueueSize">100</Set>
- <Set name="Keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- <Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-stats.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-stats.xml
deleted file mode 100644
index e0a0c7fec3..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-stats.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Mixin the Statistics Handler -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <Get id="oldhandler" name="handler"/>
-
- <Set name="handler">
- <New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler">
- <Set name="handler"><Ref id="oldhandler"/></Set>
- </New>
- </Set>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-win32-service.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-win32-service.xml
deleted file mode 100644
index 20287ce772..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-win32-service.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure the Jetty Server -->
-<!-- -->
-<!-- Documentation of this file format can be found at: -->
-<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
-<!-- -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.mortbay.jetty.Server">
-
-
- <Call name="addLifeCycle">
- <Arg>
- <New class="org.mortbay.jetty.win32service.Win32Service">
- <Set name="server"><Ref id="Server"/></Set>
- </New>
- </Arg>
- </Call>
-
- <Set name="stopAtShutdown">true</Set>
- <!-- ensure/prevent Server: header being sent to browsers -->
- <Set name="sendServerVersion">true</Set>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-xinetd.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-xinetd.xml
deleted file mode 100644
index 0b6582572b..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-xinetd.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configuration for starting up Jetty using inetd/xinetd -->
-<!-- This feature requires at least Java 5 -->
-<!-- -->
-<!-- Making it a mixin for convenience, but note that if used -->
-<!-- with jetty.xml, Jetty will use multiple connectors -->
-<!-- =============================================================== -->
-
-<!-- Sample xinetd configuration (restart xinetd after adding the configuration file)
-
-service jetty
-{
- disable = no
-
- id = jetty
- type = UNLISTED
- wait = yes
- socket_type = stream
-
- # change this
- user = username
- group = groupname
- port = 2001
-
- # sample script for running jetty as a service
- # replace $JETTY_HOME with /path/to/jetty_home/
- server = $JETTY_HOME/bin/jetty-xinetd.sh
-}
-
--->
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
- <Call name="addConnector">
- <Arg>
- <!-- Inherited channel (from inetd/xinetd) -->
- <New class="org.eclipse.jetty.server.nio.InheritedChannelConnector">
-
-
- <!-- Optional. Fallback in case System.inheritedChannel() does not give a ServerSocketChannel
- <Set name="port"><SystemProperty name="jetty.service.port" default="8082"/></Set>
- -->
-
- <!-- sane defaults -->
- <Set name="maxIdleTime">300000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="statsOn">false</Set>
- <Set name="lowResourcesConnections">20000</Set>
- <Set name="lowResourcesMaxIdleTime">5000</Set>
- </New>
- </Arg>
- </Call>
-</Configure>
-
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml
deleted file mode 100644
index 0f8e63625b..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml
+++ /dev/null
@@ -1,289 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure the Jetty Server -->
-<!-- -->
-<!-- Documentation of this file format can be found at: -->
-<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
-<!-- -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Server Thread Pool -->
- <!-- =========================================================== -->
- <Set name="ThreadPool">
- <!-- Default queued blocking threadpool
- -->
- <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
- <Set name="minThreads">10</Set>
- <Set name="maxThreads">200</Set>
- </New>
-
- <!-- Optional Java 5 bounded threadpool with job queue
- <New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
- <Arg name="coreSize" type="int">25</Arg>
- <Arg name="maxSize" type="int">50</Arg>
- <Arg name="maxIdleMs" type="long">30000</Arg>
- </New>
- -->
- </Set>
-
-
-
- <!-- =========================================================== -->
- <!-- Set connectors -->
- <!-- =========================================================== -->
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host"><Property name="jetty.host" /></Set>
- <Set name="port"><Property name="jetty.port" default="8080"/></Set>
- <Set name="maxIdleTime">300000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="statsOn">false</Set>
- <Set name="confidentialPort">8443</Set>
- <Set name="lowResourcesConnections">20000</Set>
- <Set name="lowResourcesMaxIdleTime">5000</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTPS SSL connector -->
- <!-- mixin jetty-ssl.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
- <Set name="Port"><Property name="jetty.port.ssl" default="8443" /></Set>
- <Set name="maxIdleTime">30000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="AcceptQueueSize">100</Set>
- <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- <Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="truststore"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- </New>
- </Arg>
- </Call>
-
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTP blocking connector -->
- <!-- mixin jetty-bio.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To allow Jetty to be started from xinetd -->
- <!-- mixin jetty-xinetd.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
- <!-- -->
- <!-- See jetty-xinetd.xml for further instructions. -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- =========================================================== -->
- <!-- Set handler Collection Structure -->
- <!-- =========================================================== -->
- <Set name="handler">
- <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
- <Set name="handlers">
- <Array type="org.eclipse.jetty.server.Handler">
- <Item>
- <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
- </Item>
- <Item>
- <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
- </Item>
- <Item>
- <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
- </Item>
- </Array>
- </Set>
- </New>
- </Set>
-
- <!-- =========================================================== -->
- <!-- Configure the deployment manager -->
- <!-- -->
- <!-- Sets up 2 monitored dir app providers that are configured -->
- <!-- to behave in a similaraly to the legacy ContextDeployer -->
- <!-- and WebAppDeployer from previous versions of Jetty. -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
- <Set name="contexts">
- <Ref id="Contexts" />
- </Set>
- <Call name="setContextAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- <!-- Providers of Apps via Context XML files.
- Configured to behave similar to the legacy ContextDeployer -->
- <Call name="addAppProvider">
- <Arg>
- <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
- <Set name="monitoredDir"><Property name="jetty.home" default="." />/contexts</Set>
- <Set name="scanInterval">5</Set>
- </New>
- </Arg>
- </Call>
- <!-- Providers of Apps via WAR file existence.
- Configured to behave similar to the legacy WebAppDeployer -->
- <Call name="addAppProvider">
- <Arg>
- <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
- <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
- <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Set name="scanInterval">5</Set>
- <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
- </New>
- </Arg>
- </Call>
- <!-- Providers of OSGi Apps -->
- <Call name="addAppProvider">
- <Arg>
- <New class="org.eclipse.jetty.osgi.boot.OSGiAppProvider">
- <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
- <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Set name="scanInterval">5</Set>
- <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
- <!-- comma separated list of bundle symbolic names that
- contain custom tag libraries (*.tld files)
- if those bundles don't exist or can't be loaded no errors or warning will be issued!
- this default value is to plug the tld files of the reference implementation of JSF -->
- <Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" default="javax.faces.jsf-impl" /></Set>
- </New>
- </Arg>
- </Call>
-
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure the context deployer -->
- <!-- A context deployer will deploy contexts described in -->
- <!-- configuration files discovered in a directory. -->
- <!-- The configuration directory can be scanned for hot -->
- <!-- deployments at the configured scanInterval. -->
- <!-- -->
- <!-- This deployer is configured to deploy contexts configured -->
- <!-- in the $JETTY_HOME/contexts directory -->
- <!-- -->
- <!-- =========================================================== -->
- <!--
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.deploy.ContextDeployer">
- <Set name="contexts"><Ref id="Contexts"/></Set>
- <Set name="configurationDir"><Property name="jetty.home" default="."/>/contexts</Set>
- <Set name="scanInterval">5</Set>
- <Call name="setAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- </New>
- </Arg>
- </Call>
- -->
-
- <!-- =========================================================== -->
- <!-- Configure the webapp deployer. -->
- <!-- A webapp deployer will deploy standard webapps discovered -->
- <!-- in a directory at startup, without the need for additional -->
- <!-- configuration files. It does not support hot deploy or -->
- <!-- non standard contexts (see ContextDeployer above). -->
- <!-- -->
- <!-- This deployer is configured to deploy webapps from the -->
- <!-- $JETTY_HOME/webapps directory -->
- <!-- -->
- <!-- Normally only one type of deployer need be used. -->
- <!-- -->
- <!-- =========================================================== -->
- <!--
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.deploy.WebAppDeployer">
- <Set name="contexts"><Ref id="Contexts"/></Set>
- <Set name="webAppDir"><Property name="jetty.home" default="."/>/webapps</Set>
- <Set name="parentLoaderPriority">false</Set>
- <Set name="extract">true</Set>
- <Set name="allowDuplicates">false</Set>
- <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Call name="setAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- </New>
- </Arg>
- </Call>
- -->
-
- <!-- =========================================================== -->
- <!-- Configure Authentication Login Service -->
- <!-- Realms may be configured for the entire server here, or -->
- <!-- they can be configured for a specific web app in a context -->
- <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
- <!-- example). -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.security.HashLoginService">
- <Set name="name">Test Realm</Set>
- <Set name="config"><Property name="jetty.home" default="."/>/etc/realm.properties</Set>
- <Set name="refreshInterval">0</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure Request Log -->
- <!-- Request logs may be configured for the entire server here, -->
- <!-- or they can be configured for a specific web app in a -->
- <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
- <!-- for an example). -->
- <!-- =========================================================== -->
- <Ref id="RequestLog">
- <Set name="requestLog">
- <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
- <Set name="filename"><Property name="jetty.home" default="."/>/logs/yyyy_mm_dd.request.log</Set>
- <Set name="filenameDateFormat">yyyy_MM_dd</Set>
- <Set name="retainDays">90</Set>
- <Set name="append">true</Set>
- <Set name="extended">false</Set>
- <Set name="logCookies">false</Set>
- <Set name="LogTimeZone">GMT</Set>
- </New>
- </Set>
- </Ref>
-
- <!-- =========================================================== -->
- <!-- extra options -->
- <!-- =========================================================== -->
- <Set name="stopAtShutdown">true</Set>
- <Set name="sendServerVersion">true</Set>
- <Set name="sendDateHeader">true</Set>
- <Set name="gracefulShutdown">1000</Set>
-
- <!-- jetty-jndi by default -->
- <Call class="java.lang.System" name="setProperty">
- <Arg>java.naming.factory.initial</Arg>
- <Arg><SystemProperty name="java.naming.factory.initial" default="org.eclipse.jetty.jndi.InitialContextFactory"/></Arg>
- </Call>
- <Call class="java.lang.System" name="setProperty">
- <Arg>java.naming.factory.url.pkgs</Arg>
- <Arg><SystemProperty name="java.naming.factory.url.pkgs" default="org.eclipse.jetty.jndi"/></Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.conf b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.conf
deleted file mode 100644
index 731956c870..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-xyz {
-org.mortbay.jetty.plus.jaas.spi.PropertyFileLoginModule required
-debug="true"
-file="${jetty.home}/etc/login.properties";
-};
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.properties b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.properties
deleted file mode 100644
index 61e3203731..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/login.properties
+++ /dev/null
@@ -1 +0,0 @@
-me=me,me,roleA
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/webdefault.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/webdefault.xml
deleted file mode 100644
index 0078e77dd7..0000000000
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/webdefault.xml
+++ /dev/null
@@ -1,404 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-<!-- ===================================================================== -->
-<!-- This file contains the default descriptor for web applications. -->
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-<!-- The intent of this descriptor is to include jetty specific or common -->
-<!-- configuration for all webapps. If a context has a webdefault.xml -->
-<!-- descriptor, it is applied before the contexts own web.xml file -->
-<!-- -->
-<!-- A context may be assigned a default descriptor by: -->
-<!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
-<!-- + Passed an arg to addWebApplications -->
-<!-- -->
-<!-- This file is used both as the resource within the jetty.jar (which is -->
-<!-- used as the default if no explicit defaults descriptor is set) and it -->
-<!-- is copied to the etc directory of the Jetty distro and explicitly -->
-<!-- by the jetty.xml file. -->
-<!-- -->
-<!-- ===================================================================== -->
-<web-app
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- metadata-complete="true"
- version="2.5">
-
- <description>
- Default web.xml file.
- This file is applied to a Web application before it's own WEB_INF/web.xml file
- </description>
-
-
- <!-- ==================================================================== -->
- <!-- Context params to control Session Cookies -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- UNCOMMENT TO ACTIVATE
- <context-param>
- <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
- <param-value>127.0.0.1</param-value>
- </context-param>
-
- <context-param>
- <param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
- <param-value>/</param-value>
- </context-param>
-
- <context-param>
- <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
- <param-value>-1</param-value>
- </context-param>
- -->
-
-
- <!-- ==================================================================== -->
- <!-- The default servlet. -->
- <!-- This servlet, normally mapped to /, provides the handling for static -->
- <!-- content, OPTIONS and TRACE methods for the context. -->
- <!-- The following initParameters are supported: -->
- <!-- -->
- <!-- acceptRanges If true, range requests and responses are -->
- <!-- supported -->
- <!-- -->
- <!-- dirAllowed If true, directory listings are returned if no -->
- <!-- welcome file is found. Else 403 Forbidden. -->
- <!-- -->
- <!-- welcomeServlets If true, attempt to dispatch to welcome files -->
- <!-- that are servlets, if no matching static -->
- <!-- resources can be found. -->
- <!-- -->
- <!-- redirectWelcome If true, redirect welcome file requests -->
- <!-- else use request dispatcher forwards -->
- <!-- -->
- <!-- gzip If set to true, then static content will be served-->
- <!-- as gzip content encoded if a matching resource is -->
- <!-- found ending with ".gz" -->
- <!-- -->
- <!-- resoureBase Can be set to replace the context resource base -->
- <!-- -->
- <!-- relativeResourceBase -->
- <!-- Set with a pathname relative to the base of the -->
- <!-- servlet context root. Useful for only serving -->
- <!-- static content from only specific subdirectories. -->
- <!-- -->
- <!-- useFileMappedBuffer -->
- <!-- If set to true (the default), a memory mapped -->
- <!-- file buffer will be used to serve static content -->
- <!-- when using an NIO connector. Setting this value -->
- <!-- to false means that a direct buffer will be used -->
- <!-- instead. If you are having trouble with Windows -->
- <!-- file locking, set this to false. -->
- <!-- -->
- <!-- cacheControl If set, all static content will have this value -->
- <!-- set as the cache-control header. -->
- <!-- -->
- <!-- maxCacheSize Maximum size of the static resource cache -->
- <!-- -->
- <!-- maxCachedFileSize Maximum size of any single file in the cache -->
- <!-- -->
- <!-- maxCachedFiles Maximum number of files in the cache -->
- <!-- -->
- <!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
- <!-- of resource cache. A bio cached buffer may be used-->
- <!-- by nio but is not as efficient as a nio buffer. -->
- <!-- An nio cached buffer may not be used by bio. -->
- <!-- -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet>
- <servlet-name>default</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
- <init-param>
- <param-name>acceptRanges</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>dirAllowed</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>welcomeServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>redirectWelcome</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>maxCacheSize</param-name>
- <param-value>256000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFileSize</param-name>
- <param-value>10000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFiles</param-name>
- <param-value>1000</param-value>
- </init-param>
- <init-param>
- <param-name>cacheType</param-name>
- <param-value>both</param-value>
- </init-param>
- <init-param>
- <param-name>gzip</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>useFileMappedBuffer</param-name>
- <param-value>true</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>cacheControl</param-name>
- <param-value>max-age=3600,public</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
-
- <!-- ==================================================================== -->
- <!-- JSP Servlet -->
- <!-- This is the jasper JSP servlet from the jakarta project -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- The JSP page compiler and execution servlet, which is the mechanism -->
- <!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
- <!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
- <!-- following initialization parameters (default values are in square -->
- <!-- brackets): -->
- <!-- -->
- <!-- checkInterval If development is false and reloading is true, -->
- <!-- background compiles are enabled. checkInterval -->
- <!-- is the time in seconds between checks to see -->
- <!-- if a JSP page needs to be recompiled. [300] -->
- <!-- -->
- <!-- compiler Which compiler Ant should use to compile JSP -->
- <!-- pages. See the Ant documenation for more -->
- <!-- information. [javac] -->
- <!-- -->
- <!-- classdebuginfo Should the class file be compiled with -->
- <!-- debugging information? [true] -->
- <!-- -->
- <!-- classpath What class path should I use while compiling -->
- <!-- generated servlets? [Created dynamically -->
- <!-- based on the current web application] -->
- <!-- Set to ? to make the container explicitly set -->
- <!-- this parameter. -->
- <!-- -->
- <!-- development Is Jasper used in development mode (will check -->
- <!-- for JSP modification on every access)? [true] -->
- <!-- -->
- <!-- enablePooling Determines whether tag handler pooling is -->
- <!-- enabled [true] -->
- <!-- -->
- <!-- fork Tell Ant to fork compiles of JSP pages so that -->
- <!-- a separate JVM is used for JSP page compiles -->
- <!-- from the one Tomcat is running in. [true] -->
- <!-- -->
- <!-- ieClassId The class-id value to be sent to Internet -->
- <!-- Explorer when using <jsp:plugin> tags. -->
- <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
- <!-- -->
- <!-- javaEncoding Java file encoding to use for generating java -->
- <!-- source files. [UTF-8] -->
- <!-- -->
- <!-- keepgenerated Should we keep the generated Java source code -->
- <!-- for each page instead of deleting it? [true] -->
- <!-- -->
- <!-- logVerbosityLevel The level of detailed messages to be produced -->
- <!-- by this servlet. Increasing levels cause the -->
- <!-- generation of more messages. Valid values are -->
- <!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
- <!-- [WARNING] -->
- <!-- -->
- <!-- mappedfile Should we generate static content with one -->
- <!-- print statement per input line, to ease -->
- <!-- debugging? [false] -->
- <!-- -->
- <!-- -->
- <!-- reloading Should Jasper check for modified JSPs? [true] -->
- <!-- -->
- <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
- <!-- debugging be suppressed? [false] -->
- <!-- -->
- <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
- <!-- dumped to a file? [false] -->
- <!-- False if suppressSmap is true -->
- <!-- -->
- <!-- scratchdir What scratch directory should we use when -->
- <!-- compiling JSP pages? [default work directory -->
- <!-- for the current web application] -->
- <!-- -->
- <!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
- <!-- -->
- <!-- xpoweredBy Determines whether X-Powered-By response -->
- <!-- header is added by generated servlet [false] -->
- <!-- -->
- <!-- If you wish to use Jikes to compile JSP pages: -->
- <!-- Set the init parameter "compiler" to "jikes". Define -->
- <!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
- <!-- to cause Jikes to emit error messages in a format compatible with -->
- <!-- Jasper. -->
- <!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
- <!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet id="jsp">
- <servlet-name>jsp</servlet-name>
- <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
- <init-param>
- <param-name>logVerbosityLevel</param-name>
- <param-value>DEBUG</param-value>
- </init-param>
- <init-param>
- <param-name>fork</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>xpoweredBy</param-name>
- <param-value>false</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>classpath</param-name>
- <param-value>?</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>jsp</servlet-name>
- <url-pattern>*.jsp</url-pattern>
- <url-pattern>*.jspf</url-pattern>
- <url-pattern>*.jspx</url-pattern>
- <url-pattern>*.xsp</url-pattern>
- <url-pattern>*.JSP</url-pattern>
- <url-pattern>*.JSPF</url-pattern>
- <url-pattern>*.JSPX</url-pattern>
- <url-pattern>*.XSP</url-pattern>
- </servlet-mapping>
-
- <!-- ==================================================================== -->
- <!-- Dynamic Servlet Invoker. -->
- <!-- This servlet invokes anonymous servlets that have not been defined -->
- <!-- in the web.xml or by other means. The first element of the pathInfo -->
- <!-- of a request passed to the envoker is treated as a servlet name for -->
- <!-- an existing servlet, or as a class name of a new servlet. -->
- <!-- This servlet is normally mapped to /servlet/* -->
- <!-- This servlet support the following initParams: -->
- <!-- -->
- <!-- nonContextServlets If false, the invoker can only load -->
- <!-- servlets from the contexts classloader. -->
- <!-- This is false by default and setting this -->
- <!-- to true may have security implications. -->
- <!-- -->
- <!-- verbose If true, log dynamic loads -->
- <!-- -->
- <!-- * All other parameters are copied to the -->
- <!-- each dynamic servlet as init parameters -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- Uncomment for dynamic invocation
- <servlet>
- <servlet-name>invoker</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class>
- <init-param>
- <param-name>verbose</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>nonContextServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>dynamicParam</param-name>
- <param-value>anyValue</param-value>
- </init-param>
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
- -->
-
-
-
- <!-- ==================================================================== -->
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
-
- <!-- ==================================================================== -->
- <!-- Default MIME mappings -->
- <!-- The default MIME mappings are provided by the mime.properties -->
- <!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
- <!-- mappings may be specified here -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- UNCOMMENT TO ACTIVATE
- <mime-mapping>
- <extension>mysuffix</extension>
- <mime-type>mymime/type</mime-type>
- </mime-mapping>
- -->
-
- <!-- ==================================================================== -->
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <!-- ==================================================================== -->
- <locale-encoding-mapping-list>
- <locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>
- </locale-encoding-mapping-list>
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Disable TRACE</web-resource-name>
- <url-pattern>/</url-pattern>
- <http-method>TRACE</http-method>
- </web-resource-collection>
- <auth-constraint/>
- </security-constraint>
-
-</web-app>
-
diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml
index a3e659924b..daf9f05ebc 100644
--- a/jetty-osgi/jetty-osgi-boot/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>8.0.0.M1</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -78,11 +78,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.osgi.boot.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml.tycho b/jetty-osgi/jetty-osgi-boot/pom.xml.tycho
deleted file mode 100644
index 22cf4d5aa6..0000000000
--- a/jetty-osgi/jetty-osgi-boot/pom.xml.tycho
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>jetty-osgi</artifactId>
- <groupId>org.eclipse.jetty.osgi</groupId>
- <version>7.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>org.eclipse.jetty.osgi.boot</artifactId>
- <packaging>eclipse-plugin</packaging>
-
- <!--build>
- <resources>
- <resource>
- <excludes>
- <exclude>jettyhome/lib/ext/*.jar</exclude>
- <exclude>jettyhome/logs/*.log</exclude>
- </excludes>
- </resource>
- </resources>
- </build-->
-</project>
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
index 1c7250fcef..a7484296bf 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
@@ -18,8 +18,11 @@ import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Properties;
-import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerExtender;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker;
+import org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper;
import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker;
+import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
@@ -27,8 +30,8 @@ import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.BundleTracker;
/**
* Experiment: bootstrap jetty's complete distrib from an OSGi bundle. Progress:
@@ -65,6 +68,11 @@ public class JettyBootstrapActivator implements BundleActivator
private Server _server;
private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker;
+ private BundleTracker _webBundleTracker;
+
+// private ServiceRegistration _jettyServerFactoryService;
+ private JettyServerServiceTracker _jettyServerServiceTracker;
+
/**
* Setup a new jetty Server, registers it as a service. Setup the Service
@@ -82,25 +90,30 @@ public class JettyBootstrapActivator implements BundleActivator
// should activate.
_packageAdminServiceTracker = new PackageAdminServiceTracker(context);
- // todo: replace all this by the ManagedFactory so that we can start
- // multiple jetty servers.
- _server = new Server();
- // expose the server as a service.
- _registeredServer = context.registerService(_server.getClass().getName(),_server,new Properties());
+ _jettyServerServiceTracker = new JettyServerServiceTracker();
+ context.addServiceListener(_jettyServerServiceTracker,"(objectclass=" + Server.class.getName() + ")");
+
+ //Register the Jetty Server Factory as a ManagedServiceFactory:
+// Properties jettyServerMgdFactoryServiceProps = new Properties();
+// jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID);
+// _jettyServerFactoryService = context.registerService(
+// ManagedServiceFactory.class.getName(), new JettyServersManagedFactory(),
+// jettyServerMgdFactoryServiceProps);
+
+ _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(_jettyServerServiceTracker);
+
// the tracker in charge of the actual deployment
// and that will configure and start the jetty server.
- _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(context,_server);
-
- // TODO: add a couple more checks on the properties?
- // kind of nice not to so we can debug what is missing easily.
context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")");
- // now ready to support the Extender pattern:
- JettyContextHandlerExtender jettyContexHandlerExtender = new JettyContextHandlerExtender();
- context.addBundleListener(jettyContexHandlerExtender);
-
- jettyContexHandlerExtender.init(context);
-
+ //see if we shoult start a default jetty instance right now.
+ DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
+
+ // now ready to support the Extender pattern:
+ _webBundleTracker = new BundleTracker(context,
+ Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer());
+ _webBundleTracker.open();
+
}
/*
@@ -113,32 +126,68 @@ public class JettyBootstrapActivator implements BundleActivator
{
try
{
+
+ if (_webBundleTracker != null)
+ {
+ _webBundleTracker.close();
+ _webBundleTracker = null;
+ }
if (_jettyContextHandlerTracker != null)
{
_jettyContextHandlerTracker.stop();
context.removeServiceListener(_jettyContextHandlerTracker);
+ _jettyContextHandlerTracker = null;
+ }
+ if (_jettyServerServiceTracker != null)
+ {
+ _jettyServerServiceTracker.stop();
+ context.removeServiceListener(_jettyServerServiceTracker);
+ _jettyServerServiceTracker = null;
}
if (_packageAdminServiceTracker != null)
{
_packageAdminServiceTracker.stop();
context.removeServiceListener(_packageAdminServiceTracker);
+ _packageAdminServiceTracker = null;
}
if (_registeredServer != null)
{
try
{
_registeredServer.unregister();
- _registeredServer = null;
}
catch (IllegalArgumentException ill)
{
// already unregistered.
}
+ finally
+ {
+ _registeredServer = null;
+ }
}
+// if (_jettyServerFactoryService != null)
+// {
+// try
+// {
+// _jettyServerFactoryService.unregister();
+// }
+// catch (IllegalArgumentException ill)
+// {
+// // already unregistered.
+// }
+// finally
+// {
+// _jettyServerFactoryService = null;
+// }
+// }
+
}
finally
{
- _server.stop();
+ if (_server != null)
+ {
+ _server.stop();
+ }
INSTANCE = null;
}
}
@@ -148,8 +197,8 @@ public class JettyBootstrapActivator implements BundleActivator
* registers it as an OSGi service. The tracker
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
*
- * @param context
- * The current bundle context
+ * @param contributor
+ * The bundle
* @param webappFolderPath
* The path to the root of the webapp. Must be a path relative to
* bundle; either an absolute path.
@@ -171,18 +220,15 @@ public class JettyBootstrapActivator implements BundleActivator
* registers it as an OSGi service. The tracker
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
*
- * @param context
- * The current bundle context
+ * @param contributor
+ * The bundle
* @param webappFolderPath
* The path to the root of the webapp. Must be a path relative to
* bundle; either an absolute path.
* @param contextPath
* The context path. Must start with "/"
- * @param thisBundleInstallationOverride
- * The location to a folder where the context file is located
- * This overrides the default behavior that consists of using the
- * location where the bundle is installed. Useful when in fact
- * the webapp contributed is not inside a bundle.
+ * @param dic
+ * TODO: parameter description
* @throws Exception
*/
public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath, Dictionary<String, String> dic) throws Exception
@@ -220,17 +266,15 @@ public class JettyBootstrapActivator implements BundleActivator
* @param contextFilePath
* The path to the file inside the bundle that defines the
* context.
- * @param thisBundleInstallationOverride
- * The location to a folder where the context file is located
- * This overrides the default behavior that consists of using the
- * location where the bundle is installed. Useful when in fact
- * the webapp contributed is not inside a bundle.
+ * @param dic
+ * TODO: parameter description
* @throws Exception
*/
public static void registerContext(Bundle contributor, String contextFilePath, Dictionary<String, String> dic) throws Exception
{
ContextHandler contextHandler = new ContextHandler();
dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH,contextFilePath);
+ dic.put(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE,Boolean.TRUE.toString());
contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
}
@@ -238,5 +282,6 @@ public class JettyBootstrapActivator implements BundleActivator
{
// todo
}
+
} \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
index 9ddc27bc74..eb93a8f3f7 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2009 Mortbay, Inc.
+// Copyright (c) 2009-2010 Mortbay, Inc.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
@@ -25,6 +25,8 @@ import org.eclipse.jetty.deploy.providers.ContextProvider;
import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.osgi.framework.Bundle;
/**
* AppProvider for OSGi. Supports the configuration of ContextHandlers and
@@ -43,7 +45,7 @@ import org.eclipse.jetty.util.resource.Resource;
public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{
- private boolean _extractWars = false;
+ private boolean _extractWars = true;
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
private String _tldBundles;
@@ -91,8 +93,6 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
/**
* Default OSGiAppProvider consutructed when none are defined in the
* jetty.xml configuration.
- *
- * @param contextsDir
*/
public OSGiAppProvider()
{
@@ -111,7 +111,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
this();
setMonitoredDir(Resource.newResource(contextsDir.toURI()));
}
-
+
/**
* Returns the ContextHandler that was created by WebappRegistractionHelper
*
@@ -140,19 +140,39 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
super.setDeploymentManager(deploymentManager);
}
+ private static String getOriginId(Bundle contributor, String pathInBundle)
+ {
+ return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() +
+ (pathInBundle.startsWith("/") ? pathInBundle : "/" + pathInBundle);
+ }
+
+ /**
+ * @param context
+ * @throws Exception
+ */
+ public void addContext(Bundle contributor, String pathInBundle, ContextHandler context) throws Exception
+ {
+ addContext(getOriginId(contributor, pathInBundle), context);
+ }
/**
* @param context
* @throws Exception
*/
- public void addContext(ContextHandler context) throws Exception
+ public void addContext(String originId, ContextHandler context) throws Exception
{
// TODO apply configuration specific to this provider
+ if (context instanceof WebAppContext)
+ {
+ ((WebAppContext)context).setExtractWAR(isExtract());
+ }
// wrap context as an App
- App app = new App(getDeploymentManager(),this,context.getDisplayName(),context);
+ App app = new App(getDeploymentManager(),this,originId,context);
getDeployedApps().put(context.getDisplayName(),app);
getDeploymentManager().addApp(app);
}
+
+
/**
* Called by the scanner of the context files directory. If we find the
@@ -274,6 +294,17 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
return null;
}
}
+
+ public boolean isExtract()
+ {
+ return _extractWars;
+ }
+
+ public void setExtract(boolean extract)
+ {
+ _extractWars=extract;
+ }
+
/* ------------------------------------------------------------ */
/**
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java
new file mode 100644
index 0000000000..c2bddc290c
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java
@@ -0,0 +1,51 @@
+// ========================================================================
+// Copyright (c) 2009 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.
+// Contributors:
+// Hugues Malphettes - initial API and implementation
+// ========================================================================
+package org.eclipse.jetty.osgi.boot;
+
+/**
+ * Name of the properties that configure a jetty Server OSGi service.
+ */
+public class OSGiServerConstants
+{
+ //for managed jetty instances, name of the configuration parameters
+ /**
+ * PID of the jetty servers's ManagedFactory
+ */
+ public static final String MANAGED_JETTY_SERVER_FACTORY_PID = "org.eclipse.jetty.osgi.boot.managedserverfactory";
+
+ /**
+ * The associated value of that configuration parameter is the name under which this
+ * instance of the jetty server is tracked.
+ * When a ContextHandler is deployed and it specifies the managedServerName property, it is deployed
+ * on the corresponding jetty managed server or it throws an exception: jetty server not available.
+ */
+ public static final String MANAGED_JETTY_SERVER_NAME = "managedServerName";
+ /**
+ * Name of the 'default' jetty server instance.
+ * Usually the first one to be created.
+ */
+ public static final String MANAGED_JETTY_SERVER_DEFAULT_NAME = "defaultJettyServer";
+
+ /**
+ * List of URLs to the jetty.xml files that configure th server.
+ */
+ public static final String MANAGED_JETTY_XML_CONFIG_URLS = "jetty.etc.config.urls";
+
+ /**
+ * List of URLs to the folders where the legacy J2EE shared libraries are stored aka lib/ext, lib/jsp etc.
+ */
+ public static final String MANAGED_JETTY_SHARED_LIB_FOLDER_URLS = "managedJettySharedLibFolderUrls";
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
index c6c35d74f8..c6abc47c5b 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
@@ -15,7 +15,7 @@
package org.eclipse.jetty.osgi.boot;
/**
- *
+ * Name of the service properties for a ContextHandler that configure a webapp deployed on jetty OSGi.
*/
public class OSGiWebappConstants
{
@@ -66,13 +66,5 @@ public class OSGiWebappConstants
* location if not null useful to install webapps or jetty context files
* that are in fact not embedded in a bundle
*/
- public static final String SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE = "thisBundleInstall";
-
- // sys prop config of jetty:
- /**
- * contains a comma separated list of pathes to the etc/jetty-*.xml files
- * used to configure jetty. By default the value is 'etc/jetty.xml' when the
- * path is relative the file is resolved relatively to jettyhome.
- */
- public static final String SYS_PROP_JETTY_ETC_FILES = "jetty.etc.files";
+ public static final String SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE = "thisBundleInstall";
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java
index 67104b7173..9c989c7f7e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java
@@ -30,7 +30,7 @@ public class TldLocatableURLClassloaderWithInsertedJettyClassloader extends TldL
/**
*
- * @param osgiClassLoader
+ * @param osgiClassLoaderParent
* The parent classloader
* @param internalClassLoader
* The classloader that will be at the same level than the
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java
new file mode 100644
index 0000000000..7456cba037
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java
@@ -0,0 +1,253 @@
+// ========================================================================
+// Copyright (c) 2010 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.
+// Contributors:
+// Hugues Malphettes - initial API and implementation
+// ========================================================================
+package org.eclipse.jetty.osgi.boot.internal.serverfactory;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
+import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
+import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
+import org.eclipse.jetty.server.Server;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Called by the {@link JettyBootstrapActivator} during the starting of the bundle.
+ * If the system property 'jetty.home' is defined and points to a folder,
+ * then setup the corresponding jetty server and starts it.
+ */
+public class DefaultJettyAtJettyHomeHelper {
+
+ /**
+ * contains a comma separated list of pathes to the etc/jetty-*.xml files
+ * used to configure jetty. By default the value is 'etc/jetty.xml' when the
+ * path is relative the file is resolved relatively to jettyhome.
+ */
+ public static final String SYS_PROP_JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS;
+
+ /**
+ * Usual system property used as the hostname for a typical jetty configuration.
+ */
+ public static final String SYS_PROP_JETTY_HOME = "jetty.home";
+ /**
+ * System property to point to a bundle that embeds a jetty configuration
+ * and that jetty configuration should be the default jetty server.
+ * First we look for jetty.home. If we don't find it then we look for this property.
+ */
+ public static final String SYS_PROP_JETTY_HOME_BUNDLE = "jetty.home.bundle";
+ /**
+ * Usual system property used as the hostname for a typical jetty configuration.
+ */
+ public static final String SYS_PROP_JETTY_HOST = "jetty.host";
+ /**
+ * Usual system property used as the port for http for a typical jetty configuration.
+ */
+ public static final String SYS_PROP_JETTY_PORT = "jetty.port";
+ /**
+ * Usual system property used as the port for https for a typical jetty configuration.
+ */
+ public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl";
+
+
+ /**
+ * Called by the JettyBootStrapActivator.
+ * If the system property jetty.home is defined and points to a folder,
+ * deploys the corresponding jetty server.
+ * <p>
+ * If the system property jetty.home.bundle is defined and points to a bundle.
+ * Look for the configuration of jetty inside that bundle and deploys the corresponding bundle.
+ * </p>
+ * <p>
+ * In both cases reads the system property 'jetty.etc.config.urls' to locate the configuration
+ * files for the deployed jetty. It is a comma spearate list of URLs or relative paths inside the bundle or folder
+ * to the config files. If underfined it defaults to 'etc/jetty.xml'.
+ * </p>
+ * <p>
+ * In both cases the system properties jetty.host, jetty.port and jetty.port.ssl are passed to the configuration files
+ * that might use them as part of their properties.
+ * </p>
+ */
+ public static void startJettyAtJettyHome(BundleContext bundleContext)
+ {
+ String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME);
+ String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE);
+ File jettyHome = null;
+ Bundle jettyHomeBundle = null;
+ if (jettyHomeSysProp != null)
+ {
+ if (jettyHomeBundleSysProp != null)
+ {
+ System.err.println("WARN: both the jetty.home property and the jetty.home.bundle property are defined."
+ + " jetty.home.bundle is not taken into account.");
+ }
+ jettyHome = new File(jettyHomeSysProp);
+ if (!jettyHome.exists() || !jettyHome.isDirectory())
+ {
+ System.err.println("Unable to locate the jetty.home folder " + jettyHomeSysProp);
+ return;
+ }
+ }
+ else if (jettyHomeBundleSysProp != null)
+ {
+ for (Bundle b : bundleContext.getBundles())
+ {
+ if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
+ {
+ jettyHomeBundle = b;
+ break;
+ }
+ }
+ if (jettyHomeBundle == null)
+ {
+ System.err.println("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
+ return;
+ }
+
+ }
+ if (jettyHome == null && jettyHomeBundle == null)
+ {
+ System.err.println("No default jetty started.");
+ return;
+ }
+ try
+ {
+ Server server = new Server();
+ Properties properties = new Properties();
+ properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
+
+ String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle);
+ properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs);
+
+ System.err.println("Configuring the default jetty server with " + configURLs);
+
+ //these properties usually are the ones passed to this type of configuration.
+ setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
+ setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
+ setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
+ setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
+
+ bundleContext.registerService(Server.class.getName(), server, properties);
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+ }
+
+ /**
+ * Minimum setup for the location of the configuration files given a jettyhome folder.
+ * Reads the system property jetty.etc.config.urls and look for the corresponding jetty
+ * configuration files that will be used to setup the jetty server.
+ * @param jettyhome
+ * @return
+ */
+ private static String getJettyConfigurationURLs(File jettyhome)
+ {
+ String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
+ StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
+ StringBuilder res = new StringBuilder();
+ while (tokenizer.hasMoreTokens())
+ {
+ String next = tokenizer.nextToken().trim();
+ if (!next.startsWith("/") && next.indexOf(':') == -1)
+ {
+ try {
+ next = new File(jettyhome, next).toURI().toURL().toString();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ continue;
+ }
+ }
+ appendToCommaSeparatedList(res, next);
+ }
+ return res.toString();
+ }
+
+ /**
+ * Minimum setup for the location of the configuration files given a configuration
+ * embedded inside a bundle.
+ * Reads the system property jetty.etc.config.urls and look for the corresponding jetty
+ * configuration files that will be used to setup the jetty server.
+ * @param jettyhome
+ * @return
+ */
+ private static String getJettyConfigurationURLs(Bundle configurationBundle)
+ {
+ String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
+ System.err.println("jettyetc=" + jettyetc);
+ StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
+ StringBuilder res = new StringBuilder();
+
+ while (tokenizer.hasMoreTokens())
+ {
+ String etcFile = tokenizer.nextToken().trim();
+ if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1)
+ {
+ appendToCommaSeparatedList(res, etcFile);
+ }
+ else
+ {
+ Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
+ .findEntries(configurationBundle, etcFile);
+
+ //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
+ //default inside jettyhome. this way fragments to the bundle can define their own configuration.
+ if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
+ {
+ enUrls = BundleFileLocatorHelper.DEFAULT
+ .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
+ System.err.println("Configuring jetty with the default embedded configuration:" +
+ "bundle: " + configurationBundle.getSymbolicName() +
+ " config: /jettyhome/etc/jetty-osgi-default.xml");
+ }
+ if (enUrls == null || !enUrls.hasMoreElements())
+ {
+ System.err.println("Unable to locate a jetty configuration file for " + etcFile);
+ }
+ if (enUrls != null)
+ {
+ while (enUrls.hasMoreElements())
+ {
+ appendToCommaSeparatedList(res, enUrls.nextElement().toString());
+ }
+ }
+ }
+ }
+ return res.toString();
+ }
+
+ private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
+ {
+ if (buffer.length() != 0)
+ {
+ buffer.append(",");
+ }
+ buffer.append(value);
+ }
+
+ private static void setProperty(Properties properties, String key, String value)
+ {
+ if (value != null)
+ {
+ properties.put(key, value);
+ }
+ }
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java
new file mode 100644
index 0000000000..796447496d
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java
@@ -0,0 +1,28 @@
+// ========================================================================
+// Copyright (c) 2010 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.
+// Contributors:
+// Hugues Malphettes - initial API and implementation
+// ========================================================================
+package org.eclipse.jetty.osgi.boot.internal.serverfactory;
+
+/**
+ * Keeps track of the running jetty servers. They are named.
+ */
+public interface IManagedJettyServerRegistry {
+
+ /**
+ * @param managedServerName The server name
+ * @return the corresponding jetty server wrapped with its deployment properties.
+ */
+ public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName);
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java
new file mode 100644
index 0000000000..200647cecc
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java
@@ -0,0 +1,161 @@
+// ========================================================================
+// Copyright (c) 2009-2010 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.osgi.boot.internal.serverfactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
+import org.eclipse.jetty.server.Server;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Deploy the jetty server instances when they are registered as an OSGi service.
+ */
+public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
+{
+
+ /**
+ * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
+ */
+ private Map<String, ServerInstanceWrapper> _serversIndexedByName = new HashMap<String, ServerInstanceWrapper>();
+ /** The context-handler to deactivate indexed by ServerInstanceWrapper */
+ private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
+
+
+ /**
+ * Stops each one of the registered servers.
+ */
+ public void stop()
+ {
+ //not sure that this is really useful but here we go.
+ for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
+ {
+ try
+ {
+ wrapper.stop();
+ }
+ catch (Throwable t)
+ {
+
+ }
+ }
+ }
+
+
+ /**
+ * Receives notification that a service has had a lifecycle change.
+ *
+ * @param ev
+ * The <code>ServiceEvent</code> object.
+ */
+ public void serviceChanged(ServiceEvent ev)
+ {
+ ServiceReference sr = ev.getServiceReference();
+ switch (ev.getType())
+ {
+ case ServiceEvent.MODIFIED:
+ case ServiceEvent.UNREGISTERING:
+ {
+ ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
+ if (instance != null)
+ {
+ try
+ {
+ instance.stop();
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ if (ev.getType() == ServiceEvent.UNREGISTERING)
+ {
+ break;
+ }
+ else
+ {
+ // modified, meaning: we reload it. now that we stopped it;
+ // we can register it.
+ }
+ case ServiceEvent.REGISTERED:
+ {
+ Bundle contributor = sr.getBundle();
+ Server server = (Server)contributor.getBundleContext().getService(sr);
+ ServerInstanceWrapper wrapper = registerInIndex(server, sr);
+ Properties props = new Properties();
+ for (String key : sr.getPropertyKeys())
+ {
+ Object value = sr.getProperty(key);
+ props.put(key, value);
+ }
+ wrapper.start(server, props);
+ break;
+ }
+ }
+ }
+
+ private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
+ {
+ String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ if (name == null)
+ {
+ throw new IllegalArgumentException("The property " +
+ OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory");
+ }
+ ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
+ _indexByServiceReference.put(sr,wrapper);
+ _serversIndexedByName.put(name,wrapper);
+ return wrapper;
+ }
+
+ /**
+ * Returns the ContextHandler to stop.
+ *
+ * @param reg
+ * @return the ContextHandler to stop.
+ */
+ private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
+ {
+ ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
+ if (handler == null)
+ {
+ // a warning?
+ return null;
+ }
+ String name = handler.getManagedServerName();
+ if (name != null)
+ {
+ _serversIndexedByName.remove(name);
+ }
+ return handler;
+ }
+
+ /**
+ * @param managedServerName The server name
+ * @return the corresponding jetty server wrapped with its deployment properties.
+ */
+ public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
+ {
+ return _serversIndexedByName.get(managedServerName == null
+ ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
+ }
+
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java
index d6b8aa9853..31ad22534b 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java
@@ -14,45 +14,30 @@
// ========================================================================
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
+import java.net.URL;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.Hashtable;
import java.util.Map;
+import java.util.StringTokenizer;
+import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
+import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
import org.eclipse.jetty.server.Server;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
/**
- * This is a work in progress. <br/>
- * In particular there is a lot of work required during the update of the
- * configuration of a server. It might not be practical to in fact support that
- * and re-deploy the webapps in the same state than before the server was
- * stopped.
- * <p>
- * jetty servers are managed as OSGi services registered here. try to find out
- * if a configuration will fail (ports already opened etc).
- * </p>
- * <p>
- * Try to enable the creation and configuration of jetty servers in all the
- * usual standard ways. The configuration of the server is defined by the
- * properties passed to the service:
- * <ol>
- * <li>First look for jettyfactory. If the value is a jetty server, use that
- * server</li>
- * <li>Then look for jettyhome key. The value should be a java.io.File or a
- * String that is a path to the folder It is required that a etc/jetty.xml file
- * will be loated from that folder.</li>
- * <li>Then look for a jettyxml key. The value should be a java.io.File or an
- * InputStream that contains a jetty configuration file.</li>
- * <li>TODO: More ways to configure a jetty server? (other IOCs like spring,
- * equinox properties...)</li>
- * <li>Throw an exception if none of the relevant parameters are found</li>
- * </ol>
- * </p>
+ * Manages the deployment of jetty server instances.
+ * Not sure this is bringing much compared to the JettyServerServiceTracker.
*
* @author hmalphettes
*/
-public class JettyServersManagedFactory implements ManagedServiceFactory
+public class JettyServersManagedFactory implements ManagedServiceFactory, IManagedJettyServerRegistry
{
/**
@@ -79,7 +64,18 @@ public class JettyServersManagedFactory implements ManagedServiceFactory
*/
public static final String JETTY_HTTPS_PORT = "jetty.http.port";
- private Map<String, Server> _servers = new HashMap<String, Server>();
+ /**
+ * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
+ */
+ private Map<String, ServerInstanceWrapper> _serversIndexedByPID = new HashMap<String, ServerInstanceWrapper>();
+ /**
+ * PID -> {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME}
+ */
+ private Map<String, String> _serversNameIndexedByPID = new HashMap<String, String>();
+ /**
+ * {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} -> PID
+ */
+ private Map<String, String> _serversPIDIndexedByName = new HashMap<String, String>();
/**
* Return a descriptive name of this factory.
@@ -93,24 +89,43 @@ public class JettyServersManagedFactory implements ManagedServiceFactory
public void updated(String pid, Dictionary properties) throws ConfigurationException
{
- Server server = _servers.get(pid);
+ ServerInstanceWrapper serverInstanceWrapper = getServerByPID(pid);
deleted(pid);
// do we need to collect the currently deployed http services and
// webapps
// to be able to re-deploy them later?
// probably not. simply restart and see the various service trackers
// do everything that is needed.
-
+ String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ if (name == null)
+ {
+ throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
+ "The name of the server is mandatory");
+ }
+ serverInstanceWrapper = new ServerInstanceWrapper(name);
+ _serversIndexedByPID.put(pid, serverInstanceWrapper);
+ _serversNameIndexedByPID.put(pid, name);
+ _serversPIDIndexedByName.put(name, pid);
+ serverInstanceWrapper.start(new Server(), properties);
}
public synchronized void deleted(String pid)
{
- Server server = (Server)_servers.remove(pid);
+ ServerInstanceWrapper server = (ServerInstanceWrapper)_serversIndexedByPID.remove(pid);
+ String name = _serversNameIndexedByPID.remove(pid);
+ if (name != null)
+ {
+ _serversPIDIndexedByName.remove(name);
+ }
+ else
+ {
+ //something incorrect going on.
+ }
if (server != null)
{
try
{
- server.stop();
+ server.stop();
}
catch (Exception e)
{
@@ -119,4 +134,74 @@ public class JettyServersManagedFactory implements ManagedServiceFactory
}
}
+ public synchronized ServerInstanceWrapper getServerByPID(String pid)
+ {
+ return _serversIndexedByPID.get(pid);
+ }
+
+ /**
+ * @param managedServerName The server name
+ * @return the corresponding jetty server wrapped with its deployment properties.
+ */
+ public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
+ {
+ String pid = _serversPIDIndexedByName.get(managedServerName);
+ return pid != null ? _serversIndexedByPID.get(pid) : null;
+ }
+
+ /**
+ * Helper method to create and configure a new Jetty Server via the ManagedServiceFactory
+ * @param contributor
+ * @param serverName
+ * @param urlsToJettyXml
+ * @throws Exception
+ */
+ public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
+ {
+ ServiceReference configurationAdminReference =
+ contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
+
+ ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext()
+ .getService( configurationAdminReference );
+
+ Configuration configuration = confAdmin.createFactoryConfiguration(
+ OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
+ Dictionary properties = new Hashtable();
+ properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName);
+
+ StringBuilder actualBundleUrls = new StringBuilder();
+ StringTokenizer tokenizer = new StringTokenizer(urlsToJettyXml, ",", false);
+ while (tokenizer.hasMoreTokens())
+ {
+ if (actualBundleUrls.length() != 0)
+ {
+ actualBundleUrls.append(",");
+ }
+ String token = tokenizer.nextToken();
+ if (token.indexOf(':') != -1)
+ {
+ //a complete url. no change needed:
+ actualBundleUrls.append(token);
+ }
+ else if (token.startsWith("/"))
+ {
+ //url relative to the contributor bundle:
+ URL url = contributor.getEntry(token);
+ if (url == null)
+ {
+ actualBundleUrls.append(token);
+ }
+ else
+ {
+ actualBundleUrls.append(url.toString());
+ }
+ }
+
+ }
+
+ properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, actualBundleUrls.toString());
+ configuration.update(properties);
+
+ }
+
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
new file mode 100644
index 0000000000..7e4afc5b29
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
@@ -0,0 +1,422 @@
+// ========================================================================
+// Copyright (c) 2009 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.osgi.boot.internal.serverfactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.deploy.AppProvider;
+import org.eclipse.jetty.deploy.DeploymentManager;
+import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
+import org.eclipse.jetty.osgi.boot.OSGiAppProvider;
+import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
+import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader;
+import org.eclipse.jetty.osgi.boot.internal.webapp.LibExtClassLoaderHelper;
+import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleDeployerHelper;
+import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlConfiguration;
+import org.xml.sax.SAXParseException;
+
+
+/**
+ * Exposes a Jetty Server to be managed by an OSGi ManagedServiceFactory
+ * Configure and start it.
+ * Can also be used from the ManagedServiceFactory
+ */
+public class ServerInstanceWrapper {
+
+ private static Logger __logger = Log.getLogger(ServerInstanceWrapper.class.getName());
+
+ private final String _managedServerName;
+
+ /**
+ * The managed jetty server
+ */
+ private Server _server;
+ private ContextHandlerCollection _ctxtHandler;
+
+ /**
+ * This is the class loader that should be the parent classloader of any
+ * webapp classloader. It is in fact the _libExtClassLoader with a trick to
+ * let the TldScanner find the jars where the tld files are.
+ */
+ private ClassLoader _commonParentClassLoaderForWebapps;
+ private DeploymentManager _deploymentManager;
+ private OSGiAppProvider _provider;
+
+ private WebBundleDeployerHelper _webBundleDeployerHelper;
+
+
+ public ServerInstanceWrapper(String managedServerName)
+ {
+ _managedServerName = managedServerName;
+ }
+
+ public String getManagedServerName()
+ {
+ return _managedServerName;
+ }
+
+ /**
+ * The classloader that should be the parent classloader for
+ * each webapp deployed on this server.
+ * @return
+ */
+ public ClassLoader getParentClassLoaderForWebapps()
+ {
+ return _commonParentClassLoaderForWebapps;
+ }
+
+ /**
+ * @return The deployment manager registered on this server.
+ */
+ public DeploymentManager getDeploymentManager()
+ {
+ return _deploymentManager;
+ }
+
+ /**
+ * @return The app provider registered on this server.
+ */
+ public OSGiAppProvider getOSGiAppProvider()
+ {
+ return _provider;
+ }
+
+
+ public Server getServer()
+ {
+ return _server;
+ }
+
+
+ public WebBundleDeployerHelper getWebBundleDeployerHelp()
+ {
+ return _webBundleDeployerHelper;
+ }
+
+ /**
+ * @return The collection of context handlers
+ */
+ public ContextHandlerCollection getContextHandlerCollection()
+ {
+ return _ctxtHandler;
+ }
+
+
+ public void start(Server server, Dictionary props)
+ {
+ _server = server;
+ ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ // passing this bundle's classloader as the context classlaoder
+ // makes sure there is access to all the jetty's bundles
+ ClassLoader libExtClassLoader = null;
+ String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
+ try
+ {
+ List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
+ libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(
+ shared, null, server, JettyBootstrapActivator.class.getClassLoader());
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+
+ Thread.currentThread().setContextClassLoader(libExtClassLoader);
+
+ configure(server, props);
+
+ init();
+
+ //now that we have an app provider we can call the registration customizer.
+ try
+ {
+ URL[] jarsWithTlds = getJarsWithTlds();
+ _commonParentClassLoaderForWebapps = jarsWithTlds == null
+ ? libExtClassLoader
+ :new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds);
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+
+
+ server.start();
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader(contextCl);
+ }
+ _webBundleDeployerHelper = new WebBundleDeployerHelper(this);
+ }
+
+
+ public void stop()
+ {
+ try {
+ if (_server.isRunning())
+ {
+ _server.stop();
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * TODO: right now only the jetty-jsp bundle is scanned for common taglibs.
+ * Should support a way to plug more bundles that contain taglibs.
+ *
+ * The jasper TldScanner expects a URLClassloader to parse a jar for the
+ * /META-INF/*.tld it may contain. We place the bundles that we know contain
+ * such tag-libraries. Please note that it will work if and only if the
+ * bundle is a jar (!) Currently we just hardcode the bundle that contains
+ * the jstl implemenation.
+ *
+ * A workaround when the tld cannot be parsed with this method is to copy
+ * and paste it inside the WEB-INF of the webapplication where it is used.
+ *
+ * Support only 2 types of packaging for the bundle: - the bundle is a jar
+ * (recommended for runtime.) - the bundle is a folder and contain jars in
+ * the root and/or in the lib folder (nice for PDE developement situations)
+ * Unsupported: the bundle is a jar that embeds more jars.
+ *
+ * @return
+ * @throws Exception
+ */
+ private URL[] getJarsWithTlds() throws Exception
+ {
+ ArrayList<URL> res = new ArrayList<URL>();
+ WebBundleDeployerHelper.staticInit();//that is not looking great.
+ for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS)
+ {
+ URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER);
+ for (URL url : urls)
+ {
+ if (!res.contains(url))
+ res.add(url);
+ }
+ }
+ if (!res.isEmpty())
+ return res.toArray(new URL[res.size()]);
+ else
+ return null;
+ }
+
+ private void configure(Server server, Dictionary props) throws Exception
+ {
+ String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
+ List<URL> jettyConfigurations = jettyConfigurationUrls != null
+ ? extractResources(jettyConfigurationUrls) : null;
+ if (jettyConfigurations == null || jettyConfigurations.isEmpty())
+ {
+ return;
+ }
+ Map<Object,Object> id_map = new HashMap<Object,Object>();
+ id_map.put("Server",server);
+ Map<Object,Object> properties = new HashMap<Object,Object>();
+ Enumeration en = props.keys();
+ while (en.hasMoreElements())
+ {
+ Object key = en.nextElement();
+ Object value = props.get(key);
+ properties.put(key, value);
+ }
+
+ for (URL jettyConfiguration : jettyConfigurations)
+ {
+ InputStream is = null;
+ try
+ {
+ // Execute a Jetty configuration file
+ is = jettyConfiguration.openStream();
+ XmlConfiguration config = new XmlConfiguration(is);
+ config.setIdMap(id_map);
+ config.setProperties(properties);
+ config.configure();
+ id_map=config.getIdMap();
+ }
+ catch (SAXParseException saxparse)
+ {
+ __logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse);
+ throw saxparse;
+ }
+ finally
+ {
+ IO.close(is);
+ }
+ }
+
+ }
+
+
+ /**
+ * Must be called after the server is configured.
+ *
+ * Locate the actual instance of the ContextDeployer and WebAppDeployer that
+ * was created when configuring the server through jetty.xml. If there is no
+ * such thing it won't be possible to deploy webapps from a context and we
+ * throw IllegalStateExceptions.
+ */
+ private void init()
+ {
+ // Get the context handler
+ _ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class);
+
+ // get a deployerManager
+ List<DeploymentManager> deployers = _server.getBeans(DeploymentManager.class);
+ if (deployers != null && !deployers.isEmpty())
+ {
+ _deploymentManager = deployers.get(0);
+
+ for (AppProvider provider : _deploymentManager.getAppProviders())
+ {
+ if (provider instanceof OSGiAppProvider)
+ {
+ _provider=(OSGiAppProvider)provider;
+ break;
+ }
+ }
+ if (_provider == null)
+ {
+ //create it on the fly with reasonable default values.
+ try
+ {
+ _provider = new OSGiAppProvider();
+ _provider.setMonitoredDir(
+ Resource.newResource(getDefaultOSGiContextsHome(
+ new File(System.getProperty("jetty.home"))).toURI()));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ _deploymentManager.addAppProvider(_provider);
+ }
+ }
+
+ if (_ctxtHandler == null || _provider==null)
+ throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
+
+
+ }
+
+ /**
+ * @return The default folder in which the context files of the osgi bundles
+ * are located and watched. Or null when the system property
+ * "jetty.osgi.contexts.home" is not defined.
+ * If the configuration file defines the OSGiAppProvider's context.
+ * This will not be taken into account.
+ */
+ File getDefaultOSGiContextsHome(File jettyHome)
+ {
+ String jettyContextsHome = System.getProperty("jetty.osgi.contexts.home");
+ if (jettyContextsHome != null)
+ {
+ File contextsHome = new File(jettyContextsHome);
+ if (!contextsHome.exists() || !contextsHome.isDirectory())
+ {
+ throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder");
+ }
+ return contextsHome;
+ }
+ return new File(jettyHome, "/contexts");
+ }
+
+ File getOSGiContextsHome()
+ {
+ return _provider.getContextXmlDirAsFile();
+ }
+
+ /**
+ * @return the urls in this string.
+ */
+ private List<URL> extractResources(String propertyValue)
+ {
+ StringTokenizer tokenizer = new StringTokenizer(propertyValue, ",;", false);
+ List<URL> urls = new ArrayList<URL>();
+ while (tokenizer.hasMoreTokens())
+ {
+ String tok = tokenizer.nextToken();
+ try
+ {
+ urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper
+ .BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok)));
+ }
+ catch (Throwable mfe)
+ {
+
+ }
+ }
+ return urls;
+ }
+
+ /**
+ * Get the folders that might contain jars for the legacy J2EE shared libraries
+ */
+ private List<File> extractFiles(String propertyValue)
+ {
+ StringTokenizer tokenizer = new StringTokenizer(propertyValue, ",;", false);
+ List<File> files = new ArrayList<File>();
+ while (tokenizer.hasMoreTokens())
+ {
+ String tok = tokenizer.nextToken();
+ try
+ {
+ URL url = new URL(tok);
+ url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper
+ .BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url);
+ if (url.getProtocol().equals("file"))
+ {
+ Resource res = Resource.newResource(url);
+ File folder = res.getFile();
+ if (folder != null)
+ {
+ files.add(folder);
+ }
+ }
+ }
+ catch (Throwable mfe)
+ {
+
+ }
+ }
+ return files;
+ }
+
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java
new file mode 100644
index 0000000000..8805561480
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java
@@ -0,0 +1,84 @@
+// ========================================================================
+// Copyright (c) 2010 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.
+// Contributors:
+// Hugues Malphettes - initial API and implementation
+// ========================================================================
+package org.eclipse.jetty.osgi.boot.internal.webapp;
+
+import org.eclipse.jetty.deploy.ContextDeployer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.osgi.framework.Bundle;
+
+/**
+ * Internal interface for the class that deploys a webapp on a server.
+ * Used as we migrate from the single instance of the jety server to multiple jetty servers.
+ */
+public interface IWebBundleDeployerHelper {
+
+ /** when this property is present, the type of context handler registered is not
+ * known in advance. */
+ public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType";
+
+
+ /**
+ * Deploy a new web application on the jetty server.
+ *
+ * @param bundle
+ * The bundle
+ * @param webappFolderPath
+ * The path to the root of the webapp. Must be a path relative to
+ * bundle; either an absolute path.
+ * @param contextPath
+ * The context path. Must start with "/"
+ * @param extraClasspath
+ * @param overrideBundleInstallLocation
+ * @param webXmlPath
+ * @param defaultWebXmlPath
+ * TODO: parameter description
+ * @return The contexthandler created and started
+ * @throws Exception
+ */
+ public abstract WebAppContext registerWebapplication(Bundle bundle,
+ String webappFolderPath, String contextPath, String extraClasspath,
+ String overrideBundleInstallLocation, String webXmlPath,
+ String defaultWebXmlPath, WebAppContext webAppContext) throws Exception;
+
+ /**
+ * Stop a ContextHandler and remove it from the collection.
+ *
+ * @see ContextDeployer#undeploy
+ * @param contextHandler
+ * @throws Exception
+ */
+ public abstract void unregister(ContextHandler contextHandler)
+ throws Exception;
+
+ /**
+ * This type of registration relies on jetty's complete context xml file.
+ * Context encompasses jndi and all other things. This makes the definition
+ * of the webapp a lot more self-contained.
+ *
+ * @param contributor
+ * @param contextFileRelativePath
+ * @param extraClasspath
+ * @param overrideBundleInstallLocation
+ * @param handler the context handler passed in the server
+ * reference that will be configured, deployed and started.
+ * @return The contexthandler created and started
+ * @throws Exception
+ */
+ public abstract ContextHandler registerContext(Bundle contributor,
+ String contextFileRelativePath, String extraClasspath,
+ String overrideBundleInstallLocation, ContextHandler handler) throws Exception;
+
+} \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java
index 153267b1d8..efb908239a 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java
@@ -13,12 +13,15 @@
package org.eclipse.jetty.osgi.boot.internal.webapp;
import java.io.File;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
+import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
-import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -49,62 +52,26 @@ import org.osgi.framework.ServiceReference;
public class JettyContextHandlerServiceTracker implements ServiceListener
{
- private final WebappRegistrationHelper _helper;
+ /** New style: ability to manage multiple jetty instances */
+ private final IManagedJettyServerRegistry _registry;
/** The context-handler to deactivate indexed by context handler */
private Map<ServiceReference, ContextHandler> _indexByServiceReference = new HashMap<ServiceReference, ContextHandler>();
/**
- * The index is the bundle-symbolic-name/paht/to/context/file when there is
- * such thing
+ * The index is the bundle-symbolic-name/path/to/context/file when there is such thing
*/
private Map<String, ServiceReference> _indexByContextFile = new HashMap<String, ServiceReference>();
- /** or null when */
- private String _osgiContextHomeFolderCanonicalPath;
/** in charge of detecting changes in the osgi contexts home folder. */
private Scanner _scanner;
/**
- * @param context
- * @param server
+ * @param registry
*/
- public JettyContextHandlerServiceTracker(BundleContext context, Server server) throws Exception
+ public JettyContextHandlerServiceTracker(IManagedJettyServerRegistry registry) throws Exception
{
- _helper = new WebappRegistrationHelper(server);
- _helper.setup(context,new HashMap<String, String>());
- File contextHome = _helper.getOSGiContextsHome();
- if (contextHome != null)
- {
- _osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
- _scanner = new Scanner();
- _scanner.setRecursive(true);
- _scanner.setReportExistingFilesOnStartup(false);
- _scanner.addListener(new Scanner.DiscreteListener()
- {
- public void fileAdded(String filename) throws Exception
- {
- // adding a file does not create a new app,
- // it just reloads it with the new custom file.
- // well, if the file does not define a context handler,
- // then in fact it does remove it.
- reloadJettyContextHandler(filename);
- }
-
- public void fileChanged(String filename) throws Exception
- {
- reloadJettyContextHandler(filename);
- }
-
- public void fileRemoved(String filename) throws Exception
- {
- // removing a file does not remove the app:
- // it just goes back to the default embedded in the bundle.
- // well, if there was no default then it does remove it.
- reloadJettyContextHandler(filename);
- }
- });
- }
+ _registry = registry;
}
public void stop()
@@ -117,6 +84,49 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
// nothing to stop in the WebappRegistrationHelper
}
+
+ /**
+ * @param contextHome Parent folder where the context files can override the context files
+ * defined in the web bundles: equivalent to the contexts folder in a traditional
+ * jetty installation.
+ * when null, just do nothing.
+ */
+ protected void setupContextHomeScanner(File contextHome) throws IOException
+ {
+ if (contextHome == null)
+ {
+ return;
+ }
+ final String osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
+ _scanner = new Scanner();
+ _scanner.setRecursive(true);
+ _scanner.setReportExistingFilesOnStartup(false);
+ _scanner.addListener(new Scanner.DiscreteListener()
+ {
+ public void fileAdded(String filename) throws Exception
+ {
+ // adding a file does not create a new app,
+ // it just reloads it with the new custom file.
+ // well, if the file does not define a context handler,
+ // then in fact it does remove it.
+ reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
+ }
+
+ public void fileChanged(String filename) throws Exception
+ {
+ reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
+ }
+
+ public void fileRemoved(String filename) throws Exception
+ {
+ // removing a file does not remove the app:
+ // it just goes back to the default embedded in the bundle.
+ // well, if there was no default then it does remove it.
+ reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
+ }
+ });
+
+ }
/**
* Receives notification that a service has had a lifecycle change.
@@ -137,7 +147,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
{
try
{
- _helper.unregister(ctxtHandler);
+ getWebBundleDeployerHelp(sr).unregister(ctxtHandler);
}
catch (Exception e)
{
@@ -146,15 +156,15 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
}
}
}
- if (ev.getType() == ServiceEvent.UNREGISTERING)
- {
- break;
- }
- else
- {
- // modified, meaning: we reload it. now that we stopped it;
- // we can register it.
- }
+ if (ev.getType() == ServiceEvent.UNREGISTERING)
+ {
+ break;
+ }
+ else
+ {
+ // modified, meaning: we reload it. now that we stopped it;
+ // we can register it.
+ }
case ServiceEvent.REGISTERED:
{
Bundle contributor = sr.getBundle();
@@ -165,7 +175,11 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
// is configured elsewhere.
return;
}
- if (contextHandler instanceof WebAppContext)
+ String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
+ if (contextHandler instanceof WebAppContext && contextFilePath == null)
+ //it could be a web-application that will in fact be configured via a context file.
+ //that case is identified by the fact that the contextFilePath is not null
+ //in that case we must use the register context methods.
{
WebAppContext webapp = (WebAppContext)contextHandler;
String contextPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
@@ -186,13 +200,23 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
String war = (String)sr.getProperty("war");
try
{
- ContextHandler handler = _helper.registerWebapplication(contributor,war,contextPath,(String)sr
+ IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr);
+ if (deployerHelper == null)
+ {
+
+ }
+ else
+ {
+ WebAppContext handler = deployerHelper
+ .registerWebapplication(contributor,war,contextPath,(String)sr
.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),(String)sr
- .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),webXmlPath,defaultWebXmlPath);
- if (handler != null)
- {
- registerInIndex(handler,sr);
- }
+ .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),
+ webXmlPath,defaultWebXmlPath,webapp);
+ if (handler != null)
+ {
+ registerInIndex(handler,sr);
+ }
+ }
}
catch (Throwable e)
{
@@ -202,20 +226,33 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
else
{
// consider this just an empty skeleton:
- String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
if (contextFilePath == null)
{
throw new IllegalArgumentException("the property contextFilePath is required");
}
try
{
- ContextHandler handler = _helper.registerContext(contributor,contextFilePath,(String)sr
- .getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),(String)sr
- .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE));
- if (handler != null)
- {
- registerInIndex(handler,sr);
- }
+ IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr);
+ if (deployerHelper == null)
+ {
+ //more warnings?
+ }
+ else
+ {
+ if (Boolean.TRUE.toString().equals(sr.getProperty(
+ IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE)))
+ {
+ contextHandler = null;
+ }
+ ContextHandler handler = deployerHelper.registerContext(contributor,contextFilePath,
+ (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),
+ (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),
+ contextHandler);
+ if (handler != null)
+ {
+ registerInIndex(handler,sr);
+ }
+ }
}
catch (Throwable e)
{
@@ -279,9 +316,9 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
*
* @param contextFileFully
*/
- void reloadJettyContextHandler(String canonicalNameOfFileChanged)
+ public void reloadJettyContextHandler(String canonicalNameOfFileChanged, String osgiContextHomeFolderCanonicalPath)
{
- String key = getNormalizedRelativePath(canonicalNameOfFileChanged);
+ String key = getNormalizedRelativePath(canonicalNameOfFileChanged, osgiContextHomeFolderCanonicalPath);
if (key == null)
{
return;
@@ -299,16 +336,45 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
* @param canFilename
* @return
*/
- private String getNormalizedRelativePath(String canFilename)
+ private String getNormalizedRelativePath(String canFilename, String osgiContextHomeFolderCanonicalPath)
{
- if (!canFilename.startsWith(_osgiContextHomeFolderCanonicalPath))
+ if (!canFilename.startsWith(osgiContextHomeFolderCanonicalPath))
{
// why are we here: this does not look like a child of the osgi
// contexts home.
// warning?
return null;
}
- return canFilename.substring(_osgiContextHomeFolderCanonicalPath.length()).replace('\\','/');
+ return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\','/');
}
-
+
+ /**
+ * @return The server on which this webapp is meant to be deployed
+ */
+ private ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
+ {
+ if (_registry == null)
+ {
+ return null;
+ }
+ if (managedServerName == null)
+ {
+ managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
+ }
+ ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName);
+ System.err.println("Returning " + managedServerName + " = " + wrapper);
+ return wrapper;
+ }
+
+ private IWebBundleDeployerHelper getWebBundleDeployerHelp(ServiceReference sr)
+ {
+ if (_registry == null)
+ {
+ return null;
+ }
+ String managedServerName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName);
+ return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null;
+ }
+
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyHomeHelper.java
deleted file mode 100644
index c6f7c3db49..0000000000
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyHomeHelper.java
+++ /dev/null
@@ -1,272 +0,0 @@
-// ========================================================================
-// Copyright (c) 2009 Intalio, Inc.
-// ------------------------------------------------------------------------
-// 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.osgi.boot.internal.webapp;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import org.eclipse.jetty.util.URIUtil;
-
-/**
- * <p>
- * Magically extract the jettyhome folder from this bundle's jar place it
- * somewhere in the file-system. Currently we do this only when we detect a
- * system property 'jetty.magic.home.parent' or if we are inside the pde in dev
- * mode. In dev mode we use the osgi.configuration.area folder.
- * </p>
- * <p>
- * This work is done through the jetty launch configuration inside the
- * "Jetty Config" tab. We could choose to remove this code at some point
- * although it does not hurt and it helps for users who don't go through the
- * jetty launch.
- * </p>
- */
-class JettyHomeHelper
-{
-
- /** only magically extract jettyhome if we are inside the pde. */
- static boolean magic_install_only_in_pde = Boolean.valueOf(System.getProperty("jetty.magic.home.pde.only","true"));
-
- /**
- * Hack for eclipse-PDE. When no jetty.home was set, detect if we running
- * inside eclipse-PDE in development mode. In that case extract the
- * jettyhome folder embedded inside this plugin inside the configuration
- * area folder. It is specific to the workspace. Set the folder as
- * jetty.home. If the folder already exist don't extract it again.
- * <p>
- * If we are not pde dev mode, the same but look in the installation folder
- * of eclipse itself.
- * </p>
- *
- * @return
- * @throws URISyntaxException
- */
- static String setupJettyHomeInEclipsePDE(File thisbundlejar)
- {
- File ecFolder = getParentFolderOfMagicHome();
- if (ecFolder == null || !ecFolder.exists())
- {
- return null;
- }
- File jettyhome = new File(ecFolder,"jettyhome");
- String path;
- try
- {
- path = jettyhome.getCanonicalPath();
- if (jettyhome.exists())
- {
- System.setProperty("jetty.home",path);
- return path;
- }
- else
- {
- // now grab the jar and unzip the relevant portion
- unzipJettyHomeIntoDirectory(thisbundlejar,ecFolder);
- System.setProperty("jetty.home",path);
- return path;
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * @return true when we are currently being run by the pde in development
- * mode.
- */
- private static boolean isPDEDevelopment()
- {
- String eclipseCommands = System.getProperty("eclipse.commands");
- // detect if we are being run from the pde: ie during development.
- return eclipseCommands != null && eclipseCommands.indexOf("-dev") != -1
- && (eclipseCommands.indexOf("-dev\n") != -1 || eclipseCommands.indexOf("-dev\r") != -1 || eclipseCommands.indexOf("-dev ") != -1);
- }
-
- /**
- * @return
- */
- private static File getConfigurationAreaDirectory()
- {
- return getFile(System.getProperty("osgi.configuration.area"));
- }
-
- /**
- * @param zipFile
- * The current jar file for this bundle. contains an archive of
- * the default jettyhome
- * @param parentOfMagicJettyHome
- * The folder inside which jettyhome is created.
- */
- private static void unzipJettyHomeIntoDirectory(File thisbundlejar, File parentOfMagicJettyHome) throws IOException
- {
- ZipFile zipFile = null;
- try
- {
- zipFile = new ZipFile(thisbundlejar);
- Enumeration<? extends ZipEntry> files = zipFile.entries();
- File f = null;
- FileOutputStream fos = null;
-
- while (files.hasMoreElements())
- {
- try
- {
- ZipEntry entry = files.nextElement();
- String entryName = entry.getName();
- if (!entryName.startsWith("jettyhome"))
- {
- continue;
- }
-
- InputStream eis = zipFile.getInputStream(entry);
- byte[] buffer = new byte[1024];
- int bytesRead = 0;
- f = new File(parentOfMagicJettyHome,entry.getName());
-
- if (entry.isDirectory())
- {
- f.mkdirs();
- }
- else
- {
- f.getParentFile().mkdirs();
- f.createNewFile();
- fos = new FileOutputStream(f);
- while ((bytesRead = eis.read(buffer)) != -1)
- {
- fos.write(buffer,0,bytesRead);
- }
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- continue;
- }
- finally
- {
- if (fos != null)
- {
- try
- {
- fos.close();
- }
- catch (IOException e)
- {
- }
- fos = null;
- }
- }
- }
- }
- finally
- {
- if (zipFile != null)
- try
- {
- zipFile.close();
- }
- catch (Throwable t)
- {
- }
- }
- }
-
- /**
- * Look for the parent folder that contains jettyhome. Can be specified by
- * the sys property jetty.magic.home.parent or if inside the pde will
- * default on the configuration area. Otherwise returns null.
- *
- * @return The folder inside which jettyhome should be placed.
- */
- private static File getParentFolderOfMagicHome()
- {
- // for (java.util.Map.Entry<Object, Object> e :
- // System.getProperties().entrySet()) {
- // System.err.println(e.getKey() + " -> " + e.getValue());
- // }
- String magicParent = WebappRegistrationHelper.stripQuotesIfPresent(System.getProperty("jetty.magic.home.parent"));
- String magicParentValue = magicParent != null?System.getProperty(magicParent):null;
- File specifiedMagicParent = magicParentValue != null?getFile(magicParentValue) // in
- // that
- // case
- // it
- // was
- // pointing
- // to
- // another
- // system
- // property.
- :getFile(magicParent); // in that case it was directly a file.
- if (specifiedMagicParent != null && specifiedMagicParent.exists())
- {
- return specifiedMagicParent;
- }
- if (isPDEDevelopment())
- {
- return getConfigurationAreaDirectory();
- }
- return null;
- }
-
- /**
- * Be flexible with the url/uri/path that can be the value of the various
- * system properties.
- *
- * @param file
- * @return a file. might not exist.
- */
- private static File getFile(String file)
- {
- if (file == null)
- {
- return null;
- }
- file = WebappRegistrationHelper.stripQuotesIfPresent(file);
- try
- {
- if (file.startsWith("file:/"))
- {
- if (!file.startsWith("file://"))
- {
- return new File(new URI(URIUtil.encodePath(file)));
- }
- else
- {
- return new File(new URL(file).toURI());
- }
- }
- else
- {
- return new File(file);
- }
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- return new File(file);
- }
-
- }
-}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
index e93585277d..ee5e3c97de 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
@@ -19,6 +19,7 @@ import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -91,9 +92,13 @@ public class LibExtClassLoaderHelper
* is the JettyBootStrapper (an osgi classloader.
* @throws MalformedURLException
*/
- public static URLClassLoader createLibEtcClassLoaderHelper(File jettyHome, Server server, ClassLoader parentClassLoader) throws MalformedURLException
+ public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server,
+ ClassLoader parentClassLoader) throws MalformedURLException
{
-
+ if (jettyHome == null)
+ {
+ return parentClassLoader;
+ }
ArrayList<URL> urls = new ArrayList<URL>();
File jettyResources = new File(jettyHome,"resources");
if (jettyResources.exists())
@@ -139,6 +144,52 @@ public class LibExtClassLoaderHelper
}
/**
+ * @param server
+ * @return a url classloader with the jars of resources, lib/ext and the
+ * jars passed in the other argument. The parent classloader usually
+ * is the JettyBootStrapper (an osgi classloader).
+ * If there was no extra jars to insert, then just return the parentClassLoader.
+ * @throws MalformedURLException
+ */
+ public static ClassLoader createLibExtClassLoader(List<File> jarsContainerOrJars,
+ List<URL> otherJarsOrFolder, Server server,
+ ClassLoader parentClassLoader) throws MalformedURLException
+ {
+ if (jarsContainerOrJars == null && otherJarsOrFolder == null)
+ {
+ return parentClassLoader;
+ }
+ List<URL> urls = new ArrayList<URL>();
+ if (otherJarsOrFolder != null)
+ {
+ urls.addAll(otherJarsOrFolder);
+ }
+ if (jarsContainerOrJars != null)
+ {
+ for (File libExt : jarsContainerOrJars)
+ {
+ if (libExt.isDirectory())
+ {
+ for (File f : libExt.listFiles())
+ {
+ if (f.getName().endsWith(".jar"))
+ {
+ // cheap to tolerate folders so let's do it.
+ URL url = f.toURI().toURL();
+ if (f.isFile())
+ {// is this necessary anyways?
+ url = new URL("jar:" + url.toString() + "!/");
+ }
+ urls.add(url);
+ }
+ }
+ }
+ }
+ }
+ return new URLClassLoader(urls.toArray(new URL[urls.size()]),parentClassLoader);
+ }
+
+ /**
* When we find files typically used for central logging configuration we do
* what it takes in this method to do what the user expects. Without
* depending too much directly on a particular logging framework.
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
index 50cec93fda..13c097e85e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
@@ -29,18 +29,20 @@ import java.util.jar.JarFile;
import javax.servlet.http.HttpServlet;
+import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
/**
* Extends the webappclassloader to insert the classloader provided by the osgi
* bundle at the same level than any other jars palced in the webappclassloader.
*/
-public class OSGiWebappClassLoader extends WebAppClassLoader
+public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference
{
private Logger __logger = Log.getLogger(OSGiWebappClassLoader.class.getName().toString());
@@ -67,14 +69,34 @@ public class OSGiWebappClassLoader extends WebAppClassLoader
}
private ClassLoader _osgiBundleClassLoader;
+ private Bundle _contributor;
private boolean _lookInOsgiFirst = true;
private Set<String> _libsAlreadyInManifest = new HashSet<String>();
- public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor) throws IOException
+ /**
+ * @param parent The parent classloader. In this case
+ * @param context The WebAppContext
+ * @param contributor The bundle that defines this web-application.
+ * @throws IOException
+ */
+ public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor,
+ BundleClassLoaderHelper bundleClassLoaderHelper) throws IOException
{
super(parent,context);
- _osgiBundleClassLoader = WebappRegistrationHelper.BUNDLE_CLASS_LOADER_HELPER.getBundleClassLoader(contributor);
+ _contributor = contributor;
+ _osgiBundleClassLoader = bundleClassLoaderHelper.getBundleClassLoader(contributor);
}
+
+ /**
+ * Returns the <code>Bundle</code> that defined this web-application.
+ *
+ * @return The <code>Bundle</code> object associated with this
+ * <code>BundleReference</code>.
+ */
+ public Bundle getBundle()
+ {
+ return _contributor;
+ }
/**
* Reads the manifest. If the manifest is already configured to loads a few
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
new file mode 100644
index 0000000000..f43dbb31df
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
@@ -0,0 +1,619 @@
+// ========================================================================
+// Copyright (c) 2009 Intalio, Inc.
+// ------------------------------------------------------------------------
+// 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.
+// Contributors:
+// Hugues Malphettes - initial API and implementation
+// ========================================================================
+package org.eclipse.jetty.osgi.boot.internal.webapp;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+import org.eclipse.jetty.deploy.ContextDeployer;
+import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
+import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
+import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
+import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper;
+import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.xml.XmlConfiguration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.xml.sax.SAXException;
+
+/**
+ * Bridges the jetty deployers with the OSGi lifecycle where applications are
+ * managed inside OSGi-bundles.
+ * <p>
+ * This class should be called as a consequence of the activation of a new
+ * service that is a ContextHandler.<br/>
+ * This way the new webapps are exposed as OSGi services.
+ * </p>
+ * <p>
+ * Helper methods to register a bundle that is a web-application or a context.
+ * </p>
+ * Limitations:
+ * <ul>
+ * <li>support for jarred webapps is somewhat limited.</li>
+ * </ul>
+ */
+public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
+{
+
+ private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName());
+
+ private static boolean INITIALIZED = false;
+
+ /**
+ * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
+ * equinox and apache-felix fragment bundles that are specific to an OSGi
+ * implementation should set a different implementation.
+ */
+ public static BundleClassLoaderHelper BUNDLE_CLASS_LOADER_HELPER = null;
+ /**
+ * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
+ * equinox and apache-felix fragment bundles that are specific to an OSGi
+ * implementation should set a different implementation.
+ */
+ public static BundleFileLocatorHelper BUNDLE_FILE_LOCATOR_HELPER = null;
+
+ /**
+ * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
+ * equinox and apache-felix fragment bundles that are specific to an OSGi
+ * implementation should set a different implementation.
+ * <p>
+ * Several of those objects can be added here: For example we could have an optional fragment that setups
+ * a specific implementation of JSF for the whole of jetty-osgi.
+ * </p>
+ */
+ public static Collection<WebappRegistrationCustomizer> JSP_REGISTRATION_HELPERS = new ArrayList<WebappRegistrationCustomizer>();
+
+ /**
+ * this class loader loads the jars inside {$jetty.home}/lib/ext it is meant
+ * as a migration path and for jars that are not OSGi ready. also gives
+ * access to the jsp jars.
+ */
+ // private URLClassLoader _libExtClassLoader;
+
+ private ServerInstanceWrapper _wrapper;
+
+ public WebBundleDeployerHelper(ServerInstanceWrapper wrapper)
+ {
+ staticInit();
+ _wrapper = wrapper;
+ }
+
+ // Inject the customizing classes that might be defined in fragment bundles.
+ public static synchronized void staticInit()
+ {
+ if (!INITIALIZED)
+ {
+ INITIALIZED = true;
+ // setup the custom BundleClassLoaderHelper
+ try
+ {
+ BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance();
+ }
+ catch (Throwable t)
+ {
+ // System.err.println("support for equinox and felix");
+ BUNDLE_CLASS_LOADER_HELPER = new DefaultBundleClassLoaderHelper();
+ }
+ // setup the custom FileLocatorHelper
+ try
+ {
+ BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance();
+ }
+ catch (Throwable t)
+ {
+ // System.err.println("no jsp/jasper support");
+ BUNDLE_FILE_LOCATOR_HELPER = new DefaultFileLocatorHelper();
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+ */
+ public WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
+ String overrideBundleInstallLocation, String webXmlPath, String defaultWebXmlPath, WebAppContext webAppContext) throws Exception
+ {
+ File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File(
+ overrideBundleInstallLocation);
+ File webapp = null;
+ URL baseWebappInstallURL = null;
+ if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals("."))
+ {
+ if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:"))
+ {
+ webapp = new File(webappFolderPath);
+ }
+ else if (bundleInstall != null && bundleInstall.isDirectory())
+ {
+ webapp = new File(bundleInstall,webappFolderPath);
+ }
+ else if (bundleInstall != null)
+ {
+ Enumeration<URL> urls = BUNDLE_FILE_LOCATOR_HELPER.findEntries(bundle, webappFolderPath);
+ if (urls != null && urls.hasMoreElements())
+ {
+ baseWebappInstallURL = urls.nextElement();
+ }
+ }
+ }
+ else
+ {
+ webapp = bundleInstall;
+ }
+ if (baseWebappInstallURL == null && (webapp == null || !webapp.exists()))
+ {
+ throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside "
+ + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'"));
+ }
+ if (baseWebappInstallURL == null && webapp != null)
+ {
+ baseWebappInstallURL = webapp.toURI().toURL();
+ }
+ return registerWebapplication(bundle,webappFolderPath,baseWebappInstallURL,contextPath,
+ extraClasspath,bundleInstall,webXmlPath,defaultWebXmlPath,webAppContext);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.io.File, java.lang.String, java.lang.String, java.io.File, java.lang.String, java.lang.String)
+ */
+ private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp,
+ URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall,
+ String webXmlPath, String defaultWebXmlPath, WebAppContext context) throws Exception
+ {
+
+ ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
+ String[] oldServerClasses = null;
+
+ try
+ {
+ // make sure we provide access to all the jetty bundles by going
+ // through this bundle.
+ OSGiWebappClassLoader composite = createWebappClassLoader(contributor);
+ // configure with access to all jetty classes and also all the classes
+ // that the contributor gives access to.
+ Thread.currentThread().setContextClassLoader(composite);
+
+ context.setWar(baseWebappInstallURL.toString());
+ context.setContextPath(contextPath);
+ context.setExtraClasspath(extraClasspath);
+
+ if (webXmlPath != null && webXmlPath.length() != 0)
+ {
+ File webXml = null;
+ if (webXmlPath.startsWith("/") || webXmlPath.startsWith("file:/"))
+ {
+ webXml = new File(webXmlPath);
+ }
+ else
+ {
+ webXml = new File(bundleInstall,webXmlPath);
+ }
+ if (webXml.exists())
+ {
+ context.setDescriptor(webXml.getAbsolutePath());
+ }
+ }
+
+ if (defaultWebXmlPath == null || defaultWebXmlPath.length() == 0)
+ {
+ //use the one defined by the OSGiAppProvider.
+ defaultWebXmlPath = _wrapper.getOSGiAppProvider().getDefaultsDescriptor();
+ }
+ if (defaultWebXmlPath != null && defaultWebXmlPath.length() != 0)
+ {
+ File defaultWebXml = null;
+ if (defaultWebXmlPath.startsWith("/") || defaultWebXmlPath.startsWith("file:/"))
+ {
+ defaultWebXml = new File(webXmlPath);
+ }
+ else
+ {
+ defaultWebXml = new File(bundleInstall,defaultWebXmlPath);
+ }
+ if (defaultWebXml.exists())
+ {
+ context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath());
+ }
+ }
+
+ //other parameters that might be defines on the OSGiAppProvider:
+ context.setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
+
+ configureWebAppContext(context,contributor);
+ configureWebappClassLoader(contributor,context,composite);
+
+ // @see
+ // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
+ // during initialization of the webapp all the jetty packages are
+ // visible
+ // through the webapp classloader.
+ oldServerClasses = context.getServerClasses();
+ context.setServerClasses(null);
+
+ _wrapper.getOSGiAppProvider().addContext(contributor,pathInBundleToWebApp,context);
+
+ return context;
+ }
+ finally
+ {
+ if (context != null && oldServerClasses != null)
+ {
+ context.setServerClasses(oldServerClasses);
+ }
+ Thread.currentThread().setContextClassLoader(contextCl);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#unregister(org.eclipse.jetty.server.handler.ContextHandler)
+ */
+ public void unregister(ContextHandler contextHandler) throws Exception
+ {
+ _wrapper.getOSGiAppProvider().removeContext(contextHandler);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerContext(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String)
+ */
+ public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath,
+ String overrideBundleInstallLocation, ContextHandler handler)
+ throws Exception
+ {
+ File contextsHome = _wrapper.getOSGiAppProvider().getContextXmlDirAsFile();
+ if (contextsHome != null)
+ {
+ File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath);
+ if (prodContextFile.exists())
+ {
+ return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath,
+ overrideBundleInstallLocation,handler);
+ }
+ }
+ File rootFolder = overrideBundleInstallLocation != null
+ ? Resource.newResource(overrideBundleInstallLocation).getFile()
+ : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor);
+ File contextFile = rootFolder != null?new File(rootFolder,contextFileRelativePath):null;
+ if (contextFile != null && contextFile.exists())
+ {
+ return registerContext(contributor,contextFileRelativePath,contextFile,extraClasspath,overrideBundleInstallLocation,handler);
+ }
+ else
+ {
+ if (contextFileRelativePath.startsWith("./"))
+ {
+ contextFileRelativePath = contextFileRelativePath.substring(1);
+ }
+ if (!contextFileRelativePath.startsWith("/"))
+ {
+ contextFileRelativePath = "/" + contextFileRelativePath;
+ }
+
+ URL contextURL = contributor.getEntry(contextFileRelativePath);
+ if (contextURL != null)
+ {
+ return registerContext(contributor,contextFileRelativePath,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation,handler);
+ }
+ throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle "
+ + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:""));
+ }
+ }
+
+ /**
+ * This type of registration relies on jetty's complete context xml file.
+ * Context encompasses jndi and all other things. This makes the definition
+ * of the webapp a lot more self-contained.
+ *
+ * @param webapp
+ * @param contextPath
+ * @param classInBundle
+ * @throws Exception
+ */
+ private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile,
+ String extraClasspath, String overrideBundleInstallLocation, ContextHandler handler) throws Exception
+ {
+ InputStream contextFileInputStream = null;
+ try
+ {
+ contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile));
+ return registerContext(contributor, pathInBundle, contextFileInputStream,extraClasspath,overrideBundleInstallLocation, handler);
+ }
+ finally
+ {
+ IO.close(contextFileInputStream);
+ }
+ }
+
+ /**
+ * @param contributor
+ * @param contextFileInputStream
+ * @return The ContextHandler created and registered or null if it did not
+ * happen.
+ * @throws Exception
+ */
+ private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream,
+ String extraClasspath, String overrideBundleInstallLocation, ContextHandler handler)
+ throws Exception
+ {
+ ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
+ String[] oldServerClasses = null;
+ WebAppContext webAppContext = null;
+ try
+ {
+ // make sure we provide access to all the jetty bundles by going
+ // through this bundle.
+ OSGiWebappClassLoader composite = createWebappClassLoader(contributor);
+ // configure with access to all jetty classes and also all the
+ // classes
+ // that the contributor gives access to.
+ Thread.currentThread().setContextClassLoader(composite);
+ ContextHandler context = createContextHandler(handler, contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation);
+ if (context == null)
+ {
+ return null;// did not happen
+ }
+
+ // ok now register this webapp. we checked when we started jetty
+ // that there
+ // was at least one such handler for webapps.
+ //the actual registration must happen via the new Deployment API.
+// _ctxtHandler.addHandler(context);
+
+ configureWebappClassLoader(contributor,context,composite);
+ if (context instanceof WebAppContext)
+ {
+ webAppContext = (WebAppContext)context;
+ // @see
+ // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
+ oldServerClasses = webAppContext.getServerClasses();
+ webAppContext.setServerClasses(null);
+ }
+ _wrapper.getOSGiAppProvider().addContext(contributor, pathInsideBundle, context);
+ return context;
+ }
+ finally
+ {
+ if (webAppContext != null)
+ {
+ webAppContext.setServerClasses(oldServerClasses);
+ }
+ Thread.currentThread().setContextClassLoader(contextCl);
+ }
+
+ }
+
+ /**
+ * Applies the properties of WebAppDeployer as defined in jetty.xml.
+ *
+ * @see {WebAppDeployer#scan} around the comment
+ * <code>// configure it</code>
+ */
+ protected void configureWebAppContext(WebAppContext wah, Bundle contributor)
+ {
+ // rfc66
+ wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext());
+
+ //spring-dm-1.2.1 looks for the BundleContext as a different attribute.
+ //not a spec... but if we want to support
+ //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
+ //then we need to do this to:
+ wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(),
+ contributor.getBundleContext());
+
+ }
+
+ /**
+ * @See {@link ContextDeployer#scan}
+ * @param contextFile
+ * @return
+ */
+ protected ContextHandler createContextHandler(ContextHandler handlerToConfigure,
+ Bundle bundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation)
+ {
+ try
+ {
+ return createContextHandler(handlerToConfigure,bundle,new BufferedInputStream(new FileInputStream(contextFile)),extraClasspath,overrideBundleInstallLocation);
+ }
+ catch (FileNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * @See {@link ContextDeployer#scan}
+ * @param contextFile
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ protected ContextHandler createContextHandler(ContextHandler handlerToConfigure,
+ Bundle bundle, InputStream contextInputStream, String extraClasspath, String overrideBundleInstallLocation)
+ {
+ /*
+ * Do something identical to what the ContextProvider would have done:
+ * XmlConfiguration xmlConfiguration=new
+ * XmlConfiguration(resource.getURL()); HashMap properties = new
+ * HashMap(); properties.put("Server", _contexts.getServer()); if
+ * (_configMgr!=null) properties.putAll(_configMgr.getProperties());
+ *
+ * xmlConfiguration.setProperties(properties); ContextHandler
+ * context=(ContextHandler)xmlConfiguration.configure();
+ * context.setAttributes(new AttributesMap(_contextAttributes));
+ */
+ try
+ {
+ XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream);
+ HashMap properties = new HashMap();
+ properties.put("Server",_wrapper.getServer());
+
+ // insert the bundle's location as a property.
+ setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation);
+ xmlConfiguration.setProperties(properties);
+
+ ContextHandler context = null;
+ if (handlerToConfigure == null)
+ {
+ context = (ContextHandler)xmlConfiguration.configure();
+ }
+ else
+ {
+ xmlConfiguration.configure(handlerToConfigure);
+ context = handlerToConfigure;
+ }
+
+ if (context instanceof WebAppContext)
+ {
+ ((WebAppContext)context).setExtraClasspath(extraClasspath);
+ ((WebAppContext)context).setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
+ if (_wrapper.getOSGiAppProvider().getDefaultsDescriptor() != null && _wrapper.getOSGiAppProvider().getDefaultsDescriptor().length() != 0)
+ {
+ ((WebAppContext)context).setDefaultsDescriptor(_wrapper.getOSGiAppProvider().getDefaultsDescriptor());
+ }
+ }
+
+ // rfc-66:
+ context.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,bundle.getBundleContext());
+
+ //spring-dm-1.2.1 looks for the BundleContext as a different attribute.
+ //not a spec... but if we want to support
+ //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
+ //then we need to do this to:
+ context.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(),
+ bundle.getBundleContext());
+ return context;
+ }
+ catch (FileNotFoundException e)
+ {
+ return null;
+ }
+ catch (SAXException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ catch (IOException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ catch (Throwable e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ finally
+ {
+ IO.close(contextInputStream);
+ }
+ return null;
+ }
+
+ /**
+ * Configure a classloader onto the context. If the context is a
+ * WebAppContext, build a WebAppClassLoader that has access to all the jetty
+ * classes thanks to the classloader of the JettyBootStrapper bundle and
+ * also has access to the classloader of the bundle that defines this
+ * context.
+ * <p>
+ * If the context is not a WebAppContext, same but with a simpler
+ * URLClassLoader. Note that the URLClassLoader is pretty much fake: it
+ * delegate all actual classloading to the parent classloaders.
+ * </p>
+ * <p>
+ * The URL[] returned by the URLClassLoader create contained specifically
+ * the jars that some j2ee tools expect and look into. For example the jars
+ * that contain tld files for jasper's jstl support.
+ * </p>
+ * <p>
+ * Also as the jars in the lib folder and the classes in the classes folder
+ * might already be in the OSGi classloader we filter them out of the
+ * WebAppClassLoader
+ * </p>
+ *
+ * @param context
+ * @param contributor
+ * @param webapp
+ * @param contextPath
+ * @param classInBundle
+ * @throws Exception
+ */
+ protected void configureWebappClassLoader(Bundle contributor, ContextHandler context, OSGiWebappClassLoader webappClassLoader) throws Exception
+ {
+ if (context instanceof WebAppContext)
+ {
+ WebAppContext webappCtxt = (WebAppContext)context;
+ context.setClassLoader(webappClassLoader);
+ webappClassLoader.setWebappContext(webappCtxt);
+ }
+ else
+ {
+ context.setClassLoader(webappClassLoader);
+ }
+ }
+
+ /**
+ * No matter what the type of webapp, we create a WebappClassLoader.
+ */
+ protected OSGiWebappClassLoader createWebappClassLoader(Bundle contributor) throws Exception
+ {
+ // we use a temporary WebAppContext object.
+ // if this is a real webapp we will set it on it a bit later: once we
+ // know.
+ OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(
+ _wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER);
+ return webappClassLoader;
+ }
+
+ /**
+ * Set the property &quot;this.bundle.install&quot; to point to the location
+ * of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is
+ * used.
+ */
+ private void setThisBundleHomeProperty(Bundle bundle, HashMap<String, Object> properties, String overrideBundleInstallLocation)
+ {
+ try
+ {
+ File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER
+ .getBundleInstallLocation(bundle);
+ properties.put("this.bundle.install",location.getCanonicalPath());
+ properties.put("this.bundle.install.url",bundle.getEntry("/").toString());
+ }
+ catch (Throwable t)
+ {
+ System.err.println("Unable to set 'this.bundle.install' " + " for the bundle " + bundle.getSymbolicName());
+ t.printStackTrace();
+ }
+ }
+
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerExtender.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
index b82bd29050..df257839fd 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerExtender.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2009 Intalio, Inc.
+// Copyright (c) 2009-2010 Intalio, Inc.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
@@ -18,9 +18,10 @@ import java.util.Dictionary;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+
/**
* Support bundles that declare the webapp directly through headers in their
@@ -46,44 +47,102 @@ import org.osgi.framework.BundleListener;
*
* @author hmalphettes
*/
-public class JettyContextHandlerExtender implements BundleListener
-{
+public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
+
- /**
- * Receives notification that a bundle has had a lifecycle change.
- *
- * @param event
- * The <code>BundleEvent</code>.
- */
- public void bundleChanged(BundleEvent event)
- {
- switch (event.getType())
- {
- case BundleEvent.STARTED:
- register(event.getBundle());
- break;
- case BundleEvent.STOPPING:
- unregister(event.getBundle());
- break;
- }
- }
+ /**
+ * A bundle is being added to the <code>BundleTracker</code>.
+ *
+ * <p>
+ * This method is called before a bundle which matched the search parameters
+ * of the <code>BundleTracker</code> is added to the
+ * <code>BundleTracker</code>. This method should return the object to be
+ * tracked for the specified <code>Bundle</code>. The returned object is
+ * stored in the <code>BundleTracker</code> and is available from the
+ * {@link BundleTracker#getObject(Bundle) getObject} method.
+ *
+ * @param bundle The <code>Bundle</code> being added to the
+ * <code>BundleTracker</code>.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @return The object to be tracked for the specified <code>Bundle</code>
+ * object or <code>null</code> if the specified <code>Bundle</code>
+ * object should not be tracked.
+ */
+ public Object addingBundle(Bundle bundle, BundleEvent event)
+ {
+ if (bundle.getState() == Bundle.ACTIVE)
+ {
+ boolean isWebBundle = register(bundle);
+ return isWebBundle ? bundle : null;
+ }
+ else if (bundle.getState() == Bundle.STOPPING)
+ {
+ unregister(bundle);
+ }
+ else
+ {
+ //we should not be called in that state as
+ //we are registered only for ACTIVE and STOPPING
+ }
+ return null;
+ }
- /**
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been modified.
*
+ * <p>
+ * This method is called when a bundle being tracked by the
+ * <code>BundleTracker</code> has had its state modified.
+ *
+ * @param bundle The <code>Bundle</code> whose state has been modified.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The tracked object for the specified bundle.
*/
- public void init(BundleContext context)
- {
- Bundle bundles[] = context.getBundles();
- for (int i = 0; i < bundles.length; i++)
- {
- if ((bundles[i].getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0)
- {
- register(bundles[i]);
- }
- }
- }
+ public void modifiedBundle(Bundle bundle, BundleEvent event,
+ Object object)
+ {
+ //nothing the web-bundle was already track. something changed.
+ //we only reload the webapps if the bundle is stopped and restarted.
+// System.err.println(bundle.getSymbolicName());
+ if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
+ {
+ unregister(bundle);
+ }
+ if (bundle.getState() == Bundle.ACTIVE)
+ {
+ register(bundle);
+ }
+ }
- private void register(Bundle bundle)
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been removed.
+ *
+ * <p>
+ * This method is called after a bundle is no longer being tracked by the
+ * <code>BundleTracker</code>.
+ *
+ * @param bundle The <code>Bundle</code> that has been removed.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The tracked object for the specified bundle.
+ */
+ public void removedBundle(Bundle bundle, BundleEvent event,
+ Object object)
+ {
+ unregister(bundle);
+ }
+
+
+ /**
+ * @param bundle
+ * @return true if this bundle in indeed a web-bundle.
+ */
+ private boolean register(Bundle bundle)
{
Dictionary<?, ?> dic = bundle.getHeaders();
String warFolderRelativePath = (String)dic.get(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH);
@@ -99,11 +158,13 @@ public class JettyContextHandlerExtender implements BundleListener
try
{
JettyBootstrapActivator.registerWebapplication(bundle,warFolderRelativePath,contextPath);
+ return true;
}
catch (Throwable e)
{
// TODO Auto-generated catch block
e.printStackTrace();
+ return true;//maybe it did not work maybe it did. safer to track this bundle.
}
}
else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null)
@@ -112,7 +173,7 @@ public class JettyContextHandlerExtender implements BundleListener
if (contextFileRelativePath == null)
{
// nothing to register here.
- return;
+ return false;
}
// support for multiple webapps in the same bundle:
String[] pathes = contextFileRelativePath.split(",;");
@@ -128,6 +189,7 @@ public class JettyContextHandlerExtender implements BundleListener
e.printStackTrace();
}
}
+ return true;
}
else
{
@@ -137,7 +199,7 @@ public class JettyContextHandlerExtender implements BundleListener
URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml");
if (rfc66Webxml == null)
{
- return;// no webapp in here
+ return false;// no webapp in here
}
// this is risky: should we make sure that there is no classes and
// jars directly available
@@ -151,11 +213,13 @@ public class JettyContextHandlerExtender implements BundleListener
try
{
JettyBootstrapActivator.registerWebapplication(bundle,".",rfc66ContextPath);
+ return true;
}
catch (Throwable e)
{
// TODO Auto-generated catch block
e.printStackTrace();
+ return true;//maybe it did not work maybe it did. safer to track this bundle.
}
}
}
@@ -195,4 +259,7 @@ public class JettyContextHandlerExtender implements BundleListener
// webapps registered in that bundle.
}
+
+
+
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java
deleted file mode 100644
index 447893d315..0000000000
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java
+++ /dev/null
@@ -1,979 +0,0 @@
-// ========================================================================
-// Copyright (c) 2009 Intalio, Inc.
-// ------------------------------------------------------------------------
-// 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.
-// Contributors:
-// Hugues Malphettes - initial API and implementation
-// ========================================================================
-package org.eclipse.jetty.osgi.boot.internal.webapp;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-
-import org.eclipse.jetty.deploy.AppProvider;
-import org.eclipse.jetty.deploy.ContextDeployer;
-import org.eclipse.jetty.deploy.DeploymentManager;
-import org.eclipse.jetty.deploy.WebAppDeployer;
-import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
-import org.eclipse.jetty.osgi.boot.OSGiAppProvider;
-import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
-import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader;
-import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
-import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
-import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
-import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper;
-import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.handler.ContextHandlerCollection;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.xml.XmlConfiguration;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * Bridges the jetty deployers with the OSGi lifecycle where applications are
- * managed inside OSGi-bundles.
- * <p>
- * This class should be called as a consequence of the activation of a new
- * service that is a ContextHandler.<br/>
- * This way the new webapps are exposed as OSGi services.
- * </p>
- * <p>
- * Helper methods to register a bundle that is a web-application or a context.
- * </p>
- * Limitations:
- * <ul>
- * <li>support for jarred webapps is somewhat limited.</li>
- * </ul>
- */
-public class WebappRegistrationHelper
-{
-
- private static Logger __logger = Log.getLogger(WebappRegistrationHelper.class.getName());
-
- private static boolean INITIALIZED = false;
-
- /**
- * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
- * equinox and apache-felix fragment bundles that are specific to an OSGi
- * implementation should set a different implementation.
- */
- public static BundleClassLoaderHelper BUNDLE_CLASS_LOADER_HELPER = null;
- /**
- * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
- * equinox and apache-felix fragment bundles that are specific to an OSGi
- * implementation should set a different implementation.
- */
- public static BundleFileLocatorHelper BUNDLE_FILE_LOCATOR_HELPER = null;
-
- /**
- * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports
- * equinox and apache-felix fragment bundles that are specific to an OSGi
- * implementation should set a different implementation.
- * <p>
- * Several of those objects can be added here: For example we could have an optional fragment that setups
- * a specific implementation of JSF for the whole of jetty-osgi.
- * </p>
- */
- public static Collection<WebappRegistrationCustomizer> JSP_REGISTRATION_HELPERS = new ArrayList<WebappRegistrationCustomizer>();
-
- private Server _server;
- private ContextHandlerCollection _ctxtHandler;
-
- /**
- * this class loader loads the jars inside {$jetty.home}/lib/ext it is meant
- * as a migration path and for jars that are not OSGi ready. also gives
- * access to the jsp jars.
- */
- // private URLClassLoader _libExtClassLoader;
-
- /**
- * This is the class loader that should be the parent classloader of any
- * webapp classloader. It is in fact the _libExtClassLoader with a trick to
- * let the TldScanner find the jars where the tld files are.
- */
- private URLClassLoader _commonParentClassLoaderForWebapps;
-
- private DeploymentManager _deploymentManager;
-
- private OSGiAppProvider _provider;
-
- public WebappRegistrationHelper(Server server)
- {
- _server = server;
- staticInit();
- }
-
- // Inject the customizing classes that might be defined in fragment bundles.
- private static synchronized void staticInit()
- {
- if (!INITIALIZED)
- {
- INITIALIZED = true;
- // setup the custom BundleClassLoaderHelper
- try
- {
- BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance();
- }
- catch (Throwable t)
- {
- // System.err.println("support for equinox and felix");
- BUNDLE_CLASS_LOADER_HELPER = new DefaultBundleClassLoaderHelper();
- }
- // setup the custom FileLocatorHelper
- try
- {
- BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance();
- }
- catch (Throwable t)
- {
- // System.err.println("no jsp/jasper support");
- BUNDLE_FILE_LOCATOR_HELPER = new DefaultFileLocatorHelper();
- }
- }
- }
-
- /**
- * Removes quotes around system property values before we try to make them
- * into file pathes.
- */
- public static String stripQuotesIfPresent(String filePath)
- {
- if (filePath == null)
- return null;
-
- if ((filePath.startsWith("\"") || filePath.startsWith("'")) && (filePath.endsWith("\"") || filePath.endsWith("'")))
- return filePath.substring(1,filePath.length() - 1);
- return filePath;
- }
-
- /**
- * Look for the home directory of jetty as defined by the system property
- * 'jetty.home'. If undefined, look at the current bundle and uses its own
- * jettyhome folder for this feature.
- * <p>
- * Special case: inside eclipse-SDK:<br/>
- * If the bundle is jarred, see if we are inside eclipse-PDE itself. In that
- * case, look for the installation directory of eclipse-PDE, try to create a
- * jettyhome folder there and install the sample jettyhome folder at that
- * location. This makes the installation in eclipse-SDK easier. <br/>
- * This is a bit redundant with the work done by the jetty configuration
- * launcher.
- * </p>
- *
- * @param context
- * @throws Exception
- */
- public void setup(BundleContext context, Map<String, String> configProperties) throws Exception
- {
- File _installLocation = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(context.getBundle());
- // debug:
- // new File("~/proj/eclipse-install/eclipse-3.5.1-SDK-jetty7/" +
- // "dropins/jetty7/plugins/org.eclipse.jetty.osgi.boot_0.0.1.001-SNAPSHOT.jar");
- boolean bootBundleCanBeJarred = true;
- String jettyHome = stripQuotesIfPresent(System.getProperty("jetty.home"));
-
- if (jettyHome == null || jettyHome.length() == 0)
- {
- if (_installLocation.getName().endsWith(".jar"))
- {
- jettyHome = JettyHomeHelper.setupJettyHomeInEclipsePDE(_installLocation);
- }
- if (jettyHome == null)
- {
- jettyHome = _installLocation.getAbsolutePath() + "/jettyhome";
- bootBundleCanBeJarred = false;
- }
- }
- // in case we stripped the quotes.
- System.setProperty("jetty.home",jettyHome);
-
- String jettyLogs = stripQuotesIfPresent(System.getProperty("jetty.logs"));
- if (jettyLogs == null || jettyLogs.length() == 0)
- {
- System.setProperty("jetty.logs",jettyHome + "/logs");
- }
-
- if (!bootBundleCanBeJarred && !_installLocation.isDirectory())
- {
- String install = _installLocation != null?_installLocation.getCanonicalPath():" unresolved_install_location";
- throw new IllegalArgumentException("The system property -Djetty.home" + " must be set to a directory or the bundle "
- + context.getBundle().getSymbolicName() + " installed here " + install + " must be unjarred.");
-
- }
- try
- {
- System.err.println("JETTY_HOME set to " + new File(jettyHome).getCanonicalPath());
- }
- catch (Throwable t)
- {
- System.err.println("JETTY_HOME _set to " + new File(jettyHome).getAbsolutePath());
- }
-
- ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
- try
- {
-
- // passing this bundle's classloader as the context classlaoder
- // makes sure there is access to all the jetty's bundles
-
- File jettyHomeF = new File(jettyHome);
- URLClassLoader libExtClassLoader = null;
- try
- {
- libExtClassLoader = LibExtClassLoaderHelper.createLibEtcClassLoaderHelper(jettyHomeF,_server,
- JettyBootstrapActivator.class.getClassLoader());
- }
- catch (MalformedURLException e)
- {
- e.printStackTrace();
- }
-
- Thread.currentThread().setContextClassLoader(libExtClassLoader);
-
- String jettyetc = System.getProperty(OSGiWebappConstants.SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
- StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,");
-
- Map<Object,Object> id_map = new HashMap<Object,Object>();
- id_map.put("Server",_server);
- Map<Object,Object> properties = new HashMap<Object,Object>();
- properties.put("jetty.home",jettyHome);
- properties.put("jetty.host",System.getProperty("jetty.host",""));
- properties.put("jetty.port",System.getProperty("jetty.port","8080"));
- properties.put("jetty.port.ssl",System.getProperty("jetty.port.ssl","8443"));
-
- while (tokenizer.hasMoreTokens())
- {
- String etcFile = tokenizer.nextToken().trim();
- File conffile = etcFile.startsWith("/")?new File(etcFile):new File(jettyHomeF,etcFile);
- if (!conffile.exists())
- {
- __logger.warn("Unable to resolve the jetty/etc file " + etcFile);
-
- if ("etc/jetty.xml".equals(etcFile))
- {
- // Missing jetty.xml file, so create a minimal Jetty configuration
- __logger.info("Configuring default server on 8080");
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setPort(8080);
- _server.addConnector(connector);
-
- HandlerCollection handlers = new HandlerCollection();
- ContextHandlerCollection contexts = new ContextHandlerCollection();
- RequestLogHandler requestLogHandler = new RequestLogHandler();
- handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler });
- _server.setHandler(handlers);
- }
- }
- else
- {
- try
- {
- // Execute a Jetty configuration file
- XmlConfiguration config = new XmlConfiguration(new FileInputStream(conffile));
- config.setIdMap(id_map);
- config.setProperties(properties);
- config.configure();
- id_map=config.getIdMap();
- }
- catch (SAXParseException saxparse)
- {
- Log.getLogger(WebappRegistrationHelper.class.getName()).warn("Unable to configure the jetty/etc file " + etcFile,saxparse);
- throw saxparse;
- }
- }
- }
-
- init();
-
- //now that we have an app provider we can call the registration customizer.
- try
- {
- URL[] jarsWithTlds = getJarsWithTlds();
- _commonParentClassLoaderForWebapps = jarsWithTlds == null?libExtClassLoader:new TldLocatableURLClassloader(libExtClassLoader,getJarsWithTlds());
- }
- catch (MalformedURLException e)
- {
- e.printStackTrace();
- }
-
-
- _server.start();
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- }
- finally
- {
- Thread.currentThread().setContextClassLoader(contextCl);
- }
-
- }
-
- /**
- * Must be called after the server is configured.
- *
- * Locate the actual instance of the ContextDeployer and WebAppDeployer that
- * was created when configuring the server through jetty.xml. If there is no
- * such thing it won't be possible to deploy webapps from a context and we
- * throw IllegalStateExceptions.
- */
- private void init()
- {
- // Get the context handler
- _ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class);
-
- // get a deployerManager
- List<DeploymentManager> deployers = _server.getBeans(DeploymentManager.class);
- if (deployers != null && !deployers.isEmpty())
- {
- _deploymentManager = deployers.get(0);
-
- for (AppProvider provider : _deploymentManager.getAppProviders())
- {
- if (provider instanceof OSGiAppProvider)
- {
- _provider=(OSGiAppProvider)provider;
- break;
- }
- }
- if (_provider == null)
- {
- //create it on the fly with reasonable default values.
- try
- {
- _provider = new OSGiAppProvider();
- _provider.setMonitoredDir(
- Resource.newResource(getDefaultOSGiContextsHome(
- new File(System.getProperty("jetty.home"))).toURI()));
- } catch (IOException e) {
- e.printStackTrace();
- }
- _deploymentManager.addAppProvider(_provider);
- }
- }
-
- if (_ctxtHandler == null || _provider==null)
- throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
-
-
- }
-
- /**
- * Deploy a new web application on the jetty server.
- *
- * @param context
- * The current bundle context
- * @param webappFolderPath
- * The path to the root of the webapp. Must be a path relative to
- * bundle; either an absolute path.
- * @param contextPath
- * The context path. Must start with "/"
- * @param classInBundle
- * A class that belongs to the current bundle to inherit from the
- * osgi classloader. Null to not have access to the OSGI
- * classloader.
- * @throws Exception
- */
- public ContextHandler registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
- String overrideBundleInstallLocation, String webXmlPath, String defaultWebXmlPath) throws Exception
- {
- File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File(
- overrideBundleInstallLocation);
- File webapp = null;
- if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals("."))
- {
- if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:/"))
- {
- webapp = new File(webappFolderPath);
- }
- else
- {
- webapp = new File(bundleInstall,webappFolderPath);
- }
- }
- else
- {
- webapp = bundleInstall;
- }
- if (!webapp.exists())
- {
- throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside "
- + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'"));
- }
- return registerWebapplication(bundle,webapp,contextPath,extraClasspath,bundleInstall,webXmlPath,defaultWebXmlPath);
- }
-
- /**
- * @See {@link WebAppDeployer#scan()}
- * TODO: refacotr this into the createContext method of OSGiAppProvider.
- *
- * @param webapp
- * @param contextPath
- * @param classInBundle
- * @return The contexthandler created and started
- * @throws Exception
- */
- public ContextHandler registerWebapplication(Bundle contributor, File webapp, String contextPath, String extraClasspath, File bundleInstall,
- String webXmlPath, String defaultWebXmlPath) throws Exception
- {
-
- ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
- String[] oldServerClasses = null;
- WebAppContext context = null;
- try
- {
- // make sure we provide access to all the jetty bundles by going
- // through this bundle.
- OSGiWebappClassLoader composite = createWebappClassLoader(contributor);
- // configure with access to all jetty classes and also all the classes
- // that the contributor gives access to.
- Thread.currentThread().setContextClassLoader(composite);
-
- context = new WebAppContext(webapp.getAbsolutePath(),contextPath);
- context.setExtraClasspath(extraClasspath);
-
- if (webXmlPath != null && webXmlPath.length() != 0)
- {
- File webXml = null;
- if (webXmlPath.startsWith("/") || webXmlPath.startsWith("file:/"))
- {
- webXml = new File(webXmlPath);
- }
- else
- {
- webXml = new File(bundleInstall,webXmlPath);
- }
- if (webXml.exists())
- {
- context.setDescriptor(webXml.getAbsolutePath());
- }
- }
-
- if (defaultWebXmlPath == null || defaultWebXmlPath.length() == 0)
- {
- //use the one defined by the OSGiAppProvider.
- defaultWebXmlPath = _provider.getDefaultsDescriptor();
- }
- if (defaultWebXmlPath != null && defaultWebXmlPath.length() != 0)
- {
- File defaultWebXml = null;
- if (defaultWebXmlPath.startsWith("/") || defaultWebXmlPath.startsWith("file:/"))
- {
- defaultWebXml = new File(webXmlPath);
- }
- else
- {
- defaultWebXml = new File(bundleInstall,defaultWebXmlPath);
- }
- if (defaultWebXml.exists())
- {
- context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath());
- }
- }
-
- //other parameters that might be defines on the OSGiAppProvider:
- context.setParentLoaderPriority(_provider.isParentLoaderPriority());
-
- configureWebAppContext(context,contributor);
- configureWebappClassLoader(contributor,context,composite);
-
- // @see
- // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
- // during initialization of the webapp all the jetty packages are
- // visible
- // through the webapp classloader.
- oldServerClasses = context.getServerClasses();
- context.setServerClasses(null);
- _provider.addContext(context);
-
- return context;
- }
- finally
- {
- if (context != null && oldServerClasses != null)
- {
- context.setServerClasses(oldServerClasses);
- }
- Thread.currentThread().setContextClassLoader(contextCl);
- }
-
- }
-
- /**
- * Stop a ContextHandler and remove it from the collection.
- *
- * @See ContextDeployer#undeploy
- * @param contextHandler
- * @throws Exception
- */
- public void unregister(ContextHandler contextHandler) throws Exception
- {
- contextHandler.stop();
- _ctxtHandler.removeHandler(contextHandler);
- }
-
- /**
- * @return The default folder in which the context files of the osgi bundles
- * are located and watched. Or null when the system property
- * "jetty.osgi.contexts.home" is not defined.
- * If the configuration file defines the OSGiAppProvider's context.
- * This will not be taken into account.
- */
- File getDefaultOSGiContextsHome(File jettyHome)
- {
- String jettyContextsHome = System.getProperty("jetty.osgi.contexts.home");
- if (jettyContextsHome != null)
- {
- File contextsHome = new File(jettyContextsHome);
- if (!contextsHome.exists() || !contextsHome.isDirectory())
- {
- throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder");
- }
- return contextsHome;
- }
- return new File(jettyHome, "/contexts");
- }
-
- File getOSGiContextsHome()
- {
- return _provider.getContextXmlDirAsFile();
- }
-
- /**
- * This type of registration relies on jetty's complete context xml file.
- * Context encompasses jndi and all other things. This makes the definition
- * of the webapp a lot more self-contained.
- *
- * @param webapp
- * @param contextPath
- * @param classInBundle
- * @throws Exception
- */
- public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation)
- throws Exception
- {
- File contextsHome = _provider.getContextXmlDirAsFile();
- if (contextsHome != null)
- {
- File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath);
- if (prodContextFile.exists())
- {
- return registerContext(contributor,prodContextFile,extraClasspath,overrideBundleInstallLocation);
- }
- }
- File contextFile = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation,contextFileRelativePath):new File(
- BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor),contextFileRelativePath);
- if (contextFile.exists())
- {
- return registerContext(contributor,contextFile,extraClasspath,overrideBundleInstallLocation);
- }
- else
- {
- if (contextFileRelativePath.startsWith("./"))
- {
- contextFileRelativePath = contextFileRelativePath.substring(1);
- }
- if (!contextFileRelativePath.startsWith("/"))
- {
- contextFileRelativePath = "/" + contextFileRelativePath;
- }
- if (overrideBundleInstallLocation == null)
- {
- URL contextURL = contributor.getEntry(contextFileRelativePath);
- if (contextURL != null)
- {
- return registerContext(contributor,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation);
- }
- }
- else
- {
- JarFile zipFile = null;
- try
- {
- zipFile = new JarFile(overrideBundleInstallLocation);
- ZipEntry entry = zipFile.getEntry(contextFileRelativePath.substring(1));
- return registerContext(contributor,zipFile.getInputStream(entry),extraClasspath,overrideBundleInstallLocation);
- }
- catch (Throwable t)
- {
-
- }
- finally
- {
- if (zipFile != null)
- try
- {
- zipFile.close();
- }
- catch (IOException ioe)
- {
- }
- }
- }
- throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle "
- + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:""));
- }
- }
-
- /**
- * This type of registration relies on jetty's complete context xml file.
- * Context encompasses jndi and all other things. This makes the definition
- * of the webapp a lot more self-contained.
- *
- * @param webapp
- * @param contextPath
- * @param classInBundle
- * @throws Exception
- */
- private ContextHandler registerContext(Bundle contributor, File contextFile, String extraClasspath, String overrideBundleInstallLocation) throws Exception
- {
- InputStream contextFileInputStream = null;
- try
- {
- contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile));
- return registerContext(contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation);
- }
- finally
- {
- if (contextFileInputStream != null)
- try
- {
- contextFileInputStream.close();
- }
- catch (IOException ioe)
- {
- }
- }
- }
-
- /**
- * @param contributor
- * @param contextFileInputStream
- * @return The ContextHandler created and registered or null if it did not
- * happen.
- * @throws Exception
- */
- private ContextHandler registerContext(Bundle contributor, InputStream contextFileInputStream, String extraClasspath, String overrideBundleInstallLocation)
- throws Exception
- {
- ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
- String[] oldServerClasses = null;
- WebAppContext webAppContext = null;
- try
- {
- // make sure we provide access to all the jetty bundles by going
- // through this bundle.
- OSGiWebappClassLoader composite = createWebappClassLoader(contributor);
- // configure with access to all jetty classes and also all the
- // classes
- // that the contributor gives access to.
- Thread.currentThread().setContextClassLoader(composite);
- ContextHandler context = createContextHandler(contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation);
- if (context == null)
- {
- return null;// did not happen
- }
-
- // ok now register this webapp. we checked when we started jetty
- // that there
- // was at least one such handler for webapps.
- //the actual registration must happen via the new Deployment API.
-// _ctxtHandler.addHandler(context);
-
- configureWebappClassLoader(contributor,context,composite);
- if (context instanceof WebAppContext)
- {
- webAppContext = (WebAppContext)context;
- // @see
- // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
- oldServerClasses = webAppContext.getServerClasses();
- webAppContext.setServerClasses(null);
- }
-
- context.start();
- return context;
- }
- finally
- {
- if (webAppContext != null)
- {
- webAppContext.setServerClasses(oldServerClasses);
- }
- Thread.currentThread().setContextClassLoader(contextCl);
- }
-
- }
-
- /**
- * TODO: right now only the jetty-jsp bundle is scanned for common taglibs.
- * Should support a way to plug more bundles that contain taglibs.
- *
- * The jasper TldScanner expects a URLClassloader to parse a jar for the
- * /META-INF/*.tld it may contain. We place the bundles that we know contain
- * such tag-libraries. Please note that it will work if and only if the
- * bundle is a jar (!) Currently we just hardcode the bundle that contains
- * the jstl implemenation.
- *
- * A workaround when the tld cannot be parsed with this method is to copy
- * and paste it inside the WEB-INF of the webapplication where it is used.
- *
- * Support only 2 types of packaging for the bundle: - the bundle is a jar
- * (recommended for runtime.) - the bundle is a folder and contain jars in
- * the root and/or in the lib folder (nice for PDE developement situations)
- * Unsupported: the bundle is a jar that embeds more jars.
- *
- * @return
- * @throws Exception
- */
- private URL[] getJarsWithTlds() throws Exception
- {
- ArrayList<URL> res = new ArrayList<URL>();
- for (WebappRegistrationCustomizer regCustomizer : JSP_REGISTRATION_HELPERS)
- {
- URL[] urls = regCustomizer.getJarsWithTlds(_provider, BUNDLE_FILE_LOCATOR_HELPER);
- for (URL url : urls)
- {
- if (!res.contains(url))
- res.add(url);
- }
- }
- if (!res.isEmpty())
- return res.toArray(new URL[res.size()]);
- else
- return null;
- }
-
- /**
- * Applies the properties of WebAppDeployer as defined in jetty.xml.
- *
- * @see {WebAppDeployer#scan} around the comment
- * <code>// configure it</code>
- */
- protected void configureWebAppContext(WebAppContext wah, Bundle contributor)
- {
- // rfc66
- wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext());
-
- //spring-dm-1.2.1 looks for the BundleContext as a different attribute.
- //not a spec... but if we want to support
- //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
- //then we need to do this to:
- wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(),
- contributor.getBundleContext());
-
- }
-
- /**
- * @See {@link ContextDeployer#scan}
- * @param contextFile
- * @return
- */
- protected ContextHandler createContextHandler(Bundle bundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation)
- {
- try
- {
- return createContextHandler(bundle,new BufferedInputStream(new FileInputStream(contextFile)),extraClasspath,overrideBundleInstallLocation);
- }
- catch (FileNotFoundException e)
- {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * @See {@link ContextDeployer#scan}
- * @param contextFile
- * @return
- */
- @SuppressWarnings("unchecked")
- protected ContextHandler createContextHandler(Bundle bundle, InputStream contextInputStream, String extraClasspath, String overrideBundleInstallLocation)
- {
- /*
- * Do something identical to what the ContextProvider would have done:
- * XmlConfiguration xmlConfiguration=new
- * XmlConfiguration(resource.getURL()); HashMap properties = new
- * HashMap(); properties.put("Server", _contexts.getServer()); if
- * (_configMgr!=null) properties.putAll(_configMgr.getProperties());
- *
- * xmlConfiguration.setProperties(properties); ContextHandler
- * context=(ContextHandler)xmlConfiguration.configure();
- * context.setAttributes(new AttributesMap(_contextAttributes));
- */
- try
- {
- XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream);
- HashMap properties = new HashMap();
- properties.put("Server",_server);
-
- // insert the bundle's location as a property.
- setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation);
- xmlConfiguration.setProperties(properties);
-
- ContextHandler context = (ContextHandler)xmlConfiguration.configure();
- if (context instanceof WebAppContext)
- {
- ((WebAppContext)context).setExtraClasspath(extraClasspath);
- ((WebAppContext)context).setParentLoaderPriority(_provider.isParentLoaderPriority());
- if (_provider.getDefaultsDescriptor() != null && _provider.getDefaultsDescriptor().length() != 0)
- {
- ((WebAppContext)context).setDefaultsDescriptor(_provider.getDefaultsDescriptor());
- }
- }
-
- // rfc-66:
- context.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,bundle.getBundleContext());
-
- //spring-dm-1.2.1 looks for the BundleContext as a different attribute.
- //not a spec... but if we want to support
- //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
- //then we need to do this to:
- context.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(),
- bundle.getBundleContext());
- return context;
- }
- catch (FileNotFoundException e)
- {
- return null;
- }
- catch (SAXException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (Throwable e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- finally
- {
- if (contextInputStream != null)
- try
- {
- contextInputStream.close();
- }
- catch (IOException ioe)
- {
- }
- }
- return null;
- }
-
- /**
- * Configure a classloader onto the context. If the context is a
- * WebAppContext, build a WebAppClassLoader that has access to all the jetty
- * classes thanks to the classloader of the JettyBootStrapper bundle and
- * also has access to the classloader of the bundle that defines this
- * context.
- * <p>
- * If the context is not a WebAppContext, same but with a simpler
- * URLClassLoader. Note that the URLClassLoader is pretty much fake: it
- * delegate all actual classloading to the parent classloaders.
- * </p>
- * <p>
- * The URL[] returned by the URLClassLoader create contained specifically
- * the jars that some j2ee tools expect and look into. For example the jars
- * that contain tld files for jasper's jstl support.
- * </p>
- * <p>
- * Also as the jars in the lib folder and the classes in the classes folder
- * might already be in the OSGi classloader we filter them out of the
- * WebAppClassLoader
- * </p>
- *
- * @param context
- * @param contributor
- * @param webapp
- * @param contextPath
- * @param classInBundle
- * @throws Exception
- */
- protected void configureWebappClassLoader(Bundle contributor, ContextHandler context, OSGiWebappClassLoader webappClassLoader) throws Exception
- {
- if (context instanceof WebAppContext)
- {
- WebAppContext webappCtxt = (WebAppContext)context;
- context.setClassLoader(webappClassLoader);
- webappClassLoader.setWebappContext(webappCtxt);
- }
- else
- {
- context.setClassLoader(webappClassLoader);
- }
- }
-
- /**
- * No matter what the type of webapp, we create a WebappClassLoader.
- */
- protected OSGiWebappClassLoader createWebappClassLoader(Bundle contributor) throws Exception
- {
- // we use a temporary WebAppContext object.
- // if this is a real webapp we will set it on it a bit later: once we
- // know.
- OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(_commonParentClassLoaderForWebapps,new WebAppContext(),contributor);
- return webappClassLoader;
- }
-
- /**
- * Set the property &quot;this.bundle.install&quot; to point to the location
- * of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is
- * used.
- */
- private void setThisBundleHomeProperty(Bundle bundle, HashMap<String, Object> properties, String overrideBundleInstallLocation)
- {
- try
- {
- File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER
- .getBundleInstallLocation(bundle);
- properties.put("this.bundle.install",location.getCanonicalPath());
- }
- catch (Throwable t)
- {
- System.err.println("Unable to set 'this.bundle.install' " + " for the bundle " + bundle.getSymbolicName());
- t.printStackTrace();
- }
- }
-
-
-}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
index 8aef238472..820a627e1f 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
@@ -13,6 +13,8 @@
package org.eclipse.jetty.osgi.boot.utils;
import java.io.File;
+import java.net.URL;
+import java.util.Enumeration;
import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
import org.osgi.framework.Bundle;
@@ -53,7 +55,7 @@ public interface BundleFileLocatorHelper
*
* @param bundle
* @param path
- * @return
+ * @return file object
* @throws Exception
*/
public File getFileInBundle(Bundle bundle, String path) throws Exception;
@@ -73,5 +75,16 @@ public interface BundleFileLocatorHelper
* embedded inside it.
*/
public File[] locateJarsInsideBundle(Bundle bundle) throws Exception;
+
+
+ /**
+ * Helper method equivalent to Bundle#getEntry(String entryPath) except that
+ * it searches for entries in the fragments by using the findEntries method.
+ *
+ * @param bundle
+ * @param entryPath
+ * @return null or all the entries found for that path.
+ */
+ public Enumeration<URL> findEntries(Bundle bundle, String entryPath);
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java
index 5db0a2f4de..1a37a046c6 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java
@@ -46,7 +46,7 @@ public interface WebappRegistrationCustomizer
* the root and/or in the lib folder (nice for PDE developement situations)
* Unsupported: the bundle is a jar that embeds more jars.
*
- * @return
+ * @return array of URLs
* @throws Exception
*/
URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper fileLocator) throws Exception;
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
index a3541b60ac..a918cd7706 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
@@ -14,6 +14,8 @@ package org.eclipse.jetty.osgi.boot.utils.internal;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLConnection;
import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
import org.osgi.framework.Bundle;
@@ -59,7 +61,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
* Assuming the bundle is started.
*
* @param bundle
- * @return
+ * @return classloader object
*/
public ClassLoader getBundleClassLoader(Bundle bundle)
{
@@ -180,4 +182,5 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
}
return null;
}
+
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
index 5dfc3676df..ec8f997d69 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
@@ -14,10 +14,13 @@ package org.eclipse.jetty.osgi.boot.utils.internal;
import java.io.File;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
+import java.net.URLDecoder;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.zip.ZipFile;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
@@ -66,8 +69,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
// grab the MANIFEST.MF's url
// and then do what it takes.
URL url = bundle.getEntry("/META-INF/MANIFEST.MF");
- // System.err.println(url.toString() + " " + url.toURI() + " " +
- // url.getProtocol());
+// System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol());
if (url.getProtocol().equals("file"))
{
// some osgi frameworks do use the file protocole directly in some
@@ -130,11 +132,36 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
{
// observed this on felix-2.0.0
String location = bundle.getLocation();
+// System.err.println("location " + location);
if (location.startsWith("file:/"))
{
URI uri = new URI(URIUtil.encodePath(location));
return new File(uri);
}
+ else if (location.startsWith("file:"))
+ {
+ //location defined in the BundleArchive m_bundleArchive
+ //it is relative to relative to the BundleArchive's m_archiveRootDir
+ File res = new File(location.substring("file:".length()));
+ if (!res.exists())
+ {
+ return null;
+// Object bundleArchive = getFelixBundleArchive(bundle);
+// File archiveRoot = getFelixBundleArchiveRootDir(bundleArchive);
+// String currentLocation = getFelixBundleArchiveCurrentLocation(bundleArchive);
+// System.err.println("Got the archive root " + archiveRoot.getAbsolutePath()
+// + " current location " + currentLocation + " is directory ?");
+// res = new File(archiveRoot, currentLocation != null
+// ? currentLocation : location.substring("file:".length()));
+ }
+ return res;
+ }
+ else if (location.startsWith("reference:file:"))
+ {
+ location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8");
+ File file = new File(location.substring("file:".length()));
+ return file;
+ }
}
return null;
}
@@ -144,7 +171,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
*
* @param bundle
* @param path
- * @return
+ * @return file object
* @throws Exception
*/
public File getFileInBundle(Bundle bundle, String path) throws Exception
@@ -162,6 +189,29 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
}
return webapp;
}
+
+ /**
+ * Helper method equivalent to Bundle#getEntry(String entryPath) except that
+ * it searches for entries in the fragments by using the Bundle#findEntries method.
+ *
+ * @param bundle
+ * @param entryPath
+ * @return null or all the entries found for that path.
+ */
+ public Enumeration<URL> findEntries(Bundle bundle, String entryPath)
+ {
+ int last = entryPath.lastIndexOf('/');
+ String path = last != -1 && last < entryPath.length() -2
+ ? entryPath.substring(0, last) : "/";
+ if (!path.startsWith("/"))
+ {
+ path = "/" + path;
+ }
+ String pattern = last != -1 && last < entryPath.length() -2
+ ? entryPath.substring(last+1) : entryPath;
+ Enumeration<URL> enUrls = bundle.findEntries(path, pattern, false);
+ return enUrls;
+ }
/**
* If the bundle is a jar, returns the jar. If the bundle is a folder, look
@@ -205,9 +255,78 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
}
else
{
- return new File[]
- { jasperLocation };
+ return new File[] { jasperLocation };
}
}
+
+
+ //introspection on equinox to invoke the getLocalURL method on BundleURLConnection
+ //equivalent to using the FileLocator without depending on an equinox class.
+ private static Method BUNDLE_URL_CONNECTION_getLocalURL = null;
+ private static Method BUNDLE_URL_CONNECTION_getFileURL = null;
+ /**
+ * Only useful for equinox: on felix we get the file:// or jar:// url already.
+ * Other OSGi implementations have not been tested
+ * <p>
+ * Get a URL to the bundle entry that uses a common protocol (i.e. file:
+ * jar: or http: etc.).
+ * </p>
+ * @return a URL to the bundle entry that uses a common protocol
+ */
+ public static URL getLocalURL(URL url) {
+ if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) {
+ try {
+ URLConnection conn = url.openConnection();
+ if (BUNDLE_URL_CONNECTION_getLocalURL == null &&
+ conn.getClass().getName().equals(
+ "org.eclipse.osgi.framework.internal.core.BundleURLConnection")) {
+ BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
+ BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
+ }
+ if (BUNDLE_URL_CONNECTION_getLocalURL != null) {
+ return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null);
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ return url;
+ }
+ /**
+ * Only useful for equinox: on felix we get the file:// url already.
+ * Other OSGi implementations have not been tested
+ * <p>
+ * Get a URL to the content of the bundle entry that uses the file: protocol.
+ * The content of the bundle entry may be downloaded or extracted to the local
+ * file system in order to create a file: URL.
+ * @return a URL to the content of the bundle entry that uses the file: protocol
+ * </p>
+ */
+ public static URL getFileURL(URL url)
+ {
+ if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
+ {
+ try
+ {
+ URLConnection conn = url.openConnection();
+ if (BUNDLE_URL_CONNECTION_getFileURL == null &&
+ conn.getClass().getName().equals(
+ "org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
+ {
+ BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
+ BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
+ }
+ if (BUNDLE_URL_CONNECTION_getFileURL != null)
+ {
+ return (URL)BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null);
+ }
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+ }
+ return url;
+ }
}
diff --git a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF
index c71a82e4c4..6cc44e2155 100644
--- a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF
+++ b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: OSGi HttpService provided by equinox HttpServiceServlet deployed on jetty
Bundle-SymbolicName: org.eclipse.jetty.osgi.httpservice
-Bundle-Version: 8.0.0.M0.qualifier
+Bundle-Version: 8.0.0.qualifier
Bundle-Vendor: Mort Bay Consulting
Bundle-RequiredExecutionEnvironment: J2SE-1.6
Import-Package: javax.servlet;version="3.0",
diff --git a/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml b/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml
index caf77ba90d..b4a931d492 100644
--- a/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml
+++ b/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml
@@ -19,5 +19,6 @@
<Call name="addServlet">
<Arg>org.eclipse.jetty.osgi.httpservice.HttpServiceServletX</Arg>
<Arg>/*</Arg>
+ <Set name="InitOrder">0</Set>
</Call>
</Configure> \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml
index f74c49fa0e..be3a6ea356 100644
--- a/jetty-osgi/jetty-osgi-httpservice/pom.xml
+++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>8.0.0.M1</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -72,11 +72,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.osgi.httpservice.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml.tycho b/jetty-osgi/jetty-osgi-httpservice/pom.xml.tycho
deleted file mode 100644
index c6efbeb50f..0000000000
--- a/jetty-osgi/jetty-osgi-httpservice/pom.xml.tycho
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>jetty-osgi</artifactId>
- <groupId>org.eclipse.jetty.osgi</groupId>
- <version>7.0.1-SNAPSHOT</version>
- </parent>
- <artifactId>org.eclipse.jetty.osgi.httpservice</artifactId>
- <packaging>eclipse-plugin</packaging>
-</project>
diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml
index 4db0740817..c5e67f39b3 100644
--- a/jetty-osgi/pom.xml
+++ b/jetty-osgi/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>8.0.0.M1</version>
+ <version>8.0.0.M1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.jetty.osgi</groupId>
@@ -19,10 +19,8 @@
</properties>
<modules>
<module>jetty-osgi-boot</module>
- <!-- remove until jsp jars available in main maven repo -->
+ <!-- remove until we update the code to make it work with the jsp-2.2 jars -->
<!-- module>jetty-osgi-boot-jsp</module -->
- <!-- logback is currently under CQs -->
- <module>jetty-osgi-boot-logback</module>
<module>jetty-osgi-boot-warurl</module>
<module>jetty-osgi-httpservice</module>
<!-- module>example-jetty-osgi</module -->
@@ -56,19 +54,6 @@
</resources>
<plugins>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.3</version>
- <executions>
- <execution>
- <id>parse-version</id>
- <goals>
- <goal>parse-version</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
@@ -88,67 +73,56 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${project.version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
<version>${project.version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>osgi</artifactId>
<version>${osgi-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>services</artifactId>
<version>${osgi-services-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.equinox.http</groupId>
<artifactId>servlet</artifactId>
<version>${equinox-http-servlet-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback-version}</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-version}</version>
- <scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index 1abf83079a..2a6c9ff77e 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -13,7 +13,7 @@
</properties>
<build>
<plugins>
-<!--
+<!--
COMMENTED OUT UNTIL CORRECT CONFIG IS FOUND FOR Export uses clauses
-->
<plugin>
@@ -39,16 +39,11 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
@@ -72,6 +67,13 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.plus.*</onlyAnalyze>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
@@ -84,6 +86,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-plus/src/main/config/etc/jetty-plus.xml b/jetty-plus/src/main/config/etc/jetty-plus.xml
index c9352f5526..fd6cca33bf 100644
--- a/jetty-plus/src/main/config/etc/jetty-plus.xml
+++ b/jetty-plus/src/main/config/etc/jetty-plus.xml
@@ -47,6 +47,7 @@
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
+ <Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
<Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
</Array>
@@ -57,13 +58,12 @@
<!-- Uncomment the following to set up a deployer that will -->
<!-- deploy webapps from a directory called webapps-plus. Note -->
<!-- that you will need to create this directory first! -->
- <!--
<Ref id="DeploymentManager">
<Call name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps-plus</Set>
- <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+ <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">5</Set>
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
<Set name="parentLoaderPriority">false</Set>
@@ -73,6 +73,5 @@
</Arg>
</Call>
</Ref>
- -->
</Configure>
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java
index 20728938e2..79a80e264f 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java
@@ -161,7 +161,6 @@ public class Injection
/**
* Inject a value for a Resource from JNDI into an object
* @param injectable
- * @throws Exception
*/
public void inject (Object injectable)
{
@@ -179,8 +178,8 @@ public class Injection
/**
* The Resource must already exist in the ENC of this webapp.
- * @return
- * @throws Exception
+ * @return the injected valud
+ * @throws NamingException
*/
public Object lookupInjectedValue ()
throws NamingException
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java
index 089e2ce292..7d87b80e77 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java
@@ -32,6 +32,7 @@ public class InjectionCollection
public static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
private HashMap<String, List<Injection>> _injectionMap = new HashMap<String, List<Injection>>();//map of classname to injections
+
public void add (Injection injection)
{
if ((injection==null) || injection.getTargetClass()==null)
@@ -47,7 +48,6 @@ public class InjectionCollection
injections = new ArrayList<Injection>();
_injectionMap.put(injection.getTargetClass().getCanonicalName(), injections);
}
-
injections.add(injection);
}
@@ -59,6 +59,7 @@ public class InjectionCollection
return _injectionMap.get(className);
}
+
public Injection getInjection (String jndiName, Class clazz, Field field)
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java
index edb930c887..fc75dd4b3f 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java
@@ -123,7 +123,7 @@ public abstract class LifeCycleCallback
* @param clazz the class under inspection
* @param methodName the method to find
* @param checkInheritance false on first entry, true if a superclass is being introspected
- * @return
+ * @return the method
*/
public Method findMethod (Package pack, Class clazz, String methodName, boolean checkInheritance)
{
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractLoginModule.java
index b531f7cc02..dc6cd9975e 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractLoginModule.java
@@ -165,7 +165,7 @@ public abstract class AbstractLoginModule implements LoginModule
/**
* @see javax.security.auth.spi.LoginModule#commit()
- * @return
+ * @return true if committed, false if not (likely not authenticated)
* @throws LoginException
*/
public boolean commit() throws LoginException
@@ -201,7 +201,7 @@ public abstract class AbstractLoginModule implements LoginModule
/**
* @see javax.security.auth.spi.LoginModule#login()
- * @return
+ * @return true if is authenticated, false otherwise
* @throws LoginException
*/
public boolean login() throws LoginException
@@ -252,7 +252,7 @@ public abstract class AbstractLoginModule implements LoginModule
/**
* @see javax.security.auth.spi.LoginModule#logout()
- * @return
+ * @return true always
* @throws LoginException
*/
public boolean logout() throws LoginException
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/DataSourceLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/DataSourceLoginModule.java
index 668c01916f..95926c30a2 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/DataSourceLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/DataSourceLoginModule.java
@@ -27,8 +27,7 @@ import javax.sql.DataSource;
* A LoginModule that uses a DataSource to retrieve user authentication
* and authorisation information.
*
- * @see org.eclipse.jetty.server.server.plus.jaas.spi.JDBCLoginModule
- *
+ * @see JDBCLoginModule
*/
public class DataSourceLoginModule extends AbstractDatabaseLoginModule
{
@@ -68,8 +67,8 @@ public class DataSourceLoginModule extends AbstractDatabaseLoginModule
/**
* Get a connection from the DataSource
- * @see org.eclipse.jetty.server.server.plus.jaas.spi.AbstractDatabaseLoginModule#getConnection()
- * @return
+ * @see AbstractDatabaseLoginModule#getConnection()
+ * @return the connection for the datasource
* @throws Exception
*/
public Connection getConnection ()
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/JDBCLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/JDBCLoginModule.java
index 5242148654..31a799861d 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/JDBCLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/JDBCLoginModule.java
@@ -36,13 +36,9 @@ import org.eclipse.jetty.util.log.Log;
*
* <p><h4>Usage</h4>
* <pre>
- */
-/*
* </pre>
*
- * @see
* @version 1.0 Tue Apr 15 2003
- *
*/
public class JDBCLoginModule extends AbstractDatabaseLoginModule
{
@@ -52,14 +48,10 @@ public class JDBCLoginModule extends AbstractDatabaseLoginModule
private String dbPassword;
-
-
-
-
/**
* Get a connection from the DriverManager
- * @see org.eclipse.jetty.server.server.plus.jaas.spi.AbstractDatabaseLoginModule#getConnection()
- * @return
+ * @see AbstractDatabaseLoginModule#getConnection()
+ * @return the connection for this datasource
* @throws Exception
*/
public Connection getConnection ()
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
index ca009978e9..586862384e 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
@@ -182,7 +182,7 @@ public class LdapLoginModule extends AbstractLoginModule
* roles are also an optional concept if required
*
* @param username
- * @return
+ * @return the userinfo for the username
* @throws Exception
*/
public UserInfo getUserInfo(String username) throws Exception
@@ -367,7 +367,7 @@ public class LdapLoginModule extends AbstractLoginModule
* then we try a binding authentication check, otherwise if we have the users encoded password then
* we can try authentication via that mechanic
*
- * @return
+ * @return true if authenticated, false otherwise
* @throws LoginException
*/
public boolean login() throws LoginException
@@ -440,7 +440,7 @@ public class LdapLoginModule extends AbstractLoginModule
* password supplied authentication check
*
* @param webCredential
- * @return
+ * @return true if authenticated
* @throws LoginException
*/
protected boolean credentialLogin(Object webCredential) throws LoginException
@@ -451,13 +451,13 @@ public class LdapLoginModule extends AbstractLoginModule
/**
* binding authentication check
- * This methode of authentication works only if the user branch of the DIT (ldap tree)
- * has an ACI (acces control instruction) that allow the access to any user or at least
+ * This method of authentication works only if the user branch of the DIT (ldap tree)
+ * has an ACI (access control instruction) that allow the access to any user or at least
* for the user that logs in.
*
* @param username
* @param password
- * @return
+ * @return true always
* @throws LoginException
*/
public boolean bindingLogin(String username, Object password) throws LoginException, NamingException
@@ -610,7 +610,7 @@ public class LdapLoginModule extends AbstractLoginModule
/**
* get the context for connection
*
- * @return
+ * @return the environment details for the context
*/
public Hashtable<Object, Object> getEnvironment()
{
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
index c2f4ee935d..d99db19a4e 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
@@ -141,7 +141,6 @@ public class PropertyFileLoginModule extends AbstractLoginModule
/**
* Don't implement this as we want to pre-fetch all of the
* users.
- * @see org.eclipse.jetty.plus.jaas.spi.AbstractLoginModule#lazyLoadUser(java.lang.String)
* @param username
* @throws Exception
*/
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java
index 2fd2bcd884..9c2d7f9952 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java
@@ -134,7 +134,7 @@ public abstract class NamingEntry
/**
* Get the unique name of the object
* relative to the scope
- * @return
+ * @return the unique jndi name of the object
*/
public String getJndiName ()
{
@@ -143,7 +143,7 @@ public abstract class NamingEntry
/**
* Get the object that is to be bound
- * @return
+ * @return the object that is to be bound
*/
public Object getObjectToBind()
throws NamingException
@@ -155,7 +155,7 @@ public abstract class NamingEntry
/**
* Get the name of the object, fully
* qualified with the scope
- * @return
+ * @return the name of the object, fully qualified with the scope
*/
public String getJndiNameInScope ()
{
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java
index 444fa68d42..fa4f8416e2 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java
@@ -40,10 +40,10 @@ public class NamingEntryUtil
* resource. The pre-existing resource can be either in the webapp's
* naming environment, or in the container's naming environment. Webapp's
* environment takes precedence over the server's namespace.
- *
+ *
+ * @param scope the scope of the lookup
* @param asName the name to bind as
* @param mappedName the name from the environment to link to asName
- * @param namingEntryType
* @throws NamingException
*/
public static boolean bindToENC (Object scope, String asName, String mappedName)
@@ -72,7 +72,7 @@ public class NamingEntryUtil
*
* @param scope
* @param jndiName
- * @return
+ * @return the naming entry for the given scope
* @throws NamingException
*/
public static NamingEntry lookupNamingEntry (Object scope, String jndiName)
@@ -115,7 +115,7 @@ public class NamingEntryUtil
*
* @param scope
* @param clazz the type of the entry
- * @return
+ * @return all NameEntries of a certain type in the given naming environment scope (server-wide names or context-specific names)
* @throws NamingException
*/
public static List lookupNamingEntries (Object scope, Class clazz)
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java
index 39cefe456e..397cad0fce 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java
@@ -27,13 +27,6 @@ import org.eclipse.jetty.util.log.Log;
* Transaction
*
* Class to represent a JTA UserTransaction impl.
- *
- *
- */
-/**
- * Transaction
- *
- *
*/
public class Transaction extends NamingEntry
{
@@ -68,7 +61,7 @@ public class Transaction extends NamingEntry
* Allow other bindings of UserTransaction.
*
* These should be in ADDITION to java:comp/UserTransaction
- * @see org.eclipse.jetty.server.server.plus.jndi.NamingEntry#bindToENC(java.lang.String)
+ * @see NamingEntry#bindToENC(java.lang.String)
*/
public void bindToENC (String localName)
throws NamingException
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
index 79728c1d8f..8d0d6ae3e8 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
@@ -277,7 +277,7 @@ public class DataSourceLoginService extends MappedLoginService
/* ------------------------------------------------------------ */
/** Load user's info from database.
*
- * @param user
+ * @param userName
*/
@Override
protected UserIdentity loadUser (String userName)
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/Configuration.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/Configuration.java
index 1a59c7f930..b767c5e78b 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/Configuration.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/Configuration.java
@@ -24,9 +24,9 @@ import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.RunAsCollection;
import org.eclipse.jetty.plus.jndi.Transaction;
import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.webapp.Fragment;
+import org.eclipse.jetty.webapp.FragmentDescriptor;
import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlProcessor;
+import org.eclipse.jetty.webapp.MetaData;
/**
@@ -59,23 +59,29 @@ public class Configuration implements org.eclipse.jetty.webapp.Configuration
{
bindUserTransaction(context);
- WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (webXmlProcessor == null)
- throw new IllegalStateException ("No processor for web xml");
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException ("No metadata");
- PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor(webXmlProcessor);
- webXmlProcessor.process(webXmlProcessor.getWebDefault(), plusProcessor);
- webXmlProcessor.process(webXmlProcessor.getWebXml(), plusProcessor);
+ metaData.addDescriptorProcessor(new PlusDescriptorProcessor());
+
+ /*
+ * THE PROCESSING IS NOW DONE IN metadata.resolve ()
+
+ PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor(metaData);
+ plusProcessor.process(metaData.getWebDefault());
+ plusProcessor.process(metaData.getWebXml());
//Process plus-elements of each descriptor
- for (Fragment frag: webXmlProcessor.getFragments())
+ for (FragmentDescriptor frag: metaData.getOrderedFragments())
{
- webXmlProcessor.process(frag, plusProcessor);
+ plusProcessor.process(frag);
}
//process the override-web.xml descriptor
- webXmlProcessor.process(webXmlProcessor.getOverrideWeb(), plusProcessor);
+ plusProcessor.process(metaData.getOverrideWeb());
+ */
}
public void postConfigure(WebAppContext context) throws Exception
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java
index d226a38429..6500b1eab1 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java
@@ -53,7 +53,7 @@ public class EnvConfiguration implements Configuration
/**
- * @see org.eclipse.jetty.webapp.Configuration#configureDefaults()
+ * @see Configuration#configure(WebAppContext)
* @throws Exception
*/
public void preConfigure (WebAppContext context) throws Exception
@@ -108,7 +108,7 @@ public class EnvConfiguration implements Configuration
/**
* Remove all jndi setup
- * @see org.eclipse.jetty.webapp.Configuration#deconfigureWebApp()
+ * @see Configuration#deconfigure(WebAppContext)
* @throws Exception
*/
public void deconfigure (WebAppContext context) throws Exception
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java
index 9261784b23..bd39d05e4b 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java
@@ -33,11 +33,11 @@ import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.Descriptor;
-import org.eclipse.jetty.webapp.Fragment;
+import org.eclipse.jetty.webapp.FragmentDescriptor;
import org.eclipse.jetty.webapp.IterativeDescriptorProcessor;
import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlProcessor;
-import org.eclipse.jetty.webapp.WebXmlProcessor.Origin;
+import org.eclipse.jetty.webapp.MetaData;
+import org.eclipse.jetty.webapp.MetaData.Origin;
import org.eclipse.jetty.xml.XmlParser;
/**
@@ -49,12 +49,10 @@ import org.eclipse.jetty.xml.XmlParser;
public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
{
protected WebAppContext _context;
- protected WebXmlProcessor _processor;
+ protected MetaData _metaData;
- public PlusDescriptorProcessor (WebXmlProcessor processor)
+ public PlusDescriptorProcessor ()
{
- _processor = processor;
- _context = _processor.getContext();
try
{
registerVisitor("env-entry", getClass().getDeclaredMethod("visitEnvEntry", __signature));
@@ -71,19 +69,26 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
}
/**
- * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start()
+ * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start(org.eclipse.jetty.webapp.Descriptor)
*/
- public void start()
- {
+ public void start(Descriptor descriptor)
+ {
+ _metaData = descriptor.getMetaData();
+ _context = _metaData.getContext();
}
-
+
+
/**
- * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end()
+ * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end(org.eclipse.jetty.webapp.Descriptor)
*/
- public void end()
+ public void end(Descriptor descriptor)
{
+ _metaData = null;
+ _context = null;
}
+
+
/**
* JavaEE 5.4.1.3
@@ -106,19 +111,19 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
return;
}
- Origin o = _processor.getOrigin("env-entry."+name);
+ Origin o = _metaData.getOrigin("env-entry."+name);
switch (o)
{
case NotSet:
{
//no descriptor has configured an env-entry of this name previously
- _processor.setOrigin("env-entry."+name, descriptor);
+ _metaData.setOrigin("env-entry."+name, descriptor);
//the javaee_5.xsd says that the env-entry-type is optional
//if there is an <injection> element, because you can get
//type from the element, but what to do if there is more
//than one <injection> element, do you just pick the type
//of the first one?
- addInjection (descriptor, node, name, TypeUtil.fromName(type));
+ addInjections (descriptor, node, name, TypeUtil.fromName(type));
Object value = TypeUtil.valueOf(type,valueStr);
bindEnvEntry(name, value);
break;
@@ -130,12 +135,12 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
//ServletSpec 3.0 p75. web.xml (or web-override/web-defaults) declared
//the env-entry. A fragment is not allowed to change that, except unless
//the web.xml did not declare any injections.
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
//We're processing web-defaults, web.xml or web-override. Any of them can
//set or change the env-entry.
- _processor.setOrigin("env-entry."+name, descriptor);
- addInjection (descriptor, node, name, TypeUtil.fromName(type));
+ _metaData.setOrigin("env-entry."+name, descriptor);
+ addInjections (descriptor, node, name, TypeUtil.fromName(type));
Object value = TypeUtil.valueOf(type,valueStr);
bindEnvEntry(name, value);
}
@@ -144,9 +149,9 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
//A web.xml declared the env-entry. Check to see if any injections have been
//declared for it. If it was declared in web.xml then don't merge any injections.
//If it was declared in a web-fragment, then we can keep merging fragments.
- Descriptor d = _processor.getOriginDescriptor("env-entry."+name+".injection");
- if (d==null || d instanceof Fragment)
- addInjection(descriptor, node, name, TypeUtil.fromName(type));
+ Descriptor d = _metaData.getOriginDescriptor("env-entry."+name+".injection");
+ if (d==null || d instanceof FragmentDescriptor)
+ addInjections(descriptor, node, name, TypeUtil.fromName(type));
}
break;
}
@@ -196,19 +201,19 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
String auth = node.getString("res-auth", false, true);
String shared = node.getString("res-sharing-scope", false, true);
- Origin o = _processor.getOrigin("resource-ref."+jndiName);
+ Origin o = _metaData.getOrigin("resource-ref."+jndiName);
switch (o)
{
case NotSet:
{
- //No descriptor previously declared a resource-ref of this name.
- _processor.setOrigin("resource-ref."+jndiName, descriptor);
+ //No descriptor or annotation previously declared a resource-ref of this name.
+ _metaData.setOrigin("resource-ref."+jndiName, descriptor);
//check for <injection> elements
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection (descriptor, node, jndiName, typeClass);
+ addInjections(descriptor, node, jndiName, typeClass);
bindResourceRef(jndiName, typeClass);
break;
}
@@ -217,33 +222,35 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//A web xml previously declared the resource-ref.
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
//We're processing web-defaults, web.xml or web-override. Any of them can
//set or change the resource-ref.
- _processor.setOrigin("resource-ref."+jndiName, descriptor);
+ _metaData.setOrigin("resource-ref."+jndiName, descriptor);
//check for <injection> elements
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection (descriptor, node, jndiName, typeClass);
+
+ addInjections(descriptor, node, jndiName, typeClass);
//bind the entry into jndi
bindResourceRef(jndiName, typeClass);
}
else
{
- //A web xml declared the resource-ref. Check to see if any injections have been
- //declared for it. If an injection was declared in web.xml then don't merge any injections.
+ //A web xml declared the resource-ref and we're processing a
+ //web-fragment. Check to see if any injections were declared for it by web.xml.
+ //If any injection was declared in web.xml then don't merge any injections.
//If it was declared in a web-fragment, then we can keep merging fragments.
- Descriptor d = _processor.getOriginDescriptor("resource-ref."+jndiName+".injection");
- if (d==null || d instanceof Fragment)
+ Descriptor d = _metaData.getOriginDescriptor("resource-ref."+jndiName+".injection");
+ if (d==null || d instanceof FragmentDescriptor)
{
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection(descriptor, node, jndiName, TypeUtil.fromName(type));
+ addInjections(descriptor, node, jndiName, TypeUtil.fromName(type));
}
}
break;
@@ -274,7 +281,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
String jndiName = node.getString("resource-env-ref-name",false,true);
String type = node.getString("resource-env-ref-type", false, true);
- Origin o = _processor.getOrigin("resource-env-ref."+jndiName);
+ Origin o = _metaData.getOrigin("resource-env-ref."+jndiName);
switch (o)
{
case NotSet:
@@ -285,7 +292,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection (descriptor, node, jndiName, typeClass);
+ addInjections (descriptor, node, jndiName, typeClass);
bindResourceEnvRef(jndiName, typeClass);
break;
}
@@ -295,28 +302,28 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
{
//A resource-env-ref of this name has been declared first in a web xml.
//Only allow other web-default, web.xml, web-override to change it.
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
//We're processing web-defaults, web.xml or web-override. Any of them can
//set or change the resource-env-ref.
- _processor.setOrigin("resource-env-ref."+jndiName, descriptor);
+ _metaData.setOrigin("resource-env-ref."+jndiName, descriptor);
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection (descriptor, node, jndiName, typeClass);
+ addInjections (descriptor, node, jndiName, typeClass);
bindResourceEnvRef(jndiName, typeClass);
}
else
{
//We're processing a web-fragment. It can only contribute injections if the
//there haven't been any injections declared yet, or they weren't declared in a WebXml file.
- Descriptor d = _processor.getOriginDescriptor("resource-env-ref."+jndiName+".injection");
- if (d == null || d instanceof Fragment)
+ Descriptor d = _metaData.getOriginDescriptor("resource-env-ref."+jndiName+".injection");
+ if (d == null || d instanceof FragmentDescriptor)
{
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection (descriptor, node, jndiName, typeClass);
+ addInjections (descriptor, node, jndiName, typeClass);
}
}
break;
@@ -345,7 +352,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
String type = node.getString("message-destination-type",false,true);
String usage = node.getString("message-destination-usage",false,true);
- Origin o = _processor.getOrigin("message-destination-ref."+jndiName);
+ Origin o = _metaData.getOrigin("message-destination-ref."+jndiName);
switch (o)
{
case NotSet:
@@ -354,9 +361,9 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection(descriptor, node, jndiName, typeClass);
+ addInjections(descriptor, node, jndiName, typeClass);
bindMessageDestinationRef(jndiName, typeClass);
- _processor.setOrigin("message-destination-ref."+jndiName, descriptor);
+ _metaData.setOrigin("message-destination-ref."+jndiName, descriptor);
break;
}
case WebXml:
@@ -365,26 +372,26 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
{
//A message-destination-ref of this name has been declared first in a web xml.
//Only allow other web-default, web.xml, web-override to change it.
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection(descriptor, node, jndiName, typeClass);
+ addInjections(descriptor, node, jndiName, typeClass);
bindMessageDestinationRef(jndiName, typeClass);
- _processor.setOrigin("message-destination-ref."+jndiName, descriptor);
+ _metaData.setOrigin("message-destination-ref."+jndiName, descriptor);
}
else
{
//A web-fragment has declared a message-destination-ref with the same name as a web xml.
//It can only contribute injections, and only if the web xml didn't declare any.
- Descriptor d = _processor.getOriginDescriptor("message-destination-ref."+jndiName+".injection");
- if (d == null || d instanceof Fragment)
+ Descriptor d = _metaData.getOriginDescriptor("message-destination-ref."+jndiName+".injection");
+ if (d == null || d instanceof FragmentDescriptor)
{
Class typeClass = TypeUtil.fromName(type);
if (typeClass==null)
typeClass = _context.loadClass(type);
- addInjection(descriptor, node, jndiName, typeClass);
+ addInjections(descriptor, node, jndiName, typeClass);
}
}
break;
@@ -427,13 +434,13 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
//ServletSpec 3.0 p80 If web.xml declares a post-construct then all post-constructs
//in fragments must be ignored. Otherwise, they are additive.
- Origin o = _processor.getOrigin("post-construct");
+ Origin o = _metaData.getOrigin("post-construct");
switch (o)
{
case NotSet:
{
//No post-constructs have been declared previously.
- _processor.setOrigin("post-construct", descriptor);
+ _metaData.setOrigin("post-construct", descriptor);
try
{
@@ -454,7 +461,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
{
//A web xml first declared a post-construct. Only allow other web xml files (web-defaults, web-overrides etc)
//to add to it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
try
{
@@ -513,14 +520,14 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
}
LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
- Origin o = _processor.getOrigin("pre-destroy");
+ Origin o = _metaData.getOrigin("pre-destroy");
switch(o)
{
case NotSet:
{
//No pre-destroys have been declared previously. Record this descriptor
//as the first declarer.
- _processor.setOrigin("pre-destroy", descriptor);
+ _metaData.setOrigin("pre-destroy", descriptor);
try
{
Class clazz = _context.loadClass(className);
@@ -540,7 +547,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
{
//A web xml file previously declared a pre-destroy. Only allow other web xml files
//(not web-fragments) to add to them.
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
try
{
@@ -585,7 +592,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
* @param valueClass
* @return
*/
- public void addInjection (Descriptor descriptor, XmlParser.Node node, String jndiName, Class valueClass)
+ public void addInjections (Descriptor descriptor, XmlParser.Node node, String jndiName, Class valueClass)
{
Iterator itor = node.iterator("injection-target");
@@ -615,9 +622,10 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
injection.setJndiName(jndiName);
injection.setTarget(clazz, targetName, valueClass);
injections.add(injection);
+
//Record which was the first descriptor to declare an injection for this name
- if (_processor.getOriginDescriptor(node.getTag()+"."+jndiName+".injection") == null)
- _processor.setOrigin(node.getTag()+"."+jndiName+".injection", descriptor);
+ if (_metaData.getOriginDescriptor(node.getTag()+"."+jndiName+".injection") == null)
+ _metaData.setOrigin(node.getTag()+"."+jndiName+".injection", descriptor);
}
catch (ClassNotFoundException e)
{
@@ -625,6 +633,8 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
}
}
}
+
+
/**
@@ -763,4 +773,6 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
else
throw new IllegalStateException("Nothing to bind for name "+nameInEnvironment);
}
+
+
}
diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java
index a83f1dd71f..d18998b5b2 100644
--- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java
+++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java
@@ -4,19 +4,17 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.plus.jndi;
-
import java.util.Hashtable;
import java.util.List;
-
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
@@ -27,138 +25,110 @@ import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
/**
- * TestEnvEntry
- *
*
*/
-public class TestNamingEntries extends TestCase
+public class TestNamingEntries
{
- public class ScopeA extends Object
+ public class ScopeA
{
public String toString()
{
return this.getClass().getName()+"@"+super.hashCode();
}
}
-
+
public class ScopeB extends ScopeA
- {}
-
-
-
+ {
+ }
+
public static class SomeObject
{
private int value;
public SomeObject (int value)
{this.value = value;}
-
+
public int getValue ()
{
return this.value;
}
}
-
+
public static class SomeObjectFactory implements ObjectFactory
{
-
public SomeObjectFactory()
{
-
}
- /**
- * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
- * @param arg0
- * @param arg1
- * @param arg2
- * @param arg3
- * @return
- * @throws Exception
- */
+
public Object getObjectInstance(Object arg0, Name arg1, Context arg2, Hashtable arg3) throws Exception
{
Reference ref = (Reference)arg0;
-
+
RefAddr refAddr = ref.get(0);
String valueName = refAddr.getType();
if (!valueName.equalsIgnoreCase("val"))
throw new RuntimeException("Unrecognized refaddr type = "+valueName);
-
+
String value = (String)refAddr.getContent();
-
+
return new SomeObject(Integer.parseInt(value.trim()));
-
}
-
}
-
+
public static class SomeOtherObject extends SomeObject implements Referenceable
{
-
- private String svalue;
public SomeOtherObject (String value)
{
super(Integer.parseInt(value.trim()));
-
}
-
- /**
- * @see javax.naming.Referenceable#getReference()
- * @return
- * @throws NamingException
- */
+
public Reference getReference() throws NamingException
{
RefAddr refAddr = new StringRefAddr("val", String.valueOf(getValue()));
- Reference ref = new Reference(SomeOtherObject.class.getName(), refAddr, SomeOtherObjectFactory.class.getName(), null);
- return ref;
+ return new Reference(SomeOtherObject.class.getName(), refAddr, SomeOtherObjectFactory.class.getName(), null);
}
}
-
+
public static class SomeOtherObjectFactory implements ObjectFactory
{
-
public SomeOtherObjectFactory()
{
-
}
- /**
- * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
- * @param arg0
- * @param arg1
- * @param arg2
- * @param arg3
- * @return
- * @throws Exception
- */
+
public Object getObjectInstance(Object arg0, Name arg1, Context arg2, Hashtable arg3) throws Exception
{
- Reference ref = (Reference)arg0;
-
+ Reference ref = (Reference)arg0;
+
RefAddr refAddr = ref.get(0);
String valueName = refAddr.getType();
if (!valueName.equalsIgnoreCase("val"))
throw new RuntimeException("Unrecognized refaddr type = "+valueName);
-
+
String value = (String)refAddr.getContent();
-
+
return new SomeOtherObject(value.trim());
}
-
}
-
- public SomeObject someObject;
-
- public void setUp ()
+ private SomeObject someObject;
+
+ @Before
+ public void init()
{
this.someObject = new SomeObject(4);
}
- public void testEnvEntryNoScope ()
- throws Exception
+ @Test
+ public void testEnvEntryNoScope() throws Exception
{
EnvEntry ee = new EnvEntry("nameZ", "zstring", true);
List list = NamingEntryUtil.lookupNamingEntries(null, EnvEntry.class);
@@ -170,10 +140,10 @@ public class TestNamingEntries extends TestCase
EnvEntry eo = (EnvEntry)o;
assertEquals ("nameZ", eo.getJndiName());
}
-
- public void testEnvEntryOverride ()
- throws Exception
- {
+
+ @Test
+ public void testEnvEntryOverride() throws Exception
+ {
ScopeA scope = new ScopeA();
EnvEntry ee = new EnvEntry (scope, "nameA", someObject, true);
@@ -188,10 +158,9 @@ public class TestNamingEntries extends TestCase
assertNotNull(namingEntriesContext);
assertEquals(someObject, scopeContext.lookup("nameA"));
}
-
- public void testEnvEntryNonOverride ()
- throws Exception
+ @Test
+ public void testEnvEntryNonOverride() throws Exception
{
ScopeA scope = new ScopeA();
EnvEntry ee = new EnvEntry (scope, "nameA", someObject, false);
@@ -208,34 +177,32 @@ public class TestNamingEntries extends TestCase
assertEquals(someObject, scopeContext.lookup("nameA"));
}
-
- public void testResource ()
- throws Exception
+ @Test
+ public void testResource () throws Exception
{
InitialContext icontext = new InitialContext();
-
+
Resource resource = new Resource (null, "resourceA/b/c", someObject);
NamingEntry ne = NamingEntryUtil.lookupNamingEntry(null, "resourceA/b/c");
assertNotNull(ne);
assertTrue(ne instanceof Resource);
assertEquals(icontext.lookup("resourceA/b/c"), someObject);
-
+
Object scope = new ScopeA();
Resource resource2 = new Resource (scope, "resourceB", someObject);
ne = NamingEntryUtil.lookupNamingEntry(scope, "resourceB");
assertNotNull(ne);
assertTrue(ne instanceof Resource);
-
+
ne = NamingEntryUtil.lookupNamingEntry(null, "resourceB");
assertNull(ne);
-
+
ne = NamingEntryUtil.lookupNamingEntry(new ScopeB(), "resourceB");
assertNull(ne);
}
-
-
- public void testLink ()
- throws Exception
+
+ @Test
+ public void testLink () throws Exception
{
ScopeA scope = new ScopeA();
InitialContext icontext = new InitialContext();
@@ -246,15 +213,13 @@ public class TestNamingEntries extends TestCase
assertEquals(icontext.lookup("resourceA"), "resourceB");
link = new Link (scope, "jdbc/resourceX", "jdbc/resourceY");
- ne = NamingEntryUtil.lookupNamingEntry(scope, "jdbc/resourceX");
+ ne = NamingEntryUtil.lookupNamingEntry(scope, "jdbc/resourceX");
assertNotNull(ne);
assertTrue(ne instanceof Link);
}
-
-
-
- public void testResourceReferenceable ()
- throws Exception
+
+ @Test
+ public void testResourceReferenceable() throws Exception
{
SomeOtherObject someOtherObj = new SomeOtherObject("100");
InitialContext icontext = new InitialContext();
@@ -263,25 +228,24 @@ public class TestNamingEntries extends TestCase
assertNotNull(o);
assertTrue (o instanceof SomeOtherObject);
assertEquals(((SomeOtherObject)o).getValue(), 100);
-
}
-
- public void testResourceReference ()
- throws Exception
+
+ @Test
+ public void testResourceReference () throws Exception
{
RefAddr refAddr = new StringRefAddr("val", "10");
Reference ref = new Reference(SomeObject.class.getName(), refAddr, SomeObjectFactory.class.getName(), null);
-
+
InitialContext icontext = new InitialContext();
Resource resource = new Resource (null, "resourceByRef", ref);
NamingEntry ne = NamingEntryUtil.lookupNamingEntry(null, "resourceByRef");
assertNotNull(ne);
assertTrue (ne instanceof Resource);
-
+
Object o = icontext.lookup("resourceByRef");
assertNotNull (o);
assertTrue (o instanceof SomeObject);
-
+
assertEquals(((SomeObject)o).getValue(), 10);
}
}
diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java
index af407897f3..ad56aa295d 100644
--- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java
+++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java
@@ -4,25 +4,30 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.plus.jndi;
import java.util.List;
-
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
-import junit.framework.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-public class TestNamingEntryUtil extends TestCase
+public class TestNamingEntryUtil
{
public class MyNamingEntry extends NamingEntry
{
@@ -33,24 +38,25 @@ public class TestNamingEntryUtil extends TestCase
}
}
- public class ScopeA extends Object
+ public class ScopeA
{
public String toString()
{
return this.getClass().getName()+"@"+super.hashCode();
}
}
- public void testGetNameForScope ()
- throws Exception
+
+ @Test
+ public void testGetNameForScope () throws Exception
{
ScopeA scope = new ScopeA();
Name name = NamingEntryUtil.getNameForScope(scope);
assertNotNull(name);
assertEquals(scope.toString(), name.toString());
}
-
- public void testGetContextForScope()
- throws Exception
+
+ @Test
+ public void testGetContextForScope() throws Exception
{
ScopeA scope = new ScopeA();
try
@@ -62,11 +68,11 @@ public class TestNamingEntryUtil extends TestCase
{
//expected
}
-
+
InitialContext ic = new InitialContext();
Context scopeContext = ic.createSubcontext(NamingEntryUtil.getNameForScope(scope));
assertNotNull(scopeContext);
-
+
try
{
Context c = NamingEntryUtil.getContextForScope(scope);
@@ -77,50 +83,49 @@ public class TestNamingEntryUtil extends TestCase
fail(e.getMessage());
}
}
-
- public void testMakeNamingEntryName ()
- throws Exception
+
+ @Test
+ public void testMakeNamingEntryName() throws Exception
{
Name name = NamingEntryUtil.makeNamingEntryName(null, "fee/fi/fo/fum");
assertNotNull(name);
assertEquals(NamingEntry.__contextName+"/fee/fi/fo/fum", name.toString());
}
-
- public void testLookupNamingEntry ()
- throws Exception
+
+ @Test
+ public void testLookupNamingEntry() throws Exception
{
ScopeA scope = new ScopeA();
NamingEntry ne = NamingEntryUtil.lookupNamingEntry(scope, "foo");
assertNull(ne);
-
- MyNamingEntry mne = new MyNamingEntry(scope, "foo", new Integer(9));
-
+
+ MyNamingEntry mne = new MyNamingEntry(scope, "foo", 9);
+
ne = NamingEntryUtil.lookupNamingEntry(scope, "foo");
assertNotNull(ne);
assertEquals(ne, mne);
}
-
- public void testLookupNamingEntries ()
- throws Exception
+
+ @Test
+ public void testLookupNamingEntries() throws Exception
{
ScopeA scope = new ScopeA();
List list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
assertTrue(list.isEmpty());
-
- MyNamingEntry mne1 = new MyNamingEntry(scope, "a/b", new Integer(1));
- MyNamingEntry mne2 = new MyNamingEntry(scope, "a/c", new Integer(2));
-
+
+ MyNamingEntry mne1 = new MyNamingEntry(scope, "a/b", 1);
+ MyNamingEntry mne2 = new MyNamingEntry(scope, "a/c", 2);
+
ScopeA scope2 = new ScopeA();
- MyNamingEntry mne3 = new MyNamingEntry(scope2, "a/b", new Integer(3));
-
+ MyNamingEntry mne3 = new MyNamingEntry(scope2, "a/b", 3);
+
list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
assertEquals(2, list.size());
assertTrue (list.contains(mne1));
assertTrue (list.contains(mne2));
-
+
list = NamingEntryUtil.lookupNamingEntries(scope2, MyNamingEntry.class);
assertEquals(1, list.size());
assertTrue(list.contains(mne3));
-
}
}
diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java
index 663972a4b0..e96b69008d 100644
--- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java
+++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java
@@ -4,30 +4,31 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.plus.webapp;
import javax.naming.Context;
import javax.naming.InitialContext;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlProcessor;
+import org.eclipse.jetty.webapp.MetaData;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
-public class TestConfiguration extends TestCase
+public class TestConfiguration
{
-
public class MyWebAppContext extends WebAppContext
{
public String toString()
@@ -35,9 +36,9 @@ public class TestConfiguration extends TestCase
return this.getClass().getName()+"@"+super.hashCode();
}
}
-
- public void testIt ()
- throws Exception
+
+ @Test
+ public void testIt () throws Exception
{
ClassLoader old_loader = Thread.currentThread().getContextClassLoader();
@@ -51,18 +52,18 @@ public class TestConfiguration extends TestCase
wac.setServer(server);
wac.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), wac));
- WebXmlProcessor processor = new WebXmlProcessor(wac);
+ MetaData metaData = new MetaData(wac);
- PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor(processor);
+ PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor();
- //bind some EnvEntrys at the server level
+ //bind some EnvEntrys at the server level
EnvEntry ee1 = new EnvEntry(server, "xxx/a", "100", true);
EnvEntry ee2 = new EnvEntry(server, "yyy/b", "200", false);
EnvEntry ee3 = new EnvEntry(server, "zzz/c", "300", false);
EnvEntry ee4 = new EnvEntry(server, "zzz/d", "400", false);
EnvEntry ee5 = new EnvEntry(server, "zzz/f", "500", true);
- //bind some EnvEntrys at the webapp level
+ //bind some EnvEntrys at the webapp level
EnvEntry ee6 = new EnvEntry(wac, "xxx/a", "900", true);
EnvEntry ee7 = new EnvEntry(wac, "yyy/b", "910", true);
EnvEntry ee8 = new EnvEntry(wac, "zzz/c", "920", false);
@@ -74,11 +75,10 @@ public class TestConfiguration extends TestCase
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/d"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "xxx/a"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "yyy/b"));
- assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/c"));
+ assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/c"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e"));
- Configuration config = new Configuration();
-
+ //make a new env configuration
EnvConfiguration envConfig = new EnvConfiguration();
diff --git a/jetty-policy/pom.xml b/jetty-policy/pom.xml
index 50bd19706e..ffb3bd233d 100644
--- a/jetty-policy/pom.xml
+++ b/jetty-policy/pom.xml
@@ -42,7 +42,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
@@ -95,7 +95,7 @@
<goal>copy</goal>
</goals>
<configuration>
- <artifactItems>
+ <artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-policy</artifactId>
@@ -103,23 +103,24 @@
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
- <outputDirectory>${jetty.test.policy.loc}</outputDirectory>
+ <outputDirectory>${jetty.test.policy.loc}</outputDirectory>
<destFileName>jetty-test-policy.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
- </executions>
+ </executions>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.policy.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
- <dependencies>
+ <dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
@@ -128,6 +129,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-policy/src/main/config/etc/jetty-policy.xml b/jetty-policy/src/main/config/etc/jetty-policy.xml
index 6d8848cc4b..2a9c393f34 100644
--- a/jetty-policy/src/main/config/etc/jetty-policy.xml
+++ b/jetty-policy/src/main/config/etc/jetty-policy.xml
@@ -11,12 +11,12 @@
<Configure id="Policy" class="org.eclipse.jetty.policy.JettyPolicyConfigurator">
<Call name="addPolicy">
- <Arg><SystemProperty name="jetty.home"/>/lib/policy/jetty.policy</Arg>
+ <Arg><Property name="jetty.home"/>/lib/policy/jetty.policy</Arg>
</Call>
<Call name="addProperty">
<Arg>jetty.home</Arg>
- <Arg><SystemProperty name="jetty.home"/></Arg>
+ <Arg><Property name="jetty.home"/></Arg>
</Call>
<Call name="initialize"/>
diff --git a/jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java b/jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java
index 3b2a67be78..0322f4b956 100644
--- a/jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java
+++ b/jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java
@@ -56,8 +56,8 @@ import org.eclipse.jetty.policy.entry.PrincipalEntry;
*
* </pre>
*
- * For semantical details of this format, see the {@link org.apache.harmony.security.DefaultPolicy default policy
- * description}. <br>
+ * For semantical details of this format, see org.apache.harmony.security.DefaultPolicy javadoc. <br>
+ *
* Keywords are case-insensitive in contrast to quoted string literals. Comma-separation rule is quite forgiving, most
* commas may be just omitted. Whitespaces, line- and block comments are ignored. Symbol-level tokenization is delegated
* to java.io.StreamTokenizer. <br>
@@ -65,6 +65,7 @@ import org.eclipse.jetty.policy.entry.PrincipalEntry;
* This implementation is effectively thread-safe, as it has no field references to data being processed (that is,
* passes all the data as method parameters).
*
+ * This implementation is a bit more strict in enforcing format then the default policy scanner as implemented in the sun jdk.
*/
public class PolicyFileScanner
{
diff --git a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
index 17e91680fe..eb893e925c 100644
--- a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
+++ b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
@@ -1,17 +1,17 @@
-package org.eclipse.jetty.policy;
//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
//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
+//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.
+//You may elect to redistribute this code under either of these licenses.
//========================================================================
+package org.eclipse.jetty.policy;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
@@ -24,65 +24,61 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class JettyPolicyRuntimeTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class JettyPolicyRuntimeTest
{
- HashMap<String, String> evaluator = new HashMap<String, String>();
-
+ private HashMap<String, String> evaluator = new HashMap<String, String>();
private boolean _runningOnWindows;
-
-
- @Override
- protected void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
System.setSecurityManager(null);
Policy.setPolicy(null);
_runningOnWindows = System.getProperty( "os.name" ).startsWith( "Windows" );
-
- super.setUp();
-
+
evaluator.put("jetty.home",MavenTestingUtils.getBaseURI().toASCIIString());
evaluator.put("basedir",MavenTestingUtils.getBaseURI().toASCIIString());
}
-
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
-
- System.setSecurityManager( null );
- Policy.setPolicy( null );
+ System.setSecurityManager(null);
+ Policy.setPolicy(null);
}
+ @Test
public void testSimplePolicyReplacement() throws Exception
- {
-
- JettyPolicy ap = new JettyPolicy(getSinglePolicy("global-all-permission.policy"),evaluator);
-
+ {
+ JettyPolicy ap = new JettyPolicy(getSinglePolicy("global-all-permission.policy"), evaluator);
ap.refresh();
-
- Policy.setPolicy( ap );
+
+ Policy.setPolicy( ap );
System.setSecurityManager( new SecurityManager() );
-
+
File test = new File( "/tmp" );
-
- assertTrue ( test.canRead() );
-
+
+ assertTrue( test.canRead() );
}
-
+
+ @Test
public void testRepeatedPolicyReplacement() throws Exception
- {
+ {
JettyPolicy ap = new JettyPolicy(getSinglePolicy("global-all-permission.policy"),evaluator);
-
ap.refresh();
-
+
Policy.setPolicy( ap );
-
System.setSecurityManager( new SecurityManager() );
-
+
// Test that the all permission policy allows us to do this
try
{
@@ -95,11 +91,10 @@ public class JettyPolicyRuntimeTest extends TestCase
ace.printStackTrace(System.err);
fail("Should NOT have thrown an AccessControlException");
}
-
+
JettyPolicy ap2 = new JettyPolicy(getSinglePolicy("global-file-read-only-tmp-permission.policy"),evaluator);
-
ap2.refresh();
-
+
Policy.setPolicy( ap2 );
// Test that the new policy does replace the old one and we are now not allowed
@@ -114,9 +109,9 @@ public class JettyPolicyRuntimeTest extends TestCase
{
// Expected Path
}
-
}
+ @Test
public void testPolicyRestrictive() throws Exception
{
// TODO - temporary, create alternate file to load for windows
@@ -127,20 +122,18 @@ public class JettyPolicyRuntimeTest extends TestCase
}
JettyPolicy ap = new JettyPolicy(getSinglePolicy("global-file-read-only-tmp-permission.policy"),evaluator);
-
ap.refresh();
-
+
Policy.setPolicy( ap );
-
System.setSecurityManager( new SecurityManager() );
-
+
File test = new File( "/tmp" );
-
+
assertTrue ( test.canRead() );
-
+
File test2 = new File( "/tmp/foo" );
assertTrue ( test2.canRead() );
-
+
try
{
File test3 = new File("/tmp/foo/bar/do");
@@ -153,9 +146,9 @@ public class JettyPolicyRuntimeTest extends TestCase
// Expected Path
}
}
-
- public void testCertificateLoader()
- throws Exception
+
+ @Test
+ public void testCertificateLoader() throws Exception
{
// TODO - temporary, create alternate file to load for windows
if (_runningOnWindows)
@@ -165,51 +158,47 @@ public class JettyPolicyRuntimeTest extends TestCase
}
JettyPolicy ap = new JettyPolicy(getSinglePolicy("jetty-certificate.policy"),evaluator);
-
ap.refresh();
-
+
Policy.setPolicy( ap );
-
System.setSecurityManager( new SecurityManager() );
-
+
URL url = MavenTestingUtils.toTargetURL("test-policy/jetty-test-policy.jar");
-
+
URLClassLoader loader ;
if (Thread.currentThread().getContextClassLoader() != null )
{
- loader = new URLClassLoader( new URL[]{ url }, Thread.currentThread().getContextClassLoader() );
+ loader = new URLClassLoader( new URL[]{ url }, Thread.currentThread().getContextClassLoader() );
}
else
{
- loader = new URLClassLoader( new URL[]{ url }, ClassLoader.getSystemClassLoader() );
+ loader = new URLClassLoader( new URL[]{ url }, ClassLoader.getSystemClassLoader() );
}
-
+
Thread.currentThread().setContextClassLoader(loader);
-
+
ap.refresh();
-
+
Class<?> clazz = loader.loadClass("org.eclipse.jetty.toolchain.test.policy.Tester");
Method m = clazz.getMethod("testEcho",new Class[]
{ String.class });
- String foo = (String)m.invoke(clazz.newInstance(),new Object[]
- { "foo" });
+ String foo = (String)m.invoke(clazz.newInstance(), "foo");
assertEquals("foo",foo);
Method m2 = clazz.getMethod("testReadSystemProperty",new Class[]
{ String.class });
- m2.invoke(clazz.newInstance(),new Object[]
- { "foo" });
+ m2.invoke(clazz.newInstance(), "foo");
assertTrue("system property access was granted",true);
// ap.dump(System.out);
}
-
-
+
+ @Test
public void testBadCertificateLoader()
throws Exception
{
@@ -221,43 +210,40 @@ public class JettyPolicyRuntimeTest extends TestCase
}
JettyPolicy ap = new JettyPolicy(getSinglePolicy("jetty-bad-certificate.policy"),evaluator);
-
ap.refresh();
-
+
Policy.setPolicy( ap );
-
System.setSecurityManager( new SecurityManager() );
-
+
URL url = MavenTestingUtils.toTargetURL("test-policy/jetty-test-policy.jar");
-
+
URLClassLoader loader ;
if (Thread.currentThread().getContextClassLoader() != null )
{
- loader = new URLClassLoader( new URL[]{ url }, Thread.currentThread().getContextClassLoader() );
+ loader = new URLClassLoader( new URL[]{ url }, Thread.currentThread().getContextClassLoader() );
}
else
{
- loader = new URLClassLoader( new URL[]{ url }, ClassLoader.getSystemClassLoader() );
+ loader = new URLClassLoader( new URL[]{ url }, ClassLoader.getSystemClassLoader() );
}
-
+
Thread.currentThread().setContextClassLoader(loader);
-
+
ap.refresh();
-
+
try
{
Class<?> clazz = loader.loadClass("org.eclipse.jetty.toolchain.test.policy.Tester");
-
+
Method m = clazz.getMethod( "testEcho", new Class[] {String.class} );
-
- String foo = (String)m.invoke( clazz.newInstance(), new Object[] {"foo"} );
-
+
+ String foo = (String)m.invoke( clazz.newInstance(), "foo");
+
assertEquals("foo", foo );
-
+
Method m2 = clazz.getMethod( "testReadSystemProperty", new Class[] {String.class} );
-
- m2.invoke(clazz.newInstance(),new Object[]
- { "foobar" });
+
+ m2.invoke(clazz.newInstance(), "foobar");
fail("Should have thrown an InvocationTargetException");
}
diff --git a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyTest.java b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyTest.java
index 182e09d36c..f5be38d151 100644
--- a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyTest.java
+++ b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyTest.java
@@ -1,4 +1,3 @@
-package org.eclipse.jetty.policy;
//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
@@ -15,6 +14,8 @@ package org.eclipse.jetty.policy;
//You may elect to redistribute this code under either of these licenses.
//========================================================================
+package org.eclipse.jetty.policy;
+
import java.io.FilePermission;
import java.net.URL;
import java.security.CodeSource;
@@ -28,98 +29,92 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
-public class JettyPolicyTest extends TestCase
+public class JettyPolicyTest
{
- HashMap<String, String> evaluator = new HashMap<String, String>();
-
+ private HashMap<String, String> evaluator = new HashMap<String, String>();
- @Override
- protected void setUp()
- throws Exception
+ @Before
+ public void setUp() throws Exception
{
- super.setUp();
-
evaluator.put("jetty.home",MavenTestingUtils.getBaseURI().toASCIIString());
evaluator.put("basedir",MavenTestingUtils.getBaseURI().toASCIIString());
}
- public void testGlobalAllPermissionLoader()
- throws Exception
+ @Test
+ public void testGlobalAllPermissionLoader() throws Exception
{
-
- JettyPolicy ap =
- new JettyPolicy( Collections.singleton( MavenTestingUtils.getBasedir().getAbsolutePath() + "/src/test/resources/global-all-permission.policy" ), evaluator );
+ JettyPolicy ap = new JettyPolicy( Collections.singleton( MavenTestingUtils.getBasedir().getAbsolutePath() + "/src/test/resources/global-all-permission.policy" ), evaluator );
ap.refresh();
-
PermissionCollection pc = ap.getPermissions( new ProtectionDomain( null, null ) );
-
+
assertNotNull( pc );
-
+
Permission testPerm = new FilePermission( "/tmp", "read" );
-
+
assertTrue( pc.implies( testPerm ) );
-
- for ( Enumeration<Permission> e = pc.elements(); e.hasMoreElements(); )
+
+ for ( Enumeration<Permission> e = pc.elements(); e.hasMoreElements(); )
{
System.out.println( "Permission: " + e.nextElement().getClass().getName() );
}
-
}
- public void testSingleCodebaseFilePermissionLoader()
- throws Exception
+ @Test
+ public void testSingleCodebaseFilePermissionLoader() throws Exception
{
JettyPolicy ap =
new JettyPolicy( Collections.singleton( MavenTestingUtils.getBasedir().getAbsolutePath()
+ "/src/test/resources/single-codebase-file-permission.policy" ), evaluator );
-
ap.refresh();
-
- URL url = new URL( "file:///foo.jar" );
+
+ URL url = new URL( "file:///foo.jar" );
CodeSource cs = new CodeSource( url, new Certificate[0]);
-
+
PermissionCollection pc = ap.getPermissions( cs );
-
+
assertNotNull( pc );
-
+
Permission testPerm = new FilePermission( "/tmp/*", "read" );
-
+
assertTrue( pc.implies( testPerm ) );
-
}
- public void testMultipleCodebaseFilePermissionLoader()
- throws Exception
+ @Test
+ public void testMultipleCodebaseFilePermissionLoader() throws Exception
{
JettyPolicy ap =
new JettyPolicy( Collections.singleton( MavenTestingUtils.getBasedir().getAbsolutePath()
+ "/src/test/resources/multiple-codebase-file-permission.policy" ), evaluator );
ap.refresh();
-
+
// ap.dump(System.out);
- URL url = new URL( "file:///bar.jar" );
+ URL url = new URL( "file:///bar.jar" );
CodeSource cs = new CodeSource( url, new Certificate[0]);
-
+
PermissionCollection pc = ap.getPermissions( cs );
-
+
assertNotNull( pc );
-
+
Permission testPerm = new FilePermission( "/tmp/*", "read,write" );
Permission testPerm2 = new FilePermission( "/usr/*", "write" ); // only read was granted
-
+
assertTrue( pc.implies( testPerm ) );
assertFalse( pc.implies( testPerm2 ) );
-
}
- public void testMultipleCodebaseMixedPermissionLoader()
- throws Exception
+ @Test
+ public void testMultipleCodebaseMixedPermissionLoader() throws Exception
{
JettyPolicy ap =
new JettyPolicy( Collections.singleton( MavenTestingUtils.getBasedir().getAbsolutePath()
@@ -129,7 +124,8 @@ public class JettyPolicyTest extends TestCase
// ap.dump(System.out);
}
-
+
+ @Test
public void testSCLoader() throws Exception
{
JettyPolicy ap = new JettyPolicy(Collections.singleton(MavenTestingUtils.getBasedir().getAbsolutePath() + "/src/main/config/lib/policy/jetty.policy"),evaluator);
@@ -138,30 +134,29 @@ public class JettyPolicyTest extends TestCase
ap.dump(System.out);
}
- public void testMultipleFilePermissionLoader()
- throws Exception
+ @Test
+ public void testMultipleFilePermissionLoader() throws Exception
{
Set<String> files = new HashSet<String>();
-
+
files.add( MavenTestingUtils.getBasedir().getAbsolutePath() + "/src/test/resources/single-codebase-file-permission.policy" );
files.add( MavenTestingUtils.getBasedir().getAbsolutePath() + "/src/test/resources/single-codebase-file-permission-2.policy" );
-
+
JettyPolicy ap = new JettyPolicy( files, evaluator );
ap.refresh();
-
- URL url = new URL( "file:///bar.jar" );
+
+ URL url = new URL( "file:///bar.jar" );
CodeSource cs = new CodeSource( url, new Certificate[0]);
-
+
PermissionCollection pc = ap.getPermissions( cs );
-
+
assertNotNull( pc );
-
+
Permission testPerm = new FilePermission( "/tmp/*", "read" );
- Permission testPerm2 = new FilePermission( "/usr/*", "write" ); //
-
+ Permission testPerm2 = new FilePermission( "/usr/*", "write" ); //
+
assertTrue( pc.implies( testPerm ) );
assertFalse( pc.implies( testPerm2 ) );
}
-
}
diff --git a/jetty-policy/src/test/java/org/eclipse/jetty/policy/PolicyContextTest.java b/jetty-policy/src/test/java/org/eclipse/jetty/policy/PolicyContextTest.java
index 4e8ad3e291..fdcf2b12ab 100644
--- a/jetty-policy/src/test/java/org/eclipse/jetty/policy/PolicyContextTest.java
+++ b/jetty-policy/src/test/java/org/eclipse/jetty/policy/PolicyContextTest.java
@@ -1,4 +1,3 @@
-package org.eclipse.jetty.policy;
//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
@@ -15,120 +14,110 @@ package org.eclipse.jetty.policy;
//You may elect to redistribute this code under either of these licenses.
//========================================================================
+package org.eclipse.jetty.policy;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.Permission;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.policy.entry.GrantEntry;
import org.eclipse.jetty.policy.entry.KeystoreEntry;
import org.eclipse.jetty.policy.loader.PolicyFileScanner;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class PolicyContextTest
- extends TestCase
{
public static final String __PRINCIPAL = "javax.security.auth.x500.X500Principal \"CN=Jetty Policy,OU=Artifact,O=Jetty Project,L=Earth,ST=Internet,C=US\"";
-
private boolean _runningOnWindows;
-
-
- @Override
- protected void setUp()
- throws Exception
+
+ @Before
+ public void init() throws Exception
{
_runningOnWindows = System.getProperty( "os.name" ).startsWith( "Windows" );
-
System.setProperty( "basedir", MavenTestingUtils.getBaseURI().toASCIIString() );
-
- super.setUp();
}
+ @Test
public void testSelfPropertyExpansion() throws Exception
{
-
- PolicyContext context = new PolicyContext();
- PolicyFileScanner loader = new PolicyFileScanner();
+ PolicyContext context = new PolicyContext();
+ PolicyFileScanner loader = new PolicyFileScanner();
List<GrantEntry> grantEntries = new ArrayList<GrantEntry>();
List<KeystoreEntry> keystoreEntries = new ArrayList<KeystoreEntry>();
-
- File policyFile = new File( getWorkingDirectory() + "/src/test/resources/context/jetty-certificate.policy" );
-
+
+ File policyFile = new File( getWorkingDirectory() + "/src/test/resources/context/jetty-certificate.policy" );
+
loader.scanStream( new InputStreamReader( new FileInputStream( policyFile ) ), grantEntries, keystoreEntries );
-
+
if ( !_runningOnWindows ) //temporary, create alternate file to load for windows
{
-
- for ( Iterator<KeystoreEntry> i = keystoreEntries.iterator(); i.hasNext();)
- {
- KeystoreEntry node = i.next();
- node.expand( context );
-
- context.setKeystore( node.toKeyStore() );
- }
-
- GrantEntry grant = grantEntries.get( 0 );
- grant.expand( context );
-
- Permission perm = grant.getPermissions().elements().nextElement();
-
-
- assertEquals( __PRINCIPAL, perm.getName() );
+ for (KeystoreEntry node : keystoreEntries)
+ {
+ node.expand(context);
+
+ context.setKeystore(node.toKeyStore());
+ }
+
+ GrantEntry grant = grantEntries.get( 0 );
+ grant.expand( context );
+
+ Permission perm = grant.getPermissions().elements().nextElement();
+
+ assertEquals( __PRINCIPAL, perm.getName() );
}
}
-
+
+ @Test
public void testAliasPropertyExpansion() throws Exception
{
-
- PolicyContext context = new PolicyContext();
- PolicyFileScanner loader = new PolicyFileScanner();
+ PolicyContext context = new PolicyContext();
+ PolicyFileScanner loader = new PolicyFileScanner();
List<GrantEntry> grantEntries = new ArrayList<GrantEntry>();
List<KeystoreEntry> keystoreEntries = new ArrayList<KeystoreEntry>();
-
- File policyFile = new File( getWorkingDirectory() + "/src/test/resources/context/jetty-certificate-alias.policy" );
-
+
+ File policyFile = new File( getWorkingDirectory() + "/src/test/resources/context/jetty-certificate-alias.policy" );
+
loader.scanStream( new InputStreamReader( new FileInputStream( policyFile ) ), grantEntries, keystoreEntries );
-
+
if ( !_runningOnWindows ) //temporary, create alternate file to load for windows
{
-
- for ( Iterator<KeystoreEntry> i = keystoreEntries.iterator(); i.hasNext();)
- {
- KeystoreEntry node = i.next();
- node.expand( context );
-
- context.setKeystore( node.toKeyStore() );
- }
-
- GrantEntry grant = grantEntries.get( 0 );
- grant.expand( context );
-
- Permission perm = grant.getPermissions().elements().nextElement();
-
- assertEquals( __PRINCIPAL, perm.getName() );
+ for (KeystoreEntry node : keystoreEntries)
+ {
+ node.expand(context);
+
+ context.setKeystore(node.toKeyStore());
+ }
+
+ GrantEntry grant = grantEntries.get( 0 );
+ grant.expand( context );
+
+ Permission perm = grant.getPermissions().elements().nextElement();
+
+ assertEquals( __PRINCIPAL, perm.getName() );
}
}
-
+
+ @Test
public void testFileSeparatorExpansion() throws Exception
{
- PolicyContext context = new PolicyContext();
+ PolicyContext context = new PolicyContext();
context.addProperty( "foo", "bar" );
-
+
assertEquals(File.separator, context.evaluate( "${/}" ) );
assertEquals(File.separator + "bar" + File.separator, context.evaluate( "${/}${foo}${/}" ) );
-
assertEquals(File.separator + File.separator, context.evaluate( "${/}${/}" ) );
}
-
+
private String getWorkingDirectory()
{
return MavenTestingUtils.getBasedir().getAbsolutePath();
}
-
}
diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml
index b52c851fd1..adb0b0b2b9 100644
--- a/jetty-rewrite/pom.xml
+++ b/jetty-rewrite/pom.xml
@@ -55,11 +55,12 @@
</execution>
</executions>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.rewrite.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -67,6 +68,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
index b0fbbcaf76..cd2bfb4042 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
@@ -72,7 +72,7 @@ public class HeaderPatternRule extends PatternRule
* the new value overwrites the previous one. Otherwise, it adds the new
* header name and value.
*
- *@see org.eclipse.jetty.server.server.rewrite.handler.Rule#matchAndApply(String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ *@see org.eclipse.jetty.rewrite.handler.Rule#matchAndApply(String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
{
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java
index 57d1572a5d..5723fb7ca4 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java
@@ -26,35 +26,32 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
/* ------------------------------------------------------------ */
/**
*<p> Rewrite handler is responsible for managing the rules. Its capabilities
- * is not only limited for url rewrites such as RewritePatternRule or RewriteRegexRule.
+ * is not only limited for URL rewrites such as RewritePatternRule or RewriteRegexRule.
* There is also handling for cookies, headers, redirection, setting status or error codes
* whenever the rule finds a match.
*
- * <p> The rules can be matched by the ff. options: pattern matching of PathMap
- * (class PatternRule), regular expressions (class RegexRule) or certain conditions set
- * (e.g. MsieSslRule - the requests must be in SSL mode).
+ * <p> The rules can be matched by the either: pattern matching of PathMap
+ * (eg {@link PatternRule}), regular expressions (eg {@link RegexRule}) or certain conditions set
+ * (eg {@link MsieSslRule} - the requests must be in SSL mode).
*
- * Here are the list of rules:
- * <ul>
- * <li> CookiePatternRule - adds a new cookie in response. </li>
- * <li> HeaderPatternRule - adds/modifies the HTTP headers in response. </li>
- * <li> RedirectPatternRule - sets the redirect location. </li>
- * <li> ResponsePatternRule - sets the status/error codes. </li>
- * <li> RewritePatternRule - rewrites the requested URI. </li>
- * <li> RewriteRegexRule - rewrites the requested URI using regular expression for pattern matching. </li>
- * <li> MsieSslRule - disables the keep alive on SSL for IE5 and IE6. </li>
- * <li> LegacyRule - the old version of rewrite. </li>
- * <li> ForwardedSchemeHeaderRule - set the scheme according to the headers present. </li>
- * </ul>
- *
- * <p> The rules can be grouped into rule containers (class RuleContainerRule), and will only
+ * <p> The rules can be grouped into rule containers (class {@link RuleContainer}), and will only
* be applied if the request matches the conditions for their container
* (e.g., by virtual host name)
- *
- * Here are a list of rule containers:
+ *
+ * <p>The list of predefined rules is:
* <ul>
- * <li> VirtualHostRuleContainerRule - checks whether the request matches one of a set of virtual host names.</li>
+ * <li> {@link CookiePatternRule} - adds a new cookie in response. </li>
+ * <li> {@link HeaderPatternRule} - adds/modifies the HTTP headers in response. </li>
+ * <li> {@link RedirectPatternRule} - sets the redirect location. </li>
+ * <li> {@link ResponsePatternRule} - sets the status/error codes. </li>
+ * <li> {@link RewritePatternRule} - rewrites the requested URI. </li>
+ * <li> {@link RewriteRegexRule} - rewrites the requested URI using regular expression for pattern matching. </li>
+ * <li> {@link MsieSslRule} - disables the keep alive on SSL for IE5 and IE6. </li>
+ * <li> {@link LegacyRule} - the old version of rewrite. </li>
+ * <li> {@link ForwardedSchemeHeaderRule} - set the scheme according to the headers present. </li>
+ * <li> {@link VirtualHostRuleContainer} - checks whether the request matches one of a set of virtual host names.</li>
* </ul>
+ *
*
* Here is a typical jetty.xml configuration would be: <pre>
*
@@ -283,7 +280,7 @@ public class RewriteHandler extends HandlerWrapper
/* ------------------------------------------------------------ */
/**
- * @param originalPathAttribte If non null, this string will be used
+ * @param originalPathAttribute If non null, this string will be used
* as the attribute name to store the original request path.
*/
public void setOriginalPathAttribute(String originalPathAttribute)
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
index eabb07837e..8b3c023be3 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
@@ -52,7 +52,7 @@ public class VirtualHostRuleContainer extends RuleContainer
/* ------------------------------------------------------------ */
/** Get the virtual hosts that the rules within this container will apply to
- * @param virtualHosts Array of virtual hosts that the rules within this container are applied to.
+ * @return Array of virtual hosts that the rules within this container are applied to.
* A null hostname or null/empty array means any hostname is acceptable.
*/
public String[] getVirtualHosts()
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
index b2b818d95e..7907fb04ab 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
@@ -4,16 +4,14 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.bio.StringEndPoint;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConnection;
@@ -21,56 +19,51 @@ import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
+import org.junit.After;
-public abstract class AbstractRuleTestCase extends TestCase
+public abstract class AbstractRuleTestCase
{
- protected Server _server=new Server();
+ protected Server _server = new Server();
protected LocalConnector _connector;
- protected StringEndPoint _endpoint=new StringEndPoint();
+ protected StringEndPoint _endpoint = new StringEndPoint();
protected HttpConnection _connection;
-
protected Request _request;
protected Response _response;
-
protected boolean _isSecure = false;
-
- public void setUp() throws Exception
- {
- start();
- }
-
- public void tearDown() throws Exception
+
+ @After
+ public void stopServer() throws Exception
{
stop();
}
-
- public void start() throws Exception
+
+ protected void start(final boolean isSecure) throws Exception
{
- _connector = new LocalConnector() {
+ _connector = new LocalConnector()
+ {
public boolean isConfidential(Request request)
{
- return _isSecure;
+ return isSecure;
}
};
-
_server.setConnectors(new Connector[]{_connector});
_server.start();
reset();
}
-
- public void stop() throws Exception
+
+ protected void stop() throws Exception
{
_server.stop();
+ _server.join();
_request = null;
_response = null;
}
-
- public void reset()
+
+ protected void reset()
{
- _connection = new HttpConnection(_connector,_endpoint,_server);
+ _connection = new HttpConnection(_connector, _endpoint, _server);
_request = new Request(_connection);
_response = new Response(_connection);
-
_request.setRequestURI("/test/");
}
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
index 4eed73b6ac..a423b29ee9 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
@@ -17,24 +17,29 @@ import java.util.Enumeration;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeaders;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
public class CookiePatternRuleTest extends AbstractRuleTestCase
-{
- public void setUp() throws Exception
+{
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
}
-
+
+ @Test
public void testSingleCookie() throws IOException
{
String[][] cookie = {
{"cookie", "value"}
};
-
assertCookies(cookie);
}
-
+
+ @Test
public void testMultipleCookies() throws IOException
{
String[][] cookies = {
@@ -42,16 +47,13 @@ public class CookiePatternRuleTest extends AbstractRuleTestCase
{"name", "wolfgangpuck"},
{"age", "28"}
};
-
assertCookies(cookies);
}
-
+
private void assertCookies(String[][] cookies) throws IOException
{
- for (int i = 0; i < cookies.length; i++)
+ for (String[] cookie : cookies)
{
- String[] cookie = cookies[i];
-
// set cookie pattern
CookiePatternRule rule = new CookiePatternRule();
rule.setPattern("*");
@@ -62,7 +64,7 @@ public class CookiePatternRuleTest extends AbstractRuleTestCase
// apply cookie pattern
rule.apply(_request.getRequestURI(), _request, _response);
-
+
// verify
HttpFields httpFields = _response.getHttpFields();
Enumeration e = httpFields.getValues(HttpHeaders.SET_COOKIE_BUFFER);
@@ -72,7 +74,7 @@ public class CookiePatternRuleTest extends AbstractRuleTestCase
String[] result = ((String)e.nextElement()).split("=");
assertEquals(cookies[index][0], result[0]);
assertEquals(cookies[index][1], result[1]);
-
+
// +1 cookies index
index++;
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
index 97bd9175a6..49623b27a9 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
@@ -4,84 +4,84 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import org.eclipse.jetty.http.HttpFields;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class ForwardedSchemeHeaderRuleTest extends AbstractRuleTestCase
{
private ForwardedSchemeHeaderRule _rule;
private HttpFields _requestHeaderFields;
- public void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new ForwardedSchemeHeaderRule();
_requestHeaderFields = _connection.getRequestFields();
_request.setScheme(null);
}
-
+
+ @Test
public void testDefaultScheme() throws Exception
{
setRequestHeader("X-Forwarded-Scheme", "https");
_rule.setHeader("X-Forwarded-Scheme");
_rule.setHeaderValue("https");
-
_rule.matchAndApply("/", _request, _response);
assertEquals("https", _request.getScheme());
}
+ @Test
public void testScheme() throws Exception
{
setRequestHeader("X-Forwarded-Scheme", "https");
_rule.setHeader("X-Forwarded-Scheme");
_rule.setHeaderValue("https");
_rule.setScheme("https");
-
_rule.matchAndApply("/", _request, _response);
assertEquals("https", _request.getScheme());
-
-
+
_rule.setScheme("http");
_rule.matchAndApply("/", _request, _response);
assertEquals("http", _request.getScheme());
}
-
+
+ @Test
public void testHeaderValue() throws Exception
{
setRequestHeader("Front-End-Https", "on");
_rule.setHeader("Front-End-Https");
_rule.setHeaderValue("on");
_rule.setScheme("https");
-
_rule.matchAndApply("/",_request,_response);
assertEquals("https",_request.getScheme());
+
_request.setScheme(null);
-
-
// header value doesn't match rule's value
setRequestHeader("Front-End-Https", "off");
-
_rule.matchAndApply("/",_request,_response);
assertEquals(null,_request.getScheme());
- _request.setScheme(null);
-
+ _request.setScheme(null);
// header value can be any value
setRequestHeader("Front-End-Https", "any");
_rule.setHeaderValue(null);
-
_rule.matchAndApply("/",_request,_response);
assertEquals("https",_request.getScheme());
}
-
+
private void setRequestHeader(String header, String headerValue)
{
_requestHeaderFields.put(header, headerValue);
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
index 2c19ec404d..6559d03c69 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
@@ -4,59 +4,64 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.Iterator;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class HeaderPatternRuleTest extends AbstractRuleTestCase
{
private HeaderPatternRule _rule;
-
- public void setUp() throws Exception
- {
- super.setUp();
+ @Before
+ public void init() throws Exception
+ {
+ start(false);
_rule = new HeaderPatternRule();
_rule.setPattern("*");
}
+ @Test
public void testHeaderWithTextValues() throws IOException
{
// different keys
- String headers[][] = {
- { "hnum#1", "test1" },
+ String headers[][] = {
+ { "hnum#1", "test1" },
{ "hnum#2", "2test2" },
- { "hnum#3", "test3" }
+ { "hnum#3", "test3" }
};
-
assertHeaders(headers);
}
+ @Test
public void testHeaderWithNumberValues() throws IOException
{
- String headers[][] = {
- { "hello", "1" },
+ String headers[][] = {
+ { "hello", "1" },
{ "hello", "-1" },
{ "hello", "100" },
{ "hello", "100" },
{ "hello", "100" },
{ "hello", "100" },
{ "hello", "100" },
-
+
{ "hello1", "200" }
};
-
assertHeaders(headers);
}
-
+
+ @Test
public void testHeaderOverwriteValues() throws IOException
{
String headers[][] = {
@@ -73,9 +78,8 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
{ "title1", "abba" },
{ "title1", "abba1" }
};
-
assertHeaders(headers);
-
+
Iterator<String> e = _response.getHeaders("size").iterator();
int count = 0;
while (e.hasNext())
@@ -83,7 +87,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
e.next();
count++;
}
-
+
assertEquals(1, count);
assertEquals("500", _response.getHeader("size"));
assertEquals("cba", _response.getHeader("title"));
@@ -92,14 +96,14 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase
private void assertHeaders(String headers[][]) throws IOException
{
- for (int i = 0; i < headers.length; i++)
+ for (String[] header : headers)
{
- _rule.setName(headers[i][0]);
- _rule.setValue(headers[i][1]);
+ _rule.setName(header[0]);
+ _rule.setValue(header[1]);
_rule.apply(null, _request, _response);
- assertEquals(headers[i][1], _response.getHeader(headers[i][0]));
+ assertEquals(header[1], _response.getHeader(header[0]));
}
}
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/LegacyRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/LegacyRuleTest.java
index 314fa08e08..00a550757b 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/LegacyRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/LegacyRuleTest.java
@@ -4,59 +4,58 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class LegacyRuleTest extends AbstractRuleTestCase
{
- private LegacyRule _rule;
-
- String[][] _tests=
+ private String[][] _tests=
{
{"/foo/bar","/*","/replace/foo/bar"},
{"/foo/bar","/foo/*","/replace/bar"},
{"/foo/bar","/foo/bar","/replace"}
};
-
- public void setUp() throws Exception
+ private LegacyRule _rule;
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new LegacyRule();
}
-
- public void tearDown()
+
+ @After
+ public void destroy()
{
_rule = null;
}
-
+
+ @Test
public void testMatchAndApply() throws Exception
{
- for (int i=0;i<_tests.length;i++)
+ for (String[] _test : _tests)
{
- _rule.addRewriteRule(_tests[i][1], "/replace");
-
- String result = _rule.matchAndApply(_tests[i][0], _request, _response);
-
- assertEquals(_tests[i][1], _tests[i][2], result);
+ _rule.addRewriteRule(_test[1], "/replace");
+ String result = _rule.matchAndApply(_test[0], _request, _response);
+ assertEquals(_test[1], _test[2], result);
}
}
-
+
+ @Test(expected = IllegalArgumentException.class)
public void testAddRewrite()
{
- try
- {
- _rule.addRewriteRule("*.txt", "/replace");
- fail();
- }
- catch (IllegalArgumentException e)
- {
- }
+ _rule.addRewriteRule("*.txt", "/replace");
}
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java
index fab8cc28e0..9bc3444995 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
@@ -16,206 +16,220 @@ package org.eclipse.jetty.rewrite.handler;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.http.HttpHeaders;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
public class MsieSslRuleTest extends AbstractRuleTestCase
-{
+{
private MsieSslRule _rule;
-
- public void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
- // enable SSL
- _isSecure = true;
-
- super.setUp();
+ // enable SSL
+ start(true);
_rule = new MsieSslRule();
}
-
+
+ @Test
public void testWin2kWithIE5() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
-
+
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
- assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));;
-
+ assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
- assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));;
+ assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWin2kWithIE6() throws Exception
- {
+ {
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWin2kWithIE7() throws Exception
- {
+ {
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWin2kSP1WithIE5() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.01)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.01)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.01)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWin2kSP1WithIE6() throws Exception
- {
+ {
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.01)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWin2kSP1WithIE7() throws Exception
- {
+ {
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.01)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinXpWithIE5() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.1)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.1)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinXpWithIE6() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinXpWithIE7() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinVistaWithIE5() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 6.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 6.0)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
-
+
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 6.0)");
result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(_request.getRequestURI(), result);
assertEquals(HttpHeaderValues.CLOSE, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinVistaWithIE6() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWinVistaWithIE7() throws Exception
{
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
-
+
+ @Test
public void testWithoutSsl() throws Exception
{
// disable SSL
- _isSecure = false;
super.stop();
- super.start();
-
+ super.start(false);
+
HttpFields fields = _connection.getRequestFields();
fields.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0)");
-
+
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
-
+
assertEquals(null, result);
assertEquals(null, _response.getHeader(HttpHeaders.CONNECTION));
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
index fa6baebeb5..80dbff2316 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
@@ -4,49 +4,54 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Request;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class PatternRuleTest extends TestCase
+import static org.junit.Assert.assertEquals;
+
+public class PatternRuleTest
{
private PatternRule _rule;
- public void setUp()
+ @Before
+ public void init()
{
_rule = new TestPatternRule();
}
-
- public void tearDown()
+
+ @After
+ public void destroy()
{
_rule = null;
}
-
+
+ @Test
public void testTrueMatch() throws IOException
{
String[][] matchCases = {
// index 0 - pattern
// index 1 - URI to match
-
+
{"/abc", "/abc"},
{"/abc/", "/abc/"},
-
+
{"/abc/path/longer", "/abc/path/longer"},
{"/abc/path/longer/", "/abc/path/longer/"},
-
+
{"/abc/*", "/abc/hello.jsp"},
{"/abc/*", "/abc/a"},
{"/abc/*", "/abc/a/hello.jsp"},
@@ -54,70 +59,69 @@ public class PatternRuleTest extends TestCase
{"/abc/*", "/abc/a/b/hello.jsp"},
{"/abc/*", "/abc/a/b/c"},
{"/abc/*", "/abc/a/b/c/hello.jsp"},
-
+
{"/abc/def/*", "/abc/def/gf"},
{"/abc/def/*", "/abc/def/gf.html"},
{"/abc/def/*", "/abc/def/ghi"},
{"/abc/def/*", "/abc/def/ghi/"},
{"/abc/def/*", "/abc/def/ghi/hello.html"},
-
+
{"*.do", "/abc.do"},
{"*.do", "/abc/hello.do"},
{"*.do", "/abc/def/hello.do"},
{"*.do", "/abc/def/ghi/hello.do"},
-
+
{"*.jsp", "/abc.jsp"},
{"*.jsp", "/abc/hello.jsp"},
{"*.jsp", "/abc/def/hello.jsp"},
{"*.jsp", "/abc/def/ghi/hello.jsp"},
-
+
{"/", "/Other"},
{"/", "/Other/hello.do"},
{"/", "/Other/path"},
{"/", "/Other/path/hello.do"},
{"/", "/abc/def"},
-
+
{"/abc:/def", "/abc:/def"}
};
-
- for (int i = 0; i < matchCases.length; i++)
+
+ for (String[] matchCase : matchCases)
{
- String[] matchCase = matchCases[i];
assertMatch(true, matchCase);
}
}
-
+
+ @Test
public void testFalseMatch() throws IOException
{
String[][] matchCases = {
-
+
{"/abc", "/abcd"},
{"/abc/", "/abcd/"},
-
+
{"/abc/path/longer", "/abc/path/longer/"},
{"/abc/path/longer", "/abc/path/longer1"},
{"/abc/path/longer/", "/abc/path/longer"},
{"/abc/path/longer/", "/abc/path/longer1/"},
-
+
{"/*.jsp", "/hello.jsp"},
{"/abc/*.jsp", "/abc/hello.jsp"},
-
+
{"*.jsp", "/hello.1jsp"},
{"*.jsp", "/hello.jsp1"},
{"*.jsp", "/hello.do"},
-
+
{"*.jsp", "/abc/hello.do"},
{"*.jsp", "/abc/def/hello.do"},
{"*.jsp", "/abc.do"}
};
-
- for (int i = 0; i < matchCases.length; i++)
+
+ for (String[] matchCase : matchCases)
{
- String[] matchCase = matchCases[i];
assertMatch(false, matchCase);
}
}
-
+
private void assertMatch(boolean flag, String[] matchCase) throws IOException
{
_rule.setPattern(matchCase[0]);
@@ -130,11 +134,10 @@ public class PatternRuleTest extends TestCase
}
}, null
);
-
+
assertEquals("pattern: " + matchCase[0] + " uri: " + matchCase[1], flag, result!=null);
}
-
-
+
private class TestPatternRule extends PatternRule
{
@Override
@@ -143,6 +146,6 @@ public class PatternRuleTest extends TestCase
{
return target;
}
-
+
}
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
index 5512fd8d28..7cfa9e5bb8 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
@@ -4,43 +4,47 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import org.eclipse.jetty.http.HttpHeaders;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
public class RedirectPatternRuleTest extends AbstractRuleTestCase
{
private RedirectPatternRule _rule;
-
- public void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new RedirectPatternRule();
_rule.setPattern("*");
}
-
- public void tearDown()
+
+ @After
+ public void destroy()
{
_rule = null;
}
-
+
+ @Test
public void testLocation() throws IOException
{
String location = "http://eclipse.com";
-
_rule.setLocation(location);
_rule.apply(null, _request, _response);
-
assertEquals(location, _response.getHeader(HttpHeaders.LOCATION));
}
-
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
index b19fa4687e..43f9a1babc 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
@@ -5,13 +5,13 @@
// 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
+// 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.apache.org/licenses/LICENSE-2.0.txt
//
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
@@ -19,22 +19,30 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import org.eclipse.jetty.http.HttpHeaders;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class RedirectRegexRuleTest extends AbstractRuleTestCase
{
private RedirectRegexRule _rule;
-
- public void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new RedirectRegexRule();
}
-
- public void tearDown()
+
+ @After
+ public void destroy()
{
_rule = null;
}
-
+
+ @Test
public void testLocationWithReplacementGroupEmpty() throws IOException
{
_rule.setRegex("/my/dir/file/(.*)$");
@@ -44,7 +52,8 @@ public class RedirectRegexRuleTest extends AbstractRuleTestCase
_rule.matchAndApply("/my/dir/file/", _request, _response);
assertEquals("http://www.mortbay.org/", _response.getHeader(HttpHeaders.LOCATION));
}
-
+
+ @Test
public void testLocationWithReplacmentGroupSimple() throws IOException
{
_rule.setRegex("/my/dir/file/(.*)$");
@@ -54,7 +63,8 @@ public class RedirectRegexRuleTest extends AbstractRuleTestCase
_rule.matchAndApply("/my/dir/file/image.png", _request, _response);
assertEquals("http://www.mortbay.org/image.png", _response.getHeader(HttpHeaders.LOCATION));
}
-
+
+ @Test
public void testLocationWithReplacementGroupDeepWithParams() throws IOException
{
_rule.setRegex("/my/dir/file/(.*)$");
@@ -64,5 +74,4 @@ public class RedirectRegexRuleTest extends AbstractRuleTestCase
_rule.matchAndApply("/my/dir/file/api/rest/foo?id=100&sort=date", _request, _response);
assertEquals("http://www.mortbay.org/api/rest/foo?id=100&sort=date", _response.getHeader(HttpHeaders.LOCATION));
}
-
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
index ef5d20025f..55f1ac4d80 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
@@ -4,85 +4,88 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.regex.Matcher;
-
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Request;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class RegexRuleTest extends TestCase
+import static org.junit.Assert.assertEquals;
+
+public class RegexRuleTest
{
private RegexRule _rule;
-
- public void setUp()
+
+ @Before
+ public void init()
{
_rule = new TestRegexRule();
-
}
-
- public void tearDown()
+
+ @After
+ public void destroy()
{
_rule = null;
}
-
+
+ @Test
public void testTrueMatch() throws IOException
{
String[][] matchCases = {
// regex: *.jsp
{"/.*.jsp", "/hello.jsp"},
{"/.*.jsp", "/abc/hello.jsp"},
-
+
// regex: /abc or /def
{"/abc|/def", "/abc"},
{"/abc|/def", "/def"},
-
+
// regex: *.do or *.jsp
{".*\\.do|.*\\.jsp", "/hello.do"},
{".*\\.do|.*\\.jsp", "/hello.jsp"},
{".*\\.do|.*\\.jsp", "/abc/hello.do"},
{".*\\.do|.*\\.jsp", "/abc/hello.jsp"},
-
+
{"/abc/.*.htm|/def/.*.htm", "/abc/hello.htm"},
{"/abc/.*.htm|/def/.*.htm", "/abc/def/hello.htm"},
-
+
// regex: /abc/*.jsp
{"/abc/.*.jsp", "/abc/hello.jsp"},
{"/abc/.*.jsp", "/abc/def/hello.jsp"}
};
-
- for (int i = 0; i < matchCases.length; i++)
+
+ for (String[] matchCase : matchCases)
{
- String[] matchCase = matchCases[i];
assertMatch(true, matchCase);
}
}
-
+
+ @Test
public void testFalseMatch() throws IOException
{
String[][] matchCases = {
{"/abc/.*.jsp", "/hello.jsp"}
};
-
- for (int i = 0; i < matchCases.length; i++)
+
+ for (String[] matchCase : matchCases)
{
- String[] matchCase = matchCases[i];
assertMatch(false, matchCase);
}
}
-
+
private void assertMatch(boolean flag, String[] matchCase) throws IOException
{
_rule.setRegex(matchCase[0]);
@@ -96,10 +99,10 @@ public class RegexRuleTest extends TestCase
}
}, null
);
-
+
assertEquals("regex: " + matchCase[0] + " uri: " + matchCase[1], flag, result!=null);
}
-
+
private class TestRegexRule extends RegexRule
{
public String apply(String target,HttpServletRequest request,HttpServletResponse response, Matcher matcher) throws IOException
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
index 0770c141ff..319b8dc18e 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
@@ -4,38 +4,46 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
public class ResponsePatternRuleTest extends AbstractRuleTestCase
{
private ResponsePatternRule _rule;
-
- public void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new ResponsePatternRule();
_rule.setPattern("/test");
}
-
+
+ @Test
public void testStatusCodeNoReason() throws IOException
{
for (int i = 1; i < 400; i++)
{
_rule.setCode("" + i);
_rule.apply(null, _request, _response);
-
+
assertEquals(i, _response.getStatus());
}
}
-
+
+ @Test
public void testStatusCodeWithReason() throws IOException
{
for (int i = 1; i < 400; i++)
@@ -43,25 +51,27 @@ public class ResponsePatternRuleTest extends AbstractRuleTestCase
_rule.setCode("" + i);
_rule.setReason("reason" + i);
_rule.apply(null, _request, _response);
-
+
assertEquals(i, _response.getStatus());
assertEquals(null, _response.getReason());
}
}
-
+
+ @Test
public void testErrorStatusNoReason() throws IOException
{
for (int i = 400; i < 600; i++)
{
_rule.setCode("" + i);
_rule.apply(null, _request, _response);
-
+
assertEquals(i, _response.getStatus());
assertEquals("", _response.getReason());
super.reset();
}
}
-
+
+ @Test
public void testErrorStatusWithReason() throws IOException
{
for (int i = 400; i < 600; i++)
@@ -69,7 +79,7 @@ public class ResponsePatternRuleTest extends AbstractRuleTestCase
_rule.setCode("" + i);
_rule.setReason("reason-" + i);
_rule.apply(null, _request, _response);
-
+
assertEquals(i, _response.getStatus());
assertEquals("reason-" + i, _response.getReason());
super.reset();
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
index 386e2ffe1d..be50988ca4 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
@@ -4,33 +4,36 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class RewriteHandlerTest extends AbstractRuleTestCase
-{
- RewriteHandler _handler;
- RewritePatternRule _rule1;
- RewritePatternRule _rule2;
- RewritePatternRule _rule3;
-
-
- public void setUp() throws Exception
+{
+ private RewriteHandler _handler;
+ private RewritePatternRule _rule1;
+ private RewritePatternRule _rule2;
+ private RewritePatternRule _rule3;
+
+ @Before
+ public void init() throws Exception
{
_handler=new RewriteHandler();
_server.setHandler(_handler);
@@ -43,9 +46,9 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
request.setAttribute("URI",request.getRequestURI());
request.setAttribute("info",request.getPathInfo());
}
-
+
});
-
+
_rule1 = new RewritePatternRule();
_rule1.setPattern("/aaa/*");
_rule1.setReplacement("/bbb");
@@ -55,13 +58,13 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_rule3 = new RewritePatternRule();
_rule3.setPattern("/ccc/*");
_rule3.setReplacement("/ddd");
-
+
_handler.setRules(new Rule[]{_rule1,_rule2,_rule3});
-
- super.setUp();
- }
-
-
+
+ start(false);
+ }
+
+ @Test
public void test() throws Exception
{
_response.setStatus(200);
@@ -77,7 +80,6 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals("/foo/bar",_request.getAttribute("URI"));
assertEquals("/foo/bar",_request.getAttribute("info"));
assertEquals(null,_request.getAttribute("before"));
-
_response.setStatus(200);
_request.setHandled(false);
@@ -90,7 +92,6 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals("/aaa/bar",_request.getAttribute("URI"));
assertEquals("/aaa/bar",_request.getAttribute("info"));
assertEquals(null,_request.getAttribute("before"));
-
_response.setStatus(200);
_request.setHandled(false);
@@ -105,7 +106,6 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals("/ddd/bar",_request.getAttribute("URI"));
assertEquals("/ddd/bar",_request.getAttribute("info"));
assertEquals("/aaa/bar",_request.getAttribute("before"));
-
_response.setStatus(200);
_request.setHandled(false);
@@ -135,8 +135,5 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals(null,_request.getAttribute("info"));
assertEquals("/aaa/bar",_request.getAttribute("before"));
assertTrue(_request.isHandled());
-
-
-
}
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
index dfecfc0279..c939b89bcc 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
@@ -4,22 +4,24 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
public class RewritePatternRuleTest extends AbstractRuleTestCase
{
- private RewritePatternRule _rule;
-
- String[][] _tests=
+ private String[][] _tests=
{
{"/foo/bar","/","/replace"},
{"/foo/bar","/*","/replace/foo/bar"},
@@ -27,25 +29,24 @@ public class RewritePatternRuleTest extends AbstractRuleTestCase
{"/foo/bar","/foo/bar","/replace"},
{"/foo/bar.txt","*.txt","/replace"},
};
-
- public void setUp() throws Exception
+ private RewritePatternRule _rule;
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule = new RewritePatternRule();
_rule.setReplacement("/replace");
- }
-
-
+ }
+
+ @Test
public void testRequestUriEnabled() throws IOException
{
- for (int i=0;i<_tests.length;i++)
+ for (String[] test : _tests)
{
- _rule.setPattern(_tests[i][1]);
-
- String result = _rule.matchAndApply(_tests[i][0], _request, _response);
-
- assertEquals(_tests[i][1],_tests[i][2], result);
+ _rule.setPattern(test[1]);
+ String result = _rule.matchAndApply(test[0], _request, _response);
+ assertEquals(test[1], test[2], result);
}
}
-
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
index 7372b6bbb4..7d05946d1e 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
@@ -4,44 +4,47 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
public class RewriteRegexRuleTest extends AbstractRuleTestCase
{
- private RewriteRegexRule _rule;
-
- String[][] _tests=
- {
+ private String[][] _tests=
+ {
{"/foo/bar",".*","/replace","/replace"},
- {"/foo/bar","/xxx.*","/replace",null},
+ {"/foo/bar","/xxx.*","/replace",null},
{"/foo/bar","/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx"},
};
-
- public void setUp() throws Exception
+ private RewriteRegexRule _rule;
+
+ @Before
+ public void init() throws Exception
{
- super.setUp();
+ start(false);
_rule=new RewriteRegexRule();
}
-
+
+ @Test
public void testRequestUriEnabled() throws IOException
{
- for (int i=0;i<_tests.length;i++)
+ for (String[] test : _tests)
{
- _rule.setRegex(_tests[i][1]);
- _rule.setReplacement(_tests[i][2]);
-
- String result = _rule.matchAndApply(_tests[i][0], _request, _response);
-
- assertEquals(_tests[i][1],_tests[i][3], result);
+ _rule.setRegex(test[1]);
+ _rule.setReplacement(test[2]);
+ String result = _rule.matchAndApply(test[0], _request, _response);
+ assertEquals(test[1], test[3], result);
}
}
-
}
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
index 208d94f1d4..210be241db 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
@@ -4,26 +4,29 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.rewrite.handler;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
{
- RewriteHandler _handler;
+ private RewriteHandler _handler;
+ private RewritePatternRule _rule;
+ private RewritePatternRule _fooRule;
+ private VirtualHostRuleContainer _fooContainerRule;
- RewritePatternRule _rule;
- RewritePatternRule _fooRule;
- VirtualHostRuleContainer _fooContainerRule;
-
- public void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_handler = new RewriteHandler();
_handler.setRewriteRequestURI(true);
@@ -35,17 +38,18 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
_fooRule = new RewritePatternRule();
_fooRule.setPattern("/cheese/bar/*");
_fooRule.setReplacement("/cheese/fooRule");
-
+
_fooContainerRule = new VirtualHostRuleContainer();
_fooContainerRule.setVirtualHosts(new String[] {"foo.com"});
_fooContainerRule.setRules(new Rule[] { _fooRule });
-
+
_server.setHandler(_handler);
- super.setUp();
+ start(false);
_request.setRequestURI("/cheese/bar");
}
+ @Test
public void testArbitraryHost() throws Exception
{
_request.setServerName("cheese.com");
@@ -54,6 +58,7 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
assertEquals("{_rule, _fooContainerRule, Host: cheese.com}: applied _rule", "/rule/bar", _request.getRequestURI());
}
+ @Test
public void testVirtualHost() throws Exception
{
_request.setServerName("foo.com");
@@ -62,84 +67,89 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
assertEquals("{_fooContainerRule, Host: foo.com}: applied _fooRule", "/cheese/fooRule", _request.getRequestURI());
}
+ @Test
public void testCascadingRules() throws Exception
{
_request.setServerName("foo.com");
_request.setRequestURI("/cheese/bar");
-
+
_rule.setTerminating(false);
_fooRule.setTerminating(false);
_fooContainerRule.setTerminating(false);
-
+
_handler.setRules(new Rule[]{_rule, _fooContainerRule});
handleRequest();
assertEquals("{_rule, _fooContainerRule}: applied _rule, didn't match _fooRule", "/rule/bar", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_handler.setRules(new Rule[] { _fooContainerRule, _rule });
handleRequest();
assertEquals("{_fooContainerRule, _rule}: applied _fooRule, _rule","/rule/fooRule", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_fooRule.setTerminating(true);
handleRequest();
assertEquals("{_fooContainerRule, _rule}: (_fooRule is terminating); applied _fooRule, _rule", "/rule/fooRule", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_fooRule.setTerminating(false);
_fooContainerRule.setTerminating(true);
handleRequest();
assertEquals("{_fooContainerRule, _rule}: (_fooContainerRule is terminating); applied _fooRule, terminated before _rule", "/cheese/fooRule", _request.getRequestURI());
}
-
- public void testCaseInsensitiveHostname() throws Exception
+
+ @Test
+ public void testCaseInsensitiveHostname() throws Exception
{
_request.setServerName("Foo.com");
_fooContainerRule.setVirtualHosts(new String[] {"foo.com"} );
-
+
_handler.setRules(new Rule[]{ _fooContainerRule });
handleRequest();
assertEquals("Foo.com and foo.com are equivalent", "/cheese/fooRule", _request.getRequestURI());
}
-
- public void testEmptyVirtualHost() throws Exception
+
+ @Test
+ public void testEmptyVirtualHost() throws Exception
{
_request.setServerName("cheese.com");
-
+
_handler.setRules(new Rule[] { _fooContainerRule });
_fooContainerRule.setVirtualHosts(null);
handleRequest();
assertEquals("{_fooContainerRule: virtual hosts array is null, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_request.setRequestURI("/cheese/bar");
_fooContainerRule.setVirtualHosts(new String[] {});
handleRequest();
assertEquals("{_fooContainerRule: virtual hosts array is empty, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_request.setRequestURI("/cheese/bar");
_fooContainerRule.setVirtualHosts(new String[] {null});
handleRequest();
assertEquals("{_fooContainerRule: virtual host is null, Host: cheese.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
-
+
}
-
- public void testMultipleVirtualHosts() throws Exception
+
+ @Test
+ public void testMultipleVirtualHosts() throws Exception
{
_request.setServerName("foo.com");
_handler.setRules(new Rule[] {_fooContainerRule });
-
+
_fooContainerRule.setVirtualHosts(new String[]{ "cheese.com" });
handleRequest();
assertEquals("{_fooContainerRule: vhosts[cheese.com], Host: foo.com}: no effect", "/cheese/bar", _request.getRequestURI());
-
+
_request.setRequestURI("/cheese/bar");
_fooContainerRule.addVirtualHost( "foo.com" );
handleRequest();
assertEquals("{_fooContainerRule: vhosts[cheese.com, foo.com], Host: foo.com}: apply _fooRule", "/cheese/fooRule", _request.getRequestURI());
}
-
+
+ @Test
public void testWildcardVirtualHosts() throws Exception
{
checkWildcardHost(true,null,new String[] {"foo.com", ".foo.com", "vhost.foo.com"});
@@ -147,18 +157,18 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
checkWildcardHost(true,new String[] {"foo.com", "*.foo.com"}, new String[] {"foo.com", ".foo.com", "vhost.foo.com"});
checkWildcardHost(false,new String[] {"foo.com", "*.foo.com"}, new String[] {"badfoo.com", ".badfoo.com", "vhost.badfoo.com"});
-
+
checkWildcardHost(false,new String[] {"*."}, new String[] {"anything.anything"});
-
+
checkWildcardHost(true,new String[] {"*.foo.com"}, new String[] {"vhost.foo.com", ".foo.com"});
checkWildcardHost(false,new String[] {"*.foo.com"}, new String[] {"vhost.www.foo.com", "foo.com", "www.vhost.foo.com"});
checkWildcardHost(true,new String[] {"*.sub.foo.com"}, new String[] {"vhost.sub.foo.com", ".sub.foo.com"});
checkWildcardHost(false,new String[] {"*.sub.foo.com"}, new String[] {".foo.com", "sub.foo.com", "vhost.foo.com"});
-
- checkWildcardHost(false,new String[] {"foo.*.com","foo.com.*"}, new String[] {"foo.vhost.com", "foo.com.vhost", "foo.com"});
+
+ checkWildcardHost(false,new String[] {"foo.*.com","foo.com.*"}, new String[] {"foo.vhost.com", "foo.com.vhost", "foo.com"});
}
-
+
private void checkWildcardHost(boolean succeed, String[] ruleHosts, String[] requestHosts) throws Exception
{
_fooContainerRule.setVirtualHosts(ruleHosts);
@@ -181,4 +191,3 @@ public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
_server.handle("/cheese/bar", _request, _request, _response);
}
}
-
diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml
index c8ec49057d..fdeed8779d 100644
--- a/jetty-security/pom.xml
+++ b/jetty-security/pom.xml
@@ -39,15 +39,17 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.security.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -60,6 +62,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
index 271fa933d8..0852bf5f9b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
@@ -53,10 +53,10 @@ public interface Authenticator
* @param request The request
* @param response The response
* @param mandatory True if authentication is mandatory.
- * @return An Authentication. If Authentication is successful, this will be a {@link Authentication.User}. If a response has
+ * @return An Authentication. If Authentication is successful, this will be a {@link org.eclipse.jetty.server.Authentication.User}. If a response has
* been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will
- * implement {@link Authentication.ResponseSent}. If Authentication is not manditory, then a {@link Authentication.Deferred}
- * may be returned.
+ * implement {@link org.eclipse.jetty.server.Authentication.ResponseSent}. If Authentication is not manditory, then a
+ * {@link org.eclipse.jetty.server.Authentication.Deferred} may be returned.
*
* @throws ServerAuthException
*/
@@ -68,7 +68,7 @@ public interface Authenticator
* @param response
* @param mandatory
* @param validatedUser
- * @return
+ * @return true if response is secure
* @throws ServerAuthException
*/
boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java
index 1135aa7591..2ec8d8db01 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.security;
+import java.util.List;
import java.util.Set;
/**
@@ -20,9 +21,29 @@ import java.util.Set;
*/
public interface ConstraintAware
{
- ConstraintMapping[] getConstraintMappings();
-
+ List<ConstraintMapping> getConstraintMappings();
Set<String> getRoles();
-
- void setConstraintMappings(ConstraintMapping[] constraintMappings, Set<String> roles);
+
+ /* ------------------------------------------------------------ */
+ /** Set Constraint Mappings and roles.
+ * Can only be called during initialization.
+ * @param constraintMappings
+ * @param roles
+ */
+ void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles);
+
+ /* ------------------------------------------------------------ */
+ /** Add a Constraint Mapping.
+ * May be called for running webapplication as an annotated servlet is instantiated.
+ * @param mapping
+ */
+ void addConstraintMapping(ConstraintMapping mapping);
+
+
+ /* ------------------------------------------------------------ */
+ /** Add a Role definition.
+ * May be called on running webapplication as an annotated servlet is instantiated.
+ * @param role
+ */
+ void addRole(String role);
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index c8daed4c99..3996a0df6e 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -14,9 +14,14 @@
package org.eclipse.jetty.security;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.http.security.Constraint;
@@ -36,9 +41,9 @@ import org.eclipse.jetty.util.StringMap;
*/
public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware
{
- private ConstraintMapping[] _constraintMappings;
- private Set<String> _roles;
- private PathMap _constraintMap = new PathMap();
+ private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<ConstraintMapping>();
+ private final Set<String> _roles = new CopyOnWriteArraySet<String>();
+ private final PathMap _constraintMap = new PathMap();
private boolean _strict = true;
@@ -76,7 +81,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
/**
* @return Returns the contraintMappings.
*/
- public ConstraintMapping[] getConstraintMappings()
+ public List<ConstraintMapping> getConstraintMappings()
{
return _constraintMappings;
}
@@ -86,7 +91,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{
return _roles;
}
-
+
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void setConstraintMappings(ConstraintMapping[] constraintMappings)
+ {
+ setConstraintMappings(Arrays.asList(constraintMappings),null);
+ }
+
/* ------------------------------------------------------------ */
/**
* Process the constraints following the combining rules in Servlet 3.0 EA
@@ -96,11 +108,19 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
* The contraintMappings to set, from which the set of known roles
* is determined.
*/
- public void setConstraintMappings(ConstraintMapping[] constraintMappings)
+ public void setConstraintMappings(List<ConstraintMapping> constraintMappings)
{
setConstraintMappings(constraintMappings,null);
}
-
+
+
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void setConstraintMappings(ConstraintMapping[] constraintMappings, Set<String> roles)
+ {
+ setConstraintMappings(Arrays.asList(constraintMappings),roles);
+ }
+
/* ------------------------------------------------------------ */
/**
* Process the constraints following the combining rules in Servlet 3.0 EA
@@ -110,11 +130,12 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
* The contraintMappings to set.
* @param roles The known roles (or null to determine them from the mappings)
*/
- public void setConstraintMappings(ConstraintMapping[] constraintMappings, Set<String> roles)
+ public void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles)
{
if (isStarted())
throw new IllegalStateException("Started");
- _constraintMappings = constraintMappings;
+ _constraintMappings.clear();
+ _constraintMappings.addAll(constraintMappings);
if (roles==null)
{
@@ -146,7 +167,48 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
if (isStarted())
throw new IllegalStateException("Started");
- this._roles = roles;
+ _roles.clear();
+ _roles.addAll(roles);
+ }
+
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping)
+ */
+ public void addConstraintMapping(ConstraintMapping mapping)
+ {
+ _constraintMappings.add(mapping);
+ if (mapping.getConstraint()!=null && mapping.getConstraint().getRoles()!=null)
+ for (String role : mapping.getConstraint().getRoles())
+ addRole(role);
+
+ if (isStarted())
+ {
+ processContraintMapping(mapping);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String)
+ */
+ public void addRole(String role)
+ {
+ boolean modified = _roles.add(role);
+ if (isStarted() && modified && _strict)
+ {
+ // Add the new role to currently defined any role role infos
+ for (Map<String,RoleInfo> map : (Collection<Map<String,RoleInfo>>)_constraintMap.values())
+ {
+ for (RoleInfo info : map.values())
+ {
+ if (info.isAnyRole())
+ info.addRole(role);
+ }
+ }
+ }
}
/* ------------------------------------------------------------ */
@@ -161,92 +223,95 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{
for (ConstraintMapping mapping : _constraintMappings)
{
- Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec());
- if (mappings == null)
- {
- mappings = new StringMap();
- _constraintMap.put(mapping.getPathSpec(),mappings);
- }
- RoleInfo allMethodsRoleInfo = mappings.get(null);
- if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden())
- {
- continue;
- }
- String httpMethod = mapping.getMethod();
- RoleInfo roleInfo = mappings.get(httpMethod);
- if (roleInfo == null)
+ processContraintMapping(mapping);
+ }
+ }
+ super.doStart();
+ }
+
+ protected void processContraintMapping(ConstraintMapping mapping)
+ {
+ Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec());
+ if (mappings == null)
+ {
+ mappings = new StringMap();
+ _constraintMap.put(mapping.getPathSpec(),mappings);
+ }
+ RoleInfo allMethodsRoleInfo = mappings.get(null);
+ if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden())
+ return;
+
+ String httpMethod = mapping.getMethod();
+ RoleInfo roleInfo = mappings.get(httpMethod);
+ if (roleInfo == null)
+ {
+ roleInfo = new RoleInfo();
+ mappings.put(httpMethod,roleInfo);
+ if (allMethodsRoleInfo != null)
+ {
+ roleInfo.combine(allMethodsRoleInfo);
+ }
+ }
+ if (roleInfo.isForbidden())
+ return;
+
+ Constraint constraint = mapping.getConstraint();
+ boolean forbidden = constraint.isForbidden();
+ roleInfo.setForbidden(forbidden);
+ if (forbidden)
+ {
+ if (httpMethod == null)
+ {
+ mappings.clear();
+ mappings.put(null,roleInfo);
+ }
+ }
+ else
+ {
+ UserDataConstraint userDataConstraint = UserDataConstraint.get(constraint.getDataConstraint());
+ roleInfo.setUserDataConstraint(userDataConstraint);
+
+ boolean checked = constraint.getAuthenticate();
+ roleInfo.setChecked(checked);
+ if (roleInfo.isChecked())
+ {
+ if (constraint.isAnyRole())
{
- roleInfo = new RoleInfo();
- mappings.put(httpMethod,roleInfo);
- if (allMethodsRoleInfo != null)
+ if (_strict)
{
- roleInfo.combine(allMethodsRoleInfo);
+ // * means "all defined roles"
+ for (String role : _roles)
+ roleInfo.addRole(role);
}
+ else
+ // * means any role
+ roleInfo.setAnyRole(true);
}
- if (roleInfo.isForbidden())
- {
- continue;
- }
- Constraint constraint = mapping.getConstraint();
- boolean forbidden = constraint.isForbidden();
- roleInfo.setForbidden(forbidden);
- if (forbidden)
+ else
{
- if (httpMethod == null)
+ String[] newRoles = constraint.getRoles();
+ for (String role : newRoles)
{
- mappings.clear();
- mappings.put(null,roleInfo);
+ if (_strict &&!_roles.contains(role))
+ throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
+ roleInfo.addRole(role);
}
}
- else
+ }
+ if (httpMethod == null)
+ {
+ for (Map.Entry<String, RoleInfo> entry : mappings.entrySet())
{
- UserDataConstraint userDataConstraint = UserDataConstraint.get(constraint.getDataConstraint());
- roleInfo.setUserDataConstraint(userDataConstraint);
-
- boolean checked = constraint.getAuthenticate();
- roleInfo.setChecked(checked);
- if (roleInfo.isChecked())
+ if (entry.getKey() != null)
{
- if (constraint.isAnyRole())
- {
- if (_strict)
- {
- // * means "all defined roles"
- for (String role : _roles)
- roleInfo.addRole(role);
- }
- else
- // * means any role
- roleInfo.setAnyRole(true);
- }
- else
- {
- String[] newRoles = constraint.getRoles();
- for (String role : newRoles)
- {
- if (_strict &&!_roles.contains(role))
- throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
- roleInfo.addRole(role);
- }
- }
- }
- if (httpMethod == null)
- {
- for (Map.Entry<String, RoleInfo> entry : mappings.entrySet())
- {
- if (entry.getKey() != null)
- {
- RoleInfo specific = entry.getValue();
- specific.combine(roleInfo);
- }
- }
+ RoleInfo specific = entry.getValue();
+ specific.combine(roleInfo);
}
}
}
}
- super.doStart();
}
-
+
protected Object prepareConstraintInfo(String pathInContext, Request request)
{
Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.match(pathInContext);
@@ -353,8 +418,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
if (roleInfo.isAnyRole() && request.getAuthType()!=null)
return true;
- String[] roles = roleInfo.getRoles();
- for (String role : roles)
+ for (String role : roleInfo.getRoles())
{
if (userIdentity.isUserInRole(role, null))
return true;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
index 290ae6b0d1..bec4b347c1 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
@@ -27,13 +27,17 @@ import org.eclipse.jetty.server.Server;
/**
* The Default Authenticator Factory.
* Uses the {@link Configuration#getAuthMethod()} to select an {@link Authenticator} from: <ul>
- * <li>{@link BasicAuthenticator}</li>
- * <li>{@link DigestAuthenticator}</li>
- * <li>{@link FormAuthenticator}</li>
- * <li>{@link ClientCertAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.BasicAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.DigestAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.FormAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.ClientCertAuthenticator}</li>
* </ul>
- * If {@link Configuration#isLazy()} is true, the Authenticator is wrapped with a {@link DeferredAuthenticator}
- * instance. The FormAuthenticator is always wrapped in a {@link SessionCachingAuthenticator}.
+ * All authenticators derived from {@link org.eclipse.jetty.security.authentication.LoginAuthenticator} are
+ * wrapped with a {@link org.eclipse.jetty.security.authentication.DeferredAuthentication}
+ * instance, which is used if authentication is not mandatory.
+ *
+ * The Authentications from the {@link org.eclipse.jetty.security.authentication.FormAuthenticator} are always wrapped in a
+ * {@link org.eclipse.jetty.security.authentication.SessionAuthentication}
* <p>
* If a {@link LoginService} has not been set on this factory, then
* the service is selected by searching the {@link Server#getBeans(Class)} results for
@@ -61,7 +65,6 @@ public class DefaultAuthenticatorFactory implements Authenticator.Factory
return authenticator;
}
-
/* ------------------------------------------------------------ */
/**
* @return the loginService
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
index e5f3335a64..2b2b746276 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
@@ -24,9 +24,10 @@ import org.eclipse.jetty.server.UserIdentity;
/**
* Default Identity Service implementation.
* This service handles only role reference maps passed in an
- * associated {@link UserIdentity.Scope}. If there are roles
+ * associated {@link org.eclipse.jetty.server.UserIdentity.Scope}. If there are roles
* refs present, then associate will wrap the UserIdentity with one
- * that uses the role references in the {@link UserIdentity#isUserInRole(String)}
+ * that uses the role references in the
+ * {@link org.eclipse.jetty.server.UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)}
* implementation. All other operations are effectively noops.
*
*/
@@ -40,7 +41,7 @@ public class DefaultIdentityService implements IdentityService
/* ------------------------------------------------------------ */
/**
* If there are roles refs present in the scope, then wrap the UserIdentity
- * with one that uses the role references in the {@link UserIdentity#isUserInRole(String)}
+ * with one that uses the role references in the {@link UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)}
*/
public Object associate(UserIdentity user)
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index 31e21af15a..eb3946bd0d 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -51,9 +51,6 @@ import org.eclipse.jetty.util.resource.Resource;
*
* If DIGEST Authentication is used, the password must be in a recoverable
* format, either plain text or OBF:.
- *
- * @see org.eclipse.jetty.security.Password
- *
*/
public class HashLoginService extends MappedLoginService
{
@@ -105,8 +102,6 @@ public class HashLoginService extends MappedLoginService
* names.
*
* @param config Filename or url of user properties file.
- * @exception java.io.IOException if user properties file could not be
- * loaded
*/
public void setConfig(String config)
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
index 06e51c8136..7075cc9792 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
@@ -23,7 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
@@ -168,7 +168,6 @@ public class JDBCLoginService extends MappedLoginService
* Load JDBC connection configuration from properties file.
*
* @param config Filename or url of user properties file.
- * @exception java.io.IOException
*/
public void setConfig(String config)
{
@@ -249,7 +248,7 @@ public class JDBCLoginService extends MappedLoginService
roles.add(rs.getString(_roleTableRoleField));
stat.close();
- return putUser(username, new Password(credentials),roles.toArray(new String[roles.size()]));
+ return putUser(username, Credential.getCredential(credentials),roles.toArray(new String[roles.size()]));
}
}
catch (SQLException e)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java
index b58558f70d..35df88ce8f 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java
@@ -13,9 +13,8 @@
package org.eclipse.jetty.security;
-import java.util.Arrays;
-
-import org.eclipse.jetty.util.LazyList;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
/**
*
@@ -27,13 +26,12 @@ import org.eclipse.jetty.util.LazyList;
*/
public class RoleInfo
{
- private final static String[] NO_ROLES={};
private boolean _isAnyRole;
private boolean _checked;
private boolean _forbidden;
private UserDataConstraint _userDataConstraint;
- private String[] _roles = NO_ROLES;
+ private final Set<String> _roles = new CopyOnWriteArraySet<String>();
public RoleInfo()
{
@@ -50,7 +48,7 @@ public class RoleInfo
if (!checked)
{
_forbidden=false;
- _roles=NO_ROLES;
+ _roles.clear();
_isAnyRole=false;
}
}
@@ -68,7 +66,7 @@ public class RoleInfo
_checked = true;
_userDataConstraint = null;
_isAnyRole=false;
- _roles=NO_ROLES;
+ _roles.clear();
}
}
@@ -83,7 +81,7 @@ public class RoleInfo
if (anyRole)
{
_checked = true;
- _roles=NO_ROLES;
+ _roles.clear();
}
}
@@ -105,14 +103,14 @@ public class RoleInfo
}
}
- public String[] getRoles()
+ public Set<String> getRoles()
{
return _roles;
}
public void addRole(String role)
{
- _roles=(String[])LazyList.addToArray(_roles,role,String.class);
+ _roles.add(role);
}
public void combine(RoleInfo other)
@@ -126,14 +124,15 @@ public class RoleInfo
else if (!_isAnyRole)
{
for (String r : other._roles)
- _roles=(String[])LazyList.addToArray(_roles,r,String.class);
+ _roles.add(r);
}
setUserDataConstraint(other._userDataConstraint);
}
+ @Override
public String toString()
{
- return "{RoleInfo"+(_forbidden?",F":"")+(_checked?",C":"")+(_isAnyRole?",*":Arrays.asList(_roles).toString())+"}";
+ return "{RoleInfo"+(_forbidden?",F":"")+(_checked?",C":"")+(_isAnyRole?",*":_roles)+"}";
}
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
index b3f9e8ac7a..0d78853666 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
@@ -256,15 +256,13 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
/* ------------------------------------------------------------ */
protected IdentityService findIdentityService()
{
- List<IdentityService> services = getServer().getBeans(IdentityService.class);
- if (services!=null && services.size()>0)
- return services.get(0);
- return null;
+ return getServer().getBean(IdentityService.class);
}
/* ------------------------------------------------------------ */
/**
*/
+ @Override
protected void doStart()
throws Exception
{
@@ -354,6 +352,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
}
+ /* ------------------------------------------------------------ */
protected boolean checkSecurity(Request request)
{
switch(request.getDispatcherType())
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
index 44f9ff3bf3..212b4ef104 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
@@ -36,9 +36,6 @@ import org.eclipse.jetty.util.StringUtil;
public class BasicAuthenticator extends LoginAuthenticator
{
/* ------------------------------------------------------------ */
- /**
- * @param loginService
- */
public BasicAuthenticator()
{
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
index a344b7c0bf..f40b7e66e8 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
@@ -46,7 +46,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator
}
/**
- * @return
+ * @return Authentication for request
* @throws ServerAuthException
*/
public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java
index b4a900f141..a22fdb5c88 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java
@@ -67,7 +67,7 @@ public class DeferredAuthentication implements Authentication.Deferred
/* ------------------------------------------------------------ */
/**
- * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate()
+ * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(ServletRequest)
*/
public Authentication authenticate(ServletRequest request)
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
index 7a624ddc7f..96833e1613 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
@@ -42,15 +42,16 @@ import org.eclipse.jetty.util.log.Log;
/**
* FORM Authenticator.
*
- * The form authenticator redirects unauthenticated requests to a log page
+ * <p>This authenticator implements form authentication will use dispatchers to
+ * the login page if the {@link #__FORM_DISPATCH} init parameter is set to true.
+ * Otherwise it will redirect.</p>
+ *
+ * <p>The form authenticator redirects unauthenticated requests to a log page
* which should use a form to gather username/password from the user and send them
- * to the /j_security_check URI within the context. FormAuthentication is intended
- * to be used together with the {@link SessionCachingAuthenticator} so that the
- * auth results may be associated with the session.
+ * to the /j_security_check URI within the context. FormAuthentication uses
+ * {@link SessionAuthentication} to wrap Authentication results so that they
+ * are associated with the session.</p>
*
- * This authenticator implements form authentication will use dispatchers to
- * the login page if the {@link #__FORM_DISPATCH} init parameter is set to true.
- * Otherwise it will redirect.
*
*/
public class FormAuthenticator extends LoginAuthenticator
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
index 5790677b01..ec20115ee5 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
@@ -24,7 +24,7 @@ import org.eclipse.jetty.security.Authenticator;
import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.UserIdentity;
-class SessionAuthentication extends UserAuthentication implements HttpSessionAttributeListener, Serializable
+public class SessionAuthentication extends UserAuthentication implements HttpSessionAttributeListener, Serializable
{
private static final long serialVersionUID = -4643200685888258706L;
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
index 184cffb9c0..de8aa34809 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
@@ -13,7 +13,11 @@
package org.eclipse.jetty.security;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.io.IOException;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -23,8 +27,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.security.B64Code;
import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.http.security.Password;
@@ -39,40 +41,52 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
/**
- *
+ * @version $Revision: 1441 $ $Date: 2010-04-02 12:28:17 +0200 (Fri, 02 Apr 2010) $
*/
-public class ConstraintTest extends TestCase
+public class ConstraintTest
{
private static final String TEST_REALM = "TestRealm";
+ private static Server _server;
+ private static LocalConnector _connector;
+ private static SessionHandler _session;
+ private ConstraintSecurityHandler _security;
- Server _server = new Server();
- LocalConnector _connector = new LocalConnector();
- ContextHandler _context = new ContextHandler();
- SessionHandler _session = new SessionHandler();
- ConstraintSecurityHandler _security = new ConstraintSecurityHandler();
- HashLoginService _loginService = new HashLoginService(TEST_REALM);
-
- RequestHandler _handler = new RequestHandler();
-
+ @BeforeClass
+ public static void startServer()
{
+ _server = new Server();
+ _connector = new LocalConnector();
_server.setConnectors(new Connector[]{_connector});
- _context.setContextPath("/ctx");
- _server.setHandler(_context);
- _context.setHandler(_session);
- _session.setHandler(_security);
- _security.setHandler(_handler);
+ ContextHandler _context = new ContextHandler();
+ _session = new SessionHandler();
+
+ HashLoginService _loginService = new HashLoginService(TEST_REALM);
_loginService.putUser("user",new Password("password"));
_loginService.putUser("user2",new Password("password"), new String[] {"user"});
_loginService.putUser("admin",new Password("password"), new String[] {"user","administrator"});
+
+ _context.setContextPath("/ctx");
+ _server.setHandler(_context);
+ _context.setHandler(_session);
+
_server.addBean(_loginService);
}
- public ConstraintTest(String arg0)
+ @Before
+ public void setupSecurity()
{
- super(arg0);
+ _security = new ConstraintSecurityHandler();
+ _session.setHandler(_security);
+ RequestHandler _handler = new RequestHandler();
+ _security.setHandler(_handler);
+
Constraint constraint0 = new Constraint();
constraint0.setAuthenticate(true);
constraint0.setName("forbid");
@@ -111,41 +125,31 @@ public class ConstraintTest extends TestCase
ConstraintMapping mapping4 = new ConstraintMapping();
mapping4.setPathSpec("/testLoginPage");
mapping4.setConstraint(constraint4);
-
+
Set<String> knownRoles=new HashSet<String>();
knownRoles.add("user");
knownRoles.add("administrator");
- _security.setConstraintMappings(new ConstraintMapping[]
+ _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[]
{
mapping0, mapping1, mapping2, mapping3, mapping4
- },knownRoles);
+ }), knownRoles);
}
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
+ @After
+ public void stopServer() throws Exception
{
- super.setUp();
-
- }
-
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
- {
- super.tearDown();
- _server.stop();
+ if (_server.isRunning())
+ {
+ _server.stop();
+ _server.join();
+ }
}
-
-
- public void testConstraints()
- throws Exception
+ @Test
+ public void testConstraints() throws Exception
{
- ConstraintMapping[] mappings =_security.getConstraintMappings();
+ ConstraintMapping[] mappings =_security.getConstraintMappings().toArray(new ConstraintMapping[0]);
assertTrue (mappings[0].getConstraint().isForbidden());
assertFalse(mappings[1].getConstraint().isForbidden());
@@ -168,9 +172,8 @@ public class ConstraintTest extends TestCase
assertFalse(mappings[3].getConstraint().getAuthenticate());
}
-
- public void testBasic()
- throws Exception
+ @Test
+ public void testBasic() throws Exception
{
_security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false);
@@ -226,8 +229,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
- public void testFormDispatch()
- throws Exception
+ @Test
+ public void testFormDispatch() throws Exception
{
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true));
_security.setStrict(false);
@@ -278,8 +281,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.indexOf("!role") > 0);
}
- public void testFormRedirect()
- throws Exception
+ @Test
+ public void testFormRedirect() throws Exception
{
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
_security.setStrict(false);
@@ -303,7 +306,7 @@ public class ConstraintTest extends TestCase
"\r\n");
assertTrue(response.indexOf(" 200 OK") > 0);
assertTrue(response.indexOf("URI=/ctx/testLoginPage") > 0);
-
+
response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
@@ -334,8 +337,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.indexOf("!role") > 0);
}
- public void testFormNoCookies()
- throws Exception
+ @Test
+ public void testFormNoCookies() throws Exception
{
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
_security.setStrict(false);
@@ -354,12 +357,12 @@ public class ConstraintTest extends TestCase
assertTrue(response.indexOf("/ctx/testLoginPage") > 0);
int jsession=response.indexOf(";jsessionid=");
String session = response.substring(jsession + 12, response.indexOf("\r\n",jsession));
-
+
response = _connector.getResponses("GET /ctx/testLoginPage;jsessionid="+session+";other HTTP/1.0\r\n"+
"\r\n");
assertTrue(response.indexOf(" 200 OK") > 0);
assertTrue(response.indexOf("URI=/ctx/testLoginPage") > 0);
-
+
response = _connector.getResponses("POST /ctx/j_security_check;jsessionid="+session+";other HTTP/1.0\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: 31\r\n" +
@@ -386,8 +389,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.indexOf("!role") > 0);
}
- public void testStrictBasic()
- throws Exception
+ @Test
+ public void testStrictBasic() throws Exception
{
_security.setAuthenticator(new BasicAuthenticator());
_server.start();
@@ -448,11 +451,11 @@ public class ConstraintTest extends TestCase
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
+ @Test
public void testStrictFormDispatch()
throws Exception
{
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true));
-
_server.start();
String response;
@@ -561,11 +564,10 @@ public class ConstraintTest extends TestCase
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
- public void testStrictFormRedirect()
- throws Exception
+ @Test
+ public void testStrictFormRedirect() throws Exception
{
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
-
_server.start();
String response;
@@ -672,8 +674,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
- public void testRoleRef()
- throws Exception
+ @Test
+ public void testRoleRef() throws Exception
{
RoleCheckHandler check=new RoleCheckHandler();
_security.setHandler(check);
@@ -704,9 +706,8 @@ public class ConstraintTest extends TestCase
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
-
- public void testDeferredBasic()
- throws Exception
+ @Test
+ public void testDeferredBasic() throws Exception
{
_security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false);
@@ -732,7 +733,7 @@ public class ConstraintTest extends TestCase
assertTrue(response.indexOf("user=admin") > 0);
}
- class RequestHandler extends AbstractHandler
+ private class RequestHandler extends AbstractHandler
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException
{
@@ -750,7 +751,7 @@ public class ConstraintTest extends TestCase
}
}
- class RoleRefHandler extends HandlerWrapper
+ private class RoleRefHandler extends HandlerWrapper
{
/* ------------------------------------------------------------ */
/**
@@ -794,7 +795,7 @@ public class ConstraintTest extends TestCase
}
}
- class RoleCheckHandler extends AbstractHandler
+ private class RoleCheckHandler extends AbstractHandler
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException
{
diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml
index 20c164823a..3afcea2c4f 100644
--- a/jetty-server/pom.xml
+++ b/jetty-server/pom.xml
@@ -51,16 +51,11 @@
</execution>
</executions>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
@@ -79,12 +74,20 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.server.*</onlyAnalyze>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-server/src/main/config/etc/jetty-bio-ssl.xml b/jetty-server/src/main/config/etc/jetty-bio-ssl.xml
index 0b0c6fc16f..9c075e46cb 100644
--- a/jetty-server/src/main/config/etc/jetty-bio-ssl.xml
+++ b/jetty-server/src/main/config/etc/jetty-bio-ssl.xml
@@ -14,10 +14,10 @@
<New class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<Set name="Port">9443</Set>
<Set name="maxIdleTime">30000</Set>
- <Set name="Keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
+ <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
+ <Set name="truststore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
</New>
</Arg>
diff --git a/jetty-server/src/main/config/etc/jetty-bio.xml b/jetty-server/src/main/config/etc/jetty-bio.xml
index 3c4c8a6b80..66950eee55 100644
--- a/jetty-server/src/main/config/etc/jetty-bio.xml
+++ b/jetty-server/src/main/config/etc/jetty-bio.xml
@@ -13,7 +13,7 @@
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.bio.SocketConnector">
- <Set name="port"><SystemProperty name="jetty.bio.port" default="8081"/></Set>
+ <Set name="port"><Property name="jetty.bio.port" default="8081"/></Set>
<Set name="maxIdleTime">50000</Set>
<Set name="lowResourceMaxIdleTime">1500</Set>
</New>
diff --git a/jetty-server/src/main/config/etc/jetty-debug.xml b/jetty-server/src/main/config/etc/jetty-debug.xml
index afc972e5ab..0ffccb69bf 100644
--- a/jetty-server/src/main/config/etc/jetty-debug.xml
+++ b/jetty-server/src/main/config/etc/jetty-debug.xml
@@ -13,7 +13,7 @@
<Set name="handler"><Ref id="oldhandler"/></Set>
<Set name="outputStream">
<New class="org.eclipse.jetty.util.RolloverFileOutputStream">
- <Arg type="String"><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg>
+ <Arg type="String"><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg>
<Arg type="boolean">true</Arg> <!-- append -->
<Arg type="int">90</Arg> <!-- retain days -->
</New>
diff --git a/jetty-server/src/main/config/etc/jetty-proxy.xml b/jetty-server/src/main/config/etc/jetty-proxy.xml
index 9fe82f1429..5bc46c389d 100644
--- a/jetty-server/src/main/config/etc/jetty-proxy.xml
+++ b/jetty-server/src/main/config/etc/jetty-proxy.xml
@@ -32,8 +32,8 @@
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host"><SystemProperty name="jetty.host" /></Set>
- <Set name="port"><SystemProperty name="jetty.port" default="8888"/></Set>
+ <Set name="host"><Property name="jetty.host" /></Set>
+ <Set name="port"><Property name="jetty.port" default="8888"/></Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
diff --git a/jetty-server/src/main/config/etc/jetty-requestlog.xml b/jetty-server/src/main/config/etc/jetty-requestlog.xml
new file mode 100644
index 0000000000..622fd84208
--- /dev/null
+++ b/jetty-server/src/main/config/etc/jetty-requestlog.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Request Log -->
+<!-- =============================================================== -->
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Configure Request Log -->
+ <!-- =========================================================== -->
+ <Ref id="Handlers">
+ <Call name="addHandler">
+ <Arg>
+ <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
+ <Set name="requestLog">
+ <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
+ <Set name="filename"><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
+ <Set name="filenameDateFormat">yyyy_MM_dd</Set>
+ <Set name="retainDays">90</Set>
+ <Set name="append">true</Set>
+ <Set name="extended">false</Set>
+ <Set name="logCookies">false</Set>
+ <Set name="LogTimeZone">GMT</Set>
+ </New>
+ </Set>
+ </New>
+ </Arg>
+ </Call>
+ </Ref>
+
+</Configure>
diff --git a/jetty-server/src/main/config/etc/jetty-ssl.xml b/jetty-server/src/main/config/etc/jetty-ssl.xml
index 955053101a..7a0d500aee 100644
--- a/jetty-server/src/main/config/etc/jetty-ssl.xml
+++ b/jetty-server/src/main/config/etc/jetty-ssl.xml
@@ -18,10 +18,10 @@
<Set name="maxIdleTime">30000</Set>
<Set name="Acceptors">2</Set>
<Set name="AcceptQueueSize">100</Set>
- <Set name="Keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
+ <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
+ <Set name="truststore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
</New>
</Arg>
diff --git a/jetty-server/src/main/config/etc/jetty-xinetd.xml b/jetty-server/src/main/config/etc/jetty-xinetd.xml
index 0b6582572b..c2fbaa285e 100644
--- a/jetty-server/src/main/config/etc/jetty-xinetd.xml
+++ b/jetty-server/src/main/config/etc/jetty-xinetd.xml
@@ -40,7 +40,7 @@ service jetty
<!-- Optional. Fallback in case System.inheritedChannel() does not give a ServerSocketChannel
- <Set name="port"><SystemProperty name="jetty.service.port" default="8082"/></Set>
+ <Set name="port"><Property name="jetty.service.port" default="8082"/></Set>
-->
<!-- sane defaults -->
diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml
index cfb371118c..f2de6a0cc8 100644
--- a/jetty-server/src/main/config/etc/jetty.xml
+++ b/jetty-server/src/main/config/etc/jetty.xml
@@ -5,8 +5,13 @@
<!-- Configure the Jetty Server -->
<!-- -->
<!-- Documentation of this file format can be found at: -->
-<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
+<!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax -->
<!-- -->
+<!-- Additional configuration files are available in $JETTY_HOME/etc -->
+<!-- and can be mixed in. For example: -->
+<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
+<!-- -->
+<!-- See start.ini file for the default configuraton files -->
<!-- =============================================================== -->
@@ -23,8 +28,6 @@
</New>
</Set>
-
-
<!-- =========================================================== -->
<!-- Set connectors -->
<!-- =========================================================== -->
@@ -32,8 +35,8 @@
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host"><SystemProperty name="jetty.host" /></Set>
- <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
+ <Set name="host"><Property name="jetty.host" /></Set>
+ <Set name="port"><Property name="jetty.port" default="8080"/></Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
@@ -44,26 +47,6 @@
</Arg>
</Call>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTPS SSL connector -->
- <!-- mixin jetty-ssl.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTP blocking connector -->
- <!-- mixin jetty-bio.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To allow Jetty to be started from xinetd -->
- <!-- mixin jetty-xinetd.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
- <!-- -->
- <!-- See jetty-xinetd.xml for further instructions. -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
<!-- =========================================================== -->
<!-- Set handler Collection Structure -->
<!-- =========================================================== -->
@@ -77,97 +60,12 @@
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
- <Item>
- <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
- </Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
- <!-- Configure the deployment manager -->
- <!-- -->
- <!-- Sets up 2 monitored dir app providers that are configured -->
- <!-- to behave in a similaraly to the legacy ContextDeployer -->
- <!-- and WebAppDeployer from previous versions of Jetty. -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
- <Set name="contexts">
- <Ref id="Contexts" />
- </Set>
- <Call name="setContextAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/servlet-api-[^/]*\.jar$</Arg>
- </Call>
- <!-- Providers of Apps via Context XML files.
- Configured to behave similar to the legacy ContextDeployer -->
- <Call name="addAppProvider">
- <Arg>
- <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
- <Set name="monitoredDir"><Property name="jetty.home" default="." />/contexts</Set>
- <Set name="scanInterval">5</Set>
- </New>
- </Arg>
- </Call>
- <!-- Providers of Apps via WAR file existence.
- Configured to behave similar to the legacy WebAppDeployer -->
- <Call name="addAppProvider">
- <Arg>
- <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
- <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
- <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Set name="scanInterval">5</Set>
- <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
- </New>
- </Arg>
- </Call>
- </New>
- </Arg>
- </Call>
-
-
- <!-- =========================================================== -->
- <!-- Configure Authentication Login Service -->
- <!-- Realms may be configured for the entire server here, or -->
- <!-- they can be configured for a specific web app in a context -->
- <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
- <!-- example). -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.security.HashLoginService">
- <Set name="name">Test Realm</Set>
- <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
- <Set name="refreshInterval">0</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure Request Log -->
- <!-- Request logs may be configured for the entire server here, -->
- <!-- or they can be configured for a specific web app in a -->
- <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
- <!-- for an example). -->
- <!-- =========================================================== -->
- <Ref id="RequestLog">
- <Set name="requestLog">
- <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
- <Set name="filename"><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.request.log</Set>
- <Set name="filenameDateFormat">yyyy_MM_dd</Set>
- <Set name="retainDays">90</Set>
- <Set name="append">true</Set>
- <Set name="extended">false</Set>
- <Set name="logCookies">false</Set>
- <Set name="LogTimeZone">GMT</Set>
- </New>
- </Set>
- </Ref>
-
- <!-- =========================================================== -->
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
diff --git a/jetty-server/src/main/config/etc/realm.properties b/jetty-server/src/main/config/etc/realm.properties
deleted file mode 100644
index cbf905de9f..0000000000
--- a/jetty-server/src/main/config/etc/realm.properties
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# This file defines users passwords and roles for a HashUserRealm
-#
-# The format is
-# <username>: <password>[,<rolename> ...]
-#
-# Passwords may be clear text, obfuscated or checksummed. The class
-# org.eclipse.util.Password should be used to generate obfuscated
-# passwords or password checksums
-#
-# If DIGEST Authentication is used, the password must be in a recoverable
-# format, either plain text or OBF:.
-#
-jetty: MD5:164c88b302622e17050af52c89945d44,user
-admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin
-other: OBF:1xmk1w261u9r1w1c1xmq,user
-plain: plain,user
-user: password,user
-
-# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
-digest: MD5:6e120743ad67abfbc385bc2bb754e297,user
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 76064c4656..7fed43a9a1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -68,15 +68,10 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
private boolean _useDNS;
private boolean _forwarded;
private String _hostHeader;
- private String _forwardedHostHeader = "X-Forwarded-Host"; // default to
- // mod_proxy_http
- // header
- private String _forwardedServerHeader = "X-Forwarded-Server"; // default to
- // mod_proxy_http
- // header
- private String _forwardedForHeader = "X-Forwarded-For"; // default to
- // mod_proxy_http
- // header
+
+ private String _forwardedHostHeader = "X-Forwarded-Host";
+ private String _forwardedServerHeader = "X-Forwarded-Server";
+ private String _forwardedForHeader = "X-Forwarded-For";
private boolean _reuseAddress = true;
protected int _maxIdleTime = 200000;
@@ -87,101 +82,70 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
private final AtomicLong _statsStartedAt = new AtomicLong(-1L);
- private final CounterStatistic _connectionStats = new CounterStatistic(); // connections
- // to
- // server
- private final SampleStatistic _requestStats = new SampleStatistic(); // requests
- // per
- // connection
- private final SampleStatistic _connectionDurationStats = new SampleStatistic(); // duration
- // of
- // a
- // connection
+ /** connections to server */
+ private final CounterStatistic _connectionStats = new CounterStatistic();
+ /** requests per connection */
+ private final SampleStatistic _requestStats = new SampleStatistic();
+ /** duration of a connection */
+ private final SampleStatistic _connectionDurationStats = new SampleStatistic();
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/**
*/
public AbstractConnector()
{
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
public final Buffer newBuffer(int size)
{
// TODO remove once no overrides established
return null;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
public Buffer newRequestBuffer(int size)
{
return new ByteArrayBuffer(size);
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
public Buffer newRequestHeader(int size)
{
return new ByteArrayBuffer(size);
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
public Buffer newResponseBuffer(int size)
{
return new ByteArrayBuffer(size);
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
public Buffer newResponseHeader(int size)
{
return new ByteArrayBuffer(size);
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
protected boolean isRequestHeader(Buffer buffer)
{
return true;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
@Override
protected boolean isResponseHeader(Buffer buffer)
{
return true;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/*
*/
public Server getServer()
@@ -189,19 +153,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
return _server;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
public void setServer(Server server)
{
_server = server;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.http.HttpListener#getHttpServer()
*/
@@ -210,19 +168,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
return _threadPool;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
public void setThreadPool(ThreadPool pool)
{
_threadPool = pool;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/**
*/
public void setHost(String host)
@@ -230,10 +182,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_host = host;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/*
*/
public String getHost()
@@ -241,10 +190,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
return _host;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.server.server.HttpListener#setPort(int)
*/
@@ -253,10 +199,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_port = port;
}
- /*
- * --------------------------------------------------------------------------
- * -----
- */
+ /* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.server.server.HttpListener#getPort()
*/
@@ -490,8 +433,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
try
{
socket.setTcpNoDelay(true);
- if (_maxIdleTime >= 0)
- socket.setSoTimeout(_maxIdleTime);
if (_soLingerTime >= 0)
socket.setSoLinger(true,_soLingerTime / 1000);
else
@@ -777,7 +718,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
- * @param forwardedHostHeader
+ * @param forwardedServerHeader
* The header name for forwarded server (default
* x-forwarded-server)
*/
@@ -794,12 +735,12 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
- * @param forwardedHostHeader
+ * @param forwardedRemoteAddressHeader
* The header name for forwarded for (default x-forwarded-for)
*/
- public void setForwardedForHeader(String forwardedRemoteAddressHeade)
+ public void setForwardedForHeader(String forwardedRemoteAddressHeader)
{
- _forwardedForHeader = forwardedRemoteAddressHeade;
+ _forwardedForHeader = forwardedRemoteAddressHeader;
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java
index b4ead4ad3b..5aad13129a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java
@@ -672,7 +672,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
{
_expireAt = System.currentTimeMillis()+_timeoutMs;
long wait=_timeoutMs;
- while (_expireAt>0 && wait>0)
+ while (_expireAt>0 && wait>0 && _connection.getServer().isRunning())
{
try
{
@@ -685,7 +685,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
wait=_expireAt-System.currentTimeMillis();
}
- if (_expireAt>0 && wait<=0)
+ if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning())
{
expired();
}
@@ -823,11 +823,19 @@ public class AsyncContinuation implements AsyncContext, Continuation
}
/* ------------------------------------------------------------ */
- public void start(Runnable run)
+ public void start(final Runnable run)
{
final AsyncEventState event=_event;
if (event!=null)
- ((Context)event.getServletContext()).getContextHandler().handle(run);
+ {
+ _connection.getServer().getThreadPool().dispatch(new Runnable()
+ {
+ public void run()
+ {
+ ((Context)event.getServletContext()).getContextHandler().handle(run);
+ }
+ });
+ }
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
index 5328a1a143..5a77634e0a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
@@ -131,14 +131,14 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The port to use when redirecting a request if a data constraint of integral is
- * required. See {@link org.eclipse.jetty.server.server.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
*/
int getIntegralPort();
/* ------------------------------------------------------------ */
/**
* @return The schema to use when redirecting a request if a data constraint of integral is
- * required. See {@link org.eclipse.jetty.server.server.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
*/
String getIntegralScheme();
@@ -152,7 +152,7 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The port to use when redirecting a request if a data constraint of confidential is
- * required. See {@link org.eclipse.jetty.server.server.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
*/
int getConfidentialPort();
@@ -160,7 +160,7 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The schema to use when redirecting a request if a data constraint of confidential is
- * required. See {@link org.eclipse.jetty.server.server.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
*/
String getConfidentialScheme();
@@ -185,15 +185,23 @@ public interface Connector extends LifeCycle
/** Persist an endpoint.
* Called after every request if the connection is to remain open.
* @param endpoint
- * @param request
* @throws IOException
*/
void persist(EndPoint endpoint) throws IOException;
/* ------------------------------------------------------------ */
+ /**
+ * @return The hostname representing the interface to which
+ * this connector will bind, or null for all interfaces.
+ */
String getHost();
/* ------------------------------------------------------------ */
+ /**
+ * Set the hostname of the interface to bind to.
+ * @param hostname The hostname representing the interface to which
+ * this connector will bind, or null for all interfaces.
+ */
void setHost(String hostname);
/* ------------------------------------------------------------ */
@@ -212,8 +220,8 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
- * @return The actual port the connector is listening on or -1 if there
- * is no port or the connector is not open.
+ * @return The actual port the connector is listening on or
+ * -1 if it has not been opened, or -2 if it has been closed.
*/
int getLocalPort();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java
index a64c0f8d0b..32406ce3f4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java
@@ -18,8 +18,8 @@ import org.eclipse.jetty.util.component.LifeCycle;
/**
* A Handler that contains other Handlers.
* <p>
- * The contained handlers may be one (see @{link {@link org.eclipse.jetty.server.server.handler.HandlerWrapper})
- * or many (see {@link org.eclipse.jetty.server.server.handler.HandlerList} or {@link org.eclipse.jetty.server.server.handler.HandlerCollection}.
+ * The contained handlers may be one (see @{link {@link org.eclipse.jetty.server.handler.HandlerWrapper})
+ * or many (see {@link org.eclipse.jetty.server.handler.HandlerList} or {@link org.eclipse.jetty.server.handler.HandlerCollection}.
*
*/
public interface HandlerContainer extends LifeCycle
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
index c85638b9cc..8c71df016c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
-
import javax.servlet.DispatcherType;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
@@ -42,13 +41,12 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.UncheckedIOException;
import org.eclipse.jetty.io.UncheckedPrintWriter;
-import org.eclipse.jetty.io.BufferCache.CachedBuffer;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
@@ -69,7 +67,7 @@ import org.eclipse.jetty.util.thread.Timeout;
* with the connection via the parser and/or generator.
* </p>
* <p>
- * The connection state is held by 3 separate state machines: The request state, the
+ * The connection state is held by 3 separate state machines: The request state, the
* response state and the continuation state. All three state machines must be driven
* to completion for every request, and all three can complete in any order.
* </p>
@@ -77,12 +75,12 @@ import org.eclipse.jetty.util.thread.Timeout;
* The HttpConnection support protocol upgrade. If on completion of a request, the
* response code is 101 (switch protocols), then the org.eclipse.jetty.io.Connection
* request attribute is checked to see if there is a new Connection instance. If so,
- * the new connection is returned from {@link #handle()} and is used for future
+ * the new connection is returned from {@link #handle()} and is used for future
* handling of the underlying connection. Note that for switching protocols that
* don't use 101 responses (eg CONNECT), the response should be sent and then the
- * status code changed to 101 before returning from the handler. Implementors
+ * status code changed to 101 before returning from the handler. Implementors
* of new Connection types should be careful to extract any buffered data from
- * (HttpParser)http.getParser()).getHeaderBuffer() and
+ * (HttpParser)http.getParser()).getHeaderBuffer() and
* (HttpParser)http.getParser()).getBodyBuffer() to initialise their new connection.
* </p>
*
@@ -150,7 +148,7 @@ public class HttpConnection implements Connection
HttpBuffers ab = (HttpBuffers)_connector;
_parser = new HttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
_requestFields = new HttpFields();
- _responseFields = new HttpFields();
+ _responseFields = new HttpFields(server.getMaxCookieVersion());
_request = new Request(this);
_response = new Response(this);
_generator = new HttpGenerator(ab.getResponseBuffers(), _endp);
@@ -167,7 +165,7 @@ public class HttpConnection implements Connection
_endp = endpoint;
_parser = parser;
_requestFields = new HttpFields();
- _responseFields = new HttpFields();
+ _responseFields = new HttpFields(server.getMaxCookieVersion());
_request = request;
_response = new Response(this);
_generator = generator;
@@ -192,7 +190,13 @@ public class HttpConnection implements Connection
{
return _requests;
}
-
+
+ /* ------------------------------------------------------------ */
+ public Server getServer()
+ {
+ return _server;
+ }
+
/* ------------------------------------------------------------ */
/**
* @return The time this connection was established.
@@ -378,6 +382,8 @@ public class HttpConnection implements Connection
/* ------------------------------------------------------------ */
public Connection handle() throws IOException
{
+ Connection connection = this;
+
// Loop while more in buffer
boolean more_in_buffer =true; // assume true until proven otherwise
boolean progress=true;
@@ -389,12 +395,15 @@ public class HttpConnection implements Connection
_handling=true;
setCurrentConnection(this);
- while (more_in_buffer)
+ while (more_in_buffer && _endp.isOpen())
{
try
{
if (_request._async.isAsync())
{
+ // TODO - handle the case of input being read for a
+ // suspended request.
+
Log.debug("async request",_request);
if (!_request._async.isComplete())
handleRequest();
@@ -454,38 +463,44 @@ public class HttpConnection implements Connection
_parser.reset(true);
_endp.close();
- throw e;
}
finally
{
more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
+ // Is this request/response round complete?
if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
{
- if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
+ // look for a switched connection instance?
+ Connection switched=(_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
+ ?(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"):null;
+
+ // have we switched?
+ if (switched!=null)
{
- Connection connection = (Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
- if (connection!=null)
+ _parser.reset(true);
+ _generator.reset(true);
+ connection=switched;
+ }
+ else
+ {
+ // No switch, so cleanup and reset
+ if (!_generator.isPersistent())
{
_parser.reset(true);
- return connection;
+ more_in_buffer=false;
+ _endp.close();
}
- }
-
- if (!_generator.isPersistent())
- {
- _parser.reset(true);
- more_in_buffer=false;
- }
- if (more_in_buffer)
- {
- reset(false);
- more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
+ if (more_in_buffer)
+ {
+ reset(false);
+ more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
+ }
+ else
+ reset(true);
+ progress=true;
}
- else
- reset(true);
- progress=true;
}
if (_request.isAsyncStarted())
@@ -493,7 +508,7 @@ public class HttpConnection implements Connection
Log.debug("return with suspended request");
more_in_buffer=false;
}
- else if (_generator.isCommitted() && !_generator.isComplete() && _endp instanceof AsyncEndPoint)
+ else if (_generator.isCommitted() && !_generator.isComplete() && _endp instanceof AsyncEndPoint)
((AsyncEndPoint)_endp).setWritable(false);
}
}
@@ -503,7 +518,7 @@ public class HttpConnection implements Connection
setCurrentConnection(null);
_handling=false;
}
- return this;
+ return connection;
}
/* ------------------------------------------------------------ */
@@ -567,7 +582,7 @@ public class HttpConnection implements Connection
{
_uri.getPort();
info=URIUtil.canonicalPath(_uri.getDecodedPath());
- if (info==null)
+ if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
throw new HttpException(400);
_request.setPathInfo(info);
@@ -623,7 +638,6 @@ public class HttpConnection implements Connection
Log.debug(e);
_request.setHandled(true);
_generator.sendError(info==null?400:500, null, null, true);
-
}
finally
{
@@ -683,6 +697,10 @@ public class HttpConnection implements Connection
_generator.setResponse(_response.getStatus(), _response.getReason());
try
{
+ // If the client was expecting 100 continues, but we sent something
+ // else, then we need to close the connection
+ if (_expect100Continue && _response.getStatus()!=100)
+ _generator.setPersistent(false);
_generator.completeHeader(_responseFields, last);
}
catch(IOException io)
@@ -832,7 +850,20 @@ public class HttpConnection implements Connection
try
{
- _uri.parse(uri.array(), uri.getIndex(), uri.length());
+ switch (HttpMethods.CACHE.getOrdinal(method))
+ {
+ case HttpMethods.CONNECT_ORDINAL:
+ _uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
+ break;
+
+ case HttpMethods.HEAD_ORDINAL:
+ _head=true;
+ // fall through
+
+ default:
+ _uri.parse(uri.array(), uri.getIndex(), uri.length());
+ }
+
_request.setUri(_uri);
if (version==null)
@@ -847,8 +878,6 @@ public class HttpConnection implements Connection
if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
_request.setProtocol(version.toString());
}
-
- _head = method == HttpMethods.HEAD_BUFFER; // depends on method being decached.
}
catch (Exception e)
{
@@ -968,6 +997,8 @@ public class HttpConnection implements Connection
@Override
public void headerComplete() throws IOException
{
+ if (_endp instanceof AsyncEndPoint)
+ ((AsyncEndPoint)_endp).scheduleIdle();
_requests++;
_generator.setVersion(_version);
switch (_version)
@@ -976,6 +1007,10 @@ public class HttpConnection implements Connection
break;
case HttpVersions.HTTP_1_0_ORDINAL:
_generator.setHead(_head);
+
+ if (_server.getSendDateHeader())
+ _generator.setDate(_request.getTimeStampBuffer());
+
break;
case HttpVersions.HTTP_1_1_ORDINAL:
_generator.setHead(_head);
@@ -994,7 +1029,10 @@ public class HttpConnection implements Connection
if (_expect)
{
- _generator.sendError(HttpStatus.EXPECTATION_FAILED_417, null, null, true);
+ _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
+ _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+ _generator.completeHeader(_responseFields, true);
+ _generator.complete();
return;
}
@@ -1019,6 +1057,8 @@ public class HttpConnection implements Connection
@Override
public void content(Buffer ref) throws IOException
{
+ if (_endp instanceof AsyncEndPoint)
+ ((AsyncEndPoint)_endp).scheduleIdle();
if (_delayedHandling)
{
_delayedHandling=false;
@@ -1148,13 +1188,13 @@ public class HttpConnection implements Connection
else
{
_responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
- contentType+";charset="+QuotedStringTokenizer.quote(enc,";= "));
+ contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
}
}
else
{
_responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
- contentType+";charset="+QuotedStringTokenizer.quote(enc,";= "));
+ contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
}
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 403c29d803..e7190a7b19 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -28,7 +28,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
/** Output.
*
* <p>
- * Implements {@link javax.servlet.ServletOutputStream} from the {@link javax.servlet} package.
+ * Implements {@link javax.servlet.ServletOutputStream} from the <code>javax.servlet</code> package.
* </p>
* A {@link ServletOutputStream} implementation that writes content
* to a {@link AbstractGenerator}. The class is designed to be reused
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
index 6385d2785a..30267c2a46 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
@@ -33,14 +33,6 @@ public class LocalConnector extends AbstractConnector
return this;
}
- /**
- * @deprecated Not needed anymore, as there is no need to reopen the connector to reset its state
- */
- @Deprecated
- public void reopen()
- {
- }
-
public String getResponses(String requests) throws Exception
{
return getResponses(requests, false);
@@ -121,7 +113,7 @@ public class LocalConnector extends AbstractConnector
boolean leaveOpen = keepOpen;
try
{
- while (endPoint.getIn().length() > 0)
+ while (endPoint.getIn().length() > 0 && endPoint.isOpen())
{
while (true)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
index 5a19545b10..f90e7818fc 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -20,7 +20,6 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.Locale;
import java.util.TimeZone;
-
import javax.servlet.http.Cookie;
import org.eclipse.jetty.http.HttpHeaders;
@@ -28,7 +27,6 @@ import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.util.DateCache;
import org.eclipse.jetty.util.RolloverFileOutputStream;
import org.eclipse.jetty.util.StringUtil;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
@@ -40,12 +38,13 @@ import org.eclipse.jetty.util.log.Log;
* Format (single log format). This log format can be output by most web
* servers, and almost all web log analysis software can understand these
* formats.
- *
- *
- *
- *
+ *
* @org.apache.xbean.XBean element="ncsaLog"
*/
+
+/* ------------------------------------------------------------ */
+/**
+ */
public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
{
private String _filename;
@@ -62,6 +61,7 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
private boolean _logLatency = false;
private boolean _logCookies = false;
private boolean _logServer = false;
+ private boolean _logDispatch = false;
private transient OutputStream _out;
private transient OutputStream _fileOut;
@@ -71,6 +71,10 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
private transient ArrayList _buffers;
private transient char[] _copy;
+ /* ------------------------------------------------------------ */
+ /**
+ * Create request log object with default settings.
+ */
public NCSARequestLog()
{
_extended = true;
@@ -80,9 +84,11 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
/* ------------------------------------------------------------ */
/**
- * @param filename
- * The filename for the request log. This may be in the
- * format expected by {@link RolloverFileOutputStream}
+ * Create request log object with specified output file name.
+ *
+ * @param filename the file name for the request log.
+ * This may be in the format expected
+ * by {@link RolloverFileOutputStream}
*/
public NCSARequestLog(String filename)
{
@@ -94,9 +100,12 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
/* ------------------------------------------------------------ */
/**
- * @param filename
- * The filename for the request log. This may be in the
- * format expected by {@link RolloverFileOutputStream}
+ * Set the output file name of the request log.
+ * The file name may be in the format expected by
+ * {@link RolloverFileOutputStream}.
+ *
+ * @param filename file name of the request log
+ *
*/
public void setFilename(String filename)
{
@@ -109,11 +118,25 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
_filename = filename;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the output file name of the request log.
+ *
+ * @return file name of the request log
+ */
public String getFilename()
{
return _filename;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the file name of the request log with the expanded
+ * date wildcard if the output is written to the disk using
+ * {@link RolloverFileOutputStream}.
+ *
+ * @return file name of the request log, or null if not applicable
+ */
public String getDatedFilename()
{
if (_fileOut instanceof RolloverFileOutputStream)
@@ -123,116 +146,306 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
/* ------------------------------------------------------------ */
/**
- * @param format
- * Format for the timestamps in the log file. If not set, the
- * pre-formated request timestamp is used.
+ * Set the timestamp format for request log entries in the file.
+ * If this is not set, the pre-formated request timestamp is used.
+ *
+ * @param format timestamp format string
*/
public void setLogDateFormat(String format)
{
_logDateFormat = format;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the timestamp format string for request log entries.
+ *
+ * @return timestamp format string.
+ */
public String getLogDateFormat()
{
return _logDateFormat;
}
-
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the locale of the request log.
+ *
+ * @param logLocale locale object
+ */
public void setLogLocale(Locale logLocale)
{
_logLocale = logLocale;
}
-
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the locale of the request log.
+ *
+ * @return locale object
+ */
public Locale getLogLocale()
{
return _logLocale;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the timezone of the request log.
+ *
+ * @param tz timezone string
+ */
public void setLogTimeZone(String tz)
{
_logTimeZone = tz;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the timezone of the request log.
+ *
+ * @return timezone string
+ */
public String getLogTimeZone()
{
return _logTimeZone;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the number of days before rotated log files are deleted.
+ *
+ * @param retainDays number of days to keep a log file
+ */
public void setRetainDays(int retainDays)
{
_retainDays = retainDays;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the number of days before rotated log files are deleted.
+ *
+ * @return number of days to keep a log file
+ */
public int getRetainDays()
{
return _retainDays;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the extended request log format flag.
+ *
+ * @param extended true - log the extended request information,
+ * false - do not log the extended request information
+ */
public void setExtended(boolean extended)
{
_extended = extended;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the extended request log format flag.
+ *
+ * @return value of the flag
+ */
public boolean isExtended()
{
return _extended;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Set append to log flag.
+ *
+ * @param append true - request log file will be appended after restart,
+ * false - request log file will be overwritten after restart
+ */
public void setAppend(boolean append)
{
_append = append;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve append to log flag.
+ *
+ * @return value of the flag
+ */
public boolean isAppend()
{
return _append;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Set request paths that will not be logged.
+ *
+ * @param ignorePaths array of request paths
+ */
public void setIgnorePaths(String[] ignorePaths)
{
_ignorePaths = ignorePaths;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the request paths that will not be logged.
+ *
+ * @return array of request paths
+ */
public String[] getIgnorePaths()
{
return _ignorePaths;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Controls logging of the request cookies.
+ *
+ * @param logCookies true - values of request cookies will be logged,
+ * false - values of request cookies will not be logged
+ */
public void setLogCookies(boolean logCookies)
{
_logCookies = logCookies;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve log cookies flag
+ *
+ * @return value of the flag
+ */
public boolean getLogCookies()
{
return _logCookies;
}
- public boolean getLogServer()
+ /* ------------------------------------------------------------ */
+ /**
+ * Controls logging of the request hostname.
+ *
+ * @param logServer true - request hostname will be logged,
+ * false - request hostname will not be logged
+ */
+ public void setLogServer(boolean logServer)
{
- return _logServer;
+ _logServer = logServer;
}
- public void setLogServer(boolean logServer)
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve log hostname flag.
+ *
+ * @return value of the flag
+ */
+ public boolean getLogServer()
{
- _logServer = logServer;
+ return _logServer;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Controls logging of request processing time.
+ *
+ * @param logLatency true - request processing time will be logged
+ * false - request processing time will not be logged
+ */
public void setLogLatency(boolean logLatency)
{
_logLatency = logLatency;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve log request processing time flag.
+ *
+ * @return value of the flag
+ */
public boolean getLogLatency()
{
return _logLatency;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Controls whether the actual IP address of the connection or
+ * the IP address from the X-Forwarded-For header will be logged.
+ *
+ * @param preferProxiedForAddress true - IP address from header will be logged,
+ * false - IP address from the connection will be logged
+ */
public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
{
_preferProxiedForAddress = preferProxiedForAddress;
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieved log X-Forwarded-For IP address flag.
+ *
+ * @return value of the flag
+ */
+ public boolean getPreferProxiedForAddress()
+ {
+ return _preferProxiedForAddress;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the log file name date format.
+ * @see RolloverFileOutputStream#RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)
+ *
+ * @param logFileDateFormat format string that is passed to {@link RolloverFileOutputStream}
+ */
+ public void setFilenameDateFormat(String logFileDateFormat)
+ {
+ _filenameDateFormat = logFileDateFormat;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the file name date format string.
+ *
+ * @return the log File Date Format
+ */
+ public String getFilenameDateFormat()
+ {
+ return _filenameDateFormat;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Controls logging of the request dispatch time
+ *
+ * @param value true - request dispatch time will be logged
+ * false - request dispatch time will not be logged
+ */
+ public void setLogDispatch(boolean value)
+ {
+ _logDispatch = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve request dispatch time logging flag
+ *
+ * @return value of the flag
+ */
+ public boolean isLogDispatch()
+ {
+ return _logDispatch;
+ }
/* ------------------------------------------------------------ */
+ /**
+ * Writes the request and response information to the output stream.
+ *
+ * @see org.eclipse.jetty.server.RequestLog#log(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response)
+ */
public void log(Request request, Response response)
{
if (!isStarted())
@@ -254,7 +467,7 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
u8buf = size==0?new Utf8StringBuilder(160):(Utf8StringBuilder)_buffers.remove(size-1);
buf = u8buf.getStringBuilder();
}
-
+
if (_logServer)
{
buf.append(request.getServerName());
@@ -277,7 +490,7 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
buf.append(((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName());
else
buf.append(" - ");
-
+
buf.append(" [");
if (_logDateCache != null)
buf.append(_logDateCache.format(request.getTimeStamp()));
@@ -335,12 +548,12 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
buf.append(StringUtil.__LINE_SEPARATOR);
int l=buf.length();
if (l>_copy.length)
- l=_copy.length;
- buf.getChars(0,l,_copy,0);
+ l=_copy.length;
+ buf.getChars(0,l,_copy,0);
_writer.write(_copy,0,l);
_writer.flush();
u8buf.reset();
- _buffers.add(u8buf);
+ _buffers.add(u8buf);
}
}
else
@@ -349,11 +562,11 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
{
int l=buf.length();
if (l>_copy.length)
- l=_copy.length;
- buf.getChars(0,l,_copy,0);
+ l=_copy.length;
+ buf.getChars(0,l,_copy,0);
_writer.write(_copy,0,l);
u8buf.reset();
- _buffers.add(u8buf);
+ _buffers.add(u8buf);
// TODO do outside synchronized scope
if (_extended)
@@ -362,13 +575,13 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
// TODO do outside synchronized scope
if (_logCookies)
{
- Cookie[] cookies = request.getCookies();
+ Cookie[] cookies = request.getCookies();
if (cookies == null || cookies.length == 0)
_writer.write(" -");
else
{
_writer.write(" \"");
- for (int i = 0; i < cookies.length; i++)
+ for (int i = 0; i < cookies.length; i++)
{
if (i != 0)
_writer.write(';');
@@ -379,11 +592,20 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
_writer.write('\"');
}
}
+
+ final long now = System.currentTimeMillis();
+ final long start = request.getTimeStamp();
+ final long dispatch = request.getDispatchTime();
+ if (_logDispatch)
+ {
+ _writer.write(' ');
+ _writer.write(Long.toString(now - (dispatch==0 ? start:dispatch)));
+ }
if (_logLatency)
{
_writer.write(' ');
- _writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp()));
+ _writer.write(Long.toString(now - start));
}
_writer.write(StringUtil.__LINE_SEPARATOR);
@@ -399,9 +621,17 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
}
/* ------------------------------------------------------------ */
- protected void logExtended(Request request,
- Response response,
- Writer writer) throws IOException
+ /**
+ * Writes extended request and response information to the output stream.
+ *
+ * @param request request object
+ * @param response response object
+ * @param writer log file writer
+ * @throws IOException
+ */
+ protected void logExtended(Request request,
+ Response response,
+ Writer writer) throws IOException
{
String referer = request.getHeader(HttpHeaders.REFERER);
if (referer == null)
@@ -425,6 +655,11 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
}
/* ------------------------------------------------------------ */
+ /**
+ * Set up request logging and open log file.
+ *
+ * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+ */
@Override
protected void doStart() throws Exception
{
@@ -461,6 +696,11 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
}
/* ------------------------------------------------------------ */
+ /**
+ * Close the log file and perform cleanup.
+ *
+ * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+ */
@Override
protected void doStop() throws Exception
{
@@ -492,28 +732,4 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
_buffers = null;
_copy = null;
}
-
- /* ------------------------------------------------------------ */
- /**
- * @return the log File Date Format
- */
- public String getFilenameDateFormat()
- {
- return _filenameDateFormat;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set the log file date format.
- *
- * @see {@link RolloverFileOutputStream#RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)}
- * @param logFileDateFormat
- * the logFileDateFormat to pass to
- * {@link RolloverFileOutputStream}
- */
- public void setFilenameDateFormat(String logFileDateFormat)
- {
- _filenameDateFormat = logFileDateFormat;
- }
-
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index 6a06cc8ffa..a1c5599fc6 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -82,26 +82,26 @@ import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
/** Jetty Request.
* <p>
- * Implements {@link javax.servlet.http.HttpServletRequest} from the {@link javax.servlet.http} package.
+ * Implements {@link javax.servlet.http.HttpServletRequest} from the <code>javax.servlet.http</code> package.
* </p>
* <p>
* The standard interface of mostly getters,
* is extended with setters so that the request is mutable by the handlers that it is
* passed to. This allows the request object to be as lightweight as possible and not
- * actually implement any significant behaviour. For example<ul>
+ * actually implement any significant behavior. For example<ul>
*
- * <li>The {@link Request#getContextPath} method will return null, until the requeset has been
- * passed to a {@link ContextHandler} which matches the {@link Request#getPathInfo} with a context
- * path and calls {@link Request#setContextPath} as a result.</li>
+ * <li>The {@link Request#getContextPath()} method will return null, until the request has been
+ * passed to a {@link ContextHandler} which matches the {@link Request#getPathInfo()} with a context
+ * path and calls {@link Request#setContextPath(String)} as a result.</li>
*
* <li>the HTTP session methods
* will all return null sessions until such time as a request has been passed to
- * a {@link org.eclipse.jetty.servlet.SessionHandler} which checks for session cookies
+ * a {@link org.eclipse.jetty.server.session.SessionHandler} which checks for session cookies
* and enables the ability to create new sessions.</li>
*
- * <li>The {@link Request#getServletPath} method will return null until the request has been
- * passed to a {@link org.eclipse.jetty.servlet.ServletHandler} and the pathInfo matched
- * against the servlet URL patterns and {@link Request#setServletPath} called as a result.</li>
+ * <li>The {@link Request#getServletPath()} method will return null until the request has been
+ * passed to a <code>org.eclipse.jetty.servlet.ServletHandler</code> and the pathInfo matched
+ * against the servlet URL patterns and {@link Request#setServletPath(String)} called as a result.</li>
* </ul>
*
* A request instance is created for each {@link HttpConnection} accepted by the server
@@ -166,7 +166,8 @@ public class Request implements HttpServletRequest
private HttpSession _session;
private SessionManager _sessionManager;
private long _timeStamp;
-
+ private long _dispatchTime;
+
private Buffer _timeStampBuffer;
private HttpURI _uri;
@@ -1225,6 +1226,16 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
+ /** Get timestamp of the request dispatch
+ *
+ * @return timestamp
+ */
+ public long getDispatchTime()
+ {
+ return _dispatchTime;
+ }
+
+ /* ------------------------------------------------------------ */
public boolean isAsyncStarted()
{
return _async.isAsyncStarted();
@@ -1565,7 +1576,9 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
/**
- * @param context
+ * Set request context
+ *
+ * @param context context object
*/
public void setContext(Context context)
{
@@ -1575,7 +1588,8 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
/**
- * @return True if this is the first call of takeNewContext() since the last {@link #setContext(Context)} call.
+ * @return True if this is the first call of {@link #takeNewContext()}
+ * since the last {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call.
*/
public boolean takeNewContext()
{
@@ -1587,7 +1601,7 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
/**
* Sets the "context path" for this request
- * @see HttpServletRequest#getContextPath
+ * @see HttpServletRequest#getContextPath()
*/
public void setContextPath(String contextPath)
{
@@ -1801,6 +1815,16 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
+ /** Set timetstamp of request dispatch
+ *
+ * @param value timestamp
+ */
+ public void setDispatchTime(long value)
+ {
+ _dispatchTime = value;
+ }
+
+ /* ------------------------------------------------------------ */
public AsyncContext startAsync() throws IllegalStateException
{
if (!_asyncSupported)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java
index 2e95bbc0e0..a2b7a9b36c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java
@@ -16,9 +16,8 @@ package org.eclipse.jetty.server;
import org.eclipse.jetty.util.component.LifeCycle;
/**
- * A <code>RequestLog</code> can be attached to a {@link org.eclipse.jetty.server.server.handler.RequestLogHandler} to enable logging of requests/responses.
- *
- * @see Server#setRequestLog
+ * A <code>RequestLog</code> can be attached to a {@link org.eclipse.jetty.server.handler.RequestLogHandler} to enable
+ * logging of requests/responses.
*/
public interface RequestLog extends LifeCycle
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index 0230f90665..37ed17efca 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -17,6 +17,8 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.List;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
@@ -29,6 +31,7 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersions;
@@ -43,14 +46,10 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
-/* ------------------------------------------------------------ */
/** Response.
* <p>
- * Implements {@link javax.servlet.HttpServletResponse} from the {@link javax.servlet} package.
+ * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package.
* </p>
- *
- *
- *
*/
public class Response implements HttpServletResponse
{
@@ -156,16 +155,30 @@ public class Response implements HttpServletResponse
*/
public String encodeURL(String url)
{
- Request request=_connection.getRequest();
+ final Request request=_connection.getRequest();
SessionManager sessionManager = request.getSessionManager();
if (sessionManager==null)
return url;
+
+ if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url))
+ {
+ HttpURI uri = new HttpURI(url);
+ int port=uri.getPort();
+ if (port<0)
+ port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
+ if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
+ request.getServerPort()!=port ||
+ !uri.getPath().startsWith(request.getContextPath()))
+ return url;
+ }
+
String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix();
if (sessionURLPrefix==null)
return url;
if (url==null)
return null;
+
// should not encode if cookies in evidence
if (request.isRequestedSessionIdFromCookie())
{
@@ -190,15 +203,12 @@ public class Response implements HttpServletResponse
if (session == null)
return url;
-
// invalid session
if (!sessionManager.isValid(session))
return url;
String id=sessionManager.getNodeId(session);
-
- // TODO Check host and port are for this server
// Already encoded
int prefix=url.indexOf(sessionURLPrefix);
if (prefix!=-1)
@@ -224,7 +234,7 @@ public class Response implements HttpServletResponse
}
/* ------------------------------------------------------------ */
- /*
+ /**
* @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String)
*/
public String encodeRedirectURL(String url)
@@ -233,21 +243,17 @@ public class Response implements HttpServletResponse
}
/* ------------------------------------------------------------ */
- /*
- * @see javax.servlet.http.HttpServletResponse#encodeUrl(java.lang.String)
- */
+ @Deprecated
public String encodeUrl(String url)
{
return encodeURL(url);
}
/* ------------------------------------------------------------ */
- /*
- * @see javax.servlet.http.HttpServletResponse#encodeRedirectUrl(java.lang.String)
- */
+ @Deprecated
public String encodeRedirectUrl(String url)
{
- return encodeURL(url);
+ return encodeRedirectURL(url);
}
/* ------------------------------------------------------------ */
@@ -288,14 +294,14 @@ public class Response implements HttpServletResponse
ContextHandler.Context context = request.getContext();
if (context!=null)
error_handler=context.getContextHandler().getErrorHandler();
+ if (error_handler==null)
+ error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class);
if (error_handler!=null)
{
- // TODO - probably should reset these after the request?
request.setAttribute(Dispatcher.ERROR_STATUS_CODE,new Integer(code));
request.setAttribute(Dispatcher.ERROR_MESSAGE, message);
request.setAttribute(Dispatcher.ERROR_REQUEST_URI, request.getRequestURI());
request.setAttribute(Dispatcher.ERROR_SERVLET_NAME,request.getServletName());
-
error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this );
}
else
@@ -715,7 +721,7 @@ public class Response implements HttpServletResponse
if (_contentType==null)
{
- _contentType = _mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
}
@@ -724,16 +730,16 @@ public class Response implements HttpServletResponse
int i1=_contentType.indexOf("charset=",i0);
if (i1<0)
{
- _contentType = _contentType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
}
else
{
int i8=i1+8;
int i2=_contentType.indexOf(" ",i8);
if (i2<0)
- _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
else
- _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ")+_contentType.substring(i2);
+ _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2);
}
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
@@ -861,12 +867,12 @@ public class Response implements HttpServletResponse
}
else if (i2<0)
{
- _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
else
{
- _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
}
@@ -912,7 +918,7 @@ public class Response implements HttpServletResponse
else // No encoding in the params.
{
_cachedMimeType=null;
- _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
}
@@ -933,13 +939,13 @@ public class Response implements HttpServletResponse
}
else
{
- _contentType=_mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
}
else
{
- _contentType=contentType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
+ _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
index 297e81f538..9ab0a6151d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
@@ -14,15 +14,12 @@
package org.eclipse.jetty.server;
import java.io.IOException;
-import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -30,7 +27,6 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpURI;
-import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.Attributes;
@@ -74,7 +70,9 @@ public class Server extends HandlerWrapper implements Attributes
private boolean _sendDateHeader = false; //send Date: header
private int _graceful=0;
private boolean _stopAtShutdown;
+ private int _maxCookieVersion=1;
+
/* ------------------------------------------------------------ */
public Server()
{
@@ -83,7 +81,7 @@ public class Server extends HandlerWrapper implements Attributes
/* ------------------------------------------------------------ */
/** Convenience constructor
- * Creates server and a {@link SocketConnector} at the passed port.
+ * Creates server and a {@link SelectChannelConnector} at the passed port.
*/
public Server(int port)
{
@@ -93,6 +91,20 @@ public class Server extends HandlerWrapper implements Attributes
connector.setPort(port);
setConnectors(new Connector[]{connector});
}
+
+ /* ------------------------------------------------------------ */
+ /** Convenience constructor
+ * Creates server and a {@link SelectChannelConnector} at the passed address.
+ */
+ public Server(InetSocketAddress addr)
+ {
+ setServer(this);
+
+ Connector connector=new SelectChannelConnector();
+ connector.setHost(addr.getHostName());
+ connector.setPort(addr.getPort());
+ setConnectors(new Connector[]{connector});
+ }
/* ------------------------------------------------------------ */
@@ -198,7 +210,13 @@ public class Server extends HandlerWrapper implements Attributes
HttpGenerator.setServerVersion(_version);
MultiException mex=new MultiException();
- Iterator itor = _dependentBeans.iterator();
+ if (_threadPool==null)
+ {
+ QueuedThreadPool tp=new QueuedThreadPool();
+ setThreadPool(tp);
+ }
+
+ Iterator<Object> itor = _dependentBeans.iterator();
while (itor.hasNext())
{
try
@@ -210,12 +228,6 @@ public class Server extends HandlerWrapper implements Attributes
catch (Throwable e) {mex.add(e);}
}
- if (_threadPool==null)
- {
- QueuedThreadPool tp=new QueuedThreadPool();
- setThreadPool(tp);
- }
-
if (_sessionIdManager!=null)
_sessionIdManager.start();
@@ -299,7 +311,7 @@ public class Server extends HandlerWrapper implements Attributes
if (!_dependentBeans.isEmpty())
{
- ListIterator itor = _dependentBeans.listIterator(_dependentBeans.size());
+ ListIterator<Object> itor = _dependentBeans.listIterator(_dependentBeans.size());
while (itor.hasPrevious())
{
try
@@ -313,7 +325,9 @@ public class Server extends HandlerWrapper implements Attributes
}
mex.ifExceptionThrow();
- ShutdownThread.deregister(this);
+
+ if (getStopAtShutdown())
+ ShutdownThread.deregister(this);
}
/* ------------------------------------------------------------ */
@@ -436,13 +450,30 @@ public class Server extends HandlerWrapper implements Attributes
{
return _sendDateHeader;
}
-
+
+ /* ------------------------------------------------------------ */
+ /** Get the maximum cookie version.
+ * @return the maximum set-cookie version sent by this server
+ */
+ public int getMaxCookieVersion()
+ {
+ return _maxCookieVersion;
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Set the maximum cookie version.
+ * @param maxCookieVersion the maximum set-cookie version sent by this server
+ */
+ public void setMaxCookieVersion(int maxCookieVersion)
+ {
+ _maxCookieVersion = maxCookieVersion;
+ }
/* ------------------------------------------------------------ */
/**
* Add a LifeCycle object to be started/stopped
* along with the Server.
- * @deprecated Use {@link #addBean(LifeCycle)}
+ * @deprecated Use {@link #addBean(Object)}
* @param c
*/
@Deprecated
@@ -457,7 +488,7 @@ public class Server extends HandlerWrapper implements Attributes
* The bean will be added to the servers {@link Container}
* and if it is a {@link LifeCycle} instance, it will be
* started/stopped along with the Server.
- * @param c
+ * @param o the bean object to add
*/
public void addBean(Object o)
{
@@ -500,6 +531,34 @@ public class Server extends HandlerWrapper implements Attributes
return beans;
}
+ /* ------------------------------------------------------------ */
+ /** Get dependent bean of a specific class.
+ * If more than one bean of the type exist, the first is returned.
+ * @see #addBean(Object)
+ * @param clazz
+ * @return bean or null
+ */
+ public <T> T getBean(Class<T> clazz)
+ {
+ Iterator<?> iter = _dependentBeans.iterator();
+ T t=null;
+ int count=0;
+ while (iter.hasNext())
+ {
+ Object o = iter.next();
+ if (clazz.isInstance(o))
+ {
+ count++;
+ if (t==null)
+ t=(T)o;
+ }
+ }
+ if (count>1)
+ Log.debug("getBean({}) 1 of {}",clazz.getName(),count);
+
+ return t;
+ }
+
/**
* Remove a LifeCycle object to be started/stopped
* along with the Server
@@ -578,7 +637,7 @@ public class Server extends HandlerWrapper implements Attributes
/* ------------------------------------------------------------ */
/**
- * Set graceful shutdown timeout. If set, the {@link #doStop()} method will not immediately stop the
+ * Set graceful shutdown timeout. If set, the internal <code>doStop()</code> method will not immediately stop the
* server. Instead, all {@link Connector}s will be closed so that new connections will not be accepted
* and all handlers that implement {@link Graceful} will be put into the shutdown mode so that no new requests
* will be accepted, but existing requests can complete. The server will then wait the configured timeout
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
index 1d76581822..cca2783673 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
@@ -20,13 +20,6 @@ import org.eclipse.jetty.util.component.LifeCycle;
/** Session ID Manager.
* Manages session IDs across multiple contexts.
- *
- *
- */
-/* ------------------------------------------------------------ */
-/**
- *
- *
*/
public interface SessionIdManager extends LifeCycle
{
@@ -57,7 +50,7 @@ public interface SessionIdManager extends LifeCycle
/**
* @param request
* @param created
- * @return
+ * @return the new session id
*/
public String newSessionId(HttpServletRequest request,long created);
@@ -68,7 +61,7 @@ public interface SessionIdManager extends LifeCycle
/** Get a cluster ID from a node ID.
* Strip node identifier from a located session ID.
* @param nodeId
- * @return
+ * @return the cluster id
*/
public String getClusterId(String nodeId);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
index 3d11dd554a..7d8ea58284 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
@@ -30,14 +30,15 @@ import org.eclipse.jetty.util.component.LifeCycle;
/**
* Session Manager.
* The API required to manage sessions for a servlet context.
+ *
*/
public interface SessionManager extends LifeCycle
{
/* ------------------------------------------------------------ */
/**
* Session cookie name.
- * Defaults to JSESSIONID, but can be set with the
- * org.eclipse.jetty.servlet.SessionCookie context init parameter.
+ * Defaults to <code>JSESSIONID</code>, but can be set with the
+ * <code>org.eclipse.jetty.servlet.SessionCookie</code> context init parameter.
*/
public final static String __SessionCookieProperty = "org.eclipse.jetty.servlet.SessionCookie";
public final static String __DefaultSessionCookie = "JSESSIONID";
@@ -46,12 +47,13 @@ public interface SessionManager extends LifeCycle
/* ------------------------------------------------------------ */
/**
* Session id path parameter name.
- * Defaults to jsessionid, but can be set with the
- * org.eclipse.jetty.servlet.SessionIdPathParameterName context init parameter.
+ * Defaults to <code>jsessionid</code>, but can be set with the
+ * <code>org.eclipse.jetty.servlet.SessionIdPathParameterName</code> context init parameter.
* If set to null or "none" no URL rewriting will be done.
*/
public final static String __SessionIdPathParameterNameProperty = "org.eclipse.jetty.servlet.SessionIdPathParameterName";
public final static String __DefaultSessionIdPathParameterName = "jsessionid";
+ public final static String __CheckRemoteSessionEncoding = "org.eclipse.jetty.servlet.CheckingRemoteSessionIdEncoding";
/* ------------------------------------------------------------ */
@@ -101,6 +103,14 @@ public interface SessionManager extends LifeCycle
*/
public HttpSession newHttpSession(HttpServletRequest request);
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return true if session cookies should be HTTP-only (Microsoft extension)
+ * @see org.eclipse.jetty.http.HttpCookie#isHttpOnly()
+ */
+ public boolean getHttpOnly();
+
/* ------------------------------------------------------------ */
/**
* @return the max period of inactivity, after which the session is invalidated, in seconds.
@@ -267,4 +277,15 @@ public interface SessionManager extends LifeCycle
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);
public SessionCookieConfig getSessionCookieConfig();
+
+ /**
+ * @return True if absolute URLs are check for remoteness before being session encoded.
+ */
+ public boolean isCheckingRemoteSessionIdEncoding();
+
+ /**
+ * @param remote True if absolute URLs are check for remoteness before being session encoded.
+ */
+ public void setCheckingRemoteSessionIdEncoding(boolean remote);
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java b/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java
index 0c849bd593..8422e85dc3 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java
@@ -51,14 +51,11 @@ public interface UserIdentity
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
/**
* A UserIdentity Scope.
* A scope is the environment in which a User Identity is to
* be interpreted. Typically it is set by the target servlet of
* a request.
- * @see org.eclipse.jetty.servlet.ServletHolder
*/
interface Scope
{
@@ -83,15 +80,11 @@ public interface UserIdentity
}
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
public interface UnauthenticatedUserIdentity extends UserIdentity
{
}
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
public static final UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity()
{
public Subject getSubject()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
index 5a39e71f38..e3104dbb8d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
@@ -4,13 +4,13 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-
+
package org.eclipse.jetty.server.bio;
import java.io.IOException;
@@ -39,21 +39,22 @@ import org.eclipse.jetty.util.log.Log;
* This connector implements a traditional blocking IO and threading model.
* Normal JRE sockets are used and a thread is allocated per connection.
* Buffers are managed so that large buffers are only allocated to active connections.
- *
+ *
* This Connector should only be used if NIO is not available.
- *
+ *
* @org.apache.xbean.XBean element="bioConnector" description="Creates a BIO based socket connector"
- *
- *
+ *
+ *
*/
public class SocketConnector extends AbstractConnector
{
protected ServerSocket _serverSocket;
protected final Set<EndPoint> _connections;
-
+ protected volatile int _localPort=-1;
+
/* ------------------------------------------------------------ */
/** Constructor.
- *
+ *
*/
public SocketConnector()
{
@@ -65,7 +66,7 @@ public class SocketConnector extends AbstractConnector
{
return _serverSocket;
}
-
+
/* ------------------------------------------------------------ */
public void open() throws IOException
{
@@ -73,6 +74,10 @@ public class SocketConnector extends AbstractConnector
if (_serverSocket==null || _serverSocket.isClosed())
_serverSocket= newServerSocket(getHost(),getPort(),getAcceptQueueSize());
_serverSocket.setReuseAddress(getReuseAddress());
+ _localPort=_serverSocket.getLocalPort();
+ if (_localPort<=0)
+ throw new IllegalStateException("port not allocated for "+this);
+
}
/* ------------------------------------------------------------ */
@@ -81,26 +86,27 @@ public class SocketConnector extends AbstractConnector
ServerSocket ss= host==null?
new ServerSocket(port,backlog):
new ServerSocket(port,backlog,InetAddress.getByName(host));
-
+
return ss;
}
-
+
/* ------------------------------------------------------------ */
public void close() throws IOException
{
if (_serverSocket!=null)
_serverSocket.close();
_serverSocket=null;
+ _localPort=-2;
}
/* ------------------------------------------------------------ */
@Override
public void accept(int acceptorID)
throws IOException, InterruptedException
- {
+ {
Socket socket = _serverSocket.accept();
configure(socket);
-
+
ConnectorEndPoint connection=new ConnectorEndPoint(socket);
connection.dispatch();
}
@@ -109,7 +115,7 @@ public class SocketConnector extends AbstractConnector
/**
* Allows subclass to override Conection if required.
*/
- protected HttpConnection newHttpConnection(EndPoint endpoint)
+ protected Connection newConnection(EndPoint endpoint)
{
return new HttpConnection(this, endpoint, getServer());
}
@@ -121,21 +127,15 @@ public class SocketConnector extends AbstractConnector
{
ConnectorEndPoint connection = (ConnectorEndPoint)endpoint;
int lrmit = isLowResources()?_lowResourceMaxIdleTime:_maxIdleTime;
- if (connection._sotimeout!=lrmit)
- {
- connection._sotimeout=lrmit;
- ((Socket)endpoint.getTransport()).setSoTimeout(lrmit);
- }
-
+ connection.setMaxIdleTime(lrmit);
+
super.customize(endpoint, request);
}
/* ------------------------------------------------------------------------------- */
public int getLocalPort()
{
- if (_serverSocket==null || _serverSocket.isClosed())
- return -1;
- return _serverSocket.getLocalPort();
+ return _localPort;
}
/* ------------------------------------------------------------------------------- */
@@ -157,7 +157,7 @@ public class SocketConnector extends AbstractConnector
{
set= new HashSet(_connections);
}
-
+
Iterator iter=set.iterator();
while(iter.hasNext())
{
@@ -173,14 +173,12 @@ public class SocketConnector extends AbstractConnector
{
boolean _dispatched=false;
volatile Connection _connection;
- int _sotimeout;
protected final Socket _socket;
-
+
public ConnectorEndPoint(Socket socket) throws IOException
{
- super(socket);
- _connection = newHttpConnection(this);
- _sotimeout=socket.getSoTimeout();
+ super(socket,_maxIdleTime);
+ _connection = newConnection(this);
_socket=socket;
}
@@ -195,7 +193,7 @@ public class SocketConnector extends AbstractConnector
connectionUpgraded(_connection,connection);
_connection=connection;
}
-
+
public void dispatch() throws IOException
{
if (getThreadPool()==null || !getThreadPool().dispatch(this))
@@ -204,7 +202,7 @@ public class SocketConnector extends AbstractConnector
close();
}
}
-
+
@Override
public int fill(Buffer buffer) throws IOException
{
@@ -212,8 +210,8 @@ public class SocketConnector extends AbstractConnector
if (l<0)
close();
return l;
- }
-
+ }
+
@Override
public void close() throws IOException
{
@@ -231,21 +229,14 @@ public class SocketConnector extends AbstractConnector
{
_connections.add(this);
}
-
+
while (isStarted() && !isClosed())
{
if (_connection.isIdle())
{
if (isLowResources())
- {
- int lrmit = getLowResourcesMaxIdleTime();
- if (lrmit>=0 && _sotimeout!= lrmit)
- {
- _sotimeout=lrmit;
- _socket.setSoTimeout(_sotimeout);
- }
- }
- }
+ setMaxIdleTime(getLowResourcesMaxIdleTime());
+ }
_connection=_connection.handle();
}
@@ -269,7 +260,7 @@ public class SocketConnector extends AbstractConnector
catch(IOException e2){Log.ignore(e2);}
}
finally
- {
+ {
connectionClosed(_connection);
synchronized(_connections)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java
index fbaa3513d2..91a65a19b1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java
@@ -94,6 +94,8 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement
int last=handlers.length-1;
for (int h=0;h<=last;h++)
{
+ if (handlers[h]==null)
+ continue;
b.append(indent);
b.append(" +-");
if (handlers[h] instanceof AbstractHandler)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 4938021beb..114a5076b3 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
@@ -73,31 +73,35 @@ import org.eclipse.jetty.util.resource.Resource;
/* ------------------------------------------------------------ */
/** ContextHandler.
- *
+ *
* This handler wraps a call to handle by setting the context and
* servlet path, plus setting the context classloader.
- *
+ *
* <p>
* If the context init parameter "org.eclipse.jetty.server.context.ManagedAttributes"
* is set to a comma separated list of names, then they are treated as context
* attribute names, which if set as attributes are passed to the servers Container
* so that they may be managed with JMX.
- *
- * @org.apache.xbean.XBean description="Creates a basic HTTP context"
- *
- *
*
+ * @org.apache.xbean.XBean description="Creates a basic HTTP context"
*/
public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful
{
private static final ThreadLocal<Context> __context=new ThreadLocal<Context>();
- public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
+ /**
+ * If a context attribute with this name is set, it is interpreted as a
+ * comma separated list of attribute name. Any other context attributes that
+ * are set with a name from this list will result in a call to {@link #setManagedAttribute(String, Object)},
+ * which typically initiates the creation of a JMX MBean for the attribute value.
+ */
+ public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
+
/* ------------------------------------------------------------ */
/** Get the current ServletContext implementation.
* This call is only valid during a call to doStart and is available to
* nested handlers to access the context.
- *
+ *
* @return ServletContext implementation
*/
public static Context getCurrentContext()
@@ -106,14 +110,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
protected Context _scontext;
-
- private AttributesMap _attributes;
- private AttributesMap _contextAttributes;
+
+ private final AttributesMap _attributes;
+ private final AttributesMap _contextAttributes;
+ private final Map<String,String> _initParams;
private ClassLoader _classLoader;
private String _contextPath="/";
- private Map<String,String> _initParams;
private String _displayName;
- private Resource _baseResource;
+ private Resource _baseResource;
private MimeTypes _mimeTypes;
private Map<String,String> _localeEncodingMap;
private String[] _welcomeFiles;
@@ -134,49 +138,51 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
private Map<String,Object> _managedAttributes;
private boolean _shutdown=false;
- private boolean _available=true;
+ private boolean _available=true;
private volatile int _availability; // 0=STOPPED, 1=AVAILABLE, 2=SHUTDOWN, 3=UNAVAILABLE
-
+
private final static int __STOPPED=0,__AVAILABLE=1,__SHUTDOWN=2,__UNAVAILABLE=3;
-
-
+
+
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public ContextHandler()
{
super();
_scontext=new Context();
_attributes=new AttributesMap();
+ _contextAttributes=new AttributesMap();
_initParams=new HashMap<String,String>();
}
-
+
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
protected ContextHandler(Context context)
{
super();
_scontext=context;
_attributes=new AttributesMap();
+ _contextAttributes=new AttributesMap();
_initParams=new HashMap<String,String>();
}
-
+
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public ContextHandler(String contextPath)
{
this();
setContextPath(contextPath);
}
-
+
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public ContextHandler(HandlerContainer parent, String contextPath)
{
@@ -193,7 +199,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _scontext;
}
-
+
/* ------------------------------------------------------------ */
/**
* @return the allowNullPathInfo true if /context is not redirected to /context/
@@ -221,13 +227,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
Server old_server=getServer();
if (old_server!=null && old_server!=server)
old_server.getContainer().update(this, _errorHandler, null, "error",true);
- super.setServer(server);
+ super.setServer(server);
if (server!=null && server!=old_server)
server.getContainer().update(this, null, _errorHandler, "error",true);
- _errorHandler.setServer(server);
+ _errorHandler.setServer(server);
}
else
- super.setServer(server);
+ super.setServer(server);
}
/* ------------------------------------------------------------ */
@@ -247,8 +253,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if ( vhosts == null )
{
_vhosts = vhosts;
- }
- else
+ }
+ else
{
_vhosts = new String[vhosts.length];
for ( int i = 0; i < vhosts.length; i++ )
@@ -274,8 +280,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated use {@link #setConnectorNames(String[])}
+ /**
+ * @deprecated use {@link #setConnectorNames(String[])}
*/
@Deprecated
public void setHosts(String[] hosts)
@@ -302,15 +308,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
if (_connectors==null || _connectors.size()==0)
return null;
-
+
return _connectors.toArray(new String[_connectors.size()]);
}
/* ------------------------------------------------------------ */
/** Set the names of accepted connectors.
- *
+ *
* Names are either "host:port" or a specific configured name for a connector.
- *
+ *
* @param connectors If non null, an array of connector names that this context
* will accept a request from.
*/
@@ -321,9 +327,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
else
_connectors= new HashSet<String>(Arrays.asList(connectors));
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getAttribute(java.lang.String)
*/
public Object getAttribute(String name)
@@ -332,7 +338,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getAttributeNames()
*/
@SuppressWarnings("unchecked")
@@ -340,7 +346,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return AttributesMap.getAttributeNamesCopy(_attributes);
}
-
+
/* ------------------------------------------------------------ */
/**
* @return Returns the attributes.
@@ -349,7 +355,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _attributes;
}
-
+
/* ------------------------------------------------------------ */
/**
* @return Returns the classLoader.
@@ -402,9 +408,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _contextPath;
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
*/
public String getInitParameter(String name)
@@ -413,7 +419,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getInitParameterNames()
*/
@SuppressWarnings("unchecked")
@@ -421,7 +427,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return Collections.enumeration(_initParams.keySet());
}
-
+
/* ------------------------------------------------------------ */
/**
* @return Returns the initParams.
@@ -432,7 +438,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServletContextName()
*/
public String getDisplayName()
@@ -445,7 +451,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _eventListeners;
}
-
+
/* ------------------------------------------------------------ */
/**
* Set the context event listeners.
@@ -460,26 +466,26 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
_contextAttributeListeners=null;
_requestListeners=null;
_requestAttributeListeners=null;
-
+
_eventListeners=eventListeners;
-
+
for (int i=0; eventListeners!=null && i<eventListeners.length;i ++)
{
EventListener listener = _eventListeners[i];
-
+
if (listener instanceof ServletContextListener)
_contextListeners= LazyList.add(_contextListeners, listener);
-
+
if (listener instanceof ServletContextAttributeListener)
_contextAttributeListeners= LazyList.add(_contextAttributeListeners, listener);
-
+
if (listener instanceof ServletRequestListener)
_requestListeners= LazyList.add(_requestListeners, listener);
-
+
if (listener instanceof ServletRequestAttributeListener)
_requestAttributeListeners= LazyList.add(_requestAttributeListeners, listener);
}
- }
+ }
/* ------------------------------------------------------------ */
/**
@@ -489,7 +495,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
* @see ServletRequestListener
* @see ServletRequestAttributeListener
*/
- public void addEventListener(EventListener listener)
+ public void addEventListener(EventListener listener)
{
setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(), listener, EventListener.class));
}
@@ -557,34 +563,34 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _logger;
}
-
+
/* ------------------------------------------------------------ */
public void setLogger(Logger logger)
{
_logger=logger;
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.thread.AbstractLifeCycle#doStart()
*/
@Override
protected void doStart() throws Exception
{
_availability=__STOPPED;
-
+
if (_contextPath==null)
throw new IllegalStateException("Null contextPath");
-
+
_logger=Log.getLogger(getDisplayName()==null?getContextPath():getDisplayName());
ClassLoader old_classloader=null;
Thread current_thread=null;
Context old_context=null;
- _contextAttributes=new AttributesMap();
+ _contextAttributes.clearAttributes();
try
{
-
+
// Set the classloader
if (_classLoader!=null)
{
@@ -592,46 +598,40 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
old_classloader=current_thread.getContextClassLoader();
current_thread.setContextClassLoader(_classLoader);
}
-
+
if (_mimeTypes==null)
_mimeTypes=new MimeTypes();
-
+
old_context=__context.get();
__context.set(_scontext);
-
- if (_errorHandler==null)
- setErrorHandler(new ErrorHandler());
-
-
+
// defers the calling of super.doStart()
startContext();
-
_availability=_shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE;
}
finally
{
__context.set(old_context);
-
+
// reset the classloader
if (_classLoader!=null)
{
current_thread.setContextClassLoader(old_classloader);
}
-
+
}
}
/* ------------------------------------------------------------ */
/**
* Extensible startContext.
- * this method is called from {@link ContextHandler#doStart()} instead of a
+ * this method is called from {@link ContextHandler#doStart()} instead of a
* call to super.doStart(). This allows derived classes to insert additional
* handling (Eg configuration) before the call to super.doStart by this method
* will start contained handlers.
- * @see org.eclipse.jetty.Scope.Context
- * @see org.eclipse.jetty.webapp.WebAppContext
+ * @see org.eclipse.jetty.server.handler.ContextHandler.Context
*/
protected void startContext()
throws Exception
@@ -643,21 +643,21 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
String[] attributes = managedAttributes.split(",");
for (String attribute : attributes)
_managedAttributes.put(attribute,null);
-
+
Enumeration e = _scontext.getAttributeNames();
while(e.hasMoreElements())
{
String name = (String)e.nextElement();
Object value = _scontext.getAttribute(name);
- setManagedAttribute(name,value);
+ checkManagedAttribute(name,value);
}
- }
-
+ }
+
super.doStart();
if (_errorHandler!=null)
_errorHandler.start();
-
+
// Context listeners
if (_contextListeners != null )
{
@@ -668,14 +668,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
}
}
-
+
public void callContextInitialized (ServletContextListener l, ServletContextEvent e)
{
l.contextInitialized(e);
}
-
+
public void callContextDestroyed (ServletContextListener l, ServletContextEvent e)
{
l.contextDestroyed(e);
@@ -684,14 +684,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.thread.AbstractLifeCycle#doStop()
*/
@Override
protected void doStop() throws Exception
{
_availability=__STOPPED;
-
+
ClassLoader old_classloader=null;
Thread current_thread=null;
@@ -706,9 +706,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
old_classloader=current_thread.getContextClassLoader();
current_thread.setContextClassLoader(_classLoader);
}
-
+
super.doStop();
-
+
// Context listeners
if (_contextListeners != null )
{
@@ -721,12 +721,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if (_errorHandler!=null)
_errorHandler.stop();
-
+
Enumeration e = _scontext.getAttributeNames();
while(e.hasMoreElements())
{
String name = (String)e.nextElement();
- setManagedAttribute(name,null);
+ checkManagedAttribute(name,null);
}
}
finally
@@ -737,20 +737,18 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
current_thread.setContextClassLoader(old_classloader);
}
- if (_contextAttributes!=null)
- _contextAttributes.clearAttributes();
- _contextAttributes=null;
+ _contextAttributes.clearAttributes();
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public boolean checkContext(final String target, final Request baseRequest, final HttpServletResponse response)
throws IOException, ServletException
- {
+ {
DispatcherType dispatch=baseRequest.getDispatcherType();
-
+
switch(_availability)
{
case __STOPPED:
@@ -763,14 +761,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if((DispatcherType.REQUEST.equals(dispatch) && baseRequest.isHandled()))
return false;
}
-
+
// Check the vhosts
if (_vhosts!=null && _vhosts.length>0)
{
String vhost = normalizeHostname( baseRequest.getServerName());
boolean match=false;
-
+
// TODO non-linear lookup
for (int i=0;!match && i<_vhosts.length;i++)
{
@@ -785,7 +783,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if (!match)
return false;
}
-
+
// Check the connector
if (_connectors!=null && _connectors.size()>0)
{
@@ -794,29 +792,31 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
return false;
}
-
- if (target.startsWith(_contextPath))
+ // Are we not the root context?
+ if (_contextPath.length()>1)
{
- if (_contextPath.length()==target.length() && _contextPath.length()>1 &&!_allowNullPathInfo)
+ // reject requests that are not for us
+ if (!target.startsWith(_contextPath))
+ return false;
+ if (target.length()>_contextPath.length() && target.charAt(_contextPath.length())!='/')
+ return false;
+
+ // redirect null path infos
+ if (!_allowNullPathInfo && _contextPath.length()==target.length())
{
// context request must end with /
baseRequest.setHandled(true);
if (baseRequest.getQueryString()!=null)
response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH)+"?"+baseRequest.getQueryString());
- else
+ else
response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH));
return false;
}
}
- else
- {
- // Not for this context!
- return false;
- }
-
+
return true;
- }
-
+ }
+
/* ------------------------------------------------------------ */
@@ -825,7 +825,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
*/
@Override
public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
+ {
Context old_context=null;
String old_context_path=null;
String old_servlet_path=null;
@@ -835,9 +835,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
String pathInfo=null;
DispatcherType dispatch=baseRequest.getDispatcherType();
-
+
old_context=baseRequest.getContext();
-
+
// Are we already in this context?
if (old_context!=_scontext)
{
@@ -848,7 +848,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
target=URIUtil.compactPath(target);
if (!checkContext(target,baseRequest,response))
return;
-
+
if (target.length()>_contextPath.length())
{
if (_contextPath.length()>1)
@@ -875,13 +875,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
current_thread.setContextClassLoader(_classLoader);
}
}
-
+
try
{
old_context_path=baseRequest.getContextPath();
old_servlet_path=baseRequest.getServletPath();
old_path_info=baseRequest.getPathInfo();
-
+
// Update the paths
baseRequest.setContext(_scontext);
if (!DispatcherType.INCLUDE.equals(dispatch) && target.startsWith("/"))
@@ -893,16 +893,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
baseRequest.setServletPath(null);
baseRequest.setPathInfo(pathInfo);
}
-
+
// start manual inline of nextScope(target,baseRequest,request,response);
- //noinspection ConstantIfStatement
- if (false)
+ if (never())
nextScope(target,baseRequest,request,response);
else if (_nextScope!=null)
_nextScope.doScope(target,baseRequest,request, response);
else if (_outerScope!=null)
_outerScope.doHandle(target,baseRequest,request, response);
- else
+ else
doHandle(target,baseRequest,request, response);
// end manual inline (pathentic attempt to reduce stack depth)
}
@@ -915,16 +914,16 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
current_thread.setContextClassLoader(old_classloader);
}
-
+
// reset the context and servlet path.
baseRequest.setContext(old_context);
baseRequest.setContextPath(old_context_path);
baseRequest.setServletPath(old_servlet_path);
- baseRequest.setPathInfo(old_path_info);
+ baseRequest.setPathInfo(old_path_info);
}
}
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.ScopedHandler#doHandle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@@ -954,13 +953,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
((ServletRequestListener)LazyList.get(_requestListeners,i)).requestInitialized(sre);
}
}
-
+
if (DispatcherType.REQUEST.equals(dispatch) && isProtectedTarget(target))
throw new HttpException(HttpServletResponse.SC_NOT_FOUND);
-
+
// start manual inline of nextHandle(target,baseRequest,request,response);
//noinspection ConstantIfStatement
- if (false)
+ if (never())
nextHandle(target,baseRequest,request,response);
else if (_nextScope!=null && _nextScope==_handler)
_nextScope.doHandle(target,baseRequest,request, response);
@@ -985,7 +984,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
for(int i=0;i<s;i++)
((ServletRequestListener)LazyList.get(_requestListeners,i)).requestDestroyed(sre);
}
-
+
if (_requestAttributeListeners!=null)
{
for(int i=LazyList.size(_requestAttributeListeners);i-->0;)
@@ -994,12 +993,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
}
}
-
+
/* ------------------------------------------------------------ */
/* Handle a runnable in this context
*/
public void handle(Runnable runnable)
- {
+ {
ClassLoader old_classloader=null;
Thread current_thread=null;
try
@@ -1011,7 +1010,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
old_classloader=current_thread.getContextClassLoader();
current_thread.setContextClassLoader(_classLoader);
}
-
+
runnable.run();
}
finally
@@ -1028,64 +1027,49 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
* Called by {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} when a
* target within a context is determined. If the target is protected, 404 is returned.
* The default implementation always returns false.
- * @see org.eclipse.jetty.webapp.WebAppContext#isProtectedTarget(String)
*/
/* ------------------------------------------------------------ */
protected boolean isProtectedTarget(String target)
- {
+ {
return false;
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
*/
public void removeAttribute(String name)
{
- setManagedAttribute(name,null);
+ checkManagedAttribute(name,null);
_attributes.removeAttribute(name);
}
/* ------------------------------------------------------------ */
/* Set a context attribute.
* Attributes set via this API cannot be overriden by the ServletContext.setAttribute API.
- * Their lifecycle spans the stop/start of a context. No attribute listener events are
+ * Their lifecycle spans the stop/start of a context. No attribute listener events are
* triggered by this API.
* @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
*/
public void setAttribute(String name, Object value)
{
- setManagedAttribute(name,value);
+ checkManagedAttribute(name,value);
_attributes.setAttribute(name,value);
}
-
+
/* ------------------------------------------------------------ */
/**
* @param attributes The attributes to set.
*/
public void setAttributes(Attributes attributes)
{
- if (attributes instanceof AttributesMap)
- {
- _attributes = (AttributesMap)attributes;
- Enumeration e = _attributes.getAttributeNames();
- while (e.hasMoreElements())
- {
- String name = (String)e.nextElement();
- setManagedAttribute(name,attributes.getAttribute(name));
- }
- }
- else
+ _attributes.clearAttributes();
+ _attributes.addAll(attributes);
+ Enumeration e = _attributes.getAttributeNames();
+ while (e.hasMoreElements())
{
- _attributes=new AttributesMap();
- Enumeration e = attributes.getAttributeNames();
- while (e.hasMoreElements())
- {
- String name = (String)e.nextElement();
- Object value=attributes.getAttribute(name);
- setManagedAttribute(name,value);
- _attributes.setAttribute(name,value);
- }
+ String name = (String)e.nextElement();
+ checkManagedAttribute(name,attributes.getAttribute(name));
}
}
@@ -1096,28 +1080,28 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
while (e.hasMoreElements())
{
String name = (String)e.nextElement();
- setManagedAttribute(name,null);
+ checkManagedAttribute(name,null);
}
_attributes.clearAttributes();
}
/* ------------------------------------------------------------ */
- private void setManagedAttribute(String name, Object value)
- {
+ public void checkManagedAttribute(String name, Object value)
+ {
if (_managedAttributes!=null && _managedAttributes.containsKey(name))
{
- Object old =_managedAttributes.put(name,value);
- if (old!=null)
- getServer().getContainer().removeBean(old);
- if (value!=null)
- {
- if (_logger.isDebugEnabled()) _logger.debug("Managing "+name);
- getServer().getContainer().addBean(value);
- }
+ setManagedAttribute(name,value);
}
}
/* ------------------------------------------------------------ */
+ public void setManagedAttribute(String name, Object value)
+ {
+ Object old =_managedAttributes.put(name,value);
+ getServer().getContainer().update(this,old,value,name);
+ }
+
+ /* ------------------------------------------------------------ */
/**
* @param classLoader The classLoader to set.
*/
@@ -1125,7 +1109,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
_classLoader = classLoader;
}
-
+
/* ------------------------------------------------------------ */
/**
* @param contextPath The _contextPath to set.
@@ -1135,7 +1119,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if (contextPath!=null && contextPath.length()>1 && contextPath.endsWith("/"))
throw new IllegalArgumentException("ends with /");
_contextPath = contextPath;
-
+
if (getServer()!=null && (getServer().isStarting() || getServer().isStarted()))
{
Handler[] contextCollections = getServer().getChildHandlersByClass(ContextHandlerCollection.class);
@@ -1143,18 +1127,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
((ContextHandlerCollection)contextCollections[h]).mapContexts();
}
}
-
- /* ------------------------------------------------------------ */
- /**
- * @param initParams The initParams to set.
- */
- public void setInitParams(Map<String,String> initParams)
- {
- if (initParams == null)
- return;
- _initParams = new HashMap<String,String>(initParams);
- }
-
+
/* ------------------------------------------------------------ */
/**
* @param servletContextName The servletContextName to set.
@@ -1163,7 +1136,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
_displayName = servletContextName;
}
-
+
/* ------------------------------------------------------------ */
/**
* @return Returns the resourceBase.
@@ -1185,12 +1158,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
return null;
return _baseResource.toString();
}
-
+
/* ------------------------------------------------------------ */
/**
* @param base The resourceBase to set.
*/
- public void setBaseResource(Resource base)
+ public void setBaseResource(Resource base)
{
_baseResource=base;
}
@@ -1199,7 +1172,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
/**
* @param resourceBase The base resource as a string.
*/
- public void setResourceBase(String resourceBase)
+ public void setResourceBase(String resourceBase)
{
try
{
@@ -1238,7 +1211,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
return _mimeTypes;
}
-
+
/* ------------------------------------------------------------ */
/**
* @param mimeTypes The mimeTypes to set.
@@ -1251,7 +1224,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
/* ------------------------------------------------------------ */
/**
*/
- public void setWelcomeFiles(String[] files)
+ public void setWelcomeFiles(String[] files)
{
_welcomeFiles=files;
}
@@ -1262,7 +1235,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
* @see <a href="http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html">The Servlet Specification</a>
* @see #setWelcomeFiles
*/
- public String[] getWelcomeFiles()
+ public String[] getWelcomeFiles()
{
return _welcomeFiles;
}
@@ -1288,13 +1261,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
getServer().getContainer().update(this, _errorHandler, errorHandler, "errorHandler",true);
_errorHandler = errorHandler;
}
-
+
/* ------------------------------------------------------------ */
public int getMaxFormContentSize()
{
return _maxFormContentSize;
}
-
+
/* ------------------------------------------------------------ */
public void setMaxFormContentSize(int maxSize)
{
@@ -1324,7 +1297,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
@Override
public String toString()
{
-
+
return super.toString()+"@"+Integer.toHexString(hashCode())+getContextPath()+","+getBaseResource();
}
@@ -1334,13 +1307,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
if (className==null)
return null;
-
+
if (_classLoader==null)
return Loader.loadClass(this.getClass(), className);
return _classLoader.loadClass(className);
}
-
+
/* ------------------------------------------------------------ */
public void addLocaleEncoding(String locale,String encoding)
@@ -1349,12 +1322,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
_localeEncodingMap=new HashMap<String,String>();
_localeEncodingMap.put(locale, encoding);
}
-
+
/* ------------------------------------------------------------ */
/**
* Get the character encoding for a locale. The full locale name is first
* looked up in the map of encodings. If no encoding is found, then the
- * locale language is looked up.
+ * locale language is looked up.
*
* @param locale a <code>Locale</code> value
* @return a <code>String</code> representing the character encoding for
@@ -1369,7 +1342,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
encoding = _localeEncodingMap.get(locale.getLanguage());
return encoding;
}
-
+
public String getLocaleEncoding (String locale)
{
if (_localeEncodingMap==null)
@@ -1379,13 +1352,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
*/
public Resource getResource(String path) throws MalformedURLException
{
if (path==null || !path.startsWith(URIUtil.SLASH))
throw new MalformedURLException(path);
-
+
if (_baseResource==null)
return null;
@@ -1393,7 +1366,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
path=URIUtil.canonicalPath(path);
Resource resource=_baseResource.addPath(path);
-
+
if (!_aliases && resource.getAlias()!=null)
{
if (resource.exists())
@@ -1402,20 +1375,20 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
Log.debug("Aliased resource: "+resource+"~="+resource.getAlias());
return null;
}
-
+
return resource;
}
catch(Exception e)
{
Log.ignore(e);
}
-
+
return null;
}
/* ------------------------------------------------------------ */
/** Convert URL to Resource
- * wrapper for {@link Resource#newResource(URL)} enables extensions to
+ * wrapper for {@link Resource#newResource(URL)} enables extensions to
* provide alternate resource implementations.
*/
public Resource newResource(URL url) throws IOException
@@ -1425,7 +1398,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
/* ------------------------------------------------------------ */
/** Convert URL to Resource
- * wrapper for {@link Resource#newResource(String)} enables extensions to
+ * wrapper for {@link Resource#newResource(String)} enables extensions to
* provide alternate resource implementations.
*/
public Resource newResource(String url) throws IOException
@@ -1434,20 +1407,20 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
*/
public Set<String> getResourcePaths(String path)
- {
+ {
try
{
path=URIUtil.canonicalPath(path);
Resource resource=getResource(path);
-
+
if (resource!=null && resource.exists())
{
if (!path.endsWith(URIUtil.SLASH))
path=path+URIUtil.SLASH;
-
+
String[] l=resource.list();
if (l!=null)
{
@@ -1455,7 +1428,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
for(int i=0;i<l.length;i++)
set.add(path+l[i]);
return set;
- }
+ }
}
}
catch(Exception e)
@@ -1472,20 +1445,20 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
if ( host == null )
return null;
-
+
if ( host.endsWith( "." ) )
return host.substring( 0, host.length() -1);
-
+
return host;
}
-
+
/* ------------------------------------------------------------ */
/** Context.
* <p>
* A partial implementation of {@link javax.servlet.ServletContext}.
- * A complete implementation is provided by the derived {@link org.eclipse.jetty.servlet.ServletContextHandler.Context}.
+ * A complete implementation is provided by the derived {@link ContextHandler}.
* </p>
- *
+ *
*
*/
public class Context implements ServletContext
@@ -1507,14 +1480,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getContext(java.lang.String)
*/
@Override
public ServletContext getContext(String uripath)
{
- // TODO this is a very poor implementation!
- // TODO move this to Server
ContextHandler context=null;
Handler[] handlers = getServer().getChildHandlersByClass(ContextHandler.class);
for (int i=0;i<handlers.length;i++)
@@ -1523,20 +1494,21 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
continue;
ContextHandler ch = (ContextHandler)handlers[i];
String context_path=ch.getContextPath();
- if (uripath.equals(context_path) || (uripath.startsWith(context_path)&&uripath.charAt(context_path.length())=='/'))
+
+ if (uripath.equals(context_path) || (uripath.startsWith(context_path)&&uripath.charAt(context_path.length())=='/') || "/".equals(context_path))
{
if (context==null || context_path.length()>context.getContextPath().length())
context=ch;
}
}
-
+
if (context!=null)
return context._scontext;
return null;
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getMajorVersion()
*/
@Override
@@ -1547,7 +1519,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getMimeType(java.lang.String)
*/
@Override
@@ -1562,7 +1534,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getMinorVersion()
*/
@Override
@@ -1572,7 +1544,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
*/
@Override
@@ -1582,7 +1554,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
*/
@Override
@@ -1593,7 +1565,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
if (!uriInContext.startsWith("/"))
return null;
-
+
try
{
String query=null;
@@ -1619,7 +1591,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getRealPath(java.lang.String)
*/
@Override
@@ -1631,7 +1603,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
path = URIUtil.SLASH;
else if(path.charAt(0)!='/')
path = URIUtil.SLASH + path;
-
+
try
{
Resource resource=ContextHandler.this.getResource(path);
@@ -1646,7 +1618,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
Log.ignore(e);
}
-
+
return null;
}
@@ -1659,9 +1631,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
return resource.getURL();
return null;
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
*/
@Override
@@ -1682,17 +1654,17 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
*/
@Override
public Set getResourcePaths(String path)
- {
+ {
return ContextHandler.this.getResourcePaths(path);
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServerInfo()
*/
@Override
@@ -1702,7 +1674,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServlet(java.lang.String)
*/
@Override
@@ -1713,7 +1685,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServletNames()
*/
@SuppressWarnings("unchecked")
@@ -1725,7 +1697,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServlets()
*/
@SuppressWarnings("unchecked")
@@ -1737,7 +1709,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String)
*/
@Override
@@ -1747,7 +1719,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#log(java.lang.String)
*/
@Override
@@ -1757,7 +1729,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable)
*/
@Override
@@ -1767,7 +1739,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
*/
@Override
@@ -1777,7 +1749,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getInitParameterNames()
*/
@SuppressWarnings("unchecked")
@@ -1788,7 +1760,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getAttribute(java.lang.String)
*/
@Override
@@ -1801,7 +1773,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getAttributeNames()
*/
@SuppressWarnings("unchecked")
@@ -1818,33 +1790,25 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
Enumeration<String> e = _attributes.getAttributeNames();
while(e.hasMoreElements())
set.add(e.nextElement());
-
+
return Collections.enumeration(set);
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
*/
@Override
public synchronized void setAttribute(String name, Object value)
{
-
- if (_contextAttributes==null)
- {
- // Set it on the handler
- ContextHandler.this.setAttribute(name, value);
- return;
- }
-
- setManagedAttribute(name,value);
+ checkManagedAttribute(name,value);
Object old_value=_contextAttributes.getAttribute(name);
-
+
if (value==null)
_contextAttributes.removeAttribute(name);
else
_contextAttributes.setAttribute(name,value);
-
+
if (_contextAttributeListeners!=null)
{
ServletContextAttributeEvent event =
@@ -1853,7 +1817,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
for(int i=0;i<LazyList.size(_contextAttributeListeners);i++)
{
ServletContextAttributeListener l = (ServletContextAttributeListener)LazyList.get(_contextAttributeListeners,i);
-
+
if (old_value==null)
l.attributeAdded(event);
else if (value==null)
@@ -1865,21 +1829,21 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
*/
@Override
public synchronized void removeAttribute(String name)
{
- setManagedAttribute(name,null);
-
+ checkManagedAttribute(name,null);
+
if (_contextAttributes==null)
{
// Set it on the handler
_attributes.removeAttribute(name);
return;
}
-
+
Object old_value=_contextAttributes.getAttribute(name);
_contextAttributes.removeAttribute(name);
if (old_value!=null)
@@ -1896,7 +1860,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.ServletContext#getServletContextName()
*/
@Override
@@ -1914,7 +1878,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
if ((_contextPath != null) && _contextPath.equals(URIUtil.SLASH))
return "";
-
+
return _contextPath;
}
@@ -2128,7 +2092,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
return _minorVersion;
}
-
public void setEffectiveMajorVersion (int v)
{
_majorVersion = v;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
index c91e067ed3..4972bcf586 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
@@ -33,7 +33,7 @@ import org.eclipse.jetty.util.log.Log;
/** ContextHandlerCollection.
*
* This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a
- * {@link org.eclipse.jetty.http.servlet.PathMap} to it's contained handlers based
+ * {@link org.eclipse.jetty.http.PathMap} to it's contained handlers based
* on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s.
* The contexts do not need to be directly contained, only children of the contained handlers.
* Multiple contexts may have the same context path and they are called in order until one
@@ -265,9 +265,7 @@ public class ContextHandlerCollection extends HandlerCollection
/* ------------------------------------------------------------ */
/** Add a context handler.
* @param contextPath The context path to add
- * @return
- * @throws IllegalAccessException
- * @throws InstantiationException
+ * @return the ContextHandler just added
*/
public ContextHandler addContext(String contextPath,String resourceBase)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
index 232aba637c..073c0dfde9 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
@@ -50,6 +50,7 @@ public class DefaultHandler extends AbstractHandler
final long _faviconModified=(System.currentTimeMillis()/1000)*1000;
byte[] _favicon;
boolean _serveIcon=true;
+ boolean _showContexts=true;
public DefaultHandler()
{
@@ -114,44 +115,47 @@ public class DefaultHandler extends AbstractHandler
writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found");
writer.write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n");
writer.write("No context on this server matched or handled this request.<BR>");
- writer.write("Contexts known to this server are: <ul>");
-
-
- Server server = getServer();
- Handler[] handlers = server==null?null:server.getChildHandlersByClass(ContextHandler.class);
-
- for (int i=0;handlers!=null && i<handlers.length;i++)
+
+ if (_showContexts)
{
- ContextHandler context = (ContextHandler)handlers[i];
- if (context.isRunning())
- {
- writer.write("<li><a href=\"");
- if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
- writer.write("http://"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
- writer.write(context.getContextPath());
- if (context.getContextPath().length()>1 && context.getContextPath().endsWith("/"))
- writer.write("/");
- writer.write("\">");
- writer.write(context.getContextPath());
- if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
- writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
- writer.write("&nbsp;--->&nbsp;");
- writer.write(context.toString());
- writer.write("</a></li>\n");
- }
- else
+ writer.write("Contexts known to this server are: <ul>");
+
+ Server server = getServer();
+ Handler[] handlers = server==null?null:server.getChildHandlersByClass(ContextHandler.class);
+
+ for (int i=0;handlers!=null && i<handlers.length;i++)
{
- writer.write("<li>");
- writer.write(context.getContextPath());
- if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
- writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
- writer.write("&nbsp;--->&nbsp;");
- writer.write(context.toString());
- if (context.isFailed())
- writer.write(" [failed]");
- if (context.isStopped())
- writer.write(" [stopped]");
- writer.write("</li>\n");
+ ContextHandler context = (ContextHandler)handlers[i];
+ if (context.isRunning())
+ {
+ writer.write("<li><a href=\"");
+ if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+ writer.write("http://"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+ writer.write(context.getContextPath());
+ if (context.getContextPath().length()>1 && context.getContextPath().endsWith("/"))
+ writer.write("/");
+ writer.write("\">");
+ writer.write(context.getContextPath());
+ if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+ writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+ writer.write("&nbsp;--->&nbsp;");
+ writer.write(context.toString());
+ writer.write("</a></li>\n");
+ }
+ else
+ {
+ writer.write("<li>");
+ writer.write(context.getContextPath());
+ if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+ writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+ writer.write("&nbsp;--->&nbsp;");
+ writer.write(context.toString());
+ if (context.isFailed())
+ writer.write(" [failed]");
+ if (context.isStopped())
+ writer.write(" [stopped]");
+ writer.write("</li>\n");
+ }
}
}
@@ -183,6 +187,15 @@ public class DefaultHandler extends AbstractHandler
{
_serveIcon = serveIcon;
}
+
+ public boolean getShowContexts()
+ {
+ return _showContexts;
+ }
+ public void setShowContexts(boolean show)
+ {
+ _showContexts = show;
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
index a8dabdaf56..6a422e9be8 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
@@ -27,13 +27,11 @@ import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
-
/* ------------------------------------------------------------ */
/** Handler for Error pages
- * A handler that is registered at the org.eclipse.http.ErrorHandler
- * context attributed and called by the HttpResponse.sendError method to write a
- * error page.
- *
+ * An ErrorHandler is registered with {@link ContextHandler#setErrorHandler(ErrorHandler)} or
+ * {@link org.eclipse.jetty.server.Server#addBean(Object)}.
+ * It is called by the HttpResponse.sendError method to write a error page.
*
*/
public class ErrorHandler extends AbstractHandler
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
index 7746bf5d75..fdb840030e 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
@@ -109,8 +109,8 @@ public class HandlerCollection extends AbstractHandlerContainer
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ /**
+ * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
*/
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java
index c25ab0e18e..35b067f508 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java
@@ -24,15 +24,15 @@ import org.eclipse.jetty.server.Request;
/* ------------------------------------------------------------ */
/** HandlerList.
- * This extension of {@link org.eclipse.jetty.server.server.handler.HandlerCollection} will call
+ * This extension of {@link HandlerCollection} will call
* each contained handler in turn until either an exception is thrown, the response
* is committed or a positive response status is set.
*/
public class HandlerList extends HandlerCollection
{
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ /**
+ * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
index 6ed3d15fdd..ebcaadf9d0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
@@ -14,10 +14,9 @@
package org.eclipse.jetty.server.handler;
import java.io.IOException;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -28,78 +27,150 @@ import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.IPAddressMap;
+import org.eclipse.jetty.util.log.Log;
/**
* IP Access Handler
* <p>
- * Control access to the wrapped handler by the real remote IP.
- * The real IP of the connection is used (not the IP reported in the forwarded for headers),
- * as this cannot be as easily forged.
+ * Controls access to the wrapped handler by the real remote IP. Control is provided
+ * by white/black lists that include both internet addresses and URIs. This handler
+ * uses the real internet address of the connection, not one reported in the forwarded
+ * for headers, as this cannot be as easily forged.
* <p>
- * Control is provided by white/black lists of both internet addresses and URIs.
- * Internet addresses may be absolute (eg 10.1.2.3) or a prefix pattern (eg 10.1.3. ).
- * URI patterns follow the servlet specification for simple prefix and suffix wild cards.
+ * Typically, the black/white lists will be used in one of three modes:
+ * <ul>
+ * <li>Blocking a few specific IPs/URLs by specifying several black list entries.
+ * <li>Allowing only some specific IPs/URLs by specifying several white lists entries.
+ * <li>Allowing a general range of IPs/URLs by specifying several general white list
+ * entries, that are then further refined by several specific black list exceptions
+ * </ul>
* <p>
- * An empty white list is treated as match all. If there is at least one entry in the
- * white list, then a request must match a white list entry. Black list entries are always
- * appied, so that even if an entry matches the white list, a black list entry will override.
+ * An empty white list is treated as match all. If there is at least one entry in
+ * the white list, then a request must match a white list entry. Black list entries
+ * are always applied, so that even if an entry matches the white list, a black list
+ * entry will override it.
+ * <p>
+ * Internet addresses may be specified as absolute address or as a combination of
+ * four octet wildcard specifications (a.b.c.d) that are defined as follows.
* </p>
+ * <pre>
+ * nnn - an absolute value (0-255)
+ * mmm-nnn - an inclusive range of absolute values,
+ * with following shorthand notations:
+ * nnn- => nnn-255
+ * -nnn => 0-nnn
+ * - => 0-255
+ * a,b,... - a list of wildcard specifications
+ * </pre>
+ * <p>
+ * Internet address specification is separated from the URI pattern using the "|" (pipe)
+ * character. URI patterns follow the servlet specification for simple * prefix and
+ * suffix wild cards (e.g. /, /foo, /foo/bar, /foo/bar/*, *.baz).
+ * <p>
+ * Earlier versions of the handler used internet address prefix wildcard specification
+ * to define a range of the internet addresses (e.g. 127., 10.10., 172.16.1.).
+ * They also used the first "/" character of the URI pattern to separate it from the
+ * internet address. Both of these features have been deprecated in the current version.
* <p>
- * Examples of match specifications are:
+ * Examples of the entry specifications are:
* <ul>
- * <li>10.1.2.3 - all requests from IP 10.1.2.3
- * <li>10.1.2.3/foo/bar - all requests from IP 10.1.2.3 to URI /foo/bar
- * <li>10.1.2.3/foo/* - all requests from IP 10.1.2.3 to URIs starting with /foo/
- * <li>10.1.2.3/*.html - all requests from IP 10.1.2.3 to URIs ending with .html
- * <li>10.1. - all requests from IPs starting with 10.1.
- * <li>10.1./foo/bar - all requests from IPs starting with 10.1. to URI /foo/bar
- * <li>10.1./foo/* - all requests from IPs starting with 10.1. to URIs starting with /foo/
+ * <li>10.10.1.2 - all requests from IP 10.10.1.2
+ * <li>10.10.1.2|/foo/bar - all requests from IP 10.10.1.2 to URI /foo/bar
+ * <li>10.10.1.2|/foo/* - all requests from IP 10.10.1.2 to URIs starting with /foo/
+ * <li>10.10.1.2|*.html - all requests from IP 10.10.1.2 to URIs ending with .html
+ * <li>10.10.0-255.0-255 - all requests from IPs within 10.10.0.0/16 subnet
+ * <li>10.10.0-.-255|/foo/bar - all requests from IPs within 10.10.0.0/16 subnet to URI /foo/bar
+ * <li>10.10.0-3,1,3,7,15|/foo/* - all requests from IPs addresses with last octet equal
+ * to 1,3,7,15 in subnet 10.10.0.0/22 to URIs starting with /foo/
* </ul>
* <p>
- * Typically, the black/white lists will be used in one of three modes:
- * <nl>
- * <li>Blocking a few specific IPs/URLs by specifying several black list entries.
- * <li>Allowing only some specific IPs/URLs by specifying several white lists entries.
- * <li>Allowing a general range of IPs/URLs by specifying serveral general white list
- * entries, that are then further refined by several specific black list exceptions
- * </ul>
- *
+ * Earlier versions of the handler used internet address prefix wildcard specification
+ * to define a range of the internet addresses (e.g. 127., 10.10., 172.16.1.).
+ * They also used the first "/" character of the URI pattern to separate it from the
+ * internet address. Both of these features have been deprecated in the current version.
*/
public class IPAccessHandler extends HandlerWrapper
{
- Map<String,PathMap> _whiteAddr = new HashMap<String, PathMap>();
- List<String> _whitePattern = new CopyOnWriteArrayList<String>();
- Map<String,PathMap> _blackAddr = new HashMap<String, PathMap>();
- List<String> _blackPattern = new CopyOnWriteArrayList<String>();
-
+ IPAddressMap<PathMap> _white = new IPAddressMap<PathMap>();
+ IPAddressMap<PathMap> _black = new IPAddressMap<PathMap>();
+
+ /* ------------------------------------------------------------ */
/**
+ * Creates new handler object
*/
public IPAccessHandler()
{
+ super();
}
- public void addBlack(String addrPath)
+ /* ------------------------------------------------------------ */
+ /**
+ * Creates new handler object and initializes white- and black-list
+ *
+ * @param white array of whitelist entries
+ * @param black array of blacklist entries
+ */
+ public IPAccessHandler(String[] white, String []black)
{
- add(addrPath, _blackAddr, _blackPattern);
+ super();
+
+ if (white != null && white.length > 0)
+ setWhite(white);
+ if (black != null && black.length > 0)
+ setBlack(black);
}
- public void addWhite(String addrPath)
+ /* ------------------------------------------------------------ */
+ /**
+ * Add a whitelist entry to an existing handler configuration
+ *
+ * @param entry new whitelist entry
+ */
+ public void addWhite(String entry)
{
- add(addrPath, _whiteAddr, _whitePattern);
+ add(entry, _white);
}
- public void setBlack(String[] addrPaths)
+ /* ------------------------------------------------------------ */
+ /**
+ * Add a blacklist entry to an existing handler configuration
+ *
+ * @param entry new blacklist entry
+ */
+ public void addBlack(String entry)
+ {
+ add(entry, _black);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Re-initialize the whitelist of existing handler object
+ *
+ * @param entries array of whitelist entries
+ */
+ public void setWhite(String[] entries)
{
- set(addrPaths, _blackAddr, _blackPattern);
+ set(entries, _white);
}
- public void setWhite(String[] addrPaths)
+ /* ------------------------------------------------------------ */
+ /**
+ * Re-initialize the blacklist of existing handler object
+ *
+ * @param entries array of blacklist entries
+ */
+ public void setBlack(String[] entries)
{
- set(addrPaths, _whiteAddr, _whitePattern);
+ set(entries, _black);
}
+ /* ------------------------------------------------------------ */
/**
+ * Checks the incoming request against the whitelist and blacklist
+ *
+ * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
@@ -123,78 +194,181 @@ public class IPAccessHandler extends HandlerWrapper
getHandler().handle(target,baseRequest, request, response);
}
+
- protected void add(String addrPath, Map<String,PathMap> addrMap, List<String> patternList)
+ /* ------------------------------------------------------------ */
+ /**
+ * Helper method to parse the new entry and add it to
+ * the specified address pattern map.
+ *
+ * @param entry new entry
+ * @param patternMap target address pattern map
+ */
+ protected void add(String entry, IPAddressMap<PathMap> patternMap)
{
- int idx = addrPath.indexOf('/');
- String addr = idx > 0 ? addrPath.substring(0,idx) : addrPath;
- String path = idx > 0 ? addrPath.substring(idx) : null;
- if (path!=null && path.length()>1 && path.charAt(1)=='*')
- path=path.substring(1);
-
- PathMap map = addrMap.get(addr);
- if (map==null)
+ if (entry != null && entry.length() > 0)
{
- map = new PathMap(true);
- addrMap.put(addr,map);
+ boolean deprecated = false;
+ int idx;
+ if (entry.indexOf('|') > 0 )
+ {
+ idx = entry.indexOf('|');
+ }
+ else
+ {
+ idx = entry.indexOf('/');
+ deprecated = (idx >= 0);
+ }
+
+ String addr = idx > 0 ? entry.substring(0,idx) : entry;
+ String path = idx > 0 ? entry.substring(idx) : "/*";
+
if (addr.endsWith("."))
- patternList.add(addr);
+ deprecated = true;
+ if (path!=null && (path.startsWith("|") || path.startsWith("/*.")))
+ path=path.substring(1);
+
+ PathMap pathMap = patternMap.get(addr);
+ if (pathMap == null)
+ {
+ pathMap = new PathMap(true);
+ patternMap.put(addr,pathMap);
+ }
+ if (path != null)
+ pathMap.put(path,path);
+
+ if (deprecated)
+ Log.debug(toString() +" - deprecated specification syntax: "+entry);
}
-
- if (path != null)
- map.put(path,path);
}
- protected void set(String[] addrPaths, Map<String,PathMap> addrMap, List<String> patternList)
+ /* ------------------------------------------------------------ */
+ /**
+ * Helper method to process a list of new entries and replace
+ * the content of the specified address pattern map
+ *
+ * @param entries new entries
+ * @param patternMap target address pattern map
+ */
+ protected void set(String[] entries, IPAddressMap<PathMap> patternMap)
{
- addrMap.clear();
- patternList.clear();
- for (String addrPath:addrPaths)
- add(addrPath, addrMap, patternList);
+ patternMap.clear();
+
+ if (entries != null && entries.length > 0)
+ {
+ for (String addrPath:entries)
+ {
+ add(addrPath, patternMap);
+ }
+ }
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Check if specified request is allowed by current IPAccess rules.
+ *
+ * @param addr internet address
+ * @param path context path
+ * @return true if request is allowed
+ *
+ */
protected boolean isAddrUriAllowed(String addr, String path)
{
- if (_whiteAddr.size()>0)
+ if (_white.size()>0)
{
- PathMap white=_whiteAddr.get(addr);
+ boolean match = false;
- if (white==null || (white.size()>0 && white.match(path)==null))
+ Object whiteObj = _white.getLazyMatches(addr);
+ if (whiteObj != null)
{
- boolean match=false;
- for (String pattern:_whitePattern)
+ List whiteList = (whiteObj instanceof List) ? (List)whiteObj : Collections.singletonList(whiteObj);
+
+ for (Object entry: whiteList)
{
- if (addr.startsWith(pattern))
- {
- white=_whiteAddr.get(pattern);
- if (white!=null && white.size()>0 && white.match(path)!=null)
- {
- match=true;
- break;
- }
- }
+ PathMap pathMap = ((Map.Entry<String,PathMap>)entry).getValue();
+ if (match = (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null)))
+ break;
}
- if (!match)
- return false;
}
+
+ if (!match)
+ return false;
}
- PathMap black=_blackAddr.get(addr);
- if (black!=null && (black.size()==0 || black.match(path)!=null))
- return false;
-
- for (String pattern:_blackPattern)
+ if (_black.size() > 0)
{
- if (addr.startsWith(pattern))
+ Object blackObj = _black.getLazyMatches(addr);
+ if (blackObj != null)
{
- black=_blackAddr.get(pattern);
- if (black!=null && black.match(path)!=null)
- return false;
- break;
+ List blackList = (blackObj instanceof List) ? (List)blackObj : Collections.singletonList(blackObj);
+
+ for (Object entry: blackList)
+ {
+ PathMap pathMap = ((Map.Entry<String,PathMap>)entry).getValue();
+ if (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null))
+ return false;
+ }
}
}
return true;
}
-}
+ /* ------------------------------------------------------------ */
+ /**
+ * Dump the white- and black-list configurations when started
+ *
+ * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
+ */
+ @Override
+ protected void doStart()
+ throws Exception
+ {
+ super.doStart();
+
+ if (Log.isDebugEnabled())
+ {
+ System.err.println(dump());
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Dump the handler configuration
+ */
+ public String dump()
+ {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append(toString());
+ buf.append(" WHITELIST:\n");
+ dump(buf, _white);
+ buf.append(toString());
+ buf.append(" BLACKLIST:\n");
+ dump(buf, _black);
+
+ return buf.toString();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Dump a pattern map into a StringBuilder buffer
+ *
+ * @param buf buffer
+ * @param patternMap pattern map to dump
+ */
+ protected void dump(StringBuilder buf, IPAddressMap<PathMap> patternMap)
+ {
+ for (String addr: patternMap.keySet())
+ {
+ for (Object path: ((PathMap)patternMap.get(addr)).values())
+ {
+ buf.append("# ");
+ buf.append(addr);
+ buf.append("|");
+ buf.append(path);
+ buf.append("\n");
+ }
+ }
+ }
+ }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxyHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxyHandler.java
new file mode 100644
index 0000000000..60ad6d10de
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxyHandler.java
@@ -0,0 +1,847 @@
+package org.eclipse.jetty.server.handler;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.HostMap;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/**
+ * <p>Implementation of a tunneling proxy that supports HTTP CONNECT and transparent proxy.</p>
+ * <p>To work as CONNECT proxy, objects of this class must be instantiated using the no-arguments
+ * constructor, since the remote server information will be present in the CONNECT URI.</p>
+ * <p>To work as transparent proxy, objects of this class must be instantiated using the string
+ * argument constructor, passing the remote host address and port in the form {@code host:port}.</p>
+ *
+ * @version $Revision$ $Date$
+ */
+public class ProxyHandler extends HandlerWrapper
+{
+ private final Logger _logger = Log.getLogger(getClass().getName());
+ private final SelectorManager _selectorManager = new Manager();
+ private volatile int _connectTimeout = 5000;
+ private volatile int _writeTimeout = 30000;
+ private volatile ThreadPool _threadPool;
+ private volatile boolean _privateThreadPool;
+ private HostMap<String> _white = new HostMap<String>();
+ private HostMap<String> _black = new HostMap<String>();
+
+ public ProxyHandler()
+ {
+ this(null);
+ }
+
+ public ProxyHandler(String[] white, String[] black)
+ {
+ this(null, white, black);
+ }
+
+ public ProxyHandler(Handler handler)
+ {
+ setHandler(handler);
+ }
+
+ public ProxyHandler(Handler handler, String[] white, String[] black)
+ {
+ setHandler(handler);
+ set(white, _white);
+ set(black, _black);
+ }
+
+ /**
+ * @return the timeout, in milliseconds, to connect to the remote server
+ */
+ public int getConnectTimeout()
+ {
+ return _connectTimeout;
+ }
+
+ /**
+ * @param connectTimeout the timeout, in milliseconds, to connect to the remote server
+ */
+ public void setConnectTimeout(int connectTimeout)
+ {
+ _connectTimeout = connectTimeout;
+ }
+
+ /**
+ * @return the timeout, in milliseconds, to write data to a peer
+ */
+ public int getWriteTimeout()
+ {
+ return _writeTimeout;
+ }
+
+ /**
+ * @param writeTimeout the timeout, in milliseconds, to write data to a peer
+ */
+ public void setWriteTimeout(int writeTimeout)
+ {
+ _writeTimeout = writeTimeout;
+ }
+
+ @Override
+ public void setServer(Server server)
+ {
+ super.setServer(server);
+
+ server.getContainer().update(this,null,_selectorManager,"selectManager");
+
+ if (_privateThreadPool)
+ server.getContainer().update(this,null,_privateThreadPool,"threadpool",true);
+ else
+ _threadPool=server.getThreadPool();
+ }
+
+ /**
+ * @return the thread pool
+ */
+ public ThreadPool getThreadPool()
+ {
+ return _threadPool;
+ }
+
+ /**
+ * @param threadPool the thread pool
+ */
+ public void setThreadPool(ThreadPool threadPool)
+ {
+ if (getServer()!=null)
+ getServer().getContainer().update(this,_privateThreadPool?_threadPool:null,threadPool,"threadpool",true);
+ _privateThreadPool=threadPool!=null;
+ _threadPool=threadPool;
+ }
+
+ @Override
+ protected void doStart() throws Exception
+ {
+ super.doStart();
+
+ if (_threadPool==null)
+ {
+ _threadPool=getServer().getThreadPool();
+ _privateThreadPool=false;
+ }
+ if (_threadPool instanceof LifeCycle && !((LifeCycle)_threadPool).isRunning())
+ ((LifeCycle)_threadPool).start();
+
+ _selectorManager.start();
+ _threadPool.dispatch(new Runnable()
+ {
+ public void run()
+ {
+ while (isRunning())
+ {
+ try
+ {
+ _selectorManager.doSelect(0);
+ }
+ catch (IOException x)
+ {
+ _logger.warn("Unexpected exception", x);
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void doStop() throws Exception
+ {
+ _selectorManager.stop();
+
+ ThreadPool threadPool = _threadPool;
+ if (_privateThreadPool && _threadPool != null && threadPool instanceof LifeCycle)
+ ((LifeCycle)threadPool).stop();
+
+ super.doStop();
+ }
+
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ if (HttpMethods.CONNECT.equalsIgnoreCase(request.getMethod()))
+ {
+ _logger.debug("CONNECT request for {}", request.getRequestURI());
+ handleConnect(baseRequest, request, response, request.getRequestURI());
+ }
+ else
+ {
+ super.handle(target, baseRequest, request, response);
+ }
+ }
+
+ /**
+ * <p>Handles a CONNECT request.</p>
+ * <p>CONNECT requests may have authentication headers such as <code>Proxy-Authorization</code>
+ * that authenticate the client with the proxy.</p>
+ *
+ * @param baseRequest Jetty-specific http request
+ * @param request the http request
+ * @param response the http response
+ * @param serverAddress the remote server address in the form {@code host:port}
+ * @throws ServletException if an application error occurs
+ * @throws IOException if an I/O error occurs
+ */
+ protected void handleConnect(Request baseRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) throws ServletException, IOException
+ {
+ boolean proceed = handleAuthentication(request, response, serverAddress);
+ if (!proceed)
+ return;
+
+ String host = serverAddress;
+ int port = 80;
+ int colon = serverAddress.indexOf(':');
+ if (colon > 0)
+ {
+ host = serverAddress.substring(0, colon);
+ port = Integer.parseInt(serverAddress.substring(colon + 1));
+ }
+
+ if (!validateDestination(host))
+ {
+ Log.info("ProxyHandler: Forbidden destination "+host);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ baseRequest.setHandled(true);
+ return;
+ }
+
+ SocketChannel channel = connectToServer(request, host, port);
+
+ // Transfer unread data from old connection to new connection
+ // We need to copy the data to avoid races:
+ // 1. when this unread data is written and the server replies before the clientToProxy
+ // connection is installed (it is only installed after returning from this method)
+ // 2. when the client sends data before this unread data has been written.
+ HttpConnection httpConnection = HttpConnection.getCurrentConnection();
+ Buffer headerBuffer = ((HttpParser)httpConnection.getParser()).getHeaderBuffer();
+ Buffer bodyBuffer = ((HttpParser)httpConnection.getParser()).getBodyBuffer();
+ int length = headerBuffer == null ? 0 : headerBuffer.length();
+ length += bodyBuffer == null ? 0 : bodyBuffer.length();
+ IndirectNIOBuffer buffer = null;
+ if (length > 0)
+ {
+ buffer = new IndirectNIOBuffer(length);
+ if (headerBuffer != null)
+ {
+ buffer.put(headerBuffer);
+ headerBuffer.clear();
+ }
+ if (bodyBuffer != null)
+ {
+ buffer.put(bodyBuffer);
+ bodyBuffer.clear();
+ }
+ }
+
+ ConcurrentMap<String, Object> context = new ConcurrentHashMap<String, Object>();
+ prepareContext(request, context);
+
+ ClientToProxyConnection clientToProxy = prepareConnections(context, channel, buffer);
+
+ // CONNECT expects a 200 response
+ response.setStatus(HttpServletResponse.SC_OK);
+
+ // Prevent close
+ baseRequest.getConnection().getGenerator().setPersistent(true);
+
+ // Close to force last flush it so that the client receives it
+ response.getOutputStream().close();
+
+ upgradeConnection(request, response, clientToProxy);
+ }
+
+ private ClientToProxyConnection prepareConnections(ConcurrentMap<String, Object> context, SocketChannel channel, Buffer buffer)
+ {
+ HttpConnection httpConnection = HttpConnection.getCurrentConnection();
+ ProxyToServerConnection proxyToServer = newProxyToServerConnection(context, buffer);
+ ClientToProxyConnection clientToProxy = newClientToProxyConnection(context, channel, httpConnection.getEndPoint(), httpConnection.getTimeStamp());
+ clientToProxy.setConnection(proxyToServer);
+ proxyToServer.setConnection(clientToProxy);
+ return clientToProxy;
+ }
+
+ /**
+ * <p>Handles the authentication before setting up the tunnel to the remote server.</p>
+ * <p>The default implementation returns true.</p>
+ *
+ * @param request the HTTP request
+ * @param response the HTTP response
+ * @param address the address of the remote server in the form {@code host:port}.
+ * @return true to allow to connect to the remote host, false otherwise
+ * @throws ServletException to report a server error to the caller
+ * @throws IOException to report a server error to the caller
+ */
+ protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) throws ServletException, IOException
+ {
+ return true;
+ }
+
+ protected ClientToProxyConnection newClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timeStamp)
+ {
+ return new ClientToProxyConnection(context, channel, endPoint, timeStamp);
+ }
+
+ protected ProxyToServerConnection newProxyToServerConnection(ConcurrentMap<String, Object> context, Buffer buffer)
+ {
+ return new ProxyToServerConnection(context, buffer);
+ }
+
+ private SocketChannel connectToServer(HttpServletRequest request, String host, int port) throws IOException
+ {
+ SocketChannel channel = connect(request, host, port);
+ channel.configureBlocking(false);
+ return channel;
+ }
+
+ /**
+ * <p>Establishes a connection to the remote server.</p>
+ * @param request the HTTP request that initiated the tunnel
+ * @param host the host to connect to
+ * @param port the port to connect to
+ * @return a {@link SocketChannel} connected to the remote server
+ * @throws IOException if the connection cannot be established
+ */
+ protected SocketChannel connect(HttpServletRequest request, String host, int port) throws IOException
+ {
+ _logger.debug("Establishing connection to {}:{}", host, port);
+ // Connect to remote server
+ SocketChannel channel = SocketChannel.open();
+ channel.socket().setTcpNoDelay(true);
+ channel.socket().connect(new InetSocketAddress(host, port), getConnectTimeout());
+ _logger.debug("Established connection to {}:{}", host, port);
+ return channel;
+ }
+
+ protected void prepareContext(HttpServletRequest request, ConcurrentMap<String, Object> context)
+ {
+ }
+
+ private void upgradeConnection(HttpServletRequest request, HttpServletResponse response, Connection connection) throws IOException
+ {
+ // Set the new connection as request attribute and change the status to 101
+ // so that Jetty understands that it has to upgrade the connection
+ request.setAttribute("org.eclipse.jetty.io.Connection", connection);
+ response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
+ _logger.debug("Upgraded connection to {}", connection);
+ }
+
+ private void register(SocketChannel channel, ProxyToServerConnection proxyToServer) throws IOException
+ {
+ _selectorManager.register(channel, proxyToServer);
+ proxyToServer.waitReady(_connectTimeout);
+ }
+
+ /**
+ * <p>Reads (with non-blocking semantic) into the given {@code buffer} from the given {@code endPoint}.</p>
+ * @param endPoint the endPoint to read from
+ * @param buffer the buffer to read data into
+ * @param context the context information related to the connection
+ * @return the number of bytes read (possibly 0 since the read is non-blocking)
+ * or -1 if the channel has been closed remotely
+ * @throws IOException if the endPoint cannot be read
+ */
+ protected int read(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+ {
+ return endPoint.fill(buffer);
+ }
+
+ /**
+ * <p>Writes (with blocking semantic) the given buffer of data onto the given endPoint.</p>
+ *
+ * @param endPoint the endPoint to write to
+ * @param buffer the buffer to write
+ * @param context the context information related to the connection
+ * @throws IOException if the buffer cannot be written
+ * @return the number of bytes written
+ */
+ protected int write(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+ {
+ if (buffer == null)
+ return 0;
+
+ int length = buffer.length();
+ StringBuilder builder = new StringBuilder();
+ int written = endPoint.flush(buffer);
+ builder.append(written);
+ buffer.compact();
+ if (!endPoint.isBlocking())
+ {
+ while (buffer.space() == 0)
+ {
+ boolean ready = endPoint.blockWritable(getWriteTimeout());
+ if (!ready)
+ throw new IOException("Write timeout");
+
+ written = endPoint.flush(buffer);
+ builder.append("+").append(written);
+ buffer.compact();
+ }
+ }
+ _logger.debug("Written {}/{} bytes {}", builder, length, endPoint);
+ return length;
+ }
+
+ private class Manager extends SelectorManager
+ {
+ @Override
+ protected SocketChannel acceptChannel(SelectionKey key) throws IOException
+ {
+ // This is a client-side selector manager
+ throw new IllegalStateException();
+ }
+
+ @Override
+ protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey selectionKey) throws IOException
+ {
+ return new SelectChannelEndPoint(channel, selectSet, selectionKey);
+ }
+
+ @Override
+ protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
+ {
+ ProxyToServerConnection proxyToServer = (ProxyToServerConnection)endpoint.getSelectionKey().attachment();
+ proxyToServer.setTimeStamp(System.currentTimeMillis());
+ proxyToServer.setEndPoint(endpoint);
+ return proxyToServer;
+ }
+
+ @Override
+ protected void endPointOpened(SelectChannelEndPoint endpoint)
+ {
+ ProxyToServerConnection proxyToServer = (ProxyToServerConnection)endpoint.getSelectionKey().attachment();
+ proxyToServer.ready();
+ }
+
+ @Override
+ public boolean dispatch(Runnable task)
+ {
+ return _threadPool.dispatch(task);
+ }
+
+ @Override
+ protected void endPointClosed(SelectChannelEndPoint endpoint)
+ {
+ }
+
+ @Override
+ protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
+ {
+ }
+ }
+
+ public class ProxyToServerConnection implements Connection
+ {
+ private final CountDownLatch _ready = new CountDownLatch(1);
+ private final Buffer _buffer = new IndirectNIOBuffer(1024);
+ private final ConcurrentMap<String, Object> _context;
+ private volatile Buffer _data;
+ private volatile ClientToProxyConnection _toClient;
+ private volatile long _timestamp;
+ private volatile SelectChannelEndPoint _endPoint;
+
+ public ProxyToServerConnection(ConcurrentMap<String, Object> context, Buffer data)
+ {
+ _context = context;
+ _data = data;
+ }
+
+ public Connection handle() throws IOException
+ {
+ _logger.debug("ProxyToServer: begin reading from server");
+ try
+ {
+ if (_data != null)
+ {
+ int written = write(_endPoint, _data, _context);
+ _logger.debug("ProxyToServer: written to server {} bytes", written);
+ _data = null;
+ }
+
+ while (true)
+ {
+ int read = read(_endPoint, _buffer, _context);
+
+ if (read == -1)
+ {
+ _logger.debug("ProxyToServer: server closed connection {}", _endPoint);
+ close();
+ break;
+ }
+
+ if (read == 0)
+ break;
+
+ _logger.debug("ProxyToServer: read from server {} bytes {}", read, _endPoint);
+ int written = write(_toClient._endPoint, _buffer, _context);
+ _logger.debug("ProxyToServer: written to client {} bytes", written);
+ }
+ return this;
+ }
+ catch (IOException x)
+ {
+ _logger.warn("ProxyToServer: Unexpected exception", x);
+ close();
+ throw x;
+ }
+ catch (RuntimeException x)
+ {
+ _logger.warn("ProxyToServer: Unexpected exception", x);
+ close();
+ throw x;
+ }
+ finally
+ {
+ _logger.debug("ProxyToServer: end reading from server");
+ }
+ }
+
+ public void setConnection(ClientToProxyConnection connection)
+ {
+ _toClient = connection;
+ }
+
+ public long getTimeStamp()
+ {
+ return _timestamp;
+ }
+
+ public void setTimeStamp(long timestamp)
+ {
+ _timestamp = timestamp;
+ }
+
+ public void setEndPoint(SelectChannelEndPoint endpoint)
+ {
+ _endPoint = endpoint;
+ _logger.debug("ProxyToServer: {}", _endPoint);
+ }
+
+ public boolean isIdle()
+ {
+ return false;
+ }
+
+ public boolean isSuspended()
+ {
+ return false;
+ }
+
+ public void ready()
+ {
+ _ready.countDown();
+ }
+
+ public void waitReady(long timeout) throws IOException
+ {
+ try
+ {
+ _ready.await(timeout, TimeUnit.MILLISECONDS);
+ }
+ catch (final InterruptedException x)
+ {
+ throw new IOException(){{initCause(x);}};
+ }
+ }
+
+ public void closeClient() throws IOException
+ {
+ _toClient.closeClient();
+ }
+
+ public void closeServer() throws IOException
+ {
+ _endPoint.close();
+ }
+
+ public void close()
+ {
+ try
+ {
+ closeClient();
+ }
+ catch (IOException x)
+ {
+ _logger.debug("ProxyToServer: Unexpected exception closing the client", x);
+ }
+
+ try
+ {
+ closeServer();
+ }
+ catch (IOException x)
+ {
+ _logger.debug("ProxyToServer: Unexpected exception closing the server", x);
+ }
+ }
+ }
+
+ public class ClientToProxyConnection implements Connection
+ {
+ private final Buffer _buffer = new IndirectNIOBuffer(1024);
+ private final ConcurrentMap<String, Object> _context;
+ private final SocketChannel _channel;
+ private final EndPoint _endPoint;
+ private final long _timestamp;
+ private volatile ProxyToServerConnection _toServer;
+ private boolean _firstTime = true;
+
+ public ClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timestamp)
+ {
+ _context = context;
+ _channel = channel;
+ _endPoint = endPoint;
+ _timestamp = timestamp;
+ _logger.debug("ClientToProxy: {}", _endPoint);
+ }
+
+ public Connection handle() throws IOException
+ {
+ _logger.debug("ClientToProxy: begin reading from client");
+ try
+ {
+ if (_firstTime)
+ {
+ _firstTime = false;
+ register(_channel, _toServer);
+ _logger.debug("ClientToProxy: registered channel {} with connection {}", _channel, _toServer);
+ }
+
+ while (true)
+ {
+ int read = read(_endPoint, _buffer, _context);
+
+ if (read == -1)
+ {
+ _logger.debug("ClientToProxy: client closed connection {}", _endPoint);
+ close();
+ break;
+ }
+
+ if (read == 0)
+ break;
+
+ _logger.debug("ClientToProxy: read from client {} bytes {}", read, _endPoint);
+ int written = write(_toServer._endPoint, _buffer, _context);
+ _logger.debug("ClientToProxy: written to server {} bytes", written);
+ }
+ return this;
+ }
+ catch (ClosedChannelException x)
+ {
+ _logger.debug("ClientToProxy",x);
+ closeServer();
+ throw x;
+ }
+ catch (IOException x)
+ {
+ _logger.warn("ClientToProxy", x);
+ close();
+ throw x;
+ }
+ catch (RuntimeException x)
+ {
+ _logger.warn("ClientToProxy", x);
+ close();
+ throw x;
+ }
+ finally
+ {
+ _logger.debug("ClientToProxy: end reading from client");
+ }
+ }
+
+ public long getTimeStamp()
+ {
+ return _timestamp;
+ }
+
+ public boolean isIdle()
+ {
+ return false;
+ }
+
+ public boolean isSuspended()
+ {
+ return false;
+ }
+
+ public void setConnection(ProxyToServerConnection connection)
+ {
+ _toServer = connection;
+ }
+
+ public void closeClient() throws IOException
+ {
+ _endPoint.close();
+ }
+
+ public void closeServer() throws IOException
+ {
+ _toServer.closeServer();
+ }
+
+ public void close()
+ {
+ try
+ {
+ closeClient();
+ }
+ catch (IOException x)
+ {
+ _logger.debug("ClientToProxy: Unexpected exception closing the client", x);
+ }
+
+ try
+ {
+ closeServer();
+ }
+ catch (IOException x)
+ {
+ _logger.debug("ClientToProxy: Unexpected exception closing the server", x);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Add a whitelist entry to an existing handler configuration
+ *
+ * @param entry new whitelist entry
+ */
+ public void addWhite(String entry)
+ {
+ add(entry, _white);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Add a blacklist entry to an existing handler configuration
+ *
+ * @param entry new blacklist entry
+ */
+ public void addBlack(String entry)
+ {
+ add(entry, _black);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Re-initialize the whitelist of existing handler object
+ *
+ * @param entries array of whitelist entries
+ */
+ public void setWhite(String[] entries)
+ {
+ set(entries, _white);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Re-initialize the blacklist of existing handler object
+ *
+ * @param entries array of blacklist entries
+ */
+ public void setBlack(String[] entries)
+ {
+ set(entries, _black);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Helper method to process a list of new entries and replace
+ * the content of the specified host map
+ *
+ * @param entries new entries
+ * @param patternMap target host map
+ */
+ protected void set(String[] entries, HostMap<String> hostMap)
+ {
+ hostMap.clear();
+
+ if (entries != null && entries.length > 0)
+ {
+ for (String addrPath:entries)
+ {
+ add(addrPath, hostMap);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Helper method to process the new entry and add it to
+ * the specified host map.
+ *
+ * @param entry new entry
+ * @param patternMap target host map
+ */
+ private void add(String entry, HostMap<String> hostMap)
+ {
+ if (entry != null && entry.length() > 0)
+ {
+ entry = entry.trim();
+ if (hostMap.get(entry) == null)
+ {
+ hostMap.put(entry,entry);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Check the request hostname against white- and blacklist.
+ *
+ * @param host hostname to check
+ * @return true if hostname is allowed to be proxied
+ */
+ public boolean validateDestination(String host)
+ {
+ if (_white.size()>0)
+ {
+ Object whiteObj = _white.getLazyMatches(host);
+ if (whiteObj == null)
+ {
+ return false;
+ }
+ }
+
+ if (_black.size() > 0)
+ {
+ Object blackObj = _black.getLazyMatches(host);
+ if (blackObj != null)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
index 61d949da32..76ee4391a0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
@@ -20,6 +20,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.AsyncContinuation;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Response;
@@ -47,9 +48,24 @@ public class RequestLogHandler extends HandlerWrapper
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
- super.handle(target, baseRequest, request, response);
- if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) && _requestLog!=null)
- _requestLog.log((Request)request, (Response)response);
+ AsyncContinuation continuation = baseRequest.getAsyncContinuation();
+ if (!continuation.isInitial())
+ {
+ baseRequest.setDispatchTime(System.currentTimeMillis());
+ }
+
+ try
+ {
+ super.handle(target, baseRequest, request, response);
+ }
+ finally
+ {
+ if (_requestLog != null && DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
+ {
+ _requestLog.log(baseRequest, (Response)response);
+ }
+
+ }
}
/* ------------------------------------------------------------ */
@@ -131,6 +147,5 @@ public class RequestLogHandler extends HandlerWrapper
if (_requestLog!=null)
_requestLog.stop();
}
-
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index 2bbc84f93d..51ba08e04a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
@@ -16,7 +16,6 @@ package org.eclipse.jetty.server.handler;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -33,7 +32,6 @@ import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.FileResource;
@@ -42,12 +40,12 @@ import org.eclipse.jetty.util.resource.Resource;
/* ------------------------------------------------------------ */
/** Resource Handler.
- *
+ *
* This handle will serve static content and handle If-Modified-Since headers.
* No caching is done.
* Requests that cannot be handled are let pass (Eg no 404's)
- *
- *
+ *
+ *
* @org.apache.xbean.XBean
*/
public class ResourceHandler extends AbstractHandler
@@ -90,7 +88,7 @@ public class ResourceHandler extends AbstractHandler
/**
* Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed.
* Allowing aliases can significantly increase security vulnerabilities.
- * If this handler is deployed inside a ContextHandler, then the
+ * If this handler is deployed inside a ContextHandler, then the
* {@link ContextHandler#isAliases()} takes precedent.
* @param aliases True if aliases are supported.
*/
@@ -124,13 +122,13 @@ public class ResourceHandler extends AbstractHandler
{
Context scontext = ContextHandler.getCurrentContext();
_context = (scontext==null?null:scontext.getContextHandler());
-
+
if (_context!=null)
_aliases=_context.isAliases();
-
+
if (!_aliases && !FileResource.getCheckAliases())
throw new IllegalStateException("Alias checking disabled");
-
+
super.doStart();
}
@@ -156,12 +154,12 @@ public class ResourceHandler extends AbstractHandler
return _baseResource.toString();
}
-
+
/* ------------------------------------------------------------ */
/**
* @param base The resourceBase to set.
*/
- public void setBaseResource(Resource base)
+ public void setBaseResource(Resource base)
{
_baseResource=base;
}
@@ -170,7 +168,7 @@ public class ResourceHandler extends AbstractHandler
/**
* @param resourceBase The base resource as a string.
*/
- public void setResourceBase(String resourceBase)
+ public void setResourceBase(String resourceBase)
{
try
{
@@ -203,18 +201,18 @@ public class ResourceHandler extends AbstractHandler
}
/* ------------------------------------------------------------ */
- /*
+ /*
*/
public Resource getResource(String path) throws MalformedURLException
{
if (path==null || !path.startsWith("/"))
throw new MalformedURLException(path);
-
+
Resource base = _baseResource;
if (base==null)
{
if (_context==null)
- return null;
+ return null;
base=_context.getBaseResource();
if (base==null)
return null;
@@ -229,7 +227,7 @@ public class ResourceHandler extends AbstractHandler
{
Log.ignore(e);
}
-
+
return null;
}
@@ -254,7 +252,7 @@ public class ResourceHandler extends AbstractHandler
{
_welcomeFiles=welcomeFiles;
}
-
+
/* ------------------------------------------------------------ */
protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
{
@@ -269,14 +267,14 @@ public class ResourceHandler extends AbstractHandler
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
*/
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if (baseRequest.isHandled())
return;
-
+
boolean skipContentBody = false;
if(!HttpMethods.GET.equals(request.getMethod()))
{
@@ -284,9 +282,9 @@ public class ResourceHandler extends AbstractHandler
return;
skipContentBody = true;
}
-
+
Resource resource=getResource(request);
-
+
if (resource==null || !resource.exists())
return;
if (!_aliases && resource.getAlias()!=null)
@@ -297,7 +295,7 @@ public class ResourceHandler extends AbstractHandler
// We are going to server something
baseRequest.setHandled(true);
-
+
if (resource.isDirectory())
{
if (!request.getPathInfo().endsWith(URIUtil.SLASH))
@@ -305,7 +303,7 @@ public class ResourceHandler extends AbstractHandler
response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)));
return;
}
-
+
Resource welcome=getWelcome(resource);
if (welcome!=null && welcome.exists())
resource=welcome;
@@ -316,7 +314,7 @@ public class ResourceHandler extends AbstractHandler
return;
}
}
-
+
// set some headers
long last_modified=resource.lastModified();
if (last_modified>0)
@@ -328,11 +326,11 @@ public class ResourceHandler extends AbstractHandler
return;
}
}
-
+
Buffer mime=_mimeTypes.getMimeByExtension(resource.toString());
if (mime==null)
mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
-
+
// set the headers
doResponseHeaders(response,resource,mime!=null?mime.toString():null);
response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified);
@@ -342,7 +340,7 @@ public class ResourceHandler extends AbstractHandler
OutputStream out =null;
try {out = response.getOutputStream();}
catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
-
+
// See if a short direct method can be used?
if (out instanceof HttpConnection.Output)
{
@@ -369,7 +367,7 @@ public class ResourceHandler extends AbstractHandler
else
response.sendError(HttpStatus.FORBIDDEN_403);
}
-
+
/* ------------------------------------------------------------ */
/** Set the response headers.
* This method is called to set the response headers such as content type and content length.
@@ -384,25 +382,25 @@ public class ResourceHandler extends AbstractHandler
response.setContentType(mimeType);
long length=resource.length();
-
+
if (response instanceof Response)
{
HttpFields fields = ((Response)response).getHttpFields();
if (length>0)
fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length);
-
+
if (_cacheControl!=null)
fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
}
else
{
if (length>0)
- response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(length));
-
+ response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length));
+
if (_cacheControl!=null)
response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
}
-
+
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java
index ae3154c3b7..d4ff318c7a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java
@@ -134,7 +134,7 @@ public abstract class ScopedHandler extends HandlerWrapper
throws IOException, ServletException
{
// this method has been manually inlined in several locations, but
- // is called protected by an in(false), so your IDE can find those
+ // is called protected by an if(never()), so your IDE can find those
// locations if this code is changed.
if (_nextScope!=null)
_nextScope.doScope(target,baseRequest,request, response);
@@ -158,7 +158,7 @@ public abstract class ScopedHandler extends HandlerWrapper
public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
// this method has been manually inlined in several locations, but
- // is called protected by an in(false), so your IDE can find those
+ // is called protected by an if(never()), so your IDE can find those
// locations if this code is changed.
if (_nextScope!=null && _nextScope==_handler)
_nextScope.doHandle(target,baseRequest,request, response);
@@ -166,4 +166,10 @@ public abstract class ScopedHandler extends HandlerWrapper
_handler.handle(target,baseRequest, request, response);
}
+ /* ------------------------------------------------------------ */
+ protected boolean never()
+ {
+ return false;
+ }
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
index 1973e0a4d0..3927cb1caf 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
@@ -100,14 +100,8 @@ public class BlockingChannelConnector extends AbstractNIOConnector
public void customize(EndPoint endpoint, Request request)
throws IOException
{
- ConnectorEndPoint connection = (ConnectorEndPoint)endpoint;
- if (connection._sotimeout!=_maxIdleTime)
- {
- connection._sotimeout=_maxIdleTime;
- ((SocketChannel)endpoint.getTransport()).socket().setSoTimeout(_maxIdleTime);
- }
-
super.customize(endpoint, request);
+ endpoint.setMaxIdleTime(_maxIdleTime);
configure(((SocketChannel)endpoint.getTransport()).socket());
}
@@ -130,12 +124,12 @@ public class BlockingChannelConnector extends AbstractNIOConnector
int _sotimeout;
ConnectorEndPoint(ByteChannel channel)
+ throws IOException
{
- super(channel);
+ super(channel,BlockingChannelConnector.this._maxIdleTime);
_connection = new HttpConnection(BlockingChannelConnector.this,this,getServer());
}
-
/* ------------------------------------------------------------ */
/** Get the connection.
* @return the connection
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
index 175bf6e176..40cb4f7fa0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.nio;
@@ -20,6 +20,7 @@ import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
@@ -44,27 +45,25 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
* This connector is best used when there are a many connections that have idle periods.
* </p>
* <p>
- * When used with {@link org.eclipse.jetty.util.ajax.Continuation}, threadless waits are supported. When
- * a filter or servlet calls getEvent on a Continuation, a {@link org.eclipse.jetty.server.RetryRequest}
- * runtime exception is thrown to allow the thread to exit the current request handling. Jetty will
- * catch this exception and will not send a response to the client. Instead the thread is released
- * and the Continuation is placed on the timer queue. If the Continuation timeout expires, or it's
+ * When used with {@link org.eclipse.jetty.continuation.Continuation}, threadless waits are supported.
+ * If a filter or servlet returns after calling {@link Continuation#suspend()} or when a
+ * runtime exception is thrown from a call to {@link Continuation#undispatch()}, Jetty will
+ * will not send a response to the client. Instead the thread is released and the Continuation is
+ * placed on the timer queue. If the Continuation timeout expires, or it's
* resume method is called, then the request is again allocated a thread and the request is retried.
* The limitation of this approach is that request content is not available on the retried request,
* thus if possible it should be read after the continuation or saved as a request attribute or as the
* associated object of the Continuation instance.
* </p>
- *
- * @org.apache.xbean.XBean element="nioConnector" description="Creates an NIO based socket connector"
- *
- *
*
+ * @org.apache.xbean.XBean element="nioConnector" description="Creates an NIO based socket connector"
*/
-public class SelectChannelConnector extends AbstractNIOConnector
+public class SelectChannelConnector extends AbstractNIOConnector
{
protected ServerSocketChannel _acceptChannel;
private int _lowResourcesConnections;
private int _lowResourcesMaxIdleTime;
+ private int _localPort=-1;
private final SelectorManager _manager = new SelectorManager()
{
@@ -99,7 +98,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
// TODO handle max connections and low resources
connectionOpened(endpoint.getConnection());
}
-
+
@Override
protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
{
@@ -118,23 +117,23 @@ public class SelectChannelConnector extends AbstractNIOConnector
return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
}
};
-
+
/* ------------------------------------------------------------------------------- */
/**
* Constructor.
- *
+ *
*/
public SelectChannelConnector()
{
}
-
+
/* ------------------------------------------------------------ */
@Override
public void accept(int acceptorID) throws IOException
{
_manager.doSelect(acceptorID);
}
-
+
/* ------------------------------------------------------------ */
public void close() throws IOException
{
@@ -154,9 +153,10 @@ public class SelectChannelConnector extends AbstractNIOConnector
if (_acceptChannel != null)
_acceptChannel.close();
_acceptChannel = null;
+ _localPort=-2;
}
}
-
+
/* ------------------------------------------------------------------------------- */
@Override
public void customize(EndPoint endpoint, Request request) throws IOException
@@ -166,7 +166,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
request.setTimeStamp(cep.getSelectSet().getNow());
super.customize(endpoint, request);
}
-
+
/* ------------------------------------------------------------------------------- */
@Override
public void persist(EndPoint endpoint) throws IOException
@@ -186,9 +186,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
{
synchronized(this)
{
- if (_acceptChannel==null || !_acceptChannel.isOpen())
- return -1;
- return _acceptChannel.socket().getLocalPort();
+ return _localPort;
}
}
@@ -209,12 +207,13 @@ public class SelectChannelConnector extends AbstractNIOConnector
InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort());
_acceptChannel.socket().bind(addr,getAcceptQueueSize());
- if (_acceptChannel.socket().getLocalPort()==-1)
+ _localPort=_acceptChannel.socket().getLocalPort();
+ if (_localPort<=0)
throw new IOException("Server channel not bound");
-
+
// Set to non blocking mode
_acceptChannel.configureBlocking(false);
-
+
}
}
}
@@ -241,7 +240,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
* Set the number of connections, which if exceeded places this manager in low resources state.
* This is not an exact measure as the connection count is averaged over the select sets.
* @param lowResourcesConnections the number of connections
- * @see {@link #setLowResourcesMaxIdleTime(int)}
+ * @see #setLowResourcesMaxIdleTime(int)
*/
public void setLowResourcesConnections(int lowResourcesConnections)
{
@@ -264,16 +263,16 @@ public class SelectChannelConnector extends AbstractNIOConnector
* than {@link #getLowResourcesConnections()} connections. This allows the server to rapidly close idle connections
* in order to gracefully handle high load situations.
* @param lowResourcesMaxIdleTime the period in ms that a connection is allowed to be idle when resources are low.
- * @see {@link #setMaxIdleTime(long)}
+ * @see #setMaxIdleTime(int)
*/
@Override
public void setLowResourcesMaxIdleTime(int lowResourcesMaxIdleTime)
{
_lowResourcesMaxIdleTime=lowResourcesMaxIdleTime;
- super.setLowResourcesMaxIdleTime(lowResourcesMaxIdleTime);
+ super.setLowResourcesMaxIdleTime(lowResourcesMaxIdleTime);
}
-
+
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.server.server.AbstractConnector#doStart()
@@ -297,7 +296,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
*/
@Override
protected void doStop() throws Exception
- {
+ {
super.doStop();
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
index f4a2ff6fff..0f7a305a0e 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
@@ -56,12 +56,9 @@ import org.eclipse.jetty.util.statistic.SampleStatistic;
* SessionManager interface provides the majority of the handling required to
* implement a SessionManager. Concrete implementations of SessionManager based
* on AbstractSessionManager need only implement the newSession method to return
- * a specialized version of the Session inner class that provides an attribute
+ * a specialised version of the Session inner class that provides an attribute
* Map.
* <p>
- * If the property
- * org.eclipse.jetty.servlet.AbstractSessionManager.23Notifications is set to
- * true, the 2.3 servlet spec notification style will be used.
*
*/
public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
@@ -97,7 +94,8 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
protected int _maxCookieAge=-1;
protected int _refreshCookieAge;
protected boolean _nodeIdInSessionId;
-
+ protected boolean _checkingRemoteSessionIdEncoding;
+ protected String _sessionComment;
public Set<SessionTrackingMode> _sessionTrackingModes;
@@ -128,7 +126,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
)
)
{
- HttpCookie cookie=getSessionCookie(session,_context.getContextPath(),secure);
+ HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure);
s.cookieSet();
s.setIdChanged(false);
return cookie;
@@ -209,6 +207,10 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
// set up the sessionPath if it isn't already
if (_sessionPath==null)
_sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty);
+
+ tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding);
+ if (tmp!=null)
+ _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
}
super.doStart();
@@ -226,6 +228,15 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
}
/* ------------------------------------------------------------ */
+ /**
+ * @return Returns the httpOnly.
+ */
+ public boolean getHttpOnly()
+ {
+ return _httpOnly;
+ }
+
+ /* ------------------------------------------------------------ */
public HttpSession getHttpSession(String nodeId)
{
String cluster_id = getIdManager().getClusterId(nodeId);
@@ -261,7 +272,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/* ------------------------------------------------------------ */
/**
- * @see getSessionsMax()
+ * @see #getSessionsMax()
*/
@Deprecated
public int getMaxSessions()
@@ -299,7 +310,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/* ------------------------------------------------------------ */
/**
- * @see getSessionsMin()
+ * @deprecated always returns 0. no replacement available.
*/
@Deprecated
public int getMinSessions()
@@ -318,16 +329,35 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
{
if (isUsingCookies())
{
+ String sessionPath = (_sessionPath==null) ? contextPath : _sessionPath;
+ sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
String id = getNodeId(session);
- HttpCookie cookie=new HttpCookie(
- _sessionCookie,
- id,
- _sessionDomain,
- (contextPath==null||contextPath.length()==0)?"/":contextPath,
- _cookieConfig.getMaxAge(),
- _cookieConfig.isHttpOnly(),
- requestIsSecure&&_cookieConfig.isSecure());
-
+ HttpCookie cookie = null;
+ if (_sessionComment == null)
+ {
+ cookie = new HttpCookie(
+ _sessionCookie,
+ id,
+ _sessionDomain,
+ sessionPath,
+ _cookieConfig.getMaxAge(),
+ _cookieConfig.isHttpOnly(),
+ _cookieConfig.isSecure());
+ }
+ else
+ {
+ cookie = new HttpCookie(
+ _sessionCookie,
+ id,
+ _sessionDomain,
+ sessionPath,
+ _cookieConfig.getMaxAge(),
+ _cookieConfig.isHttpOnly(),
+ _cookieConfig.isSecure(),
+ _sessionComment,
+ 1);
+ }
+
return cookie;
}
return null;
@@ -344,7 +374,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/* ------------------------------------------------------------ */
/**
- * @deprecated. Need to review if it is needed.
+ * @deprecated Need to review if it is needed.
*/
public abstract Map getSessionMap();
@@ -410,7 +440,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/* ------------------------------------------------------------ */
/**
- * @see statsReset()
+ * @see #statsReset()
*/
@Deprecated
public void resetStats()
@@ -530,7 +560,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/**
* Create a new session instance
* @param request
- * @return
+ * @return the new session
*/
protected abstract Session newSession(HttpServletRequest request);
@@ -671,7 +701,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
@Override
public String getComment()
{
- return null;
+ return _sessionComment;
}
@Override
@@ -713,7 +743,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
@Override
public void setComment(String comment)
{
- // TODO
+ _sessionComment = comment;
}
@Override
@@ -784,6 +814,24 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
/* ------------------------------------------------------------ */
/**
+ * @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
+ */
+ public boolean isCheckingRemoteSessionIdEncoding()
+ {
+ return _checkingRemoteSessionIdEncoding;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
+ */
+ public void setCheckingRemoteSessionIdEncoding(boolean remote)
+ {
+ _checkingRemoteSessionIdEncoding=remote;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
* Null returning implementation of HttpSessionContext
*
*
@@ -830,12 +878,10 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
}
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
/**
*
* <p>
- * Implements {@link javax.servlet.HttpSession} from the {@link javax.servlet} package.
+ * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
* </p>
*
*
@@ -1047,10 +1093,13 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
// Notify listeners and unbind values
synchronized (this)
{
- if (_requests<=0)
- doInvalidate();
- else
- _doInvalidate=true;
+ if (!_invalid)
+ {
+ if (_requests<=0)
+ doInvalidate();
+ else
+ _doInvalidate=true;
+ }
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
index bf227dd885..830cbfc7c5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
@@ -48,6 +48,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager
/* ------------------------------------------------------------ */
/** Get the session ID with any worker ID.
*
+ * @param clusterId
* @param request
* @return sessionId plus any worker ID.
*/
@@ -66,7 +67,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager
/* ------------------------------------------------------------ */
/** Get the session ID without any worker ID.
*
- * @param request
+ * @param nodeId the node id
* @return sessionId without any worker ID.
*/
public String getClusterId(String nodeId)
@@ -94,8 +95,8 @@ public class HashSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.SessionManager.MetaManager#idInUse(java.lang.String)
+ /**
+ * @see SessionIdManager#idInUse(String)
*/
public boolean idInUse(String id)
{
@@ -103,8 +104,8 @@ public class HashSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.SessionManager.MetaManager#addSession(javax.servlet.http.HttpSession)
+ /**
+ * @see SessionIdManager#addSession(HttpSession)
*/
public void addSession(HttpSession session)
{
@@ -112,8 +113,8 @@ public class HashSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.SessionManager.MetaManager#addSession(javax.servlet.http.HttpSession)
+ /**
+ * @see SessionIdManager#removeSession(HttpSession)
*/
public void removeSession(HttpSession session)
{
@@ -121,8 +122,8 @@ public class HashSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.server.SessionManager.MetaManager#invalidateAll(java.lang.String)
+ /**
+ * @see SessionIdManager#invalidateAll(String)
*/
public void invalidateAll(String id)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 50633acbc4..5452362a4d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -112,7 +112,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
* depending on the way the db stores identifiers.
*
* @param identifier
- * @return
+ * @return the converted identifier
*/
public String convertIdentifier (String identifier)
{
@@ -387,8 +387,6 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
*
* Makes necessary database tables and starts a Session
* scavenger thread.
- *
- * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStart()
*/
@Override
public void doStart()
@@ -410,8 +408,6 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
/**
* Stop the scavenger.
- *
- * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
@Override
public void doStop ()
@@ -431,7 +427,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
/**
* Get a connection from the driver or datasource.
*
- * @return
+ * @return the connection for the datasource
* @throws SQLException
*/
protected Connection getConnection ()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
index 0ddfd131d8..ecb226fe9b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -52,15 +52,15 @@ import org.eclipse.jetty.util.log.Log;
* contextPath (of the context owning the session)
* sessionId (unique in a context)
* lastNode (name of node last handled session)
- * accessTime (time in ms session was accessed)
- * lastAccessTime (previous time in ms session was accessed)
- * createTime (time in ms session created)
- * cookieTime (time in ms session cookie created)
- * lastSavedTime (last time in ms session access times were saved)
- * expiryTime (time in ms that the session is due to expire)
+ * accessTime (time in milliseconds session was accessed)
+ * lastAccessTime (previous time in milliseconds session was accessed)
+ * createTime (time in milliseconds session created)
+ * cookieTime (time in milliseconds session cookie created)
+ * lastSavedTime (last time in milliseconds session access times were saved)
+ * expiryTime (time in milliseconds that the session is due to expire)
* map (attribute map)
*
- * As an optimisation, to prevent thrashing the database, we do not persist
+ * As an optimization, to prevent thrashing the database, we do not persist
* the accessTime and lastAccessTime every time the session is accessed. Rather,
* we write it out every so often. The frequency is controlled by the saveIntervalSec
* field.
@@ -274,7 +274,7 @@ public class JDBCSessionManager extends AbstractSessionManager
/**
* Session restored in database.
- * @param row
+ * @param data
*/
protected Session (SessionData data)
{
@@ -442,7 +442,7 @@ public class JDBCSessionManager extends AbstractSessionManager
* This could be used eg with a JMS backplane to notify nodes
* that the session has changed and to delete the session from
* the node's cache, and re-read it from the database.
- * @param idInCluster
+ * @param session
*/
public void cacheInvalidate (Session session)
{
@@ -540,8 +540,6 @@ public class JDBCSessionManager extends AbstractSessionManager
/**
* Get all the sessions as a map of id to Session.
- *
- * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessionMap()
*/
@Override
public Map getSessionMap()
@@ -817,7 +815,7 @@ public class JDBCSessionManager extends AbstractSessionManager
/**
* Load a session from the database
* @param id
- * @return
+ * @return the session data that was loaded
* @throws Exception
*/
protected SessionData loadSession (String id, String canonicalContextPath, String vhost)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
index 746a2999d8..0272e8c11f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
@@ -35,9 +35,6 @@ import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
/** SessionHandler.
- *
- *
- *
*/
public class SessionHandler extends ScopedHandler
{
@@ -224,8 +221,7 @@ public class SessionHandler extends ScopedHandler
throws IOException, ServletException
{
// start manual inline of nextHandle(target,baseRequest,request,response);
- //noinspection ConstantIfStatement
- if (false)
+ if (never())
nextHandle(target,baseRequest,request,response);
else if (_nextScope!=null && _nextScope==_handler)
_nextScope.doHandle(target,baseRequest,request, response);
@@ -236,8 +232,8 @@ public class SessionHandler extends ScopedHandler
/* ------------------------------------------------------------ */
/** Look for a requested session ID in cookies and URI parameters
+ * @param baseRequest
* @param request
- * @param dispatch
*/
protected void setRequestedId(Request baseRequest, HttpServletRequest request)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslCertificates.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslCertificates.java
index 94803ab856..25b1ac7dda 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslCertificates.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslCertificates.java
@@ -10,9 +10,9 @@ import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.http.HttpSchemes;
-import org.eclipse.jetty.http.ssl.SslSelectChannelEndPoint;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
index f40159f08a..71bb96de93 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
@@ -13,14 +13,12 @@
package org.eclipse.jetty.server.ssl;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.security.KeyStore;
import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -29,7 +27,6 @@ import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
@@ -38,7 +35,6 @@ import javax.net.ssl.TrustManagerFactory;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.security.Password;
-import org.eclipse.jetty.http.ssl.SslSelectChannelEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Connection;
@@ -47,11 +43,11 @@ import org.eclipse.jetty.io.ThreadLocalBuffers;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
@@ -471,7 +467,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
/* ------------------------------------------------------------ */
/**
- * @throws Exception
* @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
*/
public SSLContext getSslContext()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
index 0d7fb53bff..ca99861cd9 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
@@ -137,7 +137,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
Socket socket = _serverSocket.accept();
configure(socket);
- ConnectorEndPoint connection=new SslConnection(socket);
+ ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
connection.dispatch();
}
@@ -205,14 +205,10 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
try
{
if (keystorePath!=null)
- {
keystoreInputStream = Resource.newResource(keystorePath).getInputStream();
- keystore=KeyStore.getInstance(keystoreType);
- keystore.load(keystoreInputStream,keystorePassword==null?null:keystorePassword.toString().toCharArray());
- return keystore;
- }
-
- return null;
+ keystore=KeyStore.getInstance(keystoreType);
+ keystore.load(keystoreInputStream,keystorePassword==null?null:keystorePassword.toString().toCharArray());
+ return keystore;
}
finally
{
@@ -363,13 +359,13 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
/* ------------------------------------------------------------ */
/**
- * @param addr The {@link SocketAddress address} that this server should listen on
+ * @param host The host name that this server should listen on
+ * @param port the port that this server should listen on
* @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
* @return A new {@link ServerSocket socket object} bound to the supplied address with all other
* settings as per the current configuration of this connector.
- * @see #setWantClientAuth
- * @see #setNeedClientAuth
- * @see #setCipherSuites
+ * @see #setWantClientAuth(boolean)
+ * @see #setNeedClientAuth(boolean)
* @exception IOException
*/
@@ -411,10 +407,10 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
excludedCSList = new ArrayList<String>();
}
String[] enabledCipherSuites = socket.getEnabledCipherSuites();
- List<String> enabledCSList=Arrays.asList(enabledCipherSuites);
+ List<String> enabledCSList = new ArrayList<String>(Arrays.asList(enabledCipherSuites));
String[] supportedCipherSuites = socket.getSupportedCipherSuites();
- List<String> supportedCSList=Arrays.asList(supportedCipherSuites);
+ List<String> supportedCSList = Arrays.asList(supportedCipherSuites);
for (String cipherName : includedCSList)
{
@@ -432,7 +428,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
enabledCSList.remove(cipherName);
}
}
- enabledCipherSuites=enabledCSList.toArray(new String[0]);
+ enabledCipherSuites = enabledCSList.toArray(new String[enabledCSList.size()]);
socket.setEnabledCipherSuites(enabledCipherSuites);
}
@@ -557,7 +553,6 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
/* ------------------------------------------------------------ */
/**
- * @throws Exception
* @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
*/
public SSLContext getSslContext()
@@ -577,10 +572,10 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
/* ------------------------------------------------------------ */
/**
- * Set the value of the _wantClientAuth property. This property is used when
- * {@link #newServerSocket(SocketAddress, int) opening server sockets}.
+ * Set the value of the _wantClientAuth property. This property is used
+ * internally when opening server sockets.
*
- * @param wantClientAuth true iff we want client certificate authentication.
+ * @param wantClientAuth true if we want client certificate authentication.
* @see SSLServerSocket#setWantClientAuth
*/
public void setWantClientAuth(boolean wantClientAuth)
@@ -607,14 +602,19 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
}
/* ------------------------------------------------------------ */
- public class SslConnection extends ConnectorEndPoint
+ public class SslConnectorEndPoint extends ConnectorEndPoint
{
- public SslConnection(Socket socket) throws IOException
+ public SslConnectorEndPoint(Socket socket) throws IOException
{
super(socket);
}
@Override
+ public void shutdownOutput() throws IOException
+ {
+ }
+
+ @Override
public void run()
{
try
@@ -667,7 +667,8 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
/* ------------------------------------------------------------ */
/**
* Unsupported.
- * @see org.eclipse.jetty.server.ssl.SslConnector#getAlgorithm()
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
*/
public String getAlgorithm()
{
@@ -677,7 +678,8 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
/* ------------------------------------------------------------ */
/**
* Unsupported.
- * @see org.eclipse.jetty.server.ssl.SslConnector#setAlgorithm(java.lang.String)
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
*/
public void setAlgorithm(String algorithm)
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
index 5fe8d82a8a..bc782a162b 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
@@ -20,184 +20,189 @@ import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
-public class AbstractConnectorTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class AbstractConnectorTest
{
- private Server _server;
- private Handler _handler;
- private AbstractConnector _connector;
-
- private String _request = "GET / HTTP/1.1\r\n" +
- "Host: localhost\r\n" +
- "\r\n";
+ private static Server _server;
+ private static AbstractConnector _connector;
+ private static CyclicBarrier _connect;
+ private static CountDownLatch _closed;
+
private Socket[] _socket;
private PrintWriter[] _out;
private BufferedReader[] _in;
-
- private CyclicBarrier _connect;
- private CountDownLatch _closed;
- @Override
- protected void setUp() throws Exception
+ @BeforeClass
+ public static void init() throws Exception
{
_connect = new CyclicBarrier(2);
_server = new Server();
+ _connector = new SelectChannelConnector()
+ {
+ public void connectionClosed(Connection connection)
+ {
+ super.connectionClosed(connection);
+ _closed.countDown();
+ }
- _connector =
- new SelectChannelConnector() {
- public void connectionClosed(Connection connection)
- {
- super.connectionClosed(connection);
- _closed.countDown();
- }
-
- };
- _server.addConnector(_connector);
+ };
_connector.setStatsOn(true);
+ _server.addConnector(_connector);
- HandlerWrapper wrapper =
- new HandlerWrapper() {
- public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
+ HandlerWrapper wrapper = new HandlerWrapper()
+ {
+ public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
+ {
+ try
+ {
+ _connect.await();
+ }
+ catch (Exception ex)
{
- try
- {
- _connect.await();
- }
- catch (Exception ex)
- {
- Log.debug(ex);
- }
- finally
- {
- super.handle(path, request, httpRequest, httpResponse);
- }
+ Log.debug(ex);
}
- };
- _server.setHandler(wrapper);
-
- _handler =
- new AbstractHandler() {
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException
+ finally
{
- baseRequest.setHandled(true);
-
- PrintWriter out = response.getWriter();
- out.write("Server response\n");
- out.close();
-
- response.setStatus(HttpServletResponse.SC_OK);
+ super.handle(path, request, httpRequest, httpResponse);
}
- };
- wrapper.setHandler(_handler);
-
+ }
+ };
+ _server.setHandler(wrapper);
+
+ Handler handler = new AbstractHandler()
+ {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+
+ PrintWriter out = response.getWriter();
+ out.write("Server response\n");
+ out.close();
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+ };
+ wrapper.setHandler(handler);
+
_server.start();
}
- @Override
- protected void tearDown() throws Exception
+ @AfterClass
+ public static void destroy() throws Exception
{
_server.stop();
_server.join();
}
- public void testSingleRequest()
- throws Exception
+ @Before
+ public void reset()
{
- doInit(1);
+ _connector.statsReset();
+ }
+
+ @Test
+ public void testSingleRequest() throws Exception
+ {
+ int connections = 1;
+ doInit(connections);
sendRequest(1, 1);
-
- doClose(1);
-
- assertEquals(1, _connector.getConnections());
+
+ doClose(connections);
+
+ assertEquals(connections, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
- assertEquals(1, _connector.getConnectionsOpenMax());
+ assertEquals(connections, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
-
+
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
-
+
assertEquals(1, _connector.getRequests());
- assertEquals(1.0, _connector.getConnectionsRequestsMean());
+ assertEquals(1.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(1, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
-
- public void testMultipleRequests()
- throws Exception
+
+ @Test
+ public void testMultipleRequests() throws Exception
{
doInit(1);
-
+
sendRequest(1, 1);
sendRequest(1, 1);
doClose(1);
-
+
assertEquals(1, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
assertEquals(1, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
-
+
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
-
+
assertEquals(2, _connector.getRequests());
- assertEquals(2.0, _connector.getConnectionsRequestsMean());
+ assertEquals(2.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(2, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
-
- public void testMultipleConnections()
- throws Exception
+
+ @Test
+ public void testMultipleConnections() throws Exception
{
doInit(3);
-
+
sendRequest(1, 1); // request 1 connection 1
-
+
sendRequest(2, 2); // request 1 connection 2
-
+
sendRequest(3, 3); // request 1 connection 3
-
+
sendRequest(2, 3); // request 2 connection 2
-
+
sendRequest(3, 3); // request 2 connection 3
-
+
sendRequest(3, 3); // request 3 connection 3
-
+
doClose(3);
assertEquals(3, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
assertEquals(3, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
-
+
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
-
+
assertEquals(6, _connector.getRequests());
- assertEquals(2.0, _connector.getConnectionsRequestsMean());
+ assertEquals(2.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(3, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
-
+
protected void doInit(int count)
{
_socket = new Socket[count];
@@ -206,9 +211,8 @@ public class AbstractConnectorTest extends TestCase
_closed = new CountDownLatch(count);
}
-
- protected void doClose(int count)
- throws Exception
+
+ private void doClose(int count) throws Exception
{
for (int idx=0; idx < count; idx++)
{
@@ -217,35 +221,34 @@ public class AbstractConnectorTest extends TestCase
if (_in[idx] != null)
_in[idx].close();
-
+
if (_socket[idx] != null)
_socket[idx].close();
}
-
+
_closed.await();
}
-
- protected void sendRequest(int id, int count)
- throws Exception
+
+ private void sendRequest(int id, int count) throws Exception
{
int idx = id - 1;
-
+
if (idx < 0)
throw new IllegalArgumentException("Connection ID <= 0");
-
+
_socket[idx] = _socket[idx] == null ? new Socket("localhost", _connector.getLocalPort()) : _socket[idx];
_out[idx] = _out[idx] == null ? new PrintWriter(_socket[idx].getOutputStream(), true) : _out[idx];
_in[idx] = _in[idx] == null ? new BufferedReader(new InputStreamReader(_socket[idx].getInputStream())) : _in[idx];
-
+
_connect.reset();
-
- _out[idx].write(_request);
+
+ _out[idx].write("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
_out[idx].flush();
-
+
_connect.await();
-
+
assertEquals(count, _connector.getConnectionsOpen());
-
+
while(_in[idx].ready())
{
_in[idx].readLine();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java
index 1fa5eab57e..22ddb943c2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger;
-
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
@@ -25,40 +24,47 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class AsyncContextTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class AsyncContextTest
{
protected Server _server = new Server();
protected SuspendHandler _handler = new SuspendHandler();
protected LocalConnector _connector;
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_connector = new LocalConnector();
_server.setConnectors(new Connector[]{ _connector });
-
+
SessionHandler session = new SessionHandler();
session.setHandler(_handler);
-
+
_server.setHandler(session);
_server.start();
}
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
_server.stop();
+ _server.join();
}
- public void testOneCycle() throws Exception
+ @Test
+ public void testSuspendResume() throws Exception
{
String response;
-
__completed.set(0);
__completed1.set(0);
_handler.setRead(0);
@@ -113,7 +119,6 @@ public class AsyncContextTest extends TestCase
response=process("wibble");
check(response,"COMPLETED");
-
_handler.setRead(6);
_handler.setResumeAfter(0);
@@ -171,7 +176,7 @@ public class AsyncContextTest extends TestCase
}
- public synchronized String process(String content) throws Exception
+ private synchronized String process(String content) throws Exception
{
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n";
@@ -194,8 +199,8 @@ public class AsyncContextTest extends TestCase
private long _completeAfter2=-1;
public SuspendHandler()
- {}
-
+ {
+ }
public int getRead()
{
@@ -508,7 +513,6 @@ public class AsyncContextTest extends TestCase
public void onError(AsyncEvent event) throws IOException
{
}
-
@Override
public void onStartAsync(AsyncEvent event) throws IOException
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java
index b4d5cafba6..8f51db579d 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java
@@ -4,24 +4,22 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InputStream;
-import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
-
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
@@ -30,8 +28,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.server.handler.HandlerWrapper;
@@ -39,8 +35,13 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class AsyncStressTest extends TestCase
+import static org.junit.Assert.assertEquals;
+
+public class AsyncStressTest
{
protected Server _server = new Server();
protected SuspendHandler _handler = new SuspendHandler();
@@ -50,9 +51,18 @@ public class AsyncStressTest extends TestCase
protected Random _random = new Random();
protected QueuedThreadPool _threads=new QueuedThreadPool();
protected boolean _stress;
+ private final static String[][] __paths =
+ {
+ {"/path","NORMAL"},
+ {"/path/info","NORMAL"},
+ {"/path?sleep=<PERIOD>","SLEPT"},
+ {"/path?suspend=<PERIOD>","TIMEOUT"},
+ {"/path?suspend=60000&resume=<PERIOD>","RESUMED"},
+ {"/path?suspend=60000&complete=<PERIOD>","COMPLETED"},
+ };
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_stress= Boolean.getBoolean("STRESS");
_threads.setMaxThreads(50);
@@ -66,23 +76,28 @@ public class AsyncStressTest extends TestCase
_addr=InetAddress.getLocalHost();
}
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
_server.stop();
+ _server.join();
}
- final static String[][] __paths =
+ @Test
+ public void testAsync() throws Throwable
{
- {"/path","NORMAL"},
- {"/path/info","NORMAL"},
- {"/path?sleep=<PERIOD>","SLEPT"},
- {"/path?suspend=<PERIOD>","TIMEOUT"},
- {"/path?suspend=60000&resume=<PERIOD>","RESUMED"},
- {"/path?suspend=60000&complete=<PERIOD>","COMPLETED"},
- };
-
- public void doConnections(int connections,final int loops) throws Throwable
+ if (_stress)
+ {
+ System.err.println("STRESS!");
+ doConnections(1600,240);
+ }
+ else
+ {
+ doConnections(80,80);
+ }
+ }
+
+ private void doConnections(int connections,final int loops) throws Throwable
{
Socket[] socket = new Socket[connections];
int [][] path = new int[connections][loops];
@@ -109,13 +124,13 @@ public class AsyncStressTest extends TestCase
String uri=__paths[p][0].replace("<PERIOD>",Integer.toString(period));
long start=System.currentTimeMillis();
- String request =
- "GET "+uri+" HTTP/1.1\r\n"+
- "Host: localhost\r\n"+
- "start: "+start+"\r\n"+
- "result: "+__paths[p][1]+"\r\n"+
- ((l+1<loops)?"":"Connection: close\r\n")+
- "\r\n";
+ String request =
+ "GET "+uri+" HTTP/1.1\r\n"+
+ "Host: localhost\r\n"+
+ "start: "+start+"\r\n"+
+ "result: "+__paths[p][1]+"\r\n"+
+ ((l+1<loops)?"":"Connection: close\r\n")+
+ "\r\n";
socket[i].getOutputStream().write(request.getBytes("UTF-8"));
socket[i].getOutputStream().flush();
}
@@ -127,7 +142,7 @@ public class AsyncStressTest extends TestCase
System.err.println();
Log.info("Sent "+(loops*__paths.length)+" requests");
-
+
String[] results=new String[connections];
for (int i=0;i<connections;i++)
{
@@ -141,14 +156,14 @@ public class AsyncStressTest extends TestCase
Log.info("Read "+connections+" connections");
for (int i=0;i<connections;i++)
- {
+ {
int offset=0;
String result=results[i];
for (int l=0;l<loops;l++)
{
String expect = __paths[path[i][l]][1];
expect=expect+" "+expect;
-
+
offset=result.indexOf("200 OK",offset)+6;
offset=result.indexOf("\r\n\r\n",offset)+4;
int end=result.indexOf("\n",offset);
@@ -159,28 +174,15 @@ public class AsyncStressTest extends TestCase
}
}
- public void testAsync() throws Throwable
- {
- if (_stress)
- {
- System.err.println("STRESS!");
- doConnections(1600,240);
- }
- else
- {
- doConnections(80,80);
- }
- }
-
private static class SuspendHandler extends HandlerWrapper
{
private final Timer _timer;
-
- public SuspendHandler()
+
+ private SuspendHandler()
{
_timer=new Timer();
}
-
+
@Override
public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
@@ -189,9 +191,9 @@ public class AsyncStressTest extends TestCase
long suspend_for=-1;
long resume_after=-1;
long complete_after=-1;
-
+
final String uri=baseRequest.getUri().toString();
-
+
if (request.getParameter("read")!=null)
read_before=Integer.parseInt(request.getParameter("read"));
if (request.getParameter("sleep")!=null)
@@ -202,7 +204,7 @@ public class AsyncStressTest extends TestCase
resume_after=Integer.parseInt(request.getParameter("resume"));
if (request.getParameter("complete")!=null)
complete_after=Integer.parseInt(request.getParameter("complete"));
-
+
if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
{
if (read_before>0)
@@ -224,7 +226,6 @@ public class AsyncStressTest extends TestCase
asyncContext.addListener(__asyncListener);
if (suspend_for>0)
asyncContext.setTimeout(suspend_for);
-
if (complete_after>0)
{
TimerTask complete = new TimerTask()
@@ -246,7 +247,7 @@ public class AsyncStressTest extends TestCase
System.err.println(baseRequest+"=="+br);
System.err.println(uri+"=="+br.getUri());
System.err.println(asyncContext+"=="+br.getAsyncContinuation());
-
+
Log.warn(e);
System.exit(1);
}
@@ -283,7 +284,7 @@ public class AsyncStressTest extends TestCase
{
asyncContext.dispatch();
}
-
+
}
else if (sleep_for>=0)
{
@@ -298,14 +299,12 @@ public class AsyncStressTest extends TestCase
response.setStatus(200);
response.getOutputStream().println("SLEPT "+request.getHeader("result"));
baseRequest.setHandled(true);
- return;
}
else
{
response.setStatus(200);
response.getOutputStream().println("NORMAL "+request.getHeader("result"));
baseRequest.setHandled(true);
- return;
}
}
else if (request.getAttribute("TIMEOUT")!=null)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java
index 3ea0a80a31..92ef496db2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java
@@ -20,89 +20,92 @@ import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSession;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.IO;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* @version $Revision: 889 $ $Date: 2009-09-14 14:52:16 +1000 (Mon, 14 Sep 2009) $
*/
-public class AsyncUploadTest extends TestCase
+public class AsyncUploadTest
{
- int _total;
-
- public void test() throws Exception
+ private static Server server;
+ private static Connector connector;
+ private static int total;
+
+ @BeforeClass
+ public static void startServer() throws Exception
{
- Server server = new Server();
- SelectChannelConnector connector = new SelectChannelConnector();
+ server = new Server();
+ connector = new SelectChannelConnector();
server.addConnector(connector);
-
server.setHandler(new EmptyHandler());
-
server.start();
- try
- {
- _total=0;
- final Socket socket = new Socket("localhost",connector.getLocalPort());
-
- byte[] content = new byte[16*4096];
- Arrays.fill(content, (byte)120);
-
- long start = System.nanoTime();
- OutputStream out = socket.getOutputStream();
- out.write("POST / HTTP/1.1\r\n".getBytes());
- out.write("Host: localhost\r\n".getBytes());
- out.write(("Content-Length: "+content.length+"\r\n").getBytes());
- out.write("Content-Type: bytes\r\n".getBytes());
- out.write("Connection: close\r\n".getBytes());
- out.write("\r\n".getBytes());
- out.flush();
-
- out.write(content,0,4*4096);
- Thread.sleep(100);
- out.write(content,8192,4*4096);
- Thread.sleep(100);
- out.write(content,8*4096,content.length-8*4096);
-
- out.flush();
-
- InputStream in = socket.getInputStream();
- String response = IO.toString(in);
- // System.err.println(response);
- assertTrue(response.indexOf("200 OK")>0);
-
- long end = System.nanoTime();
- System.err.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
- assertEquals(content.length,_total);
-
- }
- finally
- {
- server.stop();
- }
}
- private class EmptyHandler extends AbstractHandler
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ server.stop();
+ server.join();
+ }
+
+ @Test
+ public void test() throws Exception
+ {
+ final Socket socket = new Socket("localhost",connector.getLocalPort());
+
+ byte[] content = new byte[16*4096];
+ Arrays.fill(content, (byte)120);
+
+ long start = System.nanoTime();
+ OutputStream out = socket.getOutputStream();
+ out.write("POST / HTTP/1.1\r\n".getBytes());
+ out.write("Host: localhost\r\n".getBytes());
+ out.write(("Content-Length: "+content.length+"\r\n").getBytes());
+ out.write("Content-Type: bytes\r\n".getBytes());
+ out.write("Connection: close\r\n".getBytes());
+ out.write("\r\n".getBytes());
+ out.flush();
+
+ out.write(content,0,4*4096);
+ Thread.sleep(100);
+ out.write(content,8192,4*4096);
+ Thread.sleep(100);
+ out.write(content,8*4096,content.length-8*4096);
+
+ out.flush();
+
+ InputStream in = socket.getInputStream();
+ String response = IO.toString(in);
+ // System.err.println(response);
+ assertTrue(response.indexOf("200 OK")>0);
+
+ long end = System.nanoTime();
+ System.err.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
+ assertEquals(content.length, total);
+ }
+
+ private static class EmptyHandler extends AbstractHandler
{
public void handle(String path, final Request request, HttpServletRequest httpRequest, final HttpServletResponse httpResponse) throws IOException, ServletException
{
- // System.out.println("path = " + path);
-
final Continuation continuation = ContinuationSupport.getContinuation(request);
httpResponse.setStatus(500);
request.setHandled(true);
-
+
new Thread()
{
@Override
@@ -113,20 +116,15 @@ public class AsyncUploadTest extends TestCase
Thread.sleep(100);
InputStream in = request.getInputStream();
byte[] b = new byte[4*4096];
- int l;
-
- while((l=in.read(b))>=0)
- {
- // System.err.println("read "+l);
- _total+=l;
- }
-
- System.err.println("Read "+_total);
+ int read;
+ while((read =in.read(b))>=0)
+ total += read;
+ System.err.println("Read "+ total);
}
catch(Exception e)
{
e.printStackTrace();
- _total=-1;
+ total =-1;
}
finally
{
@@ -135,16 +133,8 @@ public class AsyncUploadTest extends TestCase
}
}
}.start();
-
- continuation.suspend();
- }
- }
- private class EmptyHostnameVerifier implements HostnameVerifier
- {
- public boolean verify(String s, SSLSession sslSession)
- {
- return true;
+ continuation.suspend();
}
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelServerTest.java
index d05fdc0ffd..23c415d1ed 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelServerTest.java
@@ -4,23 +4,26 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
+
import org.eclipse.jetty.server.nio.BlockingChannelConnector;
+import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BlockingChannelServerTest extends HttpServerTestBase
{
- public BlockingChannelServerTest()
+ @BeforeClass
+ public static void init() throws Exception
{
- super(new BlockingChannelConnector());
- }
+ startServer(new BlockingChannelConnector());
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java
index 2948e325b8..a697bb2c63 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -23,22 +23,18 @@ import org.eclipse.jetty.io.nio.NIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BusySelectChannelServerTest extends HttpServerTestBase
{
-
- public BusySelectChannelServerTest()
+ @BeforeClass
+ public static void init() throws Exception
{
- super(new SelectChannelConnector()
+ startServer(new SelectChannelConnector()
{
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see org.eclipse.jetty.server.server.nio.SelectChannelConnector#newEndPoint(java.nio.channels.SocketChannel, org.eclipse.io.nio.SelectorManager.SelectSet, java.nio.channels.SelectionKey)
- */
@Override
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
{
@@ -46,7 +42,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
{
int write;
int read;
-
+
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see org.eclipse.io.nio.SelectChannelEndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
@@ -103,7 +99,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(one.peek(0));
return l;
}
-
+
if (x<24 && buffer.space()>=2)
{
NIOBuffer two = new IndirectNIOBuffer(2);
@@ -114,7 +110,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(two.peek(1));
return l;
}
-
+
if (x<64 && buffer.space()>=3)
{
NIOBuffer three = new IndirectNIOBuffer(3);
@@ -127,18 +123,11 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(three.peek(2));
return l;
}
-
+
return super.fill(buffer);
}
};
- }
- });
- }
-
-
- @Override
- protected void configServer(Server server)
- {
- server.setThreadPool(new QueuedThreadPool());
+ }
+ });
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java
index 2ab4d3c99b..286fdcd75b 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java
@@ -4,42 +4,31 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import java.io.IOException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
/**
- * Test {@link AbstractConnector#checkForwardedHeaders(org.eclipse.io.EndPoint, Request)}.
+ *
*/
-public class CheckReverseProxyHeadersTest extends TestCase
+public class CheckReverseProxyHeadersTest
{
- Server server=new Server();
- LocalConnector connector=new LocalConnector();
-
- /**
- * Constructor for CheckReverseProxyHeadersTest.
- * @param name test case name.
- */
- public CheckReverseProxyHeadersTest(String name)
- {
- super(name);
- }
-
+ @Test
public void testCheckReverseProxyHeaders() throws Exception
{
// Classic ProxyPass from example.com:80 to localhost:8080
@@ -56,7 +45,7 @@ public class CheckReverseProxyHeadersTest extends TestCase
assertEquals("example.com", request.getHeader("Host"));
}
});
-
+
// ProxyPass from example.com:81 to localhost:8080
testRequest("Host: localhost:8080\n" +
"X-Forwarded-For: 10.20.30.40\n" +
@@ -72,7 +61,7 @@ public class CheckReverseProxyHeadersTest extends TestCase
assertEquals("example.com:81", request.getHeader("Host"));
}
});
-
+
// Multiple ProxyPass from example.com:80 to rp.example.com:82 to localhost:8080
testRequest("Host: localhost:8080\n" +
"X-Forwarded-For: 10.20.30.40, 10.0.0.1\n" +
@@ -94,21 +83,21 @@ public class CheckReverseProxyHeadersTest extends TestCase
{
Server server = new Server();
LocalConnector connector = new LocalConnector();
-
+
// Activate reverse proxy headers checking
connector.setForwarded(true);
-
+
server.setConnectors(new Connector[] {connector});
ValidationHandler validationHandler = new ValidationHandler(requestValidator);
server.setHandler(validationHandler);
-
+
try
{
server.start();
connector.getResponses("GET / HTTP/1.1\n" + headers + "\n\n");
-
+
Error error = validationHandler.getError();
-
+
if (error != null)
{
throw error;
@@ -137,18 +126,14 @@ public class CheckReverseProxyHeadersTest extends TestCase
*/
private static class ValidationHandler extends AbstractHandler
{
- private RequestValidator _requestValidator;
+ private final RequestValidator _requestValidator;
private Error _error;
-
- /**
- * Create the validation handler with a request validator.
- * @param requestValidator the request validator.
- */
- public ValidationHandler(RequestValidator requestValidator)
+
+ private ValidationHandler(RequestValidator requestValidator)
{
_requestValidator = requestValidator;
}
-
+
/**
* Retrieve the validation error.
* @return the validation error or <code>null</code> if there was no error.
@@ -157,7 +142,7 @@ public class CheckReverseProxyHeadersTest extends TestCase
{
return _error;
}
-
+
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
try
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
index 0d75b485f6..4395e39422 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -16,28 +16,28 @@ package org.eclipse.jetty.server;
import java.net.URLDecoder;
import java.net.URLEncoder;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.EncodedHttpURI;
+import org.junit.Test;
-public class EncodedHttpURITest extends TestCase
-{
+import static org.junit.Assert.assertEquals;
- public void testNonURIAscii ()
- throws Exception
+public class EncodedHttpURITest
+{
+ @Test
+ public void testNonURIAscii() throws Exception
{
String url = "http://www.foo.com/ma\u00F1ana";
byte[] asISO = url.getBytes("ISO-8859-1");
String str = new String(asISO, "ISO-8859-1");
-
+
//use a non UTF-8 charset as the encoding and url-escape as per
//http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
- String s = URLEncoder.encode(url, "ISO-8859-1");
+ String s = URLEncoder.encode(url, "ISO-8859-1");
EncodedHttpURI uri = new EncodedHttpURI("ISO-8859-1");
-
+
//parse it, using the same encoding
uri.parse(s);
-
+
//decode the url encoding
String d = URLDecoder.decode(uri.getCompletePath(), "ISO-8859-1");
assertEquals(url, d);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
index a779b79a33..4ea50b9c4c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
@@ -21,60 +21,49 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.PrintWriter;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
*
- *
*/
-public class HttpConnectionTest extends TestCase
+public class HttpConnectionTest
{
- Server server = new Server();
- LocalConnector connector = new LocalConnector();
-
- /**
- * Constructor
- * @param arg0
- */
- public HttpConnectionTest(String arg0)
- {
- super(arg0);
- server.setConnectors(new Connector[]{connector});
- server.setHandler(new DumpHandler());
- }
+ private Server server;
+ private LocalConnector connector;
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- super.setUp();
- connector.setHeaderBufferSize(1024);
+ server = new Server();
+ connector = new LocalConnector();
+ server.addConnector(connector);
+ connector.setRequestHeaderSize(1024);
+ connector.setResponseHeaderSize(1024);
+ server.setHandler(new DumpHandler());
server.start();
}
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
server.stop();
+ server.join();
}
-
-
- /* --------------------------------------------------------------- */
+ @Test
public void testFragmentedChunk()
{
String response=null;
@@ -118,7 +107,7 @@ public class HttpConnectionTest extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void testEmpty() throws Exception
{
String response=connector.getResponses("GET /R1 HTTP/1.1\n"+
@@ -133,7 +122,7 @@ public class HttpConnectionTest extends TestCase
offset = checkContains(response,offset,"/R1");
}
- /* --------------------------------------------------------------- */
+ @Test
public void testBad() throws Exception
{
String response=connector.getResponses("GET & HTTP/1.1\n"+
@@ -163,7 +152,7 @@ public class HttpConnectionTest extends TestCase
}
- /* --------------------------------------------------------------- */
+ @Test
public void testAutoFlush() throws Exception
{
String response=null;
@@ -184,7 +173,7 @@ public class HttpConnectionTest extends TestCase
offset = checkContains(response,offset,"12345");
}
- /* --------------------------------------------------------------- */
+ @Test
public void testCharset()
{
@@ -246,17 +235,15 @@ public class HttpConnectionTest extends TestCase
}
}
-
-
- /* --------------------------------------------------------------- */
+ @Test
public void testUnconsumedError() throws Exception
- {
+ {
String response=null;
String requests=null;
int offset=0;
- offset=0;
+ offset=0;
requests="GET /R1?read=1&error=500 HTTP/1.1\n"+
"Host: localhost\n"+
"Transfer-Encoding: chunked\n"+
@@ -280,17 +267,17 @@ public class HttpConnectionTest extends TestCase
offset = checkContains(response,offset,"/R2");
offset = checkContains(response,offset,"encoding=UTF-8");
offset = checkContains(response,offset,"abcdefghij");
-
+
}
-
- /* --------------------------------------------------------------- */
+
+ @Test
public void testUnconsumedException() throws Exception
- {
+ {
String response=null;
String requests=null;
int offset=0;
- offset=0;
+ offset=0;
requests="GET /R1?read=1&ISE=true HTTP/1.1\n"+
"Host: localhost\n"+
"Transfer-Encoding: chunked\n"+
@@ -328,7 +315,8 @@ public class HttpConnectionTest extends TestCase
}
}
- public void testConnection ()
+ @Test
+ public void testConnection()
{
String response=null;
try
@@ -356,6 +344,7 @@ public class HttpConnectionTest extends TestCase
}
}
+ @Test
public void testOversizedBuffer()
{
String response = null;
@@ -381,11 +370,10 @@ public class HttpConnectionTest extends TestCase
}
}
-
-
- public void testOversizedResponse ()
- throws Exception
- {
+
+ @Test
+ public void testOversizedResponse() throws Exception
+ {
String str = "thisisastringthatshouldreachover1kbytes";
for (int i=0;i<400;i++)
str+="xxxxxxxxxxxx";
@@ -393,7 +381,7 @@ public class HttpConnectionTest extends TestCase
String response = null;
server.stop();
server.setHandler(new DumpHandler()
- {
+ {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
try
@@ -402,7 +390,7 @@ public class HttpConnectionTest extends TestCase
response.setHeader(HttpHeaders.CONTENT_TYPE,MimeTypes.TEXT_HTML);
response.setHeader("LongStr", longstr);
PrintWriter writer = response.getWriter();
- writer.write("<html><h1>FOO</h1></html>");
+ writer.write("<html><h1>FOO</h1></html>");
writer.flush();
writer.close();
throw new RuntimeException("SHOULD NOT GET HERE");
@@ -415,28 +403,28 @@ public class HttpConnectionTest extends TestCase
}
});
server.start();
-
- try
+
+ try
{
int offset = 0;
-
+
response = connector.getResponses("GET / HTTP/1.1\n"+
"Host: localhost\n" +
"\015\012"
);
-
+
offset = checkContains(response, offset, "HTTP/1.1 500");
- }
+ }
catch(Exception e)
{
e.printStackTrace();
if(response != null)
System.err.println(response);
- fail("Exception");
+ fail("Exception");
}
}
-
+ @Test
public void testAsterisk()
{
String response = null;
@@ -492,6 +480,31 @@ public class HttpConnectionTest extends TestCase
}
+ @Test
+ public void testCONNECT()
+ {
+ String response = null;
+
+ try
+ {
+ int offset=0;
+
+ response=connector.getResponses("CONNECT www.webtide.com:8080 HTTP/1.1\n"+
+ "Host: myproxy:8888\015\012"+
+ "\015\012");
+ offset = checkContains(response,offset,"HTTP/1.1 200");
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ assertTrue(false);
+ if (response!=null)
+ System.err.println(response);
+ }
+
+ }
+
private int checkContains(String s,int offset,String c)
{
int o=s.indexOf(c,offset);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
index c12d896bd8..2f163c6387 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -26,25 +26,26 @@ import java.net.Socket;
import java.net.URL;
import java.util.Arrays;
import java.util.Random;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
/**
- * HttpServer Tester.
+ *
*/
-public class HttpServerTestBase extends TestCase
+public abstract class HttpServerTestBase
{
- private static boolean stress=Boolean.getBoolean("STRESS");
-
- // ~ Static fields/initializers
- // ---------------------------------------------
+ private static final boolean stress = Boolean.getBoolean("STRESS");
/** The request. */
private static final String REQUEST1_HEADER="POST / HTTP/1.0\n"+"Host: localhost\n"+"Content-Type: text/xml; charset=utf-8\n"+"Connection: close\n"+"Content-Length: ";
@@ -67,7 +68,6 @@ public class HttpServerTestBase extends TestCase
"Host: localhost\n"+
"Content-Type: text/xml\n"+
"Content-Length: ";
-
private static final String REQUEST2_CONTENT=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"+
"<nimbus xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+
@@ -78,9 +78,9 @@ public class HttpServerTestBase extends TestCase
" </getJobDetails>\n"+
" </request>\n"+
"</nimbus>";
-
private static final String REQUEST2=REQUEST2_HEADER+REQUEST2_CONTENT.getBytes().length+"\n\n"+REQUEST2_CONTENT;
+ /** The second expected response. */
private static final String RESPONSE2_CONTENT=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"+
"<nimbus xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+
@@ -104,87 +104,102 @@ public class HttpServerTestBase extends TestCase
private static final int LOOPS=stress?250:25;
private static final String HOST="localhost";
- private Connector _connector;
- private int port=0;
+ private static Server _server;
+ private static Connector _connector;
- protected void tearDown() throws Exception
+ protected static void startServer(Connector connector) throws Exception
{
- super.tearDown();
- Thread.sleep(100);
+ _server = new Server();
+ _connector = connector;
+ _server.addConnector(_connector);
+ _server.setHandler(new HandlerWrapper());
+ _server.start();
}
- // ~ Methods
- // ----------------------------------------------------------------
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
- /**
+ protected void configureServer(Handler handler) throws Exception
+ {
+ HandlerWrapper current = (HandlerWrapper)_server.getHandler();
+ current.stop();
+ current.setHandler(handler);
+ current.start();
+ }
+
+ /*
* Feed the server the entire request at once.
- *
- * @throws Exception
- * @throws InterruptedException
*/
- public void testRequest1_jetty() throws Exception, InterruptedException
+ @Test
+ public void testRequest1_jetty() throws Exception
{
- Server server=startServer(new HelloWorldHandler());
- Socket client=new Socket(HOST,port);
- OutputStream os=client.getOutputStream();
+ configureServer(new HelloWorldHandler());
- os.write(REQUEST1.getBytes());
- os.flush();
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
+ {
+ OutputStream os=client.getOutputStream();
- // Read the response.
- String response=readResponse(client);
+ os.write(REQUEST1.getBytes());
+ os.flush();
- // Shut down
- client.close();
- server.stop();
+ // Read the response.
+ String response=readResponse(client);
- // Check the response
- assertEquals("response",RESPONSE1,response);
+ // Check the response
+ assertEquals("response",RESPONSE1,response);
+ }
+ finally
+ {
+ client.close();
+ }
}
- /* --------------------------------------------------------------- */
+ @Test
public void testFragmentedChunk() throws Exception
{
+ configureServer(new EchoHandler());
- Server server=startServer(new EchoHandler());
- Socket client=new Socket(HOST,port);
- OutputStream os=client.getOutputStream();
-
- os.write(("GET /R2 HTTP/1.1\015\012"+"Host: localhost\015\012"+"Transfer-Encoding: chunked\015\012"+"Content-Type: text/plain\015\012"
- +"Connection: close\015\012"+"\015\012").getBytes());
- os.flush();
- Thread.sleep(PAUSE);
- os.write(("5\015\012").getBytes());
- os.flush();
- Thread.sleep(PAUSE);
- os.write(("ABCDE\015\012"+"0;\015\012\015\012").getBytes());
- os.flush();
-
- // Read the response.
- String response=readResponse(client);
-
- // Shut down
- client.close();
- server.stop();
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
+ {
+ OutputStream os=client.getOutputStream();
- assertTrue(true); // nothing checked yet.
+ os.write(("GET /R2 HTTP/1.1\015\012"+"Host: localhost\015\012"+"Transfer-Encoding: chunked\015\012"+"Content-Type: text/plain\015\012"
+ +"Connection: close\015\012"+"\015\012").getBytes());
+ os.flush();
+ Thread.sleep(PAUSE);
+ os.write(("5\015\012").getBytes());
+ os.flush();
+ Thread.sleep(PAUSE);
+ os.write(("ABCDE\015\012"+"0;\015\012\015\012").getBytes());
+ os.flush();
+ // Read the response.
+ String response=readResponse(client);
+ assertTrue(true); // nothing checked yet.
+ }
+ finally
+ {
+ client.close();
+ }
}
- /**
+ /*
* Feed the server fragmentary headers and see how it copes with it.
- *
- * @throws Exception
- * @throws InterruptedException
*/
+ @Test
public void testRequest1Fragments_jetty() throws Exception, InterruptedException
{
- Server server=startServer(new HelloWorldHandler());
- String response;
+ configureServer(new HelloWorldHandler());
+ Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
- Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
// Write a fragment, flush, sleep, write the next fragment, etc.
@@ -198,30 +213,29 @@ public class HttpServerTestBase extends TestCase
os.flush();
// Read the response
- response=readResponse(client);
+ String response = readResponse(client);
- // Shut down
- client.close();
+ // Check the response
+ assertEquals("response",RESPONSE1,response);
}
finally
{
- server.stop();
+ client.close();
}
- // Check the response
- assertEquals("response",RESPONSE1,response);
}
+ @Test
public void testRequest2_jetty() throws Exception
{
- byte[] bytes=REQUEST2.getBytes();
- Server server=startServer(new EchoHandler());
+ configureServer(new EchoHandler());
- try
+ byte[] bytes=REQUEST2.getBytes();
+ for (int i=0; i<LOOPS; i++)
{
- for (int i=0; i<LOOPS; i++)
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
{
- Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
os.write(bytes);
@@ -229,50 +243,44 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
- client.close();
// Check the response
assertEquals("response "+i,RESPONSE2,response);
}
- }
- finally
- {
- // Shut down
- server.stop();
+ finally
+ {
+ client.close();
+ }
}
}
- /**
- * @throws Exception
- */
+ @Test
public void testRequest2Fragments_jetty() throws Exception
{
- Random random=new Random(System.currentTimeMillis());
+ configureServer(new EchoHandler());
+
byte[] bytes=REQUEST2.getBytes();
final int pointCount=2;
- Server server=startServer(new EchoHandler());
-
- try
+ Random random=new Random(System.currentTimeMillis());
+ for (int i=0; i<LOOPS; i++)
{
+ int[] points=new int[pointCount];
+ StringBuilder message=new StringBuilder();
- for (int i=0; i<LOOPS; i++)
- {
+ message.append("iteration #").append(i + 1);
- int[] points=new int[pointCount];
- StringBuilder message=new StringBuilder();
-
- message.append("iteration #").append(i + 1);
-
- // Pick fragment points at random
- for (int j=0; j<points.length; ++j)
- {
- points[j]=random.nextInt(bytes.length);
- }
+ // Pick fragment points at random
+ for (int j=0; j<points.length; ++j)
+ {
+ points[j]=random.nextInt(bytes.length);
+ }
- // Sort the list
- Arrays.sort(points);
+ // Sort the list
+ Arrays.sort(points);
- Socket client=new Socket(HOST,port);
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
+ {
OutputStream os=client.getOutputStream();
writeFragments(bytes,points,message,os);
@@ -280,38 +288,35 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
- // Close the client
- client.close();
-
// Check the response
assertEquals("response for "+i+" "+message.toString(),RESPONSE2,response);
}
- }
- finally
- {
- // Shut down
- server.stop();
+ finally
+ {
+ client.close();
+ }
}
}
+ @Test
public void testRequest2Iterate_jetty() throws Exception
{
- byte[] bytes=REQUEST2.getBytes();
- Server server=startServer(new EchoHandler());
+ configureServer(new EchoHandler());
- try
+ byte[] bytes=REQUEST2.getBytes();
+ for (int i=0; i<bytes.length; i+=3)
{
- for (int i=0; i<bytes.length; i+=3)
- {
- int[] points=new int[] { i };
- StringBuilder message=new StringBuilder();
+ int[] points=new int[] { i };
+ StringBuilder message=new StringBuilder();
- message.append("iteration #").append(i + 1);
+ message.append("iteration #").append(i + 1);
- // Sort the list
- Arrays.sort(points);
+ // Sort the list
+ Arrays.sort(points);
- Socket client=new Socket(HOST,port);
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
+ {
OutputStream os=client.getOutputStream();
writeFragments(bytes,points,message,os);
@@ -319,42 +324,37 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
- // Close the client
- client.close();
-
// Check the response
assertEquals("response for "+i+" "+message.toString(),RESPONSE2,response);
}
- }
- finally
- {
- // Shut down
- server.stop();
+ finally
+ {
+ client.close();
+ }
}
}
- /**
+ /*
* After several iterations, I generated some known bad fragment points.
- *
- * @throws Exception
*/
+ @Test
public void testRequest2KnownBad_jetty() throws Exception
{
+ configureServer(new EchoHandler());
+
byte[] bytes=REQUEST2.getBytes();
int[][] badPoints=new int[][]
{
- { 70 }, // beginning here, drops last line of request
+ { 70 }, // beginning here, drops last line of request
{ 71 }, // no response at all
{ 72 }, // again starts drops last line of request
{ 74 }, // again, no response at all
};
- Server server=startServer(new EchoHandler());
-
- try
+ for (int i=0; i<badPoints.length; ++i)
{
- for (int i=0; i<badPoints.length; ++i)
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
{
- Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
StringBuilder message=new StringBuilder();
@@ -364,78 +364,66 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
- // Close the client
- client.close();
-
// Check the response
// TODO - change to equals when code gets fixed
assertNotSame("response for "+message.toString(),RESPONSE2,response);
}
- }
- finally
- {
- // Shut down
- server.stop();
+ finally
+ {
+ client.close();
+ }
}
}
- /**
- * After several iterations, I generated some known bad fragment points.
- *
- * @throws Exception
- */
+ @Test
public void testFlush() throws Exception
{
- Server server=startServer(new DataHandler());
- try
- {
- String[] encoding = {"NONE","UTF-8","ISO-8859-1","ISO-8859-2"};
+ configureServer(new DataHandler());
- for (int e =0; e<encoding.length;e++)
+ String[] encoding = {"NONE","UTF-8","ISO-8859-1","ISO-8859-2"};
+ for (int e =0; e<encoding.length;e++)
+ {
+ for (int b=1;b<=128;b=b==1?2:b==2?32:b==32?128:129)
{
- for (int b=1;b<=128;b=b==1?2:b==2?32:b==32?128:129)
+ for (int w=41;w<42;w+=4096)
{
- for (int w=41;w<42;w+=4096)
+ for (int c=0;c<1;c++)
{
- for (int c=0;c<1;c++)
+ String test=encoding[e]+"x"+b+"x"+w+"x"+c;
+ try
{
- String test=encoding[e]+"x"+b+"x"+w+"x"+c;
- URL url=new URL("http://"+HOST+":"+port+"/?writes="+w+"&block="+b+ (e==0?"":("&encoding="+encoding[e]))+(c==0?"&chars=true":""));
+ URL url=new URL("http://"+HOST+":"+_connector.getLocalPort()+"/?writes="+w+"&block="+b+ (e==0?"":("&encoding="+encoding[e]))+(c==0?"&chars=true":""));
InputStream in = (InputStream)url.getContent();
String response=IO.toString(in,e==0?null:encoding[e]);
-
+
assertEquals(test,b*w,response.length());
}
+ catch(Exception x)
+ {
+ System.err.println(test);
+ throw x;
+ }
}
}
}
}
- finally
- {
- // Shut down
- server.stop();
- Thread.yield();
- }
}
- /**
- * After several iterations, I generated some known bad fragment points.
- *
- * @throws Exception
- */
+ @Test
public void testReadWriteBlocking() throws Exception
{
- Server server=startServer(new DataHandler());
+ configureServer(new DataHandler());
+
+ long start=System.currentTimeMillis();
+ Socket client=new Socket(HOST,_connector.getLocalPort());
try
- {
- long start=System.currentTimeMillis();
- Socket client=new Socket(HOST,port);
+ {
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"GET /data?writes=1024&block=256 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"connection: close\r\n"+
"content-type: unknown\r\n"+
"content-length: 30\r\n"+
@@ -457,11 +445,11 @@ public class HttpServerTestBase extends TestCase
"0987654321\r\n"
).getBytes());
os.flush();
-
+
int total=0;
int len=0;
byte[] buf=new byte[1024*64];
-
+
while(len>=0)
{
Thread.sleep(500);
@@ -475,29 +463,21 @@ public class HttpServerTestBase extends TestCase
}
finally
{
- // Shut down
- server.stop();
- Thread.yield();
+ client.close();
}
-
}
-
- /**
- * After several iterations, I generated some known bad fragment points.
- *
- * @throws Exception
- */
+ @Test
public void testPipeline() throws Exception
{
- Server server=startServer(new HelloWorldHandler());
+ configureServer(new HelloWorldHandler());
- try
- {
- //for (int pipeline=1;pipeline<32;pipeline++)
- for (int pipeline=1;pipeline<32;pipeline++)
- {
- Socket client=new Socket(HOST,port);
+ //for (int pipeline=1;pipeline<32;pipeline++)
+ for (int pipeline=1;pipeline<32;pipeline++)
+ {
+ Socket client=new Socket(HOST,_connector.getLocalPort());
+ try
+ {
client.setSoTimeout(5000);
OutputStream os=client.getOutputStream();
@@ -506,15 +486,15 @@ public class HttpServerTestBase extends TestCase
for (int i=1;i<pipeline;i++)
request+=
"GET /data?writes=1&block=16&id="+i+" HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
"accept-encoding: nothing\r\n"+
"cookie: aaa=1234567890\r\n"+
"\r\n";
-
+
request+=
"GET /data?writes=1&block=16 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
"accept-encoding: nothing\r\n"+
"cookie: aaa=bbbbbb\r\n"+
@@ -536,53 +516,38 @@ public class HttpServerTestBase extends TestCase
}
assertEquals(pipeline,count);
}
+ finally
+ {
+ client.close();
+ }
}
- finally
- {
- // Shut down
- server.stop();
- Thread.yield();
- }
-
- }
-
- public void testStoppable() throws Exception
- {
- Server server=startServer(null);
- server.setThreadPool(new QueuedThreadPool());
- server.start();
- Thread.sleep(1000);
- server.stop();
}
-
- /**
- */
+ @Test
public void testRecycledWriters() throws Exception
{
- Server server=startServer(new EchoHandler());
-
+ configureServer(new EchoHandler());
+
+ Socket client=new Socket(HOST,_connector.getLocalPort());
try
- {
- long start=System.currentTimeMillis();
- Socket client=new Socket(HOST,port);
+ {
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n").getBytes("iso-8859-1"));
-
+
os.write((
"123456789\n"
).getBytes("utf-8"));
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n"
@@ -596,7 +561,7 @@ public class HttpServerTestBase extends TestCase
byte[] contentB=content.getBytes("utf-8");
os.write((
"POST /echo?charset=utf-16 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: "+contentB.length+"\r\n"+
"connection: close\r\n"+
@@ -605,7 +570,7 @@ public class HttpServerTestBase extends TestCase
os.write(contentB);
os.flush();
-
+
ByteArrayOutputStream bout = new ByteArrayOutputStream();
IO.copy(is,bout);
byte[] b=bout.toByteArray();
@@ -626,57 +591,51 @@ public class HttpServerTestBase extends TestCase
if (state==1||state==3)
state++;
continue;
-
+
default:
state=0;
}
}
-
-
+
String in = new String(b,0,i,"utf-8");
assertTrue(in.indexOf("123456789")>=0);
assertTrue(in.indexOf("abcdefghZ")>=0);
assertTrue(in.indexOf("Wibble")<0);
-
+
in = new String(b,i,b.length-i,"utf-16");
assertEquals("Wibble\n",in);
-
}
finally
{
- // Shut down
- server.stop();
- Thread.yield();
+ client.close();
}
}
- /**
- */
+ @Test
public void testRecycledReaders() throws Exception
{
- Server server=startServer(new EchoHandler());
-
+ configureServer(new EchoHandler());
+
+ Socket client=new Socket(HOST,_connector.getLocalPort());
try
- {
- long start=System.currentTimeMillis();
- Socket client=new Socket(HOST,port);
+ {
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n").getBytes("iso-8859-1"));
-
+
os.write((
"123456789\n"
).getBytes("utf-8"));
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n"
@@ -690,7 +649,7 @@ public class HttpServerTestBase extends TestCase
byte[] contentB=content.getBytes("utf-16");
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
- "host: "+HOST+":"+port+"\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-16\r\n"+
"content-length: "+contentB.length+"\r\n"+
"connection: close\r\n"+
@@ -699,30 +658,24 @@ public class HttpServerTestBase extends TestCase
os.write(contentB);
os.flush();
-
+
String in = IO.toString(is);
assertTrue(in.indexOf("123456789")>=0);
assertTrue(in.indexOf("abcdefghi")>=0);
assertTrue(in.indexOf("Wibble")>=0);
-
}
finally
{
- // Shut down
- server.stop();
- Thread.yield();
+ client.close();
}
}
-
+
/**
* Read entire response from the client. Close the output.
- *
- * @param client
- * Open client socket.
- *
+ *
+ * @param client Open client socket.
* @return The response string.
- *
- * @throws IOException
+ * @throws IOException in case of I/O problems
*/
private static String readResponse(Socket client) throws IOException
{
@@ -752,41 +705,6 @@ public class HttpServerTestBase extends TestCase
}
}
- protected HttpServerTestBase(Connector connector)
- {
- _connector=connector;
- }
-
- /**
- * Create the server.
- *
- * @param handler
- *
- * @return Newly created server, ready to start.
- *
- * @throws Exception
- */
- protected Server startServer(Handler handler) throws Exception
- {
- Server server=new Server();
-
- _connector.setPort(0);
- server.setConnectors(new Connector[]
- { _connector });
- server.setHandler(handler);
-
- configServer(server);
-
- server.start();
- port=_connector.getLocalPort();
- return server;
- }
-
- protected void configServer(Server server)
- {
-
- }
-
private void writeFragments(byte[] bytes, int[] points, StringBuilder message, OutputStream os) throws IOException, InterruptedException
{
int last=0;
@@ -811,12 +729,8 @@ public class HttpServerTestBase extends TestCase
Thread.sleep(PAUSE);
}
- // ~ Inner Classes
- // ----------------------------------------------------------
private static class EchoHandler extends AbstractHandler
{
- // ~ Methods
- // ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@@ -827,12 +741,12 @@ public class HttpServerTestBase extends TestCase
response.setCharacterEncoding(request.getParameter("charset"));
else if (request.getCharacterEncoding()!=null)
response.setCharacterEncoding(request.getCharacterEncoding());
-
+
PrintWriter writer=response.getWriter();
BufferedReader reader=request.getReader();
int count=0;
String line;
-
+
while ((line=reader.readLine())!=null)
{
writer.print(line);
@@ -842,20 +756,18 @@ public class HttpServerTestBase extends TestCase
if (count==0)
throw new IllegalStateException("no input recieved");
-
+
// just to be difficult
reader.close();
writer.close();
-
+
if (reader.read()>=0)
throw new IllegalStateException("Not closed");
}
}
- // ----------------------------------------------------------
private static class HelloWorldHandler extends AbstractHandler
{
- // ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@@ -864,25 +776,23 @@ public class HttpServerTestBase extends TestCase
}
}
- // ----------------------------------------------------------
private static class DataHandler extends AbstractHandler
{
- // ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setStatus(200);
-
+
InputStream in = request.getInputStream();
String input=IO.toString(in);
-
+
String tmp = request.getParameter("writes");
int writes=Integer.parseInt(tmp==null?"10":tmp);
tmp = request.getParameter("block");
int block=Integer.parseInt(tmp==null?"10":tmp);
String encoding=request.getParameter("encoding");
String chars=request.getParameter("chars");
-
+
String chunk = (input+"\u0a870123456789A\u0a87CDEFGHIJKLMNOPQRSTUVWXYZ\u0250bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
.substring(0,block);
response.setContentType("text/plain");
@@ -901,15 +811,14 @@ public class HttpServerTestBase extends TestCase
for (int i=0;i<writes;i++)
out.write(c);
}
- else
+ else
{
response.setCharacterEncoding(encoding);
Writer out=response.getWriter();
for (int i=0;i<writes;i++)
out.write(chunk);
}
-
+
}
}
-
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
index 88c8b5bfa0..2ea4cc5a9e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
@@ -4,62 +4,67 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-public class HttpURITest extends TestCase
+public class HttpURITest
{
- String[][] partial_tests=
- {
- /* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
- /* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
- /* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
- /* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
- /* 4*/ {"/path/info;param",null,null,null,null,"/path/info","param",null,null},
- /* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info","param",null,"fragment"},
- /* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info","param","query",null},
- /* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info","param","query","fragment"},
- /* 8*/ {"//host/path/info",null,"//host","host",null,"/path/info",null,null,null},
- /* 9*/ {"//user@host/path/info",null,"//user@host","host",null,"/path/info",null,null,null},
- /*10*/ {"//user@host:8080/path/info",null,"//user@host:8080","host","8080","/path/info",null,null,null},
- /*11*/ {"//host:8080/path/info",null,"//host:8080","host","8080","/path/info",null,null,null},
- /*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
- /*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
- /*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
- /*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
- /*16*/ {"http:/path/info;param","http",null,null,null,"/path/info","param",null,null},
- /*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info","param",null,"fragment"},
- /*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info","param","query",null},
- /*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info","param","query","fragment"},
- /*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info","param","query","fragment"},
- /*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info","param","query","fragment"},
- /*22*/ {"http:///;?#","http","//",null,null,"/","","",""},
- /*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
- /*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
- /*25*/ {"//host:8080//",null,"//host:8080","host","8080","//",null,null,null},
- /*26*/ {"file:///path/info","file","//",null,null,"/path/info",null,null,null},
- /*27*/ {"//",null,"//",null,null,null,null,null,null},
+ private final String[][] partial_tests=
+ {
+ /* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
+ /* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
+ /* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
+ /* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
+ /* 4*/ {"/path/info;param",null,null,null,null,"/path/info","param",null,null},
+ /* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info","param",null,"fragment"},
+ /* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info","param","query",null},
+ /* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info","param","query","fragment"},
+ /* 8*/ {"//host/path/info",null,"//host","host",null,"/path/info",null,null,null},
+ /* 9*/ {"//user@host/path/info",null,"//user@host","host",null,"/path/info",null,null,null},
+ /*10*/ {"//user@host:8080/path/info",null,"//user@host:8080","host","8080","/path/info",null,null,null},
+ /*11*/ {"//host:8080/path/info",null,"//host:8080","host","8080","/path/info",null,null,null},
+ /*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
+ /*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
+ /*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
+ /*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
+ /*16*/ {"http:/path/info;param","http",null,null,null,"/path/info","param",null,null},
+ /*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info","param",null,"fragment"},
+ /*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info","param","query",null},
+ /*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info","param","query","fragment"},
+ /*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info","param","query","fragment"},
+ /*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info","param","query","fragment"},
+ /*22*/ {"http:///;?#","http","//",null,null,"/","","",""},
+ /*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
+ /*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
+ /*25*/ {"//host:8080//",null,"//host:8080","host","8080","//",null,null,null},
+ /*26*/ {"file:///path/info","file","//",null,null,"/path/info",null,null,null},
+ /*27*/ {"//",null,"//",null,null,null,null,null,null},
/*28*/ {"/;param",null, null, null,null,"/", "param",null,null},
/*29*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*30*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null},
- /*31*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
+ /*31*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
};
- public void testPartialURIs()
- throws Exception
+ @Test
+ public void testPartialURIs() throws Exception
{
HttpURI uri = new HttpURI(true);
-
+
for (int t=0;t<partial_tests.length;t++)
{
uri.parse(partial_tests[t][0].getBytes(),0,partial_tests[t][0].length());
@@ -73,39 +78,39 @@ public class HttpURITest extends TestCase
assertEquals(t+" "+partial_tests[t][0],partial_tests[t][8],uri.getFragment());
assertEquals(partial_tests[t][0], uri.toString());
}
-
+
}
- String[][] path_tests=
- {
- /* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
- /* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
- /* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
- /* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
- /* 4*/ {"/path/info;param",null,null,null,null,"/path/info","param",null,null},
- /* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info","param",null,"fragment"},
- /* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info","param","query",null},
- /* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info","param","query","fragment"},
- /* 8*/ {"//host/path/info",null,null,null,null,"//host/path/info",null,null,null},
- /* 9*/ {"//user@host/path/info",null,null,null,null,"//user@host/path/info",null,null,null},
- /*10*/ {"//user@host:8080/path/info",null,null,null,null,"//user@host:8080/path/info",null,null,null},
- /*11*/ {"//host:8080/path/info",null,null,null,null,"//host:8080/path/info",null,null,null},
- /*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
- /*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
- /*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
- /*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
- /*16*/ {"http:/path/info;param","http",null,null,null,"/path/info","param",null,null},
- /*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info","param",null,"fragment"},
- /*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info","param","query",null},
- /*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info","param","query","fragment"},
- /*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info","param","query","fragment"},
- /*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info","param","query","fragment"},
- /*22*/ {"http:///;?#","http","//",null,null,"/","","",""},
- /*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
- /*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
- /*25*/ {"//host:8080//",null,null,null,null,"//host:8080//",null,null,null},
- /*26*/ {"file:///path/info","file","//",null,null,"/path/info",null,null,null},
- /*27*/ {"//",null,null,null,null,"//",null,null,null},
+ private final String[][] path_tests=
+ {
+ /* 0*/ {"/path/info",null,null,null,null,"/path/info",null,null,null},
+ /* 1*/ {"/path/info#fragment",null,null,null,null,"/path/info",null,null,"fragment"},
+ /* 2*/ {"/path/info?query",null,null,null,null,"/path/info",null,"query",null},
+ /* 3*/ {"/path/info?query#fragment",null,null,null,null,"/path/info",null,"query","fragment"},
+ /* 4*/ {"/path/info;param",null,null,null,null,"/path/info","param",null,null},
+ /* 5*/ {"/path/info;param#fragment",null,null,null,null,"/path/info","param",null,"fragment"},
+ /* 6*/ {"/path/info;param?query",null,null,null,null,"/path/info","param","query",null},
+ /* 7*/ {"/path/info;param?query#fragment",null,null,null,null,"/path/info","param","query","fragment"},
+ /* 8*/ {"//host/path/info",null,null,null,null,"//host/path/info",null,null,null},
+ /* 9*/ {"//user@host/path/info",null,null,null,null,"//user@host/path/info",null,null,null},
+ /*10*/ {"//user@host:8080/path/info",null,null,null,null,"//user@host:8080/path/info",null,null,null},
+ /*11*/ {"//host:8080/path/info",null,null,null,null,"//host:8080/path/info",null,null,null},
+ /*12*/ {"http:/path/info","http",null,null,null,"/path/info",null,null,null},
+ /*13*/ {"http:/path/info#fragment","http",null,null,null,"/path/info",null,null,"fragment"},
+ /*14*/ {"http:/path/info?query","http",null,null,null,"/path/info",null,"query",null},
+ /*15*/ {"http:/path/info?query#fragment","http",null,null,null,"/path/info",null,"query","fragment"},
+ /*16*/ {"http:/path/info;param","http",null,null,null,"/path/info","param",null,null},
+ /*17*/ {"http:/path/info;param#fragment","http",null,null,null,"/path/info","param",null,"fragment"},
+ /*18*/ {"http:/path/info;param?query","http",null,null,null,"/path/info","param","query",null},
+ /*19*/ {"http:/path/info;param?query#fragment","http",null,null,null,"/path/info","param","query","fragment"},
+ /*20*/ {"http://user@host:8080/path/info;param?query#fragment","http","//user@host:8080","host","8080","/path/info","param","query","fragment"},
+ /*21*/ {"xxxxx://user@host:8080/path/info;param?query#fragment","xxxxx","//user@host:8080","host","8080","/path/info","param","query","fragment"},
+ /*22*/ {"http:///;?#","http","//",null,null,"/","","",""},
+ /*23*/ {"/path/info?a=?query",null,null,null,null,"/path/info",null,"a=?query",null},
+ /*24*/ {"/path/info?a=;query",null,null,null,null,"/path/info",null,"a=;query",null},
+ /*25*/ {"//host:8080//",null,null,null,null,"//host:8080//",null,null,null},
+ /*26*/ {"file:///path/info","file","//",null,null,"/path/info",null,null,null},
+ /*27*/ {"//",null,null,null,null,"//",null,null,null},
/*28*/ {"http://localhost/","http","//localhost","localhost",null,"/",null,null,null},
/*29*/ {"http://localhost:8080/", "http", "//localhost:8080", "localhost","8080","/", null, null,null},
/*30*/ {"http://localhost/?x=y", "http", "//localhost", "localhost",null,"/", null,"x=y",null},
@@ -121,13 +126,12 @@ public class HttpURITest extends TestCase
/*40*/ {"http://user@[2001:db8::1]:8080/","http","//user@[2001:db8::1]:8080","[2001:db8::1]","8080","/",null,null,null},
/*41*/ {"*",null,null,null,null,"*",null, null,null}
};
-
-
- public void testPathURIs()
- throws Exception
+
+ @Test
+ public void testPathURIs() throws Exception
{
HttpURI uri = new HttpURI();
-
+
for (int t=0;t<path_tests.length;t++)
{
uri.parse(path_tests[t][0].getBytes(),0,path_tests[t][0].length());
@@ -141,17 +145,18 @@ public class HttpURITest extends TestCase
assertEquals(t+" "+path_tests[t][0],path_tests[t][8],uri.getFragment());
assertEquals(path_tests[t][0], uri.toString());
}
-
+
}
-
+
+ @Test
public void testInvalidAddress() throws Exception
{
assertInvalidURI("http://[ffff::1:8080/", "Invalid URL; no closing ']' -- should throw exception");
assertInvalidURI("**", "only '*', not '**'");
assertInvalidURI("*/", "only '*', not '*/'");
}
-
- public void assertInvalidURI(String invalidURI, String message)
+
+ private void assertInvalidURI(String invalidURI, String message)
{
HttpURI uri = new HttpURI();
try
@@ -165,24 +170,54 @@ public class HttpURITest extends TestCase
}
}
- String[][] encoding_tests=
- {
- /* 0*/ {"/path/info","/path/info"},
- /* 1*/ {"/path/%69nfo","/path/info"},
- /* 2*/ {"http://host/path/%69nfo","/path/info"},
- /* 3*/ {"http://host/path/%69nf%c2%a4","/path/inf\u00a4"},
+ private final String[][] encoding_tests=
+ {
+ /* 0*/ {"/path/info","/path/info"},
+ /* 1*/ {"/path/%69nfo","/path/info"},
+ /* 2*/ {"http://host/path/%69nfo","/path/info"},
+ /* 3*/ {"http://host/path/%69nf%c2%a4","/path/inf\u00a4"},
};
-
+
+ @Test
public void testEncoded()
{
-
HttpURI uri = new HttpURI();
-
+
for (int t=0;t<encoding_tests.length;t++)
{
uri.parse(encoding_tests[t][0]);
assertEquals(""+t,encoding_tests[t][1],uri.getDecodedPath());
-
+
+ }
+ }
+
+ private final String[][] connect_tests=
+ {
+ /* 0*/ {" localhost:8080 ","localhost","8080"},
+ /* 1*/ {" 127.0.0.1:8080 ","127.0.0.1","8080"},
+ /* 2*/ {" [127::0::0::1]:8080 ","[127::0::0::1]","8080"},
+ /* 3*/ {" error ",null,null},
+ /* 4*/ {" http://localhost:8080/ ",null,null},
+ };
+
+ @Test
+ public void testCONNECT() throws Exception
+ {
+ HttpURI uri = new HttpURI();
+ for (int i=0;i<connect_tests.length;i++)
+ {
+ try
+ {
+ ByteArrayBuffer buf = new ByteArrayBuffer(connect_tests[i][0]);
+ uri.parseConnect(buf.array(),2,buf.length()-4);
+ assertEquals("path"+i,connect_tests[i][1]+":"+connect_tests[i][2],uri.getPath());
+ assertEquals("host"+i,connect_tests[i][1],uri.getHost());
+ assertEquals("port"+i,Integer.parseInt(connect_tests[i][2]),uri.getPort());
+ }
+ catch(Exception e)
+ {
+ assertNull("error"+i,connect_tests[i][1]);
+ }
}
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
index ac9bea7728..73bc4ba9de 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
@@ -2,8 +2,6 @@ package org.eclipse.jetty.server;
import java.io.IOException;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.AbstractGenerator;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
@@ -13,23 +11,39 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-public class HttpWriterTest extends TestCase
+public class HttpWriterTest
{
- HttpWriter _writer;
- ByteArrayBuffer _bytes;
-
- /* ------------------------------------------------------------ */
- @Override
- protected void setUp() throws Exception
+ private HttpWriter _writer;
+ private ByteArrayBuffer _bytes;
+
+ @Before
+ public void init() throws Exception
{
_bytes = new ByteArrayBuffer(2048);
-
+
Buffers buffers = new SimpleBuffers(new ByteArrayBuffer(1024),new ByteArrayBuffer(1024));
ByteArrayEndPoint endp = new ByteArrayEndPoint();
AbstractGenerator generator = new AbstractGenerator(buffers,endp)
{
@Override
+ public boolean isRequest()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isResponse()
+ {
+ return true;
+ }
+
+ @Override
public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
{
}
@@ -56,37 +70,33 @@ public class HttpWriterTest extends TestCase
{
return false;
}
-
+
};
-
+
HttpOutput httpOut = new HttpOutput(generator,60000);
_writer = new HttpWriter(httpOut);
}
-
- private void assertArrayEquals(byte[] b1, byte[] b2)
- {
- assertEquals(b1.length,b2.length);
- for (int i=0;i<b1.length;i++)
- assertEquals(""+i,b1[i],b2[i]);
- }
-
+
+ @Test
public void testSimpleUTF8() throws Exception
{
_writer.setCharacterEncoding(StringUtil.__UTF8);
- _writer.write("Now is the time");
+ _writer.write("Now is the time");
assertArrayEquals("Now is the time".getBytes(StringUtil.__UTF8),_bytes.asArray());
}
-
+
+ @Test
public void testUTF8() throws Exception
{
_writer.setCharacterEncoding(StringUtil.__UTF8);
- _writer.write("How now \uFF22rown cow");
+ _writer.write("How now \uFF22rown cow");
assertArrayEquals("How now \uFF22rown cow".getBytes(StringUtil.__UTF8),_bytes.asArray());
}
-
+
+ @Test
public void testMultiByteOverflowUTF8() throws Exception
{
- _writer.setCharacterEncoding(StringUtil.__UTF8);
+ _writer.setCharacterEncoding(StringUtil.__UTF8);
final String singleByteStr = "a";
final String multiByteDuplicateStr = "\uFF22";
int remainSize = 1;
@@ -109,41 +119,47 @@ public class HttpWriterTest extends TestCase
assertEquals(sb.toString(),new String(_bytes.asArray(),StringUtil.__UTF8));
}
-
+
+ @Test
public void testISO8859() throws Exception
{
_writer.setCharacterEncoding(StringUtil.__ISO_8859_1);
- _writer.write("How now \uFF22rown cow");
+ _writer.write("How now \uFF22rown cow");
assertEquals("How now ?rown cow",new String(_bytes.asArray(),StringUtil.__ISO_8859_1));
}
- public void testOutput()
- throws Exception
+ @Test
+ public void testOutput() throws Exception
{
Buffer sb=new ByteArrayBuffer(1500);
Buffer bb=new ByteArrayBuffer(8096);
HttpFields fields = new HttpFields();
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
-
+
HttpGenerator hb = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
hb.setResponse(200,"OK");
-
+
HttpOutput output = new HttpOutput(hb,10000);
HttpWriter writer = new HttpWriter(output);
writer.setCharacterEncoding(StringUtil.__UTF8);
-
+
char[] chars = new char[1024];
for (int i=0;i<chars.length;i++)
chars[i]=(char)('0'+(i%10));
chars[0]='\u0553';
writer.write(chars);
-
+
hb.completeHeader(fields,true);
hb.flush(10000);
String response = new String(endp.getOut().asArray(),StringUtil.__UTF8);
assertTrue(response.startsWith("HTTP/1.1 200 OK\r\nContent-Length: 1025\r\n\r\n\u05531234567890"));
-
-
- }
+ }
+
+ private void assertArrayEquals(byte[] b1, byte[] b2)
+ {
+ assertEquals(b1.length,b2.length);
+ for (int i=0;i<b1.length;i++)
+ assertEquals(""+i,b1[i],b2[i]);
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/InclusiveByteRangeTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/InclusiveByteRangeTest.java
index ad33210b35..c80daf1a15 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/InclusiveByteRangeTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/InclusiveByteRangeTest.java
@@ -5,13 +5,13 @@
// 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
+// 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.apache.org/licenses/LICENSE-2.0.txt
//
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -19,9 +19,13 @@ package org.eclipse.jetty.server;
import java.util.List;
import java.util.Vector;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class InclusiveByteRangeTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class InclusiveByteRangeTest
{
@SuppressWarnings("unchecked")
private void assertInvalidRange(String rangeString)
@@ -32,7 +36,7 @@ public class InclusiveByteRangeTest extends TestCase
List ranges = InclusiveByteRange.satisfiableRanges(strings.elements(),200);
assertNull("Invalid Range [" + rangeString + "] should result in no satisfiable ranges",ranges);
}
-
+
private void assertRange(String msg, int expectedFirst, int expectedLast, int size, InclusiveByteRange actualRange)
{
assertEquals(msg + " - first",expectedFirst,actualRange.getFirst(size));
@@ -74,25 +78,28 @@ public class InclusiveByteRangeTest extends TestCase
assertNotNull("Satisfiable Ranges should not be null",ranges);
return ranges;
}
-
+
+ @Test
public void testHeader416RangeString()
{
assertEquals("416 Header on size 100","bytes */100",InclusiveByteRange.to416HeaderRangeString(100));
assertEquals("416 Header on size 123456789","bytes */123456789",InclusiveByteRange.to416HeaderRangeString(123456789));
}
-
+
+ @Test
public void testInvalidRanges()
{
// Invalid if parsing "Range" header
assertInvalidRange("bytes=a-b"); // letters invalid
assertInvalidRange("byte=10-3"); // key is bad
assertInvalidRange("onceuponatime=5-10"); // key is bad
- assertInvalidRange("bytes=300-310"); // outside of size (200)
+ assertInvalidRange("bytes=300-310"); // outside of size (200)
}
/**
* Ranges have a multiple ranges, all absolutely defined.
*/
+ @Test
public void testMultipleAbsoluteRanges()
{
int size = 50;
@@ -109,6 +116,7 @@ public class InclusiveByteRangeTest extends TestCase
/**
* Range definition has a range that is clipped due to the size.
*/
+ @Test
public void testMultipleRangesClipped()
{
String rangeString;
@@ -122,6 +130,7 @@ public class InclusiveByteRangeTest extends TestCase
assertRange("Range [" + rangeString + "]",45,49,50,ranges.get(2));
}
+ @Test
public void testMultipleRangesOverlapping()
{
String rangeString;
@@ -134,6 +143,7 @@ public class InclusiveByteRangeTest extends TestCase
assertRange("Range [" + rangeString + "]",15,25,200,ranges.get(1));
}
+ @Test
public void testMultipleRangesSplit()
{
String rangeString;
@@ -145,6 +155,7 @@ public class InclusiveByteRangeTest extends TestCase
assertRange("Range [" + rangeString + "]",15,20,200,ranges.get(1));
}
+ @Test
public void testSimpleRange()
{
assertSimpleRange(5,10,"bytes=5-10",200);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
index 10cda0874f..b937a23e5e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
@@ -23,33 +23,32 @@ import java.util.Date;
import java.util.Enumeration;
import java.util.List;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
*
- *
*/
-public class RFC2616Test extends TestCase
+public class RFC2616Test
{
- Server server=new Server();
- LocalConnector connector=new LocalConnector();
-
- /**
- * Constructor for RFC2616Test.
- *
- * @param arg0
- */
- public RFC2616Test(String arg0)
+ private Server server;
+ private LocalConnector connector;
+
+ @Before
+ public void init() throws Exception
{
- super(arg0);
- server.setConnectors(new Connector[]
- { connector });
+ server = new Server();
+ connector = new LocalConnector();
+ server.addConnector(connector);
ContextHandler vcontext=new ContextHandler();
vcontext.setContextPath("/");
@@ -66,28 +65,18 @@ public class RFC2616Test extends TestCase
{ vcontext, context });
server.setHandler(collection);
- }
-
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- super.setUp();
server.start();
}
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
server.stop();
+ server.join();
}
- /* --------------------------------------------------------------- */
+ @Test
public void test3_3()
{
try
@@ -114,10 +103,9 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test3_6()
{
-
String response=null;
try
{
@@ -178,7 +166,7 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test3_9()
{
try
@@ -202,12 +190,11 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test4_4()
{
try
{
-
String response;
int offset=0;
@@ -265,7 +252,7 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test5_2() throws Exception
{
String response;
@@ -297,10 +284,9 @@ public class RFC2616Test extends TestCase
offset=0;
response=connector.getResponses("GET /path/R1 HTTP/1.1\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 400","3. no host")+1;
-
}
- /* --------------------------------------------------------------- */
+ @Test
public void test8_1()
{
try
@@ -335,7 +321,7 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test8_2()
{
try
@@ -391,6 +377,20 @@ public class RFC2616Test extends TestCase
offset=checkContains(response,offset,"654321","8.2.3 expect 100")+1;
*/
+ // Expect 100 not sent
+ ((StdErrLog)Log.getLog()).setHideStacks(true);
+ offset=0;
+
+ response=connector.getResponses("GET /R1?error=401 HTTP/1.1\n"+
+ "Host: localhost\n"+
+ "Expect: 100-continue\n"+
+ "Content-Type: text/plain\n"+
+ "Content-Length: 8\n"+
+ "\n",true);
+ checkNotContained(response,offset,"HTTP/1.1 100","8.2.3 expect 100");
+ offset=checkContains(response,offset,"HTTP/1.1 401 ","8.2.3 expect 100")+1;
+ offset=checkContains(response,offset,"Connection: close","8.2.3 expect 100")+1;
+
((StdErrLog)Log.getLog()).setHideStacks(false);
}
catch (Exception e)
@@ -398,12 +398,9 @@ public class RFC2616Test extends TestCase
e.printStackTrace();
assertTrue(false);
}
- finally
- {
- }
}
- /* --------------------------------------------------------------- */
+ @Test
public void test9_2()
{
// TODO
@@ -420,7 +417,7 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
+ @Test
public void test9_4()
{
try
@@ -443,7 +440,7 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test9_8()
{
// TODO
@@ -461,7 +458,7 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
+ @Test
public void test10_2_7()
{
// TODO
@@ -514,7 +511,7 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
+ @Test
public void test10_3()
{
// TODO
@@ -564,61 +561,7 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
- public void checkContentRange(LocalConnector listener, String tname, String path, String reqRanges, int expectedStatus, String expectedRange,
- String expectedData)
- {
- try
- {
- String response;
- int offset=0;
-
- String byteRangeHeader="";
- if (reqRanges!=null)
- {
- byteRangeHeader="Range: "+reqRanges+"\n";
- }
-
- response=connector.getResponses("GET /"+path+" HTTP/1.1\n"+"Host: localhost\n"+byteRangeHeader+"Connection: close\n"+"\n");
-
- switch (expectedStatus)
- {
- case 200:
- {
- offset=checkContains(response,offset,"HTTP/1.1 200 OK\r\n",tname+".1. proper 200 OK status code");
- break;
- }
- case 206:
- {
- offset=checkContains(response,offset,"HTTP/1.1 206 Partial Content\r\n",tname+".1. proper 206 Partial Content status code");
- break;
- }
- case 416:
- {
- offset=checkContains(response,offset,"HTTP/1.1 416 Requested Range Not Satisfiable\r\n",tname
- +".1. proper 416 Requested Range not Satisfiable status code");
- break;
- }
- }
-
- if (expectedRange!=null)
- {
- String expectedContentRange="Content-Range: bytes "+expectedRange+"\r\n";
- offset=checkContains(response,offset,expectedContentRange,tname+".2. _content range "+expectedRange);
- }
-
- if (expectedStatus==200||expectedStatus==206)
- {
- offset=checkContains(response,offset,expectedData,tname+".3. subrange data: \""+expectedData+"\"");
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- assertTrue(false);
- }
- }
-
+ @Test
public void test14_16()
{
// TODO
@@ -671,12 +614,11 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
+ @Test
public void test14_23()
{
try
{
-
String response;
int offset=0;
@@ -705,7 +647,7 @@ public class RFC2616Test extends TestCase
}
}
- /* --------------------------------------------------------------- */
+ @Test
public void test14_35()
{
// TODO
@@ -742,7 +684,7 @@ public class RFC2616Test extends TestCase
* catch(Exception e) { e.printStackTrace(); assertTrue(false); }
*/}
- /* --------------------------------------------------------------- */
+ @Test
public void test14_39()
{
// TODO
@@ -764,12 +706,11 @@ public class RFC2616Test extends TestCase
*/
}
- /* --------------------------------------------------------------- */
+ @Test
public void test19_6()
{
try
{
-
String response;
int offset=0;
@@ -821,7 +762,59 @@ public class RFC2616Test extends TestCase
offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3;
assertEquals("19.6.2 closed",-1,response.indexOf("/R3"));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ assertTrue(false);
+ }
+ }
+
+ private void checkContentRange(LocalConnector listener, String tname, String path, String reqRanges, int expectedStatus, String expectedRange, String expectedData)
+ {
+ try
+ {
+ String response;
+ int offset=0;
+
+ String byteRangeHeader="";
+ if (reqRanges!=null)
+ {
+ byteRangeHeader="Range: "+reqRanges+"\n";
+ }
+ response=connector.getResponses("GET /"+path+" HTTP/1.1\n"+"Host: localhost\n"+byteRangeHeader+"Connection: close\n"+"\n");
+
+ switch (expectedStatus)
+ {
+ case 200:
+ {
+ offset=checkContains(response,offset,"HTTP/1.1 200 OK\r\n",tname+".1. proper 200 OK status code");
+ break;
+ }
+ case 206:
+ {
+ offset=checkContains(response,offset,"HTTP/1.1 206 Partial Content\r\n",tname+".1. proper 206 Partial Content status code");
+ break;
+ }
+ case 416:
+ {
+ offset=checkContains(response,offset,"HTTP/1.1 416 Requested Range Not Satisfiable\r\n",tname
+ +".1. proper 416 Requested Range not Satisfiable status code");
+ break;
+ }
+ }
+
+ if (expectedRange!=null)
+ {
+ String expectedContentRange="Content-Range: bytes "+expectedRange+"\r\n";
+ offset=checkContains(response,offset,expectedContentRange,tname+".2. _content range "+expectedRange);
+ }
+
+ if (expectedStatus==200||expectedStatus==206)
+ {
+ offset=checkContains(response,offset,expectedData,tname+".3. subrange data: \""+expectedData+"\"");
+ }
}
catch (Exception e)
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
index d8b62a085c..d6a4e73fc9 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
@@ -18,73 +18,58 @@ import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
-
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
/**
*
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
*/
-public class RequestTest extends TestCase
+public class RequestTest
{
- Server _server = new Server();
- LocalConnector _connector = new LocalConnector();
- RequestHandler _handler = new RequestHandler();
+ private Server _server;
+ private LocalConnector _connector;
+ private RequestHandler _handler;
+ @Before
+ public void init() throws Exception
{
+ _server = new Server();
+ _connector = new LocalConnector();
_connector.setHeaderBufferSize(512);
_connector.setRequestBufferSize(1024);
_connector.setResponseBufferSize(2048);
- }
-
- public RequestTest(String arg0)
- {
- super(arg0);
- _server.setConnectors(new Connector[]{_connector});
-
- }
-
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(RequestTest.class);
- }
-
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- super.setUp();
-
+ _server.addConnector(_connector);
+ _handler = new RequestHandler();
_server.setHandler(_handler);
_server.start();
}
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
_server.stop();
+ _server.join();
}
-
- public void testContentTypeEncoding()
- throws Exception
+ @Test
+ public void testContentTypeEncoding() throws Exception
{
- final ArrayList results = new ArrayList();
+ final ArrayList<String> results = new ArrayList<String>();
_handler._checker = new RequestTester()
{
public boolean check(HttpServletRequest request,HttpServletResponse response)
@@ -127,18 +112,13 @@ public class RequestTest extends TestCase
assertEquals("text/html; charset=\"utf8\"",results.get(i++));
assertEquals("utf8",results.get(i++));
- assertTrue(((String)results.get(i++)).startsWith("text/html"));
+ assertTrue(results.get(i++).startsWith("text/html"));
assertEquals(" x=z; ",results.get(i++));
-
-
}
-
-
- public void testContent()
- throws Exception
+ @Test
+ public void testContent() throws Exception
{
-
final int[] length=new int[1];
_handler._checker = new RequestTester()
@@ -170,8 +150,8 @@ public class RequestTest extends TestCase
}
}
- public void testPartialRead()
- throws Exception
+ @Test
+ public void testPartialRead() throws Exception
{
Handler handler = new AbstractHandler()
{
@@ -185,7 +165,7 @@ public class RequestTest extends TestCase
response.getOutputStream().write(b);
response.flushBuffer();
}
-
+
};
_server.stop();
_server.setHandler(handler);
@@ -207,17 +187,16 @@ public class RequestTest extends TestCase
String responses = _connector.getResponses(request);
System.err.println("response="+responses);
-
+
int index=responses.indexOf("read="+(int)'0');
assertTrue(index>0);
-
+
index=responses.indexOf("read="+(int)'A',index+7);
assertTrue(index>0);
-
}
- public void testPartialInput()
- throws Exception
+ @Test
+ public void testPartialInput() throws Exception
{
Handler handler = new AbstractHandler()
{
@@ -259,11 +238,10 @@ public class RequestTest extends TestCase
index=responses.indexOf("read="+(int)'A',index+7);
assertTrue(index>0);
-
}
- public void testConnectionClose()
- throws Exception
+ @Test
+ public void testConnectionClose() throws Exception
{
String response;
@@ -306,8 +284,6 @@ public class RequestTest extends TestCase
assertTrue(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
-
-
response=_connector.getResponses(
"GET / HTTP/1.0\n"+
"Host: whatever\n"+
@@ -337,9 +313,6 @@ public class RequestTest extends TestCase
assertTrue(response.indexOf("Connection: keep-alive")>0);
assertTrue(response.indexOf("Hello World")>0);
-
-
-
_handler._checker = new RequestTester()
{
public boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException
@@ -371,10 +344,10 @@ public class RequestTest extends TestCase
assertTrue(response.indexOf("Hello World")>0);
}
-
+ @Test
public void testCookies() throws Exception
{
- final ArrayList cookies = new ArrayList();
+ final ArrayList<Cookie> cookies = new ArrayList<Cookie>();
_handler._checker = new RequestTester()
{
@@ -409,8 +382,8 @@ public class RequestTest extends TestCase
);
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertEquals(1,cookies.size());
- assertEquals("name",((Cookie)cookies.get(0)).getName());
- assertEquals("quoted=\\\"value\\\"",((Cookie)cookies.get(0)).getValue());
+ assertEquals("name", cookies.get(0).getName());
+ assertEquals("quoted=\\\"value\\\"", cookies.get(0).getValue());
cookies.clear();
response=_connector.getResponses(
@@ -421,10 +394,10 @@ public class RequestTest extends TestCase
);
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertEquals(2,cookies.size());
- assertEquals("name",((Cookie)cookies.get(0)).getName());
- assertEquals("value",((Cookie)cookies.get(0)).getValue());
- assertEquals("other",((Cookie)cookies.get(1)).getName());
- assertEquals("quoted=;value",((Cookie)cookies.get(1)).getValue());
+ assertEquals("name", cookies.get(0).getName());
+ assertEquals("value", cookies.get(0).getValue());
+ assertEquals("other", cookies.get(1).getName());
+ assertEquals("quoted=;value", cookies.get(1).getValue());
cookies.clear();
@@ -442,14 +415,13 @@ public class RequestTest extends TestCase
);
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertEquals(4,cookies.size());
- assertEquals("name",((Cookie)cookies.get(0)).getName());
- assertEquals("value",((Cookie)cookies.get(0)).getValue());
- assertEquals("other",((Cookie)cookies.get(1)).getName());
- assertEquals("quoted=;value",((Cookie)cookies.get(1)).getValue());
-
- assertTrue((Cookie)cookies.get(0)==(Cookie)cookies.get(2));
- assertTrue((Cookie)cookies.get(1)==(Cookie)cookies.get(3));
+ assertEquals("name", cookies.get(0).getName());
+ assertEquals("value", cookies.get(0).getValue());
+ assertEquals("other", cookies.get(1).getName());
+ assertEquals("quoted=;value", cookies.get(1).getValue());
+ assertSame(cookies.get(0), cookies.get(2));
+ assertSame(cookies.get(1), cookies.get(3));
cookies.clear();
response=_connector.getResponses(
@@ -466,15 +438,17 @@ public class RequestTest extends TestCase
);
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertEquals(4,cookies.size());
- assertEquals("name",((Cookie)cookies.get(0)).getName());
- assertEquals("value",((Cookie)cookies.get(0)).getValue());
- assertEquals("other",((Cookie)cookies.get(1)).getName());
- assertEquals("quoted=;value",((Cookie)cookies.get(1)).getValue());
+ assertEquals("name", cookies.get(0).getName());
+ assertEquals("value", cookies.get(0).getValue());
+ assertEquals("other", cookies.get(1).getName());
+ assertEquals("quoted=;value", cookies.get(1).getValue());
- assertTrue((Cookie)cookies.get(0)!=(Cookie)cookies.get(2));
- assertTrue((Cookie)cookies.get(1)!=(Cookie)cookies.get(3));
+ assertNotSame(cookies.get(0), cookies.get(2));
+ assertNotSame(cookies.get(1), cookies.get(3));
cookies.clear();
+//NOTE: the javax.servlet.http.Cookie class sets the system property org.glassfish.web.rfc2109_cookie_names_enforced
+//to TRUE by default, and rejects all cookie names containing punctuation.Therefore this test cannot use "name2".
response=_connector.getResponses(
"POST / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
@@ -484,33 +458,31 @@ public class RequestTest extends TestCase
"Connection: close\r\n"+
"\r\n");
- assertEquals("name0",((Cookie)cookies.get(0)).getName());
- assertEquals("value0",((Cookie)cookies.get(0)).getValue());
- assertEquals("name1",((Cookie)cookies.get(1)).getName());
- assertEquals("value1",((Cookie)cookies.get(1)).getValue());
- assertEquals("name2",((Cookie)cookies.get(2)).getName());
- assertEquals("\"value2\"",((Cookie)cookies.get(2)).getValue());
- assertEquals("name3",((Cookie)cookies.get(3)).getName());
- assertEquals("value3=value3",((Cookie)cookies.get(3)).getValue());
- assertEquals(2,((Cookie)cookies.get(3)).getVersion());
- assertEquals("/path",((Cookie)cookies.get(3)).getPath());
- assertEquals("acme.com",((Cookie)cookies.get(3)).getDomain());
- assertEquals("$port=8080",((Cookie)cookies.get(3)).getComment());
- assertEquals("name4",((Cookie)cookies.get(4)).getName());
- assertEquals("",((Cookie)cookies.get(4)).getValue());
- assertEquals("name5",((Cookie)cookies.get(5)).getName());
- assertEquals("",((Cookie)cookies.get(5)).getValue());
- assertEquals("name6",((Cookie)cookies.get(6)).getName());
- assertEquals("",((Cookie)cookies.get(6)).getValue());
- assertEquals("name7",((Cookie)cookies.get(7)).getName());
- assertEquals("value7",((Cookie)cookies.get(7)).getValue());
-
+ assertEquals("name0", cookies.get(0).getName());
+ assertEquals("value0", cookies.get(0).getValue());
+ assertEquals("name1", cookies.get(1).getName());
+ assertEquals("value1", cookies.get(1).getValue());
+ assertEquals("name2", cookies.get(2).getName());
+ assertEquals("\"value2\"", cookies.get(2).getValue());
+ assertEquals("name3", cookies.get(3).getName());
+ assertEquals("value3=value3", cookies.get(3).getValue());
+ assertEquals(2, cookies.get(3).getVersion());
+ assertEquals("/path", cookies.get(3).getPath());
+ assertEquals("acme.com", cookies.get(3).getDomain());
+ assertEquals("$port=8080", cookies.get(3).getComment());
+ assertEquals("name4", cookies.get(4).getName());
+ assertEquals("", cookies.get(4).getValue());
+ assertEquals("name5", cookies.get(5).getName());
+ assertEquals("", cookies.get(5).getValue());
+ assertEquals("name6", cookies.get(6).getName());
+ assertEquals("", cookies.get(6).getValue());
+ assertEquals("name7", cookies.get(7).getName());
+ assertEquals("value7", cookies.get(7).getValue());
}
- public void testCookieLeak()
- throws Exception
+ @Test
+ public void testCookieLeak() throws Exception
{
-
final String[] cookie=new String[10];
_handler._checker = new RequestTester()
@@ -529,7 +501,6 @@ public class RequestTest extends TestCase
}
};
-
String request="POST / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Cookie: other=cookie\r\n"+
@@ -561,7 +532,6 @@ public class RequestTest extends TestCase
assertEquals(null,cookie[0]);
assertEquals(null,cookie[1]);
-
request="POST / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Cookie: name=value\r\n"+
@@ -579,22 +549,17 @@ public class RequestTest extends TestCase
assertEquals("value",cookie[0]);
assertEquals(null,cookie[1]);
-
-
}
-
-
-
interface RequestTester
{
boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException;
}
- class RequestHandler extends AbstractHandler
+ private class RequestHandler extends AbstractHandler
{
- RequestTester _checker;
- String _content;
+ private RequestTester _checker;
+ private String _content;
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
@@ -607,9 +572,6 @@ public class RequestTest extends TestCase
response.setStatus(200);
else
response.sendError(500);
-
-
}
}
-
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java
index c8d16f44c2..f90e1220ca 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -16,27 +16,27 @@ package org.eclipse.jetty.server;
import java.io.File;
import java.io.FileOutputStream;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.ResourceCache.Content;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-public class ResourceCacheTest extends TestCase
+public class ResourceCacheTest
{
- Resource directory;
- File[] files=new File[10];
- String[] names=new String[files.length];
- ResourceCache cache = new ResourceCache(new MimeTypes());
- ResourceFactory factory;
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception
+ private Resource directory;
+ private File[] files=new File[10];
+ private String[] names=new String[files.length];
+ private ResourceCache cache = new ResourceCache(new MimeTypes());
+ private ResourceFactory factory;
+
+ @Before
+ public void init() throws Exception
{
for (int i=0;i<files.length;i++)
{
@@ -49,9 +49,9 @@ public class ResourceCacheTest extends TestCase
out.write('\n');
out.close();
}
-
+
directory=Resource.newResource(files[0].getParentFile().getAbsolutePath());
-
+
factory = new ResourceFactory()
{
public Resource getResource(String path)
@@ -65,7 +65,7 @@ public class ResourceCacheTest extends TestCase
return null;
}
}
-
+
};
cache.setMaxCacheSize(95);
cache.setMaxCachedFileSize(85);
@@ -73,54 +73,50 @@ public class ResourceCacheTest extends TestCase
cache.start();
}
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see junit.framework.TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
cache.stop();
}
- /* ------------------------------------------------------------ */
+ @Test
public void testResourceCache() throws Exception
{
assertTrue(cache.lookup("does not exist",factory)==null);
assertTrue(cache.lookup(names[9],factory)==null);
-
+
Content content;
content=cache.lookup(names[8],factory);
assertTrue(content!=null);
assertEquals(80,content.getContentLength());
-
+
assertEquals(80,cache.getCachedSize());
assertEquals(1,cache.getCachedFiles());
content=cache.lookup(names[1],factory);
assertEquals(90,cache.getCachedSize());
assertEquals(2,cache.getCachedFiles());
-
+
content=cache.lookup(names[2],factory);
assertEquals(30,cache.getCachedSize());
assertEquals(2,cache.getCachedFiles());
-
+
content=cache.lookup(names[3],factory);
assertEquals(60,cache.getCachedSize());
assertEquals(3,cache.getCachedFiles());
-
+
content=cache.lookup(names[4],factory);
assertEquals(90,cache.getCachedSize());
assertEquals(3,cache.getCachedFiles());
-
+
content=cache.lookup(names[5],factory);
assertEquals(90,cache.getCachedSize());
assertEquals(2,cache.getCachedFiles());
-
+
content=cache.lookup(names[6],factory);
assertEquals(60,cache.getCachedSize());
assertEquals(1,cache.getCachedFiles());
-
+
FileOutputStream out = new FileOutputStream(files[6]);
out.write(' ');
out.close();
@@ -131,27 +127,25 @@ public class ResourceCacheTest extends TestCase
content=cache.lookup(names[6],factory);
assertEquals(71,cache.getCachedSize());
assertEquals(2,cache.getCachedFiles());
-
+
content=cache.lookup(names[0],factory);
assertEquals(72,cache.getCachedSize());
assertEquals(3,cache.getCachedFiles());
-
+
content=cache.lookup(names[1],factory);
assertEquals(82,cache.getCachedSize());
assertEquals(4,cache.getCachedFiles());
-
+
content=cache.lookup(names[2],factory);
assertEquals(32,cache.getCachedSize());
assertEquals(4,cache.getCachedFiles());
-
+
content=cache.lookup(names[3],factory);
assertEquals(61,cache.getCachedSize());
assertEquals(4,cache.getCachedFiles());
-
+
cache.flushCache();
assertEquals(0,cache.getCachedSize());
assertEquals(0,cache.getCachedFiles());
-
-
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index 63e736061e..c6f9842abc 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -22,15 +22,12 @@ import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
-
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionContext;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
@@ -40,54 +37,43 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.session.AbstractSessionManager;
import org.eclipse.jetty.server.session.HashSessionIdManager;
import org.eclipse.jetty.server.session.HashSessionManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
*
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
*/
-public class ResponseTest extends TestCase
+public class ResponseTest
{
- Server server = new Server();
- LocalConnector connector = new LocalConnector();
+ private Server server;
+ private LocalConnector connector;
- public ResponseTest(String arg0)
+ @Before
+ public void init() throws Exception
{
- super(arg0);
- server.setConnectors(new Connector[]{connector});
+ server = new Server();
+ connector = new LocalConnector();
+ server.addConnector(connector);
server.setHandler(new DumpHandler());
- }
-
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(ResponseTest.class);
- }
-
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- super.setUp();
-
server.start();
}
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
server.stop();
+ server.join();
}
-
- public void testContentType()
- throws Exception
+ @Test
+ public void testContentType() throws Exception
{
-
HttpConnection connection = new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
Response response = connection.getResponse();
@@ -122,9 +108,8 @@ public class ResponseTest extends TestCase
response.recycle();
}
-
- public void testLocale()
- throws Exception
+ @Test
+ public void testLocale() throws Exception
{
HttpConnection connection = new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
@@ -148,8 +133,8 @@ public class ResponseTest extends TestCase
assertTrue(response.toString().indexOf("charset=UTF-8")>0);
}
- public void testContentTypeCharacterEncoding()
- throws Exception
+ @Test
+ public void testContentTypeCharacterEncoding() throws Exception
{
HttpConnection connection = new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
@@ -181,8 +166,8 @@ public class ResponseTest extends TestCase
}
- public void testCharacterEncodingContentType()
- throws Exception
+ @Test
+ public void testCharacterEncodingContentType() throws Exception
{
Response response = new Response(new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
@@ -210,8 +195,8 @@ public class ResponseTest extends TestCase
}
- public void testContentTypeWithCharacterEncoding()
- throws Exception
+ @Test
+ public void testContentTypeWithCharacterEncoding() throws Exception
{
Response response = new Response(new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
@@ -239,8 +224,8 @@ public class ResponseTest extends TestCase
}
- public void testContentTypeWithOther()
- throws Exception
+ @Test
+ public void testContentTypeWithOther() throws Exception
{
Response response = new Response(new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
@@ -262,9 +247,8 @@ public class ResponseTest extends TestCase
assertEquals("text/xml;charset=UTF-8",response.getContentType());
}
-
- public void testContentTypeWithCharacterEncodingAndOther()
- throws Exception
+ @Test
+ public void testContentTypeWithCharacterEncodingAndOther() throws Exception
{
Response response = new Response(new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
@@ -292,6 +276,7 @@ public class ResponseTest extends TestCase
}
+ @Test
public void testStatusCodes() throws Exception
{
Response response=newResponse();
@@ -321,14 +306,18 @@ public class ResponseTest extends TestCase
assertEquals("must-revalidate,no-cache,no-store", response.getHeader(HttpHeaders.CACHE_CONTROL));
}
+ @Test
public void testEncodeRedirect()
throws Exception
{
HttpConnection connection=new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
Response response = new Response(connection);
Request request = connection.getRequest();
+ request.setServerName("myhost");
+ request.setServerPort(8888);
+ request.setContextPath("/path");
- assertEquals("http://host:port/path/info;param?query=0&more=1#target",response.encodeRedirectUrl("http://host:port/path/info;param?query=0&more=1#target"));
+ assertEquals("http://myhost:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://myhost:8888/path/info;param?query=0&more=1#target"));
request.setRequestedSessionId("12345");
request.setRequestedSessionIdFromCookie(false);
@@ -337,12 +326,22 @@ public class ResponseTest extends TestCase
request.setSessionManager(manager);
request.setSession(new TestSession(manager,"12345"));
- assertEquals("http://host:port/path/info;param;jsessionid=12345?query=0&more=1#target",response.encodeRedirectUrl("http://host:port/path/info;param?query=0&more=1#target"));
+ manager.setCheckingRemoteSessionIdEncoding(false);
+
+ assertEquals("http://myhost:8888/path/info;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost:8888/path/info;param?query=0&more=1#target"));
+ assertEquals("http://other:8888/path/info;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
+ assertEquals("http://myhost/path/info;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost/path/info;param?query=0&more=1#target"));
+ assertEquals("http://myhost:8888/other/info;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost:8888/other/info;param?query=0&more=1#target"));
+ manager.setCheckingRemoteSessionIdEncoding(true);
+ assertEquals("http://myhost:8888/path/info;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost:8888/path/info;param?query=0&more=1#target"));
+ assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
+ assertEquals("http://myhost/path/info;param?query=0&more=1#target",response.encodeURL("http://myhost/path/info;param?query=0&more=1#target"));
+ assertEquals("http://myhost:8888/other/info;param?query=0&more=1#target",response.encodeURL("http://myhost:8888/other/info;param?query=0&more=1#target"));
}
- public void testSetBufferSize ()
- throws Exception
+ @Test
+ public void testSetBufferSize () throws Exception
{
Response response = new Response(new HttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
response.setBufferSize(20*1024);
@@ -358,6 +357,7 @@ public class ResponseTest extends TestCase
}
}
+ @Test
public void testHead() throws Exception
{
Server server = new Server();
@@ -417,7 +417,7 @@ public class ResponseTest extends TestCase
return response;
}
- class TestSession extends AbstractSessionManager.Session
+ private class TestSession extends AbstractSessionManager.Session
{
public TestSession(AbstractSessionManager abstractSessionManager, String id)
{
@@ -507,7 +507,6 @@ public class ResponseTest extends TestCase
protected Map newAttributeMap()
{
- // TODO Auto-generated method stub
return null;
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java
index b7dadeda08..76f24ff9fe 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java
@@ -4,23 +4,25 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class SelectChannelServerTest extends HttpServerTestBase
{
- public SelectChannelServerTest()
+ @BeforeClass
+ public static void init() throws Exception
{
- super(new SelectChannelConnector());
- }
+ startServer(new SelectChannelConnector());
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerTest.java
index ee71c54c53..497535d752 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerTest.java
@@ -4,30 +4,33 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import java.util.Random;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
/**
* @version $Revision$
*/
-public class ServerTest extends TestCase
+public class ServerTest
{
/**
* JETTY-87, adding a handler to a server without any handlers should not
* throw an exception
*/
+ @Test
public void testAddHandlerToEmptyServer()
{
Server server=new Server();
@@ -42,6 +45,7 @@ public class ServerTest extends TestCase
}
}
+ @Test
public void testServerWithPort()
{
int port=new Random().nextInt(20000)+10000;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SocketServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SocketServerTest.java
index d644616c00..918ea9f7e3 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/SocketServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SocketServerTest.java
@@ -4,23 +4,25 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.bio.SocketConnector;
+import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class SocketServerTest extends HttpServerTestBase
{
- public SocketServerTest()
+ @BeforeClass
+ public static void init() throws Exception
{
- super(new SocketConnector());
- }
+ startServer(new SocketConnector());
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
index eecf2d80e5..7f05ba9f02 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
@@ -4,51 +4,47 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
import java.net.Socket;
import java.util.Queue;
import java.util.Random;
-import java.util.Timer;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
-public class StressTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class StressTest
{
- protected Server _server = new Server();
- protected TestHandler _handler = new TestHandler();
- protected Connector _connector;
- protected InetAddress _addr;
- protected int _port;
- protected volatile AtomicInteger[] _loops;
- protected QueuedThreadPool _threads=new QueuedThreadPool(new BlockingArrayQueue<Runnable>(4,4));
- // protected ExecutorThreadPool _threads=new ExecutorThreadPool(100,500,10000,TimeUnit.MILLISECONDS);
- protected boolean _stress;
- private AtomicInteger _handled=new AtomicInteger(0);
- private ConcurrentLinkedQueue[] _latencies= {
+ private static boolean _stress;
+ private static QueuedThreadPool _threads;
+ private static Server _server;
+ private static SelectChannelConnector _connector;
+ private static final AtomicInteger _handled=new AtomicInteger(0);
+ private static final ConcurrentLinkedQueue[] _latencies= {
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>(),
@@ -56,44 +52,10 @@ public class StressTest extends TestCase
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>()
};
- private Random _random=new Random();
-
- @Override
- protected void setUp() throws Exception
- {
- _stress= Boolean.getBoolean("STRESS");
-
- _threads.setMaxThreads(500);
- _server.setThreadPool(_threads);
- SelectChannelConnector c_connector=new SelectChannelConnector();
- c_connector.setAcceptors(1);
- c_connector.setAcceptQueueSize(1000);
-
- // c_connector.setPort(8080);
-
- _connector=c_connector;
- _connector.setMaxIdleTime(30000);
-
- _server.setConnectors(new Connector[]{ _connector });
- _server.setHandler(_handler);
- _server.start();
- _port=_connector.getLocalPort();
- _addr=InetAddress.getLocalHost();
- // _addr=Inet4Address.getByName("10.10.1.16");
- // System.err.println("ADDR "+_addr+":"+_port);
-
- for (Queue q:_latencies)
- q.clear();
- _handled.set(0);
- }
- @Override
- protected void tearDown() throws Exception
- {
- _server.stop();
- }
-
- final static String[] __tests =
+ private volatile AtomicInteger[] _loops;
+ private final Random _random=new Random();
+ private static final String[] __tests =
{
"/path/0",
"/path/1",
@@ -112,166 +74,103 @@ public class StressTest extends TestCase
"/path/e",
"/path/f",
};
-
-
- public void doPaths(int thread,String name,boolean persistent) throws Exception
- {
- if (persistent)
- {
- long start=System.currentTimeMillis();
- Socket socket= new Socket(_addr,_port);
- socket.setSoTimeout(30000);
- socket.setSoLinger(false,0);
-
- long connected=System.currentTimeMillis();
-
- for (int i=0;i<__tests.length;i++)
- {
- String uri=__tests[i]+"/"+name+"/"+i;
-
- String close=((i+1)<__tests.length)?"":"Connection: close\r\n";
- String request =
- "GET "+uri+" HTTP/1.1\r\n"+
- "Host: localhost\r\n"+
- "start: "+start+"\r\n"+
- close+"\r\n";
- socket.getOutputStream().write(request.getBytes());
- socket.getOutputStream().flush();
- Thread.yield();
- }
-
- long written=System.currentTimeMillis();
-
- String response = IO.toString(socket.getInputStream());
- socket.close();
-
- long end=System.currentTimeMillis();
-
- int bodies = count(response,"HTTP/1.1 200 OK");
- if (__tests.length!=bodies)
- System.err.println("responses=\n"+response+"\n---");
- assertEquals(name,__tests.length,bodies);bodies = count(response,"HTTP/1.1 200 OK");
-
- long bind=connected-start;
- long flush=(written-connected)/__tests.length;
- long read=(end-written)/__tests.length;
-
- int offset=0;
- for (int i=0;i<__tests.length;i++)
- {
- offset=response.indexOf("DATA "+__tests[i],offset);
- assertTrue(offset>=0);
- offset+=__tests[i].length()+5;
-
- if (bind<0 || flush<0 || read <0)
- {
- System.err.println(bind+","+flush+","+read);
- }
-
- _latencies[0].add((i==0)?new Long(bind):0);
- _latencies[1].add((i==0)?new Long(bind+flush):flush);
- _latencies[5].add((i==0)?new Long(bind+flush+read):(flush+read));
- }
- }
- else
- {
- for (int i=0;i<__tests.length;i++)
- {
- String uri=__tests[i]+"/"+name+"/"+i;
-
- long start=System.currentTimeMillis();
- String close="Connection: close\r\n";
- String request =
- "GET "+uri+" HTTP/1.1\r\n"+
- "Host: localhost\r\n"+
- "start: "+start+"\r\n"+
- close+"\r\n";
-
- Socket socket = new Socket(_addr,_port);
- socket.setSoTimeout(10000);
- socket.setSoLinger(false,0);
-
- _latencies[0].add(new Long(System.currentTimeMillis()-start));
+ @BeforeClass
+ public static void init() throws Exception
+ {
+ _stress= Boolean.getBoolean("STRESS");
- socket.getOutputStream().write(request.getBytes());
- socket.getOutputStream().flush();
+ _threads = new QueuedThreadPool(new BlockingArrayQueue<Runnable>(4,4));
+ _threads.setMaxThreads(500);
+ _server = new Server();
+ _server.setThreadPool(_threads);
- _latencies[1].add(new Long(System.currentTimeMillis()-start));
+ _connector = new SelectChannelConnector();
+ _connector.setAcceptors(1);
+ _connector.setAcceptQueueSize(1000);
+ _connector.setMaxIdleTime(30000);
+ _server.addConnector(_connector);
- String response = IO.toString(socket.getInputStream());
- socket.close();
- long end=System.currentTimeMillis();
+ TestHandler _handler = new TestHandler();
+ _server.setHandler(_handler);
- response=response.substring(response.indexOf("\r\n\r\n")+4);
+ _server.start();
+ }
- assertTrue(uri,response.startsWith("DATA "+__tests[i]));
- long latency=end-start;
+ @AfterClass
+ public static void destroy() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
- _latencies[5].add(new Long(latency));
- }
- }
+ @Before
+ public void reset()
+ {
+ _handled.set(0);
+ for (Queue q : _latencies)
+ q.clear();
}
-
- public void doLoops(int thread, String name, int loops,boolean persistent) throws Exception
+
+ @Test
+ public void testNonPersistent() throws Throwable
{
- try
+ if (_stress)
{
- for (int i=0;i<loops;i++)
- {
- _loops[thread].set(i);
- doPaths(thread,name+"-"+i,persistent);
- Thread.sleep(1+_random.nextInt(10)*_random.nextInt(10));
- Thread.sleep(10);
- }
- _loops[thread].set(loops);
+ System.err.println("STRESS!");
+ doThreads(200,100,false);
}
- catch(Exception e)
+ else
+ doThreads(10,20,false);
+ }
+
+ @Test
+ public void testPersistent() throws Throwable
+ {
+ if (_stress)
{
- System.err.println(e);
- _loops[thread].set(-_loops[thread].get());
- throw e;
+ System.err.println("STRESS!");
+ doThreads(200,100,true);
}
+ else
+ doThreads(20,40,true);
}
- public void doThreads(int threads,final int loops,final boolean persistent) throws Throwable
+ private void doThreads(int threadCount, final int loops, final boolean persistent) throws Throwable
{
- final Throwable[] throwable=new Throwable[threads];
- final Thread[] thread=new Thread[threads];
+ final Throwable[] throwables = new Throwable[threadCount];
+ final Thread[] threads = new Thread[threadCount];
try
{
- for (int i=0;i<threads;i++)
+ for (int i=0;i< threadCount;i++)
{
final int id=i;
final String name = "T"+i;
- thread[i]=new Thread()
+ threads[i]=new Thread()
{
@Override
- public void run()
- {
+ public void run()
+ {
try
{
- doLoops(id,name,loops,persistent);
+ doLoops(id,name,loops,persistent);
}
catch(Throwable th)
{
th.printStackTrace();
- throwable[id]=th;
- }
- finally
- {
+ throwables[id]=th;
}
}
};
}
- _loops=new AtomicInteger[threads];
- for (int i=0;i<threads;i++)
+ _loops=new AtomicInteger[threadCount];
+ for (int i=0;i< threadCount;i++)
{
_loops[i]=new AtomicInteger(0);
- thread[i].start();
+ threads[i].start();
}
String last=null;
@@ -285,7 +184,7 @@ public class StressTest extends TestCase
int min=loops;
int max=0;
int total=0;
- for (int i=0;i<threads;i++)
+ for (int i=0;i< threadCount;i++)
{
int l=_loops[i].get();
if (l<0)
@@ -301,10 +200,10 @@ public class StressTest extends TestCase
max=l;
total+=l;
if (l==loops)
- finished++;
- }
+ finished++;
+ }
}
- String status = "min/ave/max/target="+min+"/"+(total/threads)+"/"+max+"/"+loops+" errors/finished/loops="+errors+"/"+finished+"/"+threads+" idle/threads="+(_threads.getIdleThreads())+"/"+_threads.getThreads();
+ String status = "min/ave/max/target="+min+"/"+(total/ threadCount)+"/"+max+"/"+loops+" errors/finished/loops="+errors+"/"+finished+"/"+ threadCount +" idle/threads="+(_threads.getIdleThreads())+"/"+_threads.getThreads();
if (status.equals(last))
{
if (same++>5)
@@ -320,19 +219,19 @@ public class StressTest extends TestCase
same=0;
last=status;
Log.info(_server.getThreadPool().toString()+" "+status);
- if ((finished+errors)==threads)
+ if ((finished+errors)== threadCount)
break;
}
- for (int i=0;i<threads;i++)
- thread[i].join();
+ for (Thread thread : threads)
+ thread.join();
- for (int i=0;i<threads;i++)
- if (throwable[i]!=null)
- throw throwable[i];
-
- for (int i=0;i<_latencies.length;i++)
- assertEquals(_handled.get(),_latencies[i].size());
+ for (Throwable throwable : throwables)
+ if (throwable!=null)
+ throw throwable;
+
+ for (ConcurrentLinkedQueue _latency : _latencies)
+ assertEquals(_handled.get(), _latency.size());
}
finally
{
@@ -348,18 +247,18 @@ public class StressTest extends TestCase
length[i] = latencies.size();
loop:
- for (long latency:(Queue<Long>)(_latencies[i]))
+ for (long latency : latencies)
+ {
+ for (int q=0;q<quantums;q++)
{
- for (int q=0;q<quantums;q++)
+ if (latency>=(q*100) && latency<((q+1)*100))
{
- if (latency>=(q*100) && latency<((q+1)*100))
- {
- count[i][q]++;
- continue loop;
- }
+ count[i][q]++;
+ continue loop;
}
- other[i]++;
}
+ other[i]++;
+ }
}
System.out.println(" stage:\tbind\twrite\trecv\tdispatch\twrote\ttotal");
@@ -387,76 +286,164 @@ public class StressTest extends TestCase
}
}
- public void testNonPersistent() throws Throwable
+ private void doLoops(int thread, String name, int loops,boolean persistent) throws Exception
{
- if (_stress)
+ try
{
- System.err.println("STRESS!");
- doThreads(200,100,false);
+ for (int i=0;i<loops;i++)
+ {
+ _loops[thread].set(i);
+ doPaths(thread,name+"-"+i,persistent);
+ Thread.sleep(1+_random.nextInt(10)*_random.nextInt(10));
+ Thread.sleep(10);
+ }
+ _loops[thread].set(loops);
+ }
+ catch(Exception e)
+ {
+ System.err.println(e);
+ _loops[thread].set(-_loops[thread].get());
+ throw e;
}
- else
- doThreads(10,20,false);
}
- public void testPersistent() throws Throwable
+ private void doPaths(int thread,String name,boolean persistent) throws Exception
{
- if (_stress)
+ if (persistent)
{
- System.err.println("STRESS!");
- doThreads(200,400,true);
+ long start=System.currentTimeMillis();
+ Socket socket= new Socket("localhost", _connector.getLocalPort());
+ socket.setSoTimeout(30000);
+ socket.setSoLinger(false,0);
+
+ long connected=System.currentTimeMillis();
+
+ for (int i=0;i<__tests.length;i++)
+ {
+ String uri=__tests[i]+"/"+name+"/"+i;
+
+ String close=((i+1)<__tests.length)?"":"Connection: close\r\n";
+ String request =
+ "GET "+uri+" HTTP/1.1\r\n"+
+ "Host: localhost\r\n"+
+ "start: "+start+"\r\n"+
+ close+"\r\n";
+
+ socket.getOutputStream().write(request.getBytes());
+ socket.getOutputStream().flush();
+ Thread.yield();
+ }
+
+ long written=System.currentTimeMillis();
+
+ String response = IO.toString(socket.getInputStream());
+ socket.close();
+
+ long end=System.currentTimeMillis();
+
+ int bodies = count(response,"HTTP/1.1 200 OK");
+ if (__tests.length!=bodies)
+ System.err.println("responses=\n"+response+"\n---");
+ assertEquals(name,__tests.length,bodies);
+ bodies = count(response,"HTTP/1.1 200 OK");
+
+ long bind=connected-start;
+ long flush=(written-connected)/__tests.length;
+ long read=(end-written)/__tests.length;
+
+ int offset=0;
+ for (int i=0;i<__tests.length;i++)
+ {
+ offset=response.indexOf("DATA "+__tests[i],offset);
+ assertTrue(offset>=0);
+ offset+=__tests[i].length()+5;
+
+ if (bind<0 || flush<0 || read <0)
+ {
+ System.err.println(bind+","+flush+","+read);
+ }
+
+ _latencies[0].add((i==0)?new Long(bind):0);
+ _latencies[1].add((i==0)?new Long(bind+flush):flush);
+ _latencies[5].add((i==0)?new Long(bind+flush+read):(flush+read));
+ }
}
else
- doThreads(20,40,true);
+ {
+ for (int i=0;i<__tests.length;i++)
+ {
+ String uri=__tests[i]+"/"+name+"/"+i;
+
+ long start=System.currentTimeMillis();
+ String close="Connection: close\r\n";
+ String request =
+ "GET "+uri+" HTTP/1.1\r\n"+
+ "Host: localhost\r\n"+
+ "start: "+start+"\r\n"+
+ close+"\r\n";
+
+ Socket socket = new Socket("localhost", _connector.getLocalPort());
+ socket.setSoTimeout(10000);
+ socket.setSoLinger(false,0);
+
+ _latencies[0].add(new Long(System.currentTimeMillis()-start));
+
+ socket.getOutputStream().write(request.getBytes());
+ socket.getOutputStream().flush();
+
+ _latencies[1].add(new Long(System.currentTimeMillis()-start));
+
+ String response = IO.toString(socket.getInputStream());
+ socket.close();
+ long end=System.currentTimeMillis();
+
+ response=response.substring(response.indexOf("\r\n\r\n")+4);
+
+ assertTrue(uri,response.startsWith("DATA "+__tests[i]));
+ long latency=end-start;
+
+ _latencies[5].add(new Long(latency));
+ }
+ }
}
-
-
private int count(String s,String sub)
{
int count=0;
int index=s.indexOf(sub);
-
+
while(index>=0)
{
count++;
index=s.indexOf(sub,index+sub.length());
- }
+ }
return count;
}
-
- private class TestHandler extends HandlerWrapper
+
+ private static class TestHandler extends HandlerWrapper
{
- private Timer _timer;
-
- public TestHandler()
- {
- _timer=new Timer();
- }
-
@Override
public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
long now=System.currentTimeMillis();
long start=Long.parseLong(baseRequest.getHeader("start"));
long received=baseRequest.getTimeStamp();
-
+
_handled.incrementAndGet();
long delay=received-start;
if (delay<0)
delay=0;
_latencies[2].add(new Long(delay));
_latencies[3].add(new Long(now-start));
-
+
response.setStatus(200);
response.getOutputStream().print("DATA "+request.getPathInfo()+"\n\n");
baseRequest.setHandled(true);
long end=System.currentTimeMillis();
-
+
_latencies[4].add(new Long(System.currentTimeMillis()-start));
-
+
return;
}
}
-
-
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java
index 148dbe9c6e..a71510f82e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@@ -17,17 +17,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class UnreadInputTest extends TestCase
+public class UnreadInputTest
{
public static final String __OK_RESPONSE = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nServer: Jetty(7.0.x)\r\n\r\n";
protected Server _server = new Server();
@@ -36,23 +36,9 @@ public class UnreadInputTest extends TestCase
protected Socket _socket;
protected OutputStream _outputStream;
protected InputStream _inputStream;
-
- public class NoopHandler extends AbstractHandler
- {
- public void handle(String target, Request baseRequest,
- HttpServletRequest request, HttpServletResponse response) throws IOException,
- ServletException
- {
- //don't read the input, just send something back
- ((Request)request).setHandled(true);
- response.setStatus(200);
- }
- }
-
-
-
- @Override
- protected void setUp() throws Exception
+
+ @Before
+ public void init() throws Exception
{
//server side
_connector = new SocketConnector();
@@ -60,23 +46,24 @@ public class UnreadInputTest extends TestCase
_server.setHandler(new NoopHandler());
_server.start();
_port = _connector.getLocalPort();
-
+
//client side
_socket = new Socket((String)null, _port);
_outputStream = _socket.getOutputStream();
_inputStream = _socket.getInputStream();
}
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
+ _socket.close();
+
_server.stop();
+ _server.join();
}
-
-
- public void testUnreadInput ()
- throws Exception
+ @Test
+ public void testUnreadInput () throws Exception
{
for (int i=0; i<2; i++)
{
@@ -107,18 +94,24 @@ public class UnreadInputTest extends TestCase
Thread.sleep(1000L);
//write the rest
- _outputStream.write(bytes, bytes.length/2, (bytes.length - bytes.length/2));
+ _outputStream.write(bytes, bytes.length/2, (bytes.length - bytes.length/2));
}
-
+
byte[] inbuf = new byte[__OK_RESPONSE.getBytes().length*2];
int x = _inputStream.read(inbuf);
System.err.println(new String(inbuf, 0, x));
-
- _inputStream.close();
- _outputStream.close();
- _socket.close();
}
-
-
+
+ public class NoopHandler extends AbstractHandler
+ {
+ public void handle(String target, Request baseRequest,
+ HttpServletRequest request, HttpServletResponse response) throws IOException,
+ ServletException
+ {
+ //don't read the input, just send something back
+ ((Request)request).setHandled(true);
+ response.setStatus(200);
+ }
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/AbstractProxyHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/AbstractProxyHandlerTest.java
new file mode 100644
index 0000000000..3f9635a319
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/AbstractProxyHandlerTest.java
@@ -0,0 +1,173 @@
+package org.eclipse.jetty.server.handler;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.Socket;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.AfterClass;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public abstract class AbstractProxyHandlerTest
+{
+ protected static Server server;
+ protected static Connector serverConnector;
+ protected static Server proxy;
+ protected static Connector proxyConnector;
+
+ protected static void startServer(Connector connector, Handler handler) throws Exception
+ {
+ server = new Server();
+ serverConnector = connector;
+ server.addConnector(serverConnector);
+ server.setHandler(handler);
+ server.start();
+ }
+
+ protected static void startProxy() throws Exception
+ {
+ proxy = new Server();
+ proxyConnector = new SelectChannelConnector();
+ proxy.addConnector(proxyConnector);
+ proxy.setHandler(new ProxyHandler());
+ proxy.start();
+ }
+
+ @AfterClass
+ public static void stop() throws Exception
+ {
+ stopProxy();
+ stopServer();
+ }
+
+ protected static void stopServer() throws Exception
+ {
+ server.stop();
+ server.join();
+ }
+
+ protected static void stopProxy() throws Exception
+ {
+ proxy.stop();
+ proxy.join();
+ }
+
+ protected Response readResponse(BufferedReader reader) throws IOException
+ {
+ // Simplified parser for HTTP responses
+ String line = reader.readLine();
+ if (line == null)
+ throw new EOFException();
+ Matcher responseLine = Pattern.compile("HTTP/1\\.1\\s+(\\d+)").matcher(line);
+ assertTrue(responseLine.lookingAt());
+ String code = responseLine.group(1);
+
+ Map<String, String> headers = new LinkedHashMap<String, String>();
+ while ((line = reader.readLine()) != null)
+ {
+ if (line.trim().length() == 0)
+ break;
+
+ Matcher header = Pattern.compile("([^:]+):\\s*(.*)").matcher(line);
+ assertTrue(header.lookingAt());
+ String headerName = header.group(1);
+ String headerValue = header.group(2);
+ headers.put(headerName.toLowerCase(), headerValue.toLowerCase());
+ }
+
+ StringBuilder body = new StringBuilder();
+ if (headers.containsKey("content-length"))
+ {
+ int length = Integer.parseInt(headers.get("content-length"));
+ for (int i = 0; i < length; ++i)
+ {
+ char c = (char)reader.read();
+ body.append(c);
+ }
+ }
+ else if ("chunked".equals(headers.get("transfer-encoding")))
+ {
+ while ((line = reader.readLine()) != null)
+ {
+ if ("0".equals(line))
+ {
+ line = reader.readLine();
+ assertEquals("", line);
+ break;
+ }
+
+ int length = Integer.parseInt(line, 16);
+ for (int i = 0; i < length; ++i)
+ {
+ char c = (char)reader.read();
+ body.append(c);
+ }
+ line = reader.readLine();
+ assertEquals("", line);
+ }
+ }
+
+ return new Response(code, headers, body.toString().trim());
+ }
+
+ protected Socket newSocket() throws IOException
+ {
+ Socket socket = new Socket("localhost", proxyConnector.getLocalPort());
+ socket.setSoTimeout(5000);
+ return socket;
+ }
+
+ protected class Response
+ {
+ private final String code;
+ private final Map<String, String> headers;
+ private final String body;
+
+ private Response(String code, Map<String, String> headers, String body)
+ {
+ this.code = code;
+ this.headers = headers;
+ this.body = body;
+ }
+
+ public String getCode()
+ {
+ return code;
+ }
+
+ public Map<String, String> getHeaders()
+ {
+ return headers;
+ }
+
+ public String getBody()
+ {
+ return body;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(code).append("\r\n");
+ for (Map.Entry<String, String> entry : headers.entrySet())
+ builder.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
+ builder.append("\r\n");
+ builder.append(body);
+ return builder.toString();
+ }
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java
index 6099320cf1..fa8022e1c2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java
@@ -4,30 +4,32 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
import java.io.IOException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
+import org.junit.Test;
-public class ContextHandlerCollectionTest extends TestCase
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ContextHandlerCollectionTest
{
+ @Test
public void testVirtualHostNormalization() throws Exception
{
Server server = new Server();
@@ -83,23 +85,23 @@ public class ContextHandlerCollectionTest extends TestCase
{
server.stop();
}
-
}
-
+
+ @Test
public void testVirtualHostWildcard() throws Exception
{
Server server = new Server();
LocalConnector connector = new LocalConnector();
server.setConnectors(new Connector[] { connector });
-
+
ContextHandler context = new ContextHandler("/");
-
+
IsHandledHandler handler = new IsHandledHandler();
context.setHandler(handler);
ContextHandlerCollection c = new ContextHandlerCollection();
c.addHandler(context);
-
+
server.setHandler(c);
try
@@ -107,19 +109,19 @@ public class ContextHandlerCollectionTest extends TestCase
server.start();
checkWildcardHost(true,server,null,new String[] {"example.com", ".example.com", "vhost.example.com"});
checkWildcardHost(false,server,new String[] {null},new String[] {"example.com", ".example.com", "vhost.example.com"});
-
+
checkWildcardHost(true,server,new String[] {"example.com", "*.example.com"}, new String[] {"example.com", ".example.com", "vhost.example.com"});
checkWildcardHost(false,server,new String[] {"example.com", "*.example.com"}, new String[] {"badexample.com", ".badexample.com", "vhost.badexample.com"});
-
+
checkWildcardHost(false,server,new String[] {"*."}, new String[] {"anything.anything"});
-
+
checkWildcardHost(true,server,new String[] {"*.example.com"}, new String[] {"vhost.example.com", ".example.com"});
checkWildcardHost(false,server,new String[] {"*.example.com"}, new String[] {"vhost.www.example.com", "example.com", "www.vhost.example.com"});
checkWildcardHost(true,server,new String[] {"*.sub.example.com"}, new String[] {"vhost.sub.example.com", ".sub.example.com"});
checkWildcardHost(false,server,new String[] {"*.sub.example.com"}, new String[] {".example.com", "sub.example.com", "vhost.example.com"});
-
- checkWildcardHost(false,server,new String[] {"example.*.com","example.com.*"}, new String[] {"example.vhost.com", "example.com.vhost", "example.com"});
+
+ checkWildcardHost(false,server,new String[] {"example.*.com","example.com.*"}, new String[] {"example.vhost.com", "example.com.vhost", "example.com"});
}
finally
{
@@ -137,11 +139,11 @@ public class ContextHandlerCollectionTest extends TestCase
context.setVirtualHosts(contextHosts);
// trigger this manually; it's supposed to be called when adding the handler
handlerCollection.mapContexts();
-
+
for(String host : requestHosts)
{
connector.getResponses("GET / HTTP/1.1\n" + "Host: "+host+"\n\n");
- if(succeed)
+ if(succeed)
assertTrue("'"+host+"' should have been handled.",handler.isHandled());
else
assertFalse("'"+host + "' should not have been handled.", handler.isHandled());
@@ -149,8 +151,8 @@ public class ContextHandlerCollectionTest extends TestCase
}
}
-
- public static final class IsHandledHandler extends AbstractHandler
+
+ private static final class IsHandledHandler extends AbstractHandler
{
private boolean handled;
@@ -170,5 +172,4 @@ public class ContextHandlerCollectionTest extends TestCase
handled = false;
}
}
-
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
index 180b7fe280..8e141d64b2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
@@ -5,86 +5,56 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.handler;
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
+import junit.framework.Assert;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.Resource;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @version $Revision$
*/
-public class ContextHandlerTest extends TestCase
+public class ContextHandlerTest
{
+ @Test
public void testGetResourcePathsWhenSuppliedPathEndsInSlash() throws Exception
{
checkResourcePathsForExampleWebApp("/WEB-INF/");
}
+ @Test
public void testGetResourcePathsWhenSuppliedPathDoesNotEndInSlash() throws Exception
{
checkResourcePathsForExampleWebApp("/WEB-INF");
}
- private void checkResourcePathsForExampleWebApp(String root) throws IOException, MalformedURLException
- {
- File testDirectory = setupTestDirectory();
-
- ContextHandler handler = new ContextHandler();
-
- assertTrue("Not a directory " + testDirectory,testDirectory.isDirectory());
- handler.setBaseResource(Resource.newResource(testDirectory.toURL()));
-
- List paths = new ArrayList(handler.getResourcePaths(root));
- assertEquals(2,paths.size());
-
- Collections.sort(paths);
- assertEquals("/WEB-INF/jsp/",paths.get(0));
- assertEquals("/WEB-INF/web.xml",paths.get(1));
- }
-
- private File setupTestDirectory() throws IOException
- {
- File tmpDir = new File( System.getProperty( "basedir" ) + "/target/tmp/ContextHandlerTest" );
- tmpDir.mkdirs();
- File tmp = File.createTempFile("cht",null, tmpDir );
- tmp.delete();
- tmp.mkdir();
- tmp.deleteOnExit();
- File root = new File(tmp,getClass().getName());
- root.mkdir();
-
- File webInf = new File(root,"WEB-INF");
- webInf.mkdir();
-
- new File(webInf,"jsp").mkdir();
- new File(webInf,"web.xml").createNewFile();
-
- return root;
- }
-
+ @Test
public void testVirtualHostNormalization() throws Exception
{
Server server = new Server();
@@ -142,7 +112,8 @@ public class ContextHandlerTest extends TestCase
}
}
-
+
+ @Test
public void testVirtualHostWildcard() throws Exception
{
Server server = new Server();
@@ -150,7 +121,7 @@ public class ContextHandlerTest extends TestCase
server.setConnectors(new Connector[] { connector });
ContextHandler context = new ContextHandler("/");
-
+
IsHandledHandler handler = new IsHandledHandler();
context.setHandler(handler);
@@ -161,19 +132,118 @@ public class ContextHandlerTest extends TestCase
server.start();
checkWildcardHost(true,server,null,new String[] {"example.com", ".example.com", "vhost.example.com"});
checkWildcardHost(false,server,new String[] {null},new String[] {"example.com", ".example.com", "vhost.example.com"});
-
+
checkWildcardHost(true,server,new String[] {"example.com", "*.example.com"}, new String[] {"example.com", ".example.com", "vhost.example.com"});
checkWildcardHost(false,server,new String[] {"example.com", "*.example.com"}, new String[] {"badexample.com", ".badexample.com", "vhost.badexample.com"});
-
+
checkWildcardHost(false,server,new String[] {"*."}, new String[] {"anything.anything"});
-
+
checkWildcardHost(true,server,new String[] {"*.example.com"}, new String[] {"vhost.example.com", ".example.com"});
checkWildcardHost(false,server,new String[] {"*.example.com"}, new String[] {"vhost.www.example.com", "example.com", "www.vhost.example.com"});
checkWildcardHost(true,server,new String[] {"*.sub.example.com"}, new String[] {"vhost.sub.example.com", ".sub.example.com"});
checkWildcardHost(false,server,new String[] {"*.sub.example.com"}, new String[] {".example.com", "sub.example.com", "vhost.example.com"});
+
+ checkWildcardHost(false,server,new String[] {"example.*.com","example.com.*"}, new String[] {"example.vhost.com", "example.com.vhost", "example.com"});
+ }
+ finally
+ {
+ server.stop();
+ }
+ }
+
+ @Test
+ public void testAttributes() throws Exception
+ {
+ ContextHandler handler = new ContextHandler();
+ handler.setAttribute("aaa","111");
+ handler.getServletContext().setAttribute("bbb","222");
+ assertEquals("111",handler.getServletContext().getAttribute("aaa"));
+ assertEquals(null,handler.getAttribute("bbb"));
+
+ handler.start();
+
+ handler.getServletContext().setAttribute("aaa","000");
+ handler.setAttribute("ccc","333");
+ handler.getServletContext().setAttribute("ddd","444");
+ assertEquals("111",handler.getServletContext().getAttribute("aaa"));
+ assertEquals(null,handler.getServletContext().getAttribute("bbb"));
+ handler.getServletContext().setAttribute("bbb","222");
+ assertEquals("333",handler.getServletContext().getAttribute("ccc"));
+ assertEquals("444",handler.getServletContext().getAttribute("ddd"));
+
+ assertEquals("111",handler.getAttribute("aaa"));
+ assertEquals(null,handler.getAttribute("bbb"));
+ assertEquals("333",handler.getAttribute("ccc"));
+ assertEquals(null,handler.getAttribute("ddd"));
+
+ handler.stop();
+
+ assertEquals("111",handler.getServletContext().getAttribute("aaa"));
+ assertEquals(null,handler.getServletContext().getAttribute("bbb"));
+ assertEquals("333",handler.getServletContext().getAttribute("ccc"));
+ assertEquals(null,handler.getServletContext().getAttribute("ddd"));
+ }
+
+ private void checkResourcePathsForExampleWebApp(String root) throws IOException
+ {
+ File testDirectory = setupTestDirectory();
+
+ ContextHandler handler = new ContextHandler();
+
+ assertTrue("Not a directory " + testDirectory,testDirectory.isDirectory());
+ handler.setBaseResource(Resource.newResource(testDirectory.toURI().toURL()));
+
+ List<String> paths = new ArrayList<String>(handler.getResourcePaths(root));
+ assertEquals(2,paths.size());
+
+ Collections.sort(paths);
+ assertEquals("/WEB-INF/jsp/",paths.get(0));
+ assertEquals("/WEB-INF/web.xml",paths.get(1));
+ }
+
+ private File setupTestDirectory() throws IOException
+ {
+ File tmpDir = new File( System.getProperty( "basedir" ) + "/target/tmp/ContextHandlerTest" );
+ if (!tmpDir.exists())
+ assertTrue(tmpDir.mkdirs());
+ File tmp = File.createTempFile("cht",null, tmpDir );
+ assertTrue(tmp.delete());
+ assertTrue(tmp.mkdir());
+ tmp.deleteOnExit();
+ File root = new File(tmp,getClass().getName());
+ assertTrue(root.mkdir());
+
+ File webInf = new File(root,"WEB-INF");
+ assertTrue(webInf.mkdir());
+
+ assertTrue(new File(webInf,"jsp").mkdir());
+ assertTrue(new File(webInf,"web.xml").createNewFile());
+
+ return root;
+ }
+
+ @Test
+ public void testUncheckedPrintWriter() throws Exception
+ {
+ Server server = new Server();
+ LocalConnector connector = new LocalConnector();
+ server.setConnectors(new Connector[] { connector });
+ ContextHandler context = new ContextHandler("/");
+ WriterHandler handler = new WriterHandler();
+ context.setHandler(handler);
+ server.setHandler(context);
+
+ try
+ {
+ server.start();
- checkWildcardHost(false,server,new String[] {"example.*.com","example.com.*"}, new String[] {"example.vhost.com", "example.com.vhost", "example.com"});
+ String response = connector.getResponses("GET / HTTP/1.1\n" + "Host: www.example.com.\n\n");
+
+ Assert.assertTrue(response.indexOf("Goodbye")>0);
+ Assert.assertTrue(response.indexOf("dead")<0);
+ Assert.assertTrue(handler.error);
+ Assert.assertTrue(handler.throwable!=null);
}
finally
{
@@ -186,12 +256,12 @@ public class ContextHandlerTest extends TestCase
LocalConnector connector = (LocalConnector)server.getConnectors()[0];
ContextHandler context = (ContextHandler)server.getHandler();
context.setVirtualHosts(contextHosts);
-
+
IsHandledHandler handler = (IsHandledHandler)context.getHandler();
for(String host : requestHosts)
{
connector.getResponses("GET / HTTP/1.1\n" + "Host: "+host+"\n\n");
- if(succeed)
+ if(succeed)
assertTrue("'"+host+"' should have been handled.",handler.isHandled());
else
assertFalse("'"+host + "' should not have been handled.", handler.isHandled());
@@ -199,8 +269,8 @@ public class ContextHandlerTest extends TestCase
}
}
-
- public static final class IsHandledHandler extends AbstractHandler
+
+ private static final class IsHandledHandler extends AbstractHandler
{
private boolean handled;
@@ -220,38 +290,35 @@ public class ContextHandlerTest extends TestCase
handled = false;
}
}
-
- public void testAttributes() throws Exception
+
+ private static final class WriterHandler extends AbstractHandler
{
- ContextHandler handler = new ContextHandler();
- handler.setAttribute("aaa","111");
- handler.getServletContext().setAttribute("bbb","222");
- assertEquals("111",handler.getServletContext().getAttribute("aaa"));
- assertEquals("222",handler.getAttribute("bbb"));
-
- handler.start();
+ boolean error;
+ Throwable throwable;
- handler.getServletContext().setAttribute("aaa","000");
- handler.setAttribute("ccc","333");
- handler.getServletContext().setAttribute("ddd","444");
- assertEquals("111",handler.getServletContext().getAttribute("aaa"));
- assertEquals("222",handler.getServletContext().getAttribute("bbb"));
- assertEquals("333",handler.getServletContext().getAttribute("ccc"));
- assertEquals("444",handler.getServletContext().getAttribute("ddd"));
-
- assertEquals("111",handler.getAttribute("aaa"));
- assertEquals("222",handler.getAttribute("bbb"));
- assertEquals("333",handler.getAttribute("ccc"));
- assertEquals(null,handler.getAttribute("ddd"));
-
-
- handler.stop();
-
- assertEquals("111",handler.getServletContext().getAttribute("aaa"));
- assertEquals("222",handler.getServletContext().getAttribute("bbb"));
- assertEquals("333",handler.getServletContext().getAttribute("ccc"));
- assertEquals(null,handler.getServletContext().getAttribute("ddd"));
-
+ public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ error = false;
+ throwable=null;
+
+ response.setStatus(200);
+ response.setContentType("text/plain; charset=utf-8");
+ response.setHeader("Connection","close");
+ PrintWriter writer = response.getWriter();
+ try
+ {
+ writer.write("Goodbye cruel world\n");
+ writer.close();
+ response.flushBuffer();
+ writer.write("speaking from the dead");
+ }
+ catch(Throwable th)
+ {
+ throwable=th;
+ }
+ error=writer.checkError();
+ }
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java
new file mode 100644
index 0000000000..6ac5e7969f
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java
@@ -0,0 +1,395 @@
+// ========================================================================
+// Copyright (c) 2010 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.server.handler;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.util.log.Log;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class IPAccessHandlerTest
+{
+ private static Server _server;
+ private static Connector _connector;
+ private static IPAccessHandler _handler;
+
+ private String _white;
+ private String _black;
+ private String _host;
+ private String _uri;
+ private String _code;
+
+ @BeforeClass
+ public static void setUp()
+ throws Exception
+ {
+ _server = new Server();
+ _connector = new SocketConnector();
+ _server.setConnectors(new Connector[] { _connector });
+
+ _handler = new IPAccessHandler();
+ _handler.setHandler(new AbstractHandler()
+ {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ response.setStatus(HttpStatus.OK_200);
+ }
+ });
+ _server.setHandler(_handler);
+ _server.start();
+ }
+
+ /* ------------------------------------------------------------ */
+ @AfterClass
+ public static void tearDown()
+ throws Exception
+ {
+ _server.stop();
+ }
+
+ /* ------------------------------------------------------------ */
+ public IPAccessHandlerTest(String white, String black, String host, String uri, String code)
+ {
+ _white = white;
+ _black = black;
+ _host = host;
+ _uri = uri;
+ _code = code;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testHandler()
+ throws Exception
+ {
+ _handler.setWhite(_white.split(";",-1));
+ _handler.setBlack(_black.split(";",-1));
+
+ String request = "GET " + _uri + " HTTP/1.1\n" + "Host: "+ _host + "\n\n";
+ Socket socket = new Socket("localhost", _connector.getLocalPort());
+ socket.setSoTimeout(5000);
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ Response response = readResponse(input);
+ assertEquals(_code, response.getCode());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ protected Response readResponse(BufferedReader reader)
+ throws IOException
+ {
+ // Simplified parser for HTTP responses
+ String line = reader.readLine();
+ if (line == null)
+ throw new EOFException();
+ Matcher responseLine = Pattern.compile("HTTP/1\\.1\\s+(\\d+)").matcher(line);
+ assertTrue(responseLine.lookingAt());
+ String code = responseLine.group(1);
+
+ Map<String, String> headers = new LinkedHashMap<String, String>();
+ while ((line = reader.readLine()) != null)
+ {
+ if (line.trim().length() == 0)
+ break;
+
+ Matcher header = Pattern.compile("([^:]+):\\s*(.*)").matcher(line);
+ assertTrue(header.lookingAt());
+ String headerName = header.group(1);
+ String headerValue = header.group(2);
+ headers.put(headerName.toLowerCase(), headerValue.toLowerCase());
+ }
+
+ StringBuilder body = new StringBuilder();
+ if (headers.containsKey("content-length"))
+ {
+ int length = Integer.parseInt(headers.get("content-length"));
+ for (int i = 0; i < length; ++i)
+ {
+ char c = (char)reader.read();
+ body.append(c);
+ }
+ }
+ else if ("chunked".equals(headers.get("transfer-encoding")))
+ {
+ while ((line = reader.readLine()) != null)
+ {
+ if ("0".equals(line))
+ {
+ line = reader.readLine();
+ assertEquals("", line);
+ break;
+ }
+
+ int length = Integer.parseInt(line, 16);
+ for (int i = 0; i < length; ++i)
+ {
+ char c = (char)reader.read();
+ body.append(c);
+ }
+ line = reader.readLine();
+ assertEquals("", line);
+ }
+ }
+
+ return new Response(code, headers, body.toString().trim());
+ }
+
+ /* ------------------------------------------------------------ */
+ protected class Response
+ {
+ private final String code;
+ private final Map<String, String> headers;
+ private final String body;
+
+ /* ------------------------------------------------------------ */
+ private Response(String code, Map<String, String> headers, String body)
+ {
+ this.code = code;
+ this.headers = headers;
+ this.body = body;
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getCode()
+ {
+ return code;
+ }
+
+ /* ------------------------------------------------------------ */
+ public Map<String, String> getHeaders()
+ {
+ return headers;
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getBody()
+ {
+ return body;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(code).append("\r\n");
+ for (Map.Entry<String, String> entry : headers.entrySet())
+ builder.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
+ builder.append("\r\n");
+ builder.append(body);
+ return builder.toString();
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ @Parameters
+ public static Collection<Object[]> data() {
+ Object[][] data = new Object[][] {
+ // Empty lists
+ {"", "", "127.0.0.1", "/", "200"},
+ {"", "", "127.0.0.1", "/dump/info", "200"},
+
+ // White list
+ {"127.0.0.1", "", "127.0.0.1", "/", "200"},
+ {"127.0.0.1", "", "127.0.0.1", "/dispatch", "200"},
+ {"127.0.0.1", "", "127.0.0.1", "/dump/info", "200"},
+
+ {"127.0.0.1|/", "", "127.0.0.1", "/", "200"},
+ {"127.0.0.1|/", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.1|/", "", "127.0.0.1", "/dump/info", "403"},
+
+ {"127.0.0.1|/*", "", "127.0.0.1", "/", "200"},
+ {"127.0.0.1|/*", "", "127.0.0.1", "/dispatch", "200"},
+ {"127.0.0.1|/*", "", "127.0.0.1", "/dump/info", "200"},
+
+ {"127.0.0.1|/dump/*", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.1|/dump/*", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.1|/dump/*", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/*", "", "127.0.0.1", "/dump/test", "200"},
+
+ {"127.0.0.1|/dump/info", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.1|/dump/info", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.1|/dump/info", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/info", "", "127.0.0.1", "/dump/test", "403"},
+
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/test", "200"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/fail", "403"},
+
+ {"127.0.0.0-2|", "", "127.0.0.1", "/", "200"},
+ {"127.0.0.0-2|", "", "127.0.0.1", "/dump/info", "200"},
+
+ {"127.0.0.0-2|/", "", "127.0.0.1", "/", "200"},
+ {"127.0.0.0-2|/", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.0-2|/", "", "127.0.0.1", "/dump/info", "403"},
+
+ {"127.0.0.0-2|/dump/*", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.0-2|/dump/*", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.0-2|/dump/*", "", "127.0.0.1", "/dump/info", "200"},
+
+ {"127.0.0.0-2|/dump/info", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.0-2|/dump/info", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.0-2|/dump/info", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.0-2|/dump/info", "", "127.0.0.1", "/dump/test", "403"},
+
+ {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/test", "200"},
+ {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"},
+
+ // Black list
+ {"", "127.0.0.1", "127.0.0.1", "/", "403"},
+ {"", "127.0.0.1", "127.0.0.1", "/dispatch", "403"},
+ {"", "127.0.0.1", "127.0.0.1", "/dump/info", "403"},
+
+ {"", "127.0.0.1|/", "127.0.0.1", "/", "403"},
+ {"", "127.0.0.1|/", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.1|/", "127.0.0.1", "/dump/info", "200"},
+
+ {"", "127.0.0.1|/*", "127.0.0.1", "/", "403"},
+ {"", "127.0.0.1|/*", "127.0.0.1", "/dispatch", "403"},
+ {"", "127.0.0.1|/*", "127.0.0.1", "/dump/info", "403"},
+
+ {"", "127.0.0.1|/dump/*", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dump/info", "403"},
+ {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dump/test", "403"},
+
+ {"", "127.0.0.1|/dump/info", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.1|/dump/info", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.1|/dump/info", "127.0.0.1", "/dump/info", "403"},
+ {"", "127.0.0.1|/dump/info", "127.0.0.1", "/dump/test", "200"},
+
+ {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/info", "403"},
+ {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/test", "403"},
+ {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/fail", "200"},
+
+ {"", "127.0.0.0-2|", "127.0.0.1", "/", "403"},
+ {"", "127.0.0.0-2|", "127.0.0.1", "/dump/info", "403"},
+
+ {"", "127.0.0.0-2|/", "127.0.0.1", "/", "403"},
+ {"", "127.0.0.0-2|/", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.0-2|/", "127.0.0.1", "/dump/info", "200"},
+
+ {"", "127.0.0.0-2|/dump/*", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.0-2|/dump/*", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.0-2|/dump/*", "127.0.0.1", "/dump/info", "403"},
+
+ {"", "127.0.0.0-2|/dump/info", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.0-2|/dump/info", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.0-2|/dump/info", "127.0.0.1", "/dump/info", "403"},
+ {"", "127.0.0.0-2|/dump/info", "127.0.0.1", "/dump/test", "200"},
+
+ {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/", "200"},
+ {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dispatch", "200"},
+ {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/info", "403"},
+ {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/test", "403"},
+ {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/fail", "200"},
+
+ // Both lists
+ {"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump", "200"},
+ {"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "403"},
+ {"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/fail", "403"},
+
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump", "200"},
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/fail", "403"},
+
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump", "200"},
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/test", "403"},
+ {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/fail", "403"},
+
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump/test", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump/fail", "403"},
+
+ {"127.0.0.1|/;127.0.0.0-2|/dump/*", "127.0.0.0,1|/dump/fail", "127.0.0.1", "/", "200"},
+ {"127.0.0.1|/;127.0.0.0-2|/dump/*", "127.0.0.0,1|/dump/fail", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/;127.0.0.0-2|/dump/*", "127.0.0.0,1|/dump/fail", "127.0.0.1", "/dump/fail", "403"},
+
+ // Different address
+ {"127.0.0.2", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.2", "", "127.0.0.1", "/dump/info", "403"},
+
+ {"127.0.0.2|/dump/*", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.2|/dump/*", "", "127.0.0.1", "/dump/info", "403"},
+
+ {"127.0.0.2|/dump/info", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.2|/dump/info", "", "127.0.0.1", "/dump/info", "403"},
+ {"127.0.0.2|/dump/info", "", "127.0.0.1", "/dump/test", "403"},
+
+ {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dispatch", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/info", "200"},
+ {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/test", "403"},
+ {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"},
+
+ {"172.0.0.0-255", "", "127.0.0.1", "/", "403"},
+ {"172.0.0.0-255", "", "127.0.0.1", "/dump/info", "403"},
+
+ {"172.0.0.0-255|/dump/*;127.0.0.0-255|/dump/*", "", "127.0.0.1", "/", "403"},
+ {"172.0.0.0-255|/dump/*;127.0.0.0-255|/dump/*", "", "127.0.0.1", "/dispatch", "403"},
+ {"172.0.0.0-255|/dump/*;127.0.0.0-255|/dump/*", "", "127.0.0.1", "/dump/info", "200"},
+ };
+ return Arrays.asList(data);
+ };
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectSSLTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectSSLTest.java
new file mode 100644
index 0000000000..433ef64244
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectSSLTest.java
@@ -0,0 +1,221 @@
+package org.eclipse.jetty.server.handler;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class ProxyHandlerConnectSSLTest extends AbstractProxyHandlerTest
+{
+ @BeforeClass
+ public static void init() throws Exception
+ {
+ SslSelectChannelConnector connector = new SslSelectChannelConnector();
+
+ String keyStorePath = System.getProperty("basedir");
+ keyStorePath += File.separator + "src" + File.separator + "test" + File.separator + "resources" + File.separator + "keystore";
+ connector.setKeystore(keyStorePath);
+ connector.setPassword("storepwd");
+ connector.setKeyPassword("keypwd");
+
+ startServer(connector, new ServerHandler());
+ startProxy();
+ }
+
+ @Test
+ public void testGETRequest() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ // Be sure the buffered input does not have anything buffered
+ assertFalse(input.ready());
+
+ // Upgrade the socket to SSL
+ SSLSocket sslSocket = wrapSocket(socket);
+ try
+ {
+ output = sslSocket.getOutputStream();
+ input = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
+
+ request = "" +
+ "GET /echo HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ finally
+ {
+ sslSocket.close();
+ }
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testPOSTRequests() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ // Be sure the buffered input does not have anything buffered
+ assertFalse(input.ready());
+
+ // Upgrade the socket to SSL
+ SSLSocket sslSocket = wrapSocket(socket);
+ try
+ {
+ output = sslSocket.getOutputStream();
+ input = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
+
+ for (int i = 0; i < 10; ++i)
+ {
+ request = "" +
+ "POST /echo?param=" + i + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "Content-Length: 5\r\n" +
+ "\r\n" +
+ "HELLO";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("POST /echo?param=" + i + "\r\nHELLO", response.getBody());
+ }
+ }
+ finally
+ {
+ sslSocket.close();
+ }
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ private SSLSocket wrapSocket(Socket socket) throws Exception
+ {
+ SSLContext sslContext = SSLContext.getInstance("SSLv3");
+ sslContext.init(null, new TrustManager[]{new AlwaysTrustManager()}, new SecureRandom());
+ SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+ SSLSocket sslSocket = (SSLSocket)socketFactory.createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true);
+ sslSocket.setUseClientMode(true);
+ sslSocket.startHandshake();
+ return sslSocket;
+ }
+
+ private class AlwaysTrustManager implements X509TrustManager
+ {
+ public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
+ {
+ }
+
+ public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
+ {
+ }
+
+ public X509Certificate[] getAcceptedIssuers()
+ {
+ return null;
+ }
+ }
+
+ private static class ServerHandler extends AbstractHandler
+ {
+ public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
+ {
+ request.setHandled(true);
+
+ String uri = httpRequest.getRequestURI();
+ if ("/echo".equals(uri))
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(httpRequest.getMethod()).append(" ").append(uri);
+ if (httpRequest.getQueryString() != null)
+ builder.append("?").append(httpRequest.getQueryString());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ InputStream input = httpRequest.getInputStream();
+ int read = -1;
+ while ((read = input.read()) >= 0)
+ baos.write(read);
+ baos.close();
+
+ ServletOutputStream output = httpResponse.getOutputStream();
+ output.println(builder.toString());
+ output.write(baos.toByteArray());
+ }
+ else
+ {
+ throw new ServletException();
+ }
+ }
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectTest.java
new file mode 100644
index 0000000000..9bc2fa21ac
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ProxyHandlerConnectTest.java
@@ -0,0 +1,517 @@
+package org.eclipse.jetty.server.handler;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class ProxyHandlerConnectTest extends AbstractProxyHandlerTest
+{
+ @BeforeClass
+ public static void init() throws Exception
+ {
+ startServer(new SelectChannelConnector(), new ServerHandler());
+ startProxy();
+ }
+
+ @Test
+ public void testCONNECT() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndGET() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ request = "" +
+ "GET /echo" + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECT10AndGET() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.0\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ request = "" +
+ "GET /echo" + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndGETPipelined() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n" +
+ "GET /echo" + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ // The pipelined request must have gone up to the server as is
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndMultipleGETs() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ for (int i = 0; i < 10; ++i)
+ {
+ request = "" +
+ "GET /echo" + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndGETServerStop() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ request = "" +
+ "GET /echo HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+
+ // Idle server is shut down
+ stopServer();
+
+ int read = input.read();
+ assertEquals(-1, read);
+ }
+ finally
+ {
+ socket.close();
+ // Restart the server for the next test
+ server.start();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndGETAndServerSideClose() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ request = "" +
+ "GET /close HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ int read = input.read();
+ assertEquals(-1, read);
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndPOSTAndGET() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ request = "" +
+ "POST /echo HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "Content-Length: 5\r\n" +
+ "\r\n" +
+ "HELLO";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("POST /echo\r\nHELLO", response.getBody());
+
+ request = "" +
+ "GET /echo" + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("GET /echo", response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndPOSTWithBigBody() throws Exception
+ {
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ StringBuilder body = new StringBuilder();
+ String chunk = "0123456789ABCDEF";
+ for (int i = 0; i < 1024; ++i)
+ body.append(chunk);
+
+ request = "" +
+ "POST /echo HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "Content-Length: " + body.length() + "\r\n" +
+ "\r\n" +
+ body;
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("POST /echo\r\n" + body, response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void testCONNECTAndPOSTWithContext() throws Exception
+ {
+ final String contextKey = "contextKey";
+ final String contextValue = "contextValue";
+
+ // Replace the default ProxyHandler with a subclass to test context information passing
+ stopProxy();
+ proxy.setHandler(new ProxyHandler()
+ {
+ @Override
+ protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) throws ServletException, IOException
+ {
+ request.setAttribute(contextKey, contextValue);
+ return super.handleAuthentication(request, response, address);
+ }
+
+ @Override
+ protected SocketChannel connect(HttpServletRequest request, String host, int port) throws IOException
+ {
+ assertEquals(contextValue, request.getAttribute(contextKey));
+ return super.connect(request, host, port);
+ }
+
+ @Override
+ protected void prepareContext(HttpServletRequest request, ConcurrentMap<String, Object> context)
+ {
+ // Transfer data from the HTTP request to the connection context
+ assertEquals(contextValue, request.getAttribute(contextKey));
+ context.put(contextKey, request.getAttribute(contextKey));
+ }
+
+ @Override
+ protected int read(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+ {
+ assertEquals(contextValue, context.get(contextKey));
+ return super.read(endPoint, buffer, context);
+ }
+
+ @Override
+ protected int write(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+ {
+ assertEquals(contextValue, context.get(contextKey));
+ return super.write(endPoint, buffer, context);
+ }
+ });
+ proxy.start();
+
+ String hostPort = "localhost:" + serverConnector.getLocalPort();
+ String request = "" +
+ "CONNECT " + hostPort + " HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "\r\n";
+ Socket socket = newSocket();
+ try
+ {
+ OutputStream output = socket.getOutputStream();
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ // Expect 200 OK from the CONNECT request
+ Response response = readResponse(input);
+ assertEquals("200", response.getCode());
+
+ String body = "0123456789ABCDEF";
+ request = "" +
+ "POST /echo HTTP/1.1\r\n" +
+ "Host: " + hostPort + "\r\n" +
+ "Content-Length: " + body.length() + "\r\n" +
+ "\r\n" +
+ body;
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ response = readResponse(input);
+ assertEquals("200", response.getCode());
+ assertEquals("POST /echo\r\n" + body, response.getBody());
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+
+ private static class ServerHandler extends AbstractHandler
+ {
+ public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
+ {
+ request.setHandled(true);
+
+ String uri = httpRequest.getRequestURI();
+ if ("/echo".equals(uri))
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(httpRequest.getMethod()).append(" ").append(uri);
+ if (httpRequest.getQueryString() != null)
+ builder.append("?").append(httpRequest.getQueryString());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ InputStream input = httpRequest.getInputStream();
+ int read = -1;
+ while ((read = input.read()) >= 0)
+ baos.write(read);
+ baos.close();
+
+ ServletOutputStream output = httpResponse.getOutputStream();
+ output.println(builder.toString());
+ output.write(baos.toByteArray());
+ }
+ else if ("/close".equals(uri))
+ {
+ request.getConnection().getEndPoint().close();
+ }
+ else
+ {
+ throw new ServletException();
+ }
+ }
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ScopedHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ScopedHandlerTest.java
index 13312809f4..5956b54b48 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ScopedHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ScopedHandlerTest.java
@@ -1,23 +1,29 @@
package org.eclipse.jetty.server.handler;
import java.io.IOException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
-public class ScopedHandlerTest extends TestCase
+public class ScopedHandlerTest
{
- StringBuilder _history=new StringBuilder();
+ private StringBuilder _history=new StringBuilder();
- public void testSingle()
- throws Exception
+ @Before
+ public void resetHistory()
{
_history.setLength(0);
+ }
+
+ @Test
+ public void testSingle() throws Exception
+ {
TestHandler handler0 = new TestHandler("0");
handler0.start();
handler0.handle("target",null,null,null);
@@ -27,10 +33,9 @@ public class ScopedHandlerTest extends TestCase
assertEquals(">S0>W0<W0<S0",history);
}
- public void testSimpleDouble()
- throws Exception
+ @Test
+ public void testSimpleDouble() throws Exception
{
- _history.setLength(0);
TestHandler handler0 = new TestHandler("0");
TestHandler handler1 = new TestHandler("1");
handler0.setHandler(handler1);
@@ -42,10 +47,9 @@ public class ScopedHandlerTest extends TestCase
assertEquals(">S0>S1>W0>W1<W1<W0<S1<S0",history);
}
- public void testSimpleTriple()
- throws Exception
+ @Test
+ public void testSimpleTriple() throws Exception
{
- _history.setLength(0);
TestHandler handler0 = new TestHandler("0");
TestHandler handler1 = new TestHandler("1");
TestHandler handler2 = new TestHandler("2");
@@ -59,10 +63,9 @@ public class ScopedHandlerTest extends TestCase
assertEquals(">S0>S1>S2>W0>W1>W2<W2<W1<W0<S2<S1<S0",history);
}
- public void testDouble()
- throws Exception
+ @Test
+ public void testDouble() throws Exception
{
- _history.setLength(0);
TestHandler handler0 = new TestHandler("0");
OtherHandler handlerA = new OtherHandler("A");
TestHandler handler1 = new TestHandler("1");
@@ -78,10 +81,9 @@ public class ScopedHandlerTest extends TestCase
assertEquals(">S0>S1>W0>HA>W1>HB<HB<W1<HA<W0<S1<S0",history);
}
- public void testTriple()
- throws Exception
+ @Test
+ public void testTriple() throws Exception
{
- _history.setLength(0);
TestHandler handler0 = new TestHandler("0");
OtherHandler handlerA = new OtherHandler("A");
TestHandler handler1 = new TestHandler("1");
@@ -100,15 +102,16 @@ public class ScopedHandlerTest extends TestCase
System.err.println(history);
assertEquals(">S0>S1>S2>W0>HA>W1>HB>W2>HC<HC<W2<HB<W1<HA<W0<S2<S1<S0",history);
}
-
+
private class TestHandler extends ScopedHandler
{
- String _name;
- TestHandler(String name)
+ private final String _name;
+
+ private TestHandler(String name)
{
_name=name;
}
-
+
@Override
public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
@@ -122,7 +125,7 @@ public class ScopedHandlerTest extends TestCase
_history.append("<S").append(_name);
}
}
-
+
@Override
public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
@@ -138,16 +141,16 @@ public class ScopedHandlerTest extends TestCase
}
}
-
+
private class OtherHandler extends HandlerWrapper
{
- String _name;
-
- OtherHandler(String name)
+ private final String _name;
+
+ private OtherHandler(String name)
{
_name=name;
}
-
+
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java
index bf29e8657d..b4877e071e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java
@@ -18,29 +18,34 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-public class StatisticsHandlerTest extends TestCase
+public class StatisticsHandlerTest
{
private Server _server;
private LocalConnector _connector;
private LatchHandler _latchHandler;
private StatisticsHandler _statsHandler;
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_server = new Server();
@@ -55,17 +60,18 @@ public class StatisticsHandlerTest extends TestCase
_latchHandler.setHandler(_statsHandler);
}
- @Override
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
_server.stop();
_server.join();
}
+ @Test
public void testRequest() throws Exception
{
final CyclicBarrier barrier[] = { new CyclicBarrier(2), new CyclicBarrier(2)};
-
+
_statsHandler.setHandler(new AbstractHandler()
{
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
@@ -75,7 +81,7 @@ public class StatisticsHandlerTest extends TestCase
{
barrier[0].await();
barrier[1].await();
-
+
}
catch (Exception x)
{
@@ -94,11 +100,11 @@ public class StatisticsHandlerTest extends TestCase
barrier[0].await();
assertEquals(1, _connector.getConnectionsOpen());
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(1, _statsHandler.getDispatched());
assertEquals(1, _statsHandler.getDispatchedActive());
assertEquals(1, _statsHandler.getDispatchedActiveMax());
@@ -107,11 +113,11 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].await();
boolean passed = _latchHandler.await(1000);
assertTrue(passed);
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(1, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
assertEquals(1, _statsHandler.getDispatchedActiveMax());
@@ -120,21 +126,21 @@ public class StatisticsHandlerTest extends TestCase
assertEquals(0, _statsHandler.getResumes());
assertEquals(0, _statsHandler.getExpires());
assertEquals(1, _statsHandler.getResponses2xx());
-
+
_latchHandler.reset();
barrier[0].reset();
barrier[1].reset();
-
+
_connector.executeRequest(request);
barrier[0].await();
-
+
assertEquals(2, _connector.getConnectionsOpen());
-
+
assertEquals(2, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(2, _statsHandler.getDispatched());
assertEquals(1, _statsHandler.getDispatchedActive());
assertEquals(1, _statsHandler.getDispatchedActiveMax());
@@ -143,11 +149,11 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].await();
passed = _latchHandler.await(1000);
assertTrue(passed);
-
+
assertEquals(2, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(2, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
assertEquals(1, _statsHandler.getDispatchedActiveMax());
@@ -160,18 +166,18 @@ public class StatisticsHandlerTest extends TestCase
_latchHandler.reset(2);
barrier[0]=new CyclicBarrier(3);
barrier[1]=new CyclicBarrier(3);
-
+
_connector.executeRequest(request);
_connector.executeRequest(request);
barrier[0].await();
-
+
assertEquals(4, _connector.getConnectionsOpen());
-
+
assertEquals(4, _statsHandler.getRequests());
assertEquals(2, _statsHandler.getRequestsActive());
assertEquals(2, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(4, _statsHandler.getDispatched());
assertEquals(2, _statsHandler.getDispatchedActive());
assertEquals(2, _statsHandler.getDispatchedActiveMax());
@@ -180,11 +186,11 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].await();
passed = _latchHandler.await(1000);
assertTrue(passed);
-
+
assertEquals(4, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(2, _statsHandler.getRequestsActiveMax());
-
+
assertEquals(4, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
assertEquals(2, _statsHandler.getDispatchedActiveMax());
@@ -193,10 +199,11 @@ public class StatisticsHandlerTest extends TestCase
assertEquals(0, _statsHandler.getResumes());
assertEquals(0, _statsHandler.getExpires());
assertEquals(4, _statsHandler.getResponses2xx());
-
-
+
+
}
+ @Test
public void testSuspendResume() throws Exception
{
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
@@ -217,7 +224,7 @@ public class StatisticsHandlerTest extends TestCase
continuation.suspend();
continuationHandle.set(continuation);
}
-
+
}
catch (Exception x)
{
@@ -232,8 +239,9 @@ public class StatisticsHandlerTest extends TestCase
}
catch (Exception x)
{
+ x.printStackTrace();
Thread.currentThread().interrupt();
- throw (IOException)new IOException().initCause(x);
+ fail();
}
}
@@ -245,12 +253,12 @@ public class StatisticsHandlerTest extends TestCase
"Host: localhost\r\n" +
"\r\n";
_connector.executeRequest(request);
-
+
barrier[0].await();
-
+
assertEquals(1, _connector.getConnectionsOpen());
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
@@ -260,7 +268,7 @@ public class StatisticsHandlerTest extends TestCase
assertTrue(_latchHandler.await(1000));
assertNotNull(continuationHandle.get());
assertTrue(continuationHandle.get().isSuspended());
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
@@ -270,24 +278,24 @@ public class StatisticsHandlerTest extends TestCase
_latchHandler.reset();
barrier[0].reset();
barrier[1].reset();
-
+
continuationHandle.get().addContinuationListener(new ContinuationListener()
{
public void onTimeout(Continuation continuation)
{
}
-
+
public void onComplete(Continuation continuation)
{
try { barrier[2].await(); } catch(Exception e) {}
}
});
-
+
continuationHandle.get().resume();
-
+
barrier[0].await();
-
+
assertEquals(1, _connector.getConnectionsOpen());
assertEquals(1, _statsHandler.getRequests());
@@ -298,29 +306,30 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].await();
assertTrue(_latchHandler.await(1000));
barrier[2].await();
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(2, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
-
-
+
+
assertEquals(1, _statsHandler.getSuspends());
assertEquals(1, _statsHandler.getResumes());
assertEquals(0, _statsHandler.getExpires());
assertEquals(1, _statsHandler.getResponses2xx());
-
-
+
+
assertTrue(_statsHandler.getRequestTimeTotal()>=30);
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
- assertEquals(_statsHandler.getRequestTimeTotal()*1.0,_statsHandler.getRequestTimeMean());
-
+ assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMean(), 0.01);
+
assertTrue(_statsHandler.getDispatchedTimeTotal()>=20);
assertTrue(_statsHandler.getDispatchedTimeMean()+10<=_statsHandler.getDispatchedTimeTotal());
assertTrue(_statsHandler.getDispatchedTimeMax()+10<=_statsHandler.getDispatchedTimeTotal());
-
+
}
+ @Test
public void testSuspendExpire() throws Exception
{
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
@@ -342,7 +351,7 @@ public class StatisticsHandlerTest extends TestCase
continuation.suspend();
continuationHandle.set(continuation);
}
-
+
}
catch (Exception x)
{
@@ -357,8 +366,9 @@ public class StatisticsHandlerTest extends TestCase
}
catch (Exception x)
{
+ x.printStackTrace();
Thread.currentThread().interrupt();
- throw (IOException)new IOException().initCause(x);
+ fail();
}
}
@@ -370,10 +380,10 @@ public class StatisticsHandlerTest extends TestCase
"Host: localhost\r\n" +
"\r\n";
_connector.executeRequest(request);
-
+
barrier[0].await();
-
+
assertEquals(1, _connector.getConnectionsOpen());
assertEquals(1, _statsHandler.getRequests());
@@ -385,19 +395,19 @@ public class StatisticsHandlerTest extends TestCase
assertTrue(_latchHandler.await(1000));
assertNotNull(continuationHandle.get());
assertTrue(continuationHandle.get().isSuspended());
-
+
continuationHandle.get().addContinuationListener(new ContinuationListener()
{
public void onTimeout(Continuation continuation)
{
}
-
+
public void onComplete(Continuation continuation)
{
try { barrier[2].await(); } catch(Exception e) {}
}
});
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
@@ -408,7 +418,7 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].reset();
barrier[0].await();
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(2, _statsHandler.getDispatched());
@@ -417,28 +427,29 @@ public class StatisticsHandlerTest extends TestCase
barrier[1].await();
assertTrue(_latchHandler.await(1000));
barrier[2].await();
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(2, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
-
+
assertEquals(1, _statsHandler.getSuspends());
assertEquals(1, _statsHandler.getResumes());
assertEquals(1, _statsHandler.getExpires());
assertEquals(1, _statsHandler.getResponses2xx());
-
-
+
+
assertTrue(_statsHandler.getRequestTimeTotal()>=30);
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
- assertEquals(_statsHandler.getRequestTimeTotal()*1.0,_statsHandler.getRequestTimeMean());
-
+ assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMean(), 0.01);
+
assertTrue(_statsHandler.getDispatchedTimeTotal()>=20);
assertTrue(_statsHandler.getDispatchedTimeMean()+10<=_statsHandler.getDispatchedTimeTotal());
assertTrue(_statsHandler.getDispatchedTimeMax()+10<=_statsHandler.getDispatchedTimeTotal());
-
+
}
+ @Test
public void testSuspendComplete() throws Exception
{
final AtomicReference<Continuation> continuationHandle = new AtomicReference<Continuation>();
@@ -460,7 +471,7 @@ public class StatisticsHandlerTest extends TestCase
continuation.suspend();
continuationHandle.set(continuation);
}
-
+
}
catch (Exception x)
{
@@ -475,8 +486,9 @@ public class StatisticsHandlerTest extends TestCase
}
catch (Exception x)
{
+ x.printStackTrace();
Thread.currentThread().interrupt();
- throw (IOException)new IOException().initCause(x);
+ fail();
}
}
@@ -488,18 +500,18 @@ public class StatisticsHandlerTest extends TestCase
"Host: localhost\r\n" +
"\r\n";
_connector.executeRequest(request);
-
+
barrier[0].await();
-
+
assertEquals(1, _connector.getConnectionsOpen());
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
assertEquals(1, _statsHandler.getDispatchedActive());
-
+
barrier[1].await();
assertTrue(_latchHandler.await(1000));
assertNotNull(continuationHandle.get());
@@ -509,13 +521,13 @@ public class StatisticsHandlerTest extends TestCase
public void onTimeout(Continuation continuation)
{
}
-
+
public void onComplete(Continuation continuation)
{
try { barrier[2].await(); } catch(Exception e) {}
}
});
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(1, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
@@ -524,27 +536,27 @@ public class StatisticsHandlerTest extends TestCase
Thread.sleep(10);
continuationHandle.get().complete();
barrier[2].await();
-
+
assertEquals(1, _statsHandler.getRequests());
assertEquals(0, _statsHandler.getRequestsActive());
assertEquals(1, _statsHandler.getDispatched());
assertEquals(0, _statsHandler.getDispatchedActive());
-
+
assertEquals(1, _statsHandler.getSuspends());
assertEquals(0, _statsHandler.getResumes());
assertEquals(0, _statsHandler.getExpires());
assertEquals(1, _statsHandler.getResponses2xx());
-
+
assertTrue(_statsHandler.getRequestTimeTotal()>=20);
assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMax());
- assertEquals(_statsHandler.getRequestTimeTotal()*1.0,_statsHandler.getRequestTimeMean());
-
+ assertEquals(_statsHandler.getRequestTimeTotal(),_statsHandler.getRequestTimeMean(), 0.01);
+
assertTrue(_statsHandler.getDispatchedTimeTotal()>=10);
assertTrue(_statsHandler.getDispatchedTimeTotal()<_statsHandler.getRequestTimeTotal());
assertEquals(_statsHandler.getDispatchedTimeTotal(),_statsHandler.getDispatchedTimeMax());
- assertEquals(_statsHandler.getDispatchedTimeTotal()*1.0,_statsHandler.getDispatchedTimeMean());
+ assertEquals(_statsHandler.getDispatchedTimeTotal(),_statsHandler.getDispatchedTimeMean(), 0.01);
}
-
+
/**
* This handler is external to the statistics handler and it is used to ensure that statistics handler's
@@ -573,12 +585,12 @@ public class StatisticsHandlerTest extends TestCase
{
_latch=new CountDownLatch(1);
}
-
+
private void reset(int count)
{
_latch=new CountDownLatch(count);
}
-
+
private boolean await(long ms) throws InterruptedException
{
return _latch.await(ms, TimeUnit.MILLISECONDS);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java
index a449286267..f79a018b52 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java
@@ -10,7 +10,6 @@ import java.util.EventListener;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-
import javax.servlet.AsyncContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
@@ -27,20 +26,21 @@ import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import javax.servlet.DispatcherType;
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.SessionManager;
+import org.junit.Test;
-public class SessionHandlerTest extends TestCase
-{
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+public class SessionHandlerTest
+{
+ @Test
public void testRequestedIdFromCookies()
{
-
final String cookieName = "SessionId";
final String sessionId = "1234.host";
HttpServletRequest httpRequest = new MockHttpServletRequest()
@@ -54,7 +54,7 @@ public class SessionHandlerTest extends TestCase
Request baseRequest = new Request();
baseRequest.setDispatcherType(DispatcherType.REQUEST);
- Assert.assertEquals(DispatcherType.REQUEST,baseRequest.getDispatcherType());
+ assertEquals(DispatcherType.REQUEST,baseRequest.getDispatcherType());
SessionHandler sessionHandler = new SessionHandler();
sessionHandler.setSessionManager(new MockSessionManager()
@@ -163,14 +163,13 @@ public class SessionHandlerTest extends TestCase
});
sessionHandler.setRequestedId(baseRequest,httpRequest);
- Assert.assertEquals(sessionId,baseRequest.getRequestedSessionId());
- Assert.assertTrue(baseRequest.isRequestedSessionIdFromCookie());
-
+ assertEquals(sessionId,baseRequest.getRequestedSessionId());
+ assertTrue(baseRequest.isRequestedSessionIdFromCookie());
}
+ @Test
public void testRequestedIdFromURI()
{
-
final String parameterName = "sessionid";
final String sessionId = "1234.host";
HttpServletRequest httpRequest = new MockHttpServletRequest()
@@ -184,7 +183,7 @@ public class SessionHandlerTest extends TestCase
Request baseRequest = new Request();
baseRequest.setDispatcherType(DispatcherType.REQUEST);
- Assert.assertEquals(DispatcherType.REQUEST,baseRequest.getDispatcherType());
+ assertEquals(DispatcherType.REQUEST,baseRequest.getDispatcherType());
SessionHandler sessionHandler = new SessionHandler();
sessionHandler.setSessionManager(new MockSessionManager()
@@ -205,17 +204,16 @@ public class SessionHandlerTest extends TestCase
sessionHandler.setRequestedId(baseRequest,httpRequest);
- Assert.assertEquals(sessionId,baseRequest.getRequestedSessionId());
- Assert.assertFalse(baseRequest.isRequestedSessionIdFromCookie());
+ assertEquals(sessionId,baseRequest.getRequestedSessionId());
+ assertFalse(baseRequest.isRequestedSessionIdFromCookie());
}
/**
* Mock class for HttpServletRequest interface.
*/
@SuppressWarnings("unchecked")
- class MockHttpServletRequest implements HttpServletRequest
+ private class MockHttpServletRequest implements HttpServletRequest
{
-
public String getRequestURI()
{
return null;
@@ -595,7 +593,7 @@ public class SessionHandlerTest extends TestCase
/**
* Mock class for SessionManager interface.
*/
- class MockSessionManager implements SessionManager
+ private class MockSessionManager implements SessionManager
{
public HttpCookie access(HttpSession session, boolean secure)
{
@@ -830,6 +828,16 @@ public class SessionHandlerTest extends TestCase
}
- }
+ private boolean _checkRemote=false;
+
+ public boolean isCheckingRemoteSessionIdEncoding()
+ {
+ return _checkRemote;
+ }
+ public void setCheckingRemoteSessionIdEncoding(boolean remote)
+ {
+ _checkRemote=remote;
+ }
+ }
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
index f8b3f730f1..269c02ac0c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
// JettyTest.java --
@@ -29,7 +29,6 @@ import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URL;
-
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
@@ -41,22 +40,24 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
/**
- * HttpServer Tester.
+ *
*/
-public class SSLEngineTest extends TestCase
+public class SSLEngineTest
{
- // ~ Static fields/initializers
- // ---------------------------------------------
-
// Useful constants
private static final String HELLO_WORLD="Hello world. The quick brown fox jumped over the lazy dog. How now brown cow. The rain in spain falls mainly on the plain.\n";
private static final String JETTY_VERSION=Server.getVersion();
@@ -68,7 +69,7 @@ public class SSLEngineTest extends TestCase
private static final String REQUEST_CONTENT="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
+"<requests xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+" xsi:noNamespaceSchemaLocation=\"commander.xsd\" version=\""
+PROTOCOL_VERSION+"\">\n"+"</requests>";
-
+
private static final String REQUEST0=REQUEST0_HEADER+REQUEST_CONTENT.getBytes().length+"\n\n"+REQUEST_CONTENT;
private static final String REQUEST1=REQUEST1_HEADER+REQUEST_CONTENT.getBytes().length+"\n\n"+REQUEST_CONTENT;
@@ -76,8 +77,10 @@ public class SSLEngineTest extends TestCase
private static final String RESPONSE0="HTTP/1.1 200 OK\n"+"Content-Length: "+HELLO_WORLD.length()+"\n"+"Server: Jetty("+JETTY_VERSION+")\n"+'\n'+HELLO_WORLD;
private static final String RESPONSE1="HTTP/1.1 200 OK\n"+"Connection: close\n"+"Server: Jetty("+JETTY_VERSION+")\n"+'\n'+HELLO_WORLD;
+ private static final int BODY_SIZE=300;
+
private static final TrustManager[] s_dummyTrustManagers=new TrustManager[]
- {
+ {
new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
@@ -86,33 +89,29 @@ public class SSLEngineTest extends TestCase
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
-
{
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
-
{
}
}
};
- Server server;
- SslSelectChannelConnector connector;
-
- // ~ Methods
- // ----------------------------------------------------------------
+ private static Server server;
+ private static SslSelectChannelConnector connector;
- @Override
- public void setUp() throws Exception
+ @BeforeClass
+ public static void startServer() throws Exception
{
- super.setUp();
-
server=new Server();
connector=new SslSelectChannelConnector();
+ String keystore = System.getProperty("user.dir") + File.separator +
+ "src" + File.separator +
+ "test" + File.separator +
+ "resources" + File.separator +
+ "keystore";
- String keystore = System.getProperty("user.dir")+File.separator+"src"+File.separator+"test"+File.separator+"resources"+File.separator+"keystore";
-
connector.setPort(0);
connector.setKeystore(keystore);
connector.setPassword("storepwd");
@@ -120,32 +119,19 @@ public class SSLEngineTest extends TestCase
connector.setRequestBufferSize(512);
connector.setRequestHeaderSize(512);
- server.setConnectors(new Connector[]
- { connector });
+ server.setConnectors(new Connector[]{connector });
server.setHandler(new HelloWorldHandler());
server.start();
- Thread.sleep(100);
}
-
-
- @Override
- public void tearDown() throws Exception
+
+ @AfterClass
+ public static void stopServer() throws Exception
{
- Thread.sleep(2000);
server.stop();
- super.tearDown();
- }
-
- public void testNothing() throws Exception
- {
-
+ server.join();
}
- /**
- * Feed the server the entire request at once.
- *
- * @throws Exception
- */
+ @Test
public void testBigResponse() throws Exception
{
SSLContext ctx=SSLContext.getInstance("SSLv3");
@@ -156,25 +142,21 @@ public class SSLEngineTest extends TestCase
Socket client=ctx.getSocketFactory().createSocket("localhost",port);
OutputStream os=client.getOutputStream();
- String request =
+ String request =
"GET /?dump=102400 HTTP/1.1\r\n"+
"Host: localhost:8080\r\n"+
"Connection: close\r\n"+
"\r\n";
-
+
os.write(request.getBytes());
os.flush();
-
+
String response = IO.toString(client.getInputStream());
-
+
assertTrue(response.length()>102400);
}
-
- /**
- * Feed the server the entire request at once.
- *
- * @throws Exception
- */
+
+ @Test
public void testRequestJettyHttps() throws Exception
{
final int loops=10;
@@ -231,8 +213,6 @@ public class SSLEngineTest extends TestCase
client[i].close();
}
}
-
-
}
}
}
@@ -241,22 +221,74 @@ public class SSLEngineTest extends TestCase
System.err.println();
}
}
-
+
+ @Test
+ public void testServletPost() throws Exception
+ {
+ stopServer();
+
+ StreamHandler handler = new StreamHandler();
+ server.setHandler(handler);
+ server.start();
+
+ SSLContext context = SSLContext.getInstance("SSL");
+ context.init(null,s_dummyTrustManagers,new java.security.SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
+
+ URL url = new URL("https://localhost:"+connector.getLocalPort()+"/test");
+
+ HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+ if (conn instanceof HttpsURLConnection)
+ {
+ ((HttpsURLConnection)conn).setHostnameVerifier(new HostnameVerifier()
+ {
+ public boolean verify(String urlHostName, SSLSession session)
+ {
+ return true;
+ }
+ });
+ }
+
+ conn.setConnectTimeout(10000);
+ conn.setReadTimeout(100000);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type","text/plain");
+ conn.setChunkedStreamingMode(128);
+ conn.connect();
+ byte[] b = new byte[BODY_SIZE];
+ for (int i = 0; i < BODY_SIZE; i++)
+ {
+ b[i] = 'x';
+ }
+ OutputStream os = conn.getOutputStream();
+ os.write(b);
+ os.flush();
+
+ int len = 0;
+ InputStream is = conn.getInputStream();
+ int bytes=0;
+ while ((len = is.read(b)) > -1)
+ bytes+=len;
+ is.close();
+
+ assertEquals(BODY_SIZE,handler.bytes);
+ assertEquals(BODY_SIZE,bytes);
+ }
+
/**
- * Read entire response from the client. Close the output.
- *
- * @param client
- * Open client socket.
- *
+ * Reads entire response from the client. Close the output.
+ *
+ * @param client Open client socket.
* @return The response string.
- *
- * @throws IOException
+ * @throws IOException in case of I/O errors
*/
private static String readResponse(Socket client) throws IOException
{
BufferedReader br=null;
StringBuilder sb=new StringBuilder(1000);
-
+
try
{
client.setSoTimeout(5000);
@@ -287,9 +319,6 @@ public class SSLEngineTest extends TestCase
private static class HelloWorldHandler extends AbstractHandler
{
- // ~ Methods
- // ------------------------------------------------------------
-
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
// System.err.println("HANDLE "+request.getRequestURI());
@@ -304,7 +333,7 @@ public class SSLEngineTest extends TestCase
buf[i]=(byte)('0'+(i%10));
out.write(buf);
out.close();
- }
+ }
else
{
PrintWriter out=response.getWriter();
@@ -313,92 +342,11 @@ public class SSLEngineTest extends TestCase
}
}
}
-
-
- public final static int BODY_SIZE=300;
-
- public void testServletPost() throws Exception
- {
- Server server=new Server();
- SslSelectChannelConnector connector=new SslSelectChannelConnector();
-
- String keystore = System.getProperty("user.dir")+File.separator+"src"+File.separator+"test"+File.separator+"resources"+File.separator+"keystore";
-
- connector.setPort(0);
- connector.setKeystore(keystore);
- connector.setPassword("storepwd");
- connector.setKeyPassword("keypwd");
- connector.setTruststore(keystore);
- connector.setTrustPassword("storepwd");
-
- server.setConnectors(new Connector[]
- { connector });
- StreamHandler handler = new StreamHandler();
- server.setHandler(handler);
-
- try
- {
- SSLContext context = SSLContext.getInstance("SSL");
- context.init(null,s_dummyTrustManagers,new java.security.SecureRandom());
- HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
-
- server.start();
-
- URL url = new URL("https://localhost:"+connector.getLocalPort()+"/test");
-
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- if (conn instanceof HttpsURLConnection)
- {
- ((HttpsURLConnection)conn).setHostnameVerifier(new HostnameVerifier()
- {
- public boolean verify(String urlHostName, SSLSession session)
- {
- return true;
- }
- });
- }
-
- conn.setConnectTimeout(10000);
- conn.setReadTimeout(100000);
- conn.setDoInput(true);
- conn.setDoOutput(true);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type","text/plain"); //$NON-NLS-1$
- conn.setChunkedStreamingMode(128);
- conn.connect();
- byte[] b = new byte[BODY_SIZE];
- for (int i = 0; i < BODY_SIZE; i++)
- {
- b[i] = 'x';
- }
- OutputStream os = conn.getOutputStream();
- os.write(b);
- os.flush();
- int rc = conn.getResponseCode();
-
- int len = 0;
- InputStream is = conn.getInputStream();
- int bytes=0;
- while ((len = is.read(b)) > -1)
- bytes+=len;
- is.close();
-
- assertEquals(BODY_SIZE,handler.bytes);
- assertEquals(BODY_SIZE,bytes);
-
- }
- finally
- {
- server.stop();
- }
- }
-
-
- public static class StreamHandler extends AbstractHandler
+ private static class StreamHandler extends AbstractHandler
{
- public int bytes=0;
-
+ private int bytes=0;
+
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/plain");
@@ -406,7 +354,6 @@ public class SSLEngineTest extends TestCase
byte[] b = new byte[BODY_SIZE];
int len = 0;
InputStream is = request.getInputStream();
-
while ((len = is.read(b)) > -1)
{
bytes+=len;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslRenegotiateTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslRenegotiateTest.java
index bbc43e0856..1be64430f0 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslRenegotiateTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslRenegotiateTest.java
@@ -6,16 +6,14 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
-
-import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLProtocolException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -27,14 +25,14 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
+import org.junit.Test;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-
-public class SslRenegotiateTest extends TestCase
+public class SslRenegotiateTest
{
-
- static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
+ private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
@@ -50,47 +48,41 @@ public class SslRenegotiateTest extends TestCase
}
} };
- static HostnameVerifier hostnameVerifier = new HostnameVerifier()
- {
- public boolean verify( String urlHostName, SSLSession session )
- {
- Log.warn( "Warning: URL Host: " + urlHostName + " vs." + session.getPeerHost() );
- return true;
- }
- };
-
- ByteBuffer _outAppB;
- ByteBuffer _outPacketB;
- ByteBuffer _inAppB;
- ByteBuffer _inPacketB;
- SocketChannel _socket;
- SSLEngine _engine;
-
+ private ByteBuffer _outAppB;
+ private ByteBuffer _outPacketB;
+ private ByteBuffer _inAppB;
+ private ByteBuffer _inPacketB;
+ private SocketChannel _socket;
+ private SSLEngine _engine;
+ @Test
public void testRenegNIO() throws Exception
{
- doRequests(new SslSelectChannelConnector(),true);
+ // TODO This test breaks on JVMs with the fix
+// doRequests(new SslSelectChannelConnector(),true);
}
-
+
+ @Test
public void testNoRenegNIO() throws Exception
{
doRequests(new SslSelectChannelConnector(),false);
}
+
+ @Test
public void testRenegBIO() throws Exception
{
- /** TODO - this test is too non deterministic due to call back timing
- doRequests(new SslSocketConnector(),true);
- */
+ // TODO - this test is too non deterministic due to call back timing
+// doRequests(new SslSocketConnector(),true);
}
-
+
+ @Test
public void testNoRenegBIO() throws Exception
{
- /** TODO - this test is too non deterministic due to call back timing
- doRequests(new SslSocketConnector(),false);
- */
+ // TODO - this test is too non deterministic due to call back timing
+// doRequests(new SslSocketConnector(),false);
}
- public void doRequests(SslConnector connector,boolean reneg) throws Exception
+ private void doRequests(SslConnector connector, boolean reneg) throws Exception
{
Server server=new Server();
try
@@ -106,29 +98,29 @@ public class SslRenegotiateTest extends TestCase
server.setHandler(new HelloWorldHandler());
server.start();
-
+
SocketAddress addr = new InetSocketAddress("localhost",connector.getLocalPort());
_socket = SocketChannel.open(addr);
_socket.configureBlocking(true);
-
+
SSLContext context=SSLContext.getInstance("SSL");
context.init( null, trustAllCerts, new java.security.SecureRandom() );
_engine = context.createSSLEngine();
_engine.setUseClientMode(true);
SSLSession session=_engine.getSession();
-
+
_outAppB = ByteBuffer.allocate(session.getApplicationBufferSize());
_outPacketB = ByteBuffer.allocate(session.getPacketBufferSize());
_inAppB = ByteBuffer.allocate(session.getApplicationBufferSize());
_inPacketB = ByteBuffer.allocate(session.getPacketBufferSize());
-
-
+
+
_outAppB.put("GET /1 HTTP/1.1\r\nHost: localhost\r\n\r\n".getBytes(StringUtil.__ISO_8859_1));
_outAppB.flip();
-
+
_engine.beginHandshake();
-
+
runHandshake();
doWrap();
@@ -137,7 +129,7 @@ public class SslRenegotiateTest extends TestCase
String response=new IndirectNIOBuffer(_inAppB,true).toString();
// System.err.println(response);
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
-
+
if (response.indexOf("HELLO WORLD")<0)
{
_inAppB.clear();
@@ -145,9 +137,9 @@ public class SslRenegotiateTest extends TestCase
_inAppB.flip();
response=new IndirectNIOBuffer(_inAppB,true).toString();
}
-
+
assertTrue(response.indexOf("HELLO WORLD")>=0);
-
+
_inAppB.clear();
_outAppB.clear();
_outAppB.put("GET /2 HTTP/1.1\r\nHost: localhost\r\n\r\n".getBytes(StringUtil.__ISO_8859_1));
@@ -158,7 +150,7 @@ public class SslRenegotiateTest extends TestCase
session.invalidate();
_engine.beginHandshake();
runHandshake();
-
+
doWrap();
doUnwrap();
_inAppB.flip();
@@ -176,25 +168,19 @@ public class SslRenegotiateTest extends TestCase
Log.warn(e);
assertFalse(reneg);
}
- return;
}
-
}
finally
{
server.stop();
+ server.join();
}
}
-
+
void runHandshake() throws Exception
{
- SSLEngineResult result;
-
while (true)
{
- //System.err.println();
- //System.err.println(_engine.getHandshakeStatus());
-
switch(_engine.getHandshakeStatus())
{
case NEED_TASK:
@@ -203,25 +189,25 @@ public class SslRenegotiateTest extends TestCase
_engine.getDelegatedTask().run();
break;
}
-
+
case NEED_WRAP:
{
doWrap();
break;
}
-
+
case NEED_UNWRAP:
{
doUnwrap();
break;
}
-
+
default:
return;
}
}
}
-
+
private void doWrap() throws Exception
{
SSLEngineResult result =_engine.wrap(_outAppB,_outPacketB);
@@ -235,7 +221,7 @@ public class SslRenegotiateTest extends TestCase
}
_outPacketB.clear();
}
-
+
private void doUnwrap() throws Exception
{
_inPacketB.clear();
@@ -243,7 +229,7 @@ public class SslRenegotiateTest extends TestCase
// System.err.println("read "+l);
if (l<0)
throw new IOException("EOF");
-
+
_inPacketB.flip();
SSLEngineResult result;
@@ -251,17 +237,15 @@ public class SslRenegotiateTest extends TestCase
{
result =_engine.unwrap(_inPacketB,_inAppB);
// System.err.println("unwrapped "+result.bytesConsumed()+" to "+result.bytesProduced()+" "+_engine.getHandshakeStatus());
-
+
}
while(result.bytesConsumed()>0 &&
- _inPacketB.remaining()>0 &&
+ _inPacketB.remaining()>0 &&
(_engine.getHandshakeStatus()==HandshakeStatus.NEED_UNWRAP || _engine.getHandshakeStatus()==HandshakeStatus.NOT_HANDSHAKING));
-
}
private static class HelloWorldHandler extends AbstractHandler
{
-
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
index 8cb045bf58..e44c5d946e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
@@ -21,34 +21,37 @@ import java.io.OutputStream;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
/**
* @version $Revision$ $Date$
*/
-public class SslUploadTest extends TestCase
+public class SslUploadTest
{
- int _total;
-
- public void test() throws Exception
+ private static Server server;
+ private static SslSelectChannelConnector connector;
+ private static int total;
+
+ @BeforeClass
+ public static void startServer() throws Exception
{
- Server server = new Server();
- SslConnector connector = new SslSelectChannelConnector();
+ server = new Server();
+ connector = new SslSelectChannelConnector();
server.addConnector(connector);
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
@@ -61,100 +64,86 @@ public class SslUploadTest extends TestCase
server.setHandler(new EmptyHandler());
server.start();
- try
+ }
+
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ server.stop();
+ server.join();
+ }
+
+ @Test
+ public void test() throws Exception
+ {
+ KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keystore.load(new FileInputStream(connector.getKeystore()), "storepwd".toCharArray());
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init(keystore);
+ SSLContext sslContext = SSLContext.getInstance("SSL");
+ sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
+
+ final SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost",connector.getLocalPort());
+
+ // Simulate async close
+ /*
+ new Thread()
{
- KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
- keystore.load(new FileInputStream(keystorePath), "storepwd".toCharArray());
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init(keystore);
- SSLContext sslContext = SSLContext.getInstance("SSL");
- sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
-
- _total=0;
- final SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost",connector.getLocalPort());
-
- // Simulate async close
- /*
- new Thread()
+ @Override
+ public void run()
{
- @Override
- public void run()
+ try
{
- try
- {
- sleep(100);
- socket.close();
- }
- catch (IOException x)
- {
- x.printStackTrace();
- }
- catch (InterruptedException x)
- {
- Thread.currentThread().interrupt();
- }
+ sleep(100);
+ socket.close();
}
- }.start();
- */
-
-
-
- long start = System.nanoTime();
- OutputStream out = socket.getOutputStream();
- out.write("POST / HTTP/1.1\r\n".getBytes());
- out.write("Host: localhost\r\n".getBytes());
- out.write("Content-Length: 16777216\r\n".getBytes());
- out.write("Content-Type: bytes\r\n".getBytes());
- out.write("Connection: close\r\n".getBytes());
- out.write("\r\n".getBytes());
- out.flush();
-
- byte[] requestContent = new byte[16777216];
- Arrays.fill(requestContent, (byte)120);
- out.write(requestContent);
- out.flush();
-
- InputStream in = socket.getInputStream();
- String response = IO.toString(in);
- // System.err.println(response);
-
- long end = System.nanoTime();
- System.out.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
- assertEquals(requestContent.length,_total);
-
- }
- finally
- {
- server.stop();
- }
+ catch (IOException x)
+ {
+ x.printStackTrace();
+ }
+ catch (InterruptedException x)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }.start();
+ */
+
+ long start = System.nanoTime();
+ OutputStream out = socket.getOutputStream();
+ out.write("POST / HTTP/1.1\r\n".getBytes());
+ out.write("Host: localhost\r\n".getBytes());
+ out.write("Content-Length: 16777216\r\n".getBytes());
+ out.write("Content-Type: bytes\r\n".getBytes());
+ out.write("Connection: close\r\n".getBytes());
+ out.write("\r\n".getBytes());
+ out.flush();
+
+ byte[] requestContent = new byte[16777216];
+ Arrays.fill(requestContent, (byte)120);
+ out.write(requestContent);
+ out.flush();
+
+ InputStream in = socket.getInputStream();
+ String response = IO.toString(in);
+ // System.err.println(response);
+
+ long end = System.nanoTime();
+ System.out.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
+ assertEquals(requestContent.length, total);
}
- private class EmptyHandler extends AbstractHandler
+ private static class EmptyHandler extends AbstractHandler
{
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{
- // System.out.println("path = " + path);
request.setHandled(true);
-
InputStream in = request.getInputStream();
byte[] b = new byte[4096*4];
- int l;
-
- while((l=in.read(b))>=0)
- {
- // System.out.println("Read "+l);
- _total+=l;
- }
- System.err.println("Read "+_total);
-
- }
- }
-
- private class EmptyHostnameVerifier implements HostnameVerifier
- {
- public boolean verify(String s, SSLSession sslSession)
- {
- return true;
+ int read;
+ while((read = in.read(b))>=0)
+ total += read;
+ System.err.println("Read "+ total);
}
}
}
diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml
index 4a2779f1e9..48557e1c6b 100644
--- a/jetty-servlet/pom.xml
+++ b/jetty-servlet/pom.xml
@@ -47,11 +47,12 @@
</execution>
</executions>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.servlet.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -59,6 +60,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
index c2d32241ea..d27681f02b 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlet;
@@ -16,12 +16,12 @@ package org.eclipse.jetty.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
-
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -47,9 +47,9 @@ import org.eclipse.jetty.server.ResourceCache;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.nio.NIOConnector;
+import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.MultiPartOutputStream;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.FileResource;
@@ -60,85 +60,85 @@ import org.eclipse.jetty.util.resource.ResourceFactory;
/* ------------------------------------------------------------ */
-/** The default servlet.
- * This servlet, normally mapped to /, provides the handling for static
- * content, OPTION and TRACE methods for the context.
+/** The default servlet.
+ * This servlet, normally mapped to /, provides the handling for static
+ * content, OPTION and TRACE methods for the context.
* The following initParameters are supported, these can be set either
* on the servlet itself or as ServletContext initParameters with a prefix
- * of org.eclipse.jetty.servlet.Default. :
- * <PRE>
- * acceptRanges If true, range requests and responses are
- * supported
- *
- * dirAllowed If true, directory listings are returned if no
- * welcome file is found. Else 403 Forbidden.
+ * of org.eclipse.jetty.servlet.Default. :
+ * <PRE>
+ * acceptRanges If true, range requests and responses are
+ * supported
+ *
+ * dirAllowed If true, directory listings are returned if no
+ * welcome file is found. Else 403 Forbidden.
*
* welcomeServlets If true, attempt to dispatch to welcome files
* that are servlets, but only after no matching static
- * resources could be found. If false, then a welcome
- * file must exist on disk. If "exact", then exact
+ * resources could be found. If false, then a welcome
+ * file must exist on disk. If "exact", then exact
* servlet matches are supported without an existing file.
* Default is true.
- *
+ *
* This must be false if you want directory listings,
* but have index.jsp in your welcome file list.
*
* redirectWelcome If true, welcome files are redirected rather than
* forwarded to.
*
- * gzip If set to true, then static content will be served as
- * gzip content encoded if a matching resource is
+ * gzip If set to true, then static content will be served as
+ * gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
*
- * relativeResourceBase
+ * relativeResourceBase
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
- *
+ *
* aliases If True, aliases of resources are allowed (eg. symbolic
* links and caps variations). May bypass security constraints.
- *
+ *
* maxCacheSize The maximum total size of the cache or 0 for no cache.
* maxCachedFileSize The maximum size of a file to cache
* maxCachedFiles The maximum number of files to cache
- * cacheType Set to "bio", "nio" or "both" to determine the type resource cache.
+ * cacheType Set to "bio", "nio" or "both" to determine the type resource cache.
* A bio cached buffer may be used by nio but is not as efficient as an
- * nio buffer. An nio cached buffer may not be used by bio.
- *
- * useFileMappedBuffer
+ * nio buffer. An nio cached buffer may not be used by bio.
+ *
+ * useFileMappedBuffer
* If set to true, it will use mapped file buffer to serve static content
* when using NIO connector. Setting this value to false means that
- * a direct buffer will be used instead of a mapped file buffer.
+ * a direct buffer will be used instead of a mapped file buffer.
* By default, this is set to true.
- *
+ *
* cacheControl If set, all static content will have this value set as the cache-control
* header.
- *
- *
+ *
+ *
* </PRE>
- *
*
- *
- *
+ *
+ *
+ *
*/
public class DefaultServlet extends HttpServlet implements ResourceFactory
-{
+{
private ServletContext _servletContext;
private ContextHandler _contextHandler;
-
+
private boolean _acceptRanges=true;
private boolean _dirAllowed=true;
private boolean _welcomeServlets=true;
private boolean _welcomeExactServlets=false;
private boolean _redirectWelcome=false;
private boolean _gzip=true;
-
+
private Resource _resourceBase;
private NIOResourceCache _nioCache;
private ResourceCache _bioCache;
-
+
private MimeTypes _mimeTypes;
private String[] _welcomes;
private boolean _useFileMappedBuffer=false;
@@ -146,8 +146,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
private String _relativeResourceBase;
private ServletHandler _servletHandler;
private ServletHolder _defaultHolder;
-
-
+
+
/* ------------------------------------------------------------ */
@Override
public void init()
@@ -159,18 +159,18 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
_contextHandler=((ContextHandler.Context)_servletContext).getContextHandler();
else
_contextHandler = ContextHandler.getCurrentContext().getContextHandler();
-
+
_mimeTypes = _contextHandler.getMimeTypes();
-
+
_welcomes = _contextHandler.getWelcomeFiles();
if (_welcomes==null)
_welcomes=new String[] {"index.html","index.jsp"};
-
+
_acceptRanges=getInitBoolean("acceptRanges",_acceptRanges);
_dirAllowed=getInitBoolean("dirAllowed",_dirAllowed);
_redirectWelcome=getInitBoolean("redirectWelcome",_redirectWelcome);
_gzip=getInitBoolean("gzip",_gzip);
-
+
if ("exact".equals(getInitParameter("welcomeServlets")))
{
_welcomeExactServlets=true;
@@ -178,37 +178,37 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
else
_welcomeServlets=getInitBoolean("welcomeServlets", _welcomeServlets);
-
+
if (getInitParameter("aliases")!=null)
_contextHandler.setAliases(getInitBoolean("aliases",false));
-
+
boolean aliases=_contextHandler.isAliases();
if (!aliases && !FileResource.getCheckAliases())
throw new IllegalStateException("Alias checking disabled");
if (aliases)
_servletContext.log("Aliases are enabled");
-
+
_useFileMappedBuffer=getInitBoolean("useFileMappedBuffer",_useFileMappedBuffer);
-
+
_relativeResourceBase = getInitParameter("relativeResourceBase");
-
+
String rb=getInitParameter("resourceBase");
if (rb!=null)
{
if (_relativeResourceBase!=null)
- throw new UnavailableException("resourceBase & relativeResourceBase");
+ throw new UnavailableException("resourceBase & relativeResourceBase");
try{_resourceBase=_contextHandler.newResource(rb);}
- catch (Exception e)
+ catch (Exception e)
{
Log.warn(Log.EXCEPTION,e);
- throw new UnavailableException(e.toString());
+ throw new UnavailableException(e.toString());
}
}
-
+
String t=getInitParameter("cacheControl");
if (t!=null)
_cacheControl=new ByteArrayBuffer(t);
-
+
try
{
String cache_type =getInitParameter("cacheType");
@@ -223,9 +223,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
_nioCache=new NIOResourceCache(_mimeTypes);
_nioCache.setUseFileMappedBuffer(_useFileMappedBuffer);
if (max_cache_size>0)
- _nioCache.setMaxCacheSize(max_cache_size);
+ _nioCache.setMaxCacheSize(max_cache_size);
if (max_cached_file_size>=-1)
- _nioCache.setMaxCachedFileSize(max_cached_file_size);
+ _nioCache.setMaxCachedFileSize(max_cached_file_size);
if (max_cached_files>=-1)
_nioCache.setMaxCachedFiles(max_cached_files);
_nioCache.start();
@@ -237,9 +237,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
_bioCache=new ResourceCache(_mimeTypes);
if (max_cache_size>0)
- _bioCache.setMaxCacheSize(max_cache_size);
+ _bioCache.setMaxCacheSize(max_cache_size);
if (max_cached_file_size>=-1)
- _bioCache.setMaxCachedFileSize(max_cached_file_size);
+ _bioCache.setMaxCachedFileSize(max_cached_file_size);
if (max_cached_files>=-1)
_bioCache.setMaxCachedFiles(max_cached_files);
_bioCache.start();
@@ -247,19 +247,19 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
if (_nioCache==null)
_bioCache=null;
-
+
}
- catch (Exception e)
+ catch (Exception e)
{
Log.warn(Log.EXCEPTION,e);
- throw new UnavailableException(e.toString());
+ throw new UnavailableException(e.toString());
}
_servletHandler= (ServletHandler) _contextHandler.getChildHandlerByClass(ServletHandler.class);
for (ServletHolder h :_servletHandler.getServlets())
if (h.getServletInstance()==this)
_defaultHolder=h;
-
+
if (Log.isDebugEnabled()) Log.debug("resource base = "+_resourceBase);
}
@@ -272,7 +272,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
value=super.getInitParameter(name);
return value;
}
-
+
/* ------------------------------------------------------------ */
private boolean getInitBoolean(String name, boolean dft)
{
@@ -285,7 +285,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
value.startsWith("Y")||
value.startsWith("1"));
}
-
+
/* ------------------------------------------------------------ */
private int getInitInt(String name, int dft)
{
@@ -296,7 +296,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
return Integer.parseInt(value);
return dft;
}
-
+
/* ------------------------------------------------------------ */
/** get Resource to serve.
* Map a path to a resource. The default implementation calls
@@ -310,7 +310,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
Resource r=null;
if (_relativeResourceBase!=null)
pathInContext=URIUtil.addPaths(_relativeResourceBase,pathInContext);
-
+
try
{
if (_resourceBase!=null)
@@ -320,8 +320,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
URL u = _servletContext.getResource(pathInContext);
r = _contextHandler.newResource(u);
}
-
- if (Log.isDebugEnabled())
+
+ if (Log.isDebugEnabled())
Log.debug("RESOURCE "+pathInContext+"="+r);
}
catch (IOException e)
@@ -330,7 +330,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
return r;
}
-
+
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
@@ -361,10 +361,10 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (!hasDefinedRange(reqRanges))
reqRanges = null;
}
-
+
String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
boolean endsWithSlash=pathInContext.endsWith(URIUtil.SLASH);
-
+
// Can we gzip this request?
String pathInContextGz=null;
boolean gzip=false;
@@ -374,19 +374,19 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (accept!=null && accept.indexOf("gzip")>=0)
gzip=true;
}
-
+
// Find the resource and content
Resource resource=null;
HttpContent content=null;
-
+
Connector connector = HttpConnection.getCurrentConnection().getConnector();
- ResourceCache cache=(connector instanceof NIOConnector) ?_nioCache:_bioCache;
+ ResourceCache cache=(connector instanceof NIOConnector && !(connector instanceof SslConnector)) ?_nioCache:_bioCache;
try
- {
+ {
// Try gzipped content first
if (gzip)
{
- pathInContextGz=pathInContext+".gz";
+ pathInContextGz=pathInContext+".gz";
if (cache==null)
{
@@ -414,7 +414,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
pathInContextGz=null;
}
}
-
+
// find resource
if (!gzip)
{
@@ -430,15 +430,15 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
resource=getResource(pathInContext);
}
}
-
+
if (Log.isDebugEnabled())
Log.debug("resource="+resource+(content!=null?" content":""));
-
+
// Handle resource
if (resource==null || !resource.exists())
response.sendError(HttpServletResponse.SC_NOT_FOUND);
else if (!resource.isDirectory())
- {
+ {
if (endsWithSlash && _contextHandler.isAliases() && pathInContext.length()>1)
{
String q=request.getQueryString();
@@ -452,8 +452,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
// ensure we have content
if (content==null)
content=new UnCachedContent(resource);
-
- if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
+
+ if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
{
if (gzip)
{
@@ -462,14 +462,14 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (mt!=null)
response.setContentType(mt);
}
- sendData(request,response,included.booleanValue(),resource,content,reqRanges);
+ sendData(request,response,included.booleanValue(),resource,content,reqRanges);
}
}
}
else
{
String welcome=null;
-
+
if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.eclipse.jetty.server.nullPathInfo")!=null))
{
StringBuffer buf=request.getRequestURL();
@@ -519,7 +519,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
}
}
- else
+ else
{
content=new UnCachedContent(resource);
if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
@@ -540,9 +540,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
else if (resource!=null)
resource.release();
}
-
+
}
-
+
/* ------------------------------------------------------------ */
private boolean hasDefinedRange(Enumeration reqRanges)
{
@@ -556,7 +556,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
doGet(request,response);
}
-
+
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doTrace(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@@ -568,8 +568,16 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
/* ------------------------------------------------------------ */
+ @Override
+ protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ resp.setHeader("Allow", "GET,HEAD,POST,OPTIONS");
+ }
+
+ /* ------------------------------------------------------------ */
/**
- * Finds a matching welcome file for the supplied {@link Resource}. This will be the first entry in the list of
+ * Finds a matching welcome file for the supplied {@link Resource}. This will be the first entry in the list of
* configured {@link #_welcomes welcome files} that existing within the directory referenced by the <code>Resource</code>.
* If the resource is not a directory, or no matching file is found, then it may look for a valid servlet mapping.
* If there is none, then <code>null</code> is returned.
@@ -584,7 +592,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
if (_welcomes==null)
return null;
-
+
String welcome_servlet=null;
for (int i=0;i<_welcomes.length;i++)
{
@@ -599,7 +607,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (entry!=null && entry.getValue()!=_defaultHolder &&
(_welcomeServlets || (_welcomeExactServlets && entry.getKey().equals(welcome_in_context))))
welcome_servlet=welcome_in_context;
-
+
}
}
return welcome_servlet;
@@ -632,7 +640,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
}
}
-
+
long ifmsl=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
if (ifmsl!=-1)
{
@@ -648,7 +656,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
// Parse the if[un]modified dates and compare to resource
long date=request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
-
+
if (date!=-1)
{
if (resource.lastModified()/1000 > date/1000)
@@ -657,7 +665,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
return false;
}
}
-
+
}
}
catch(IllegalArgumentException iae)
@@ -668,8 +676,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
return true;
}
-
-
+
+
/* ------------------------------------------------------------------- */
protected void sendDirectory(HttpServletRequest request,
HttpServletResponse response,
@@ -682,16 +690,16 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
-
+
byte[] data=null;
String base = URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH);
-
+
// handle ResourceCollection
if (_resourceBase instanceof ResourceCollection)
resource=_resourceBase.addPath(pathInContext);
else if (_contextHandler.getBaseResource() instanceof ResourceCollection)
resource=_contextHandler.getBaseResource().addPath(pathInContext);
-
+
String dir = resource.getListHTML(base,pathInContext.length()>1);
if (dir==null)
{
@@ -699,13 +707,13 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
"No directory");
return;
}
-
+
data=dir.getBytes("UTF-8");
response.setContentType("text/html; charset=UTF-8");
response.setContentLength(data.length);
response.getOutputStream().write(data);
}
-
+
/* ------------------------------------------------------------ */
protected void sendData(HttpServletRequest request,
HttpServletResponse response,
@@ -716,12 +724,12 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
throws IOException
{
long content_length=content==null?resource.length():content.getContentLength();
-
+
// Get the output stream (or writer)
OutputStream out =null;
try{out = response.getOutputStream();}
catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
-
+
if ( reqRanges == null || !reqRanges.hasMoreElements() || content_length<0)
{
// if there were no ranges, send entire entity
@@ -762,19 +770,19 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
// Parse the satisfiable ranges
List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,content_length);
-
+
// if there are no satisfiable ranges, send 416 response
if (ranges==null || ranges.size()==0)
{
writeHeaders(response, content, content_length);
response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
- response.setHeader(HttpHeaders.CONTENT_RANGE,
+ response.setHeader(HttpHeaders.CONTENT_RANGE,
InclusiveByteRange.to416HeaderRangeString(content_length));
resource.writeTo(out,0,content_length);
return;
}
-
- // if there is only a single valid range (must be satisfiable
+
+ // if there is only a single valid range (must be satisfiable
// since were here now), send that range with a 216 response
if ( ranges.size()== 1)
{
@@ -783,21 +791,21 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
long singleLength = singleSatisfiableRange.getSize(content_length);
writeHeaders(response,content,singleLength );
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
- response.setHeader(HttpHeaders.CONTENT_RANGE,
+ response.setHeader(HttpHeaders.CONTENT_RANGE,
singleSatisfiableRange.toHeaderRangeString(content_length));
resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength);
return;
}
-
+
// multiple non-overlapping valid ranges cause a multipart
- // 216 response which does not require an overall
+ // 216 response which does not require an overall
// content-length header
//
writeHeaders(response,content,-1);
String mimetype=content.getContentType().toString();
MultiPartOutputStream multi = new MultiPartOutputStream(out);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
-
+
// If the request has a "Request-Range" header then we need to
// send an old style multipart/x-byteranges Content-Type. This
// keeps Netscape and acrobat happy. This is what Apache does.
@@ -807,10 +815,10 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
else
ctp = "multipart/byteranges; boundary=";
response.setContentType(ctp+multi.getBoundary());
-
+
InputStream in=resource.getInputStream();
long pos=0;
-
+
// calculate the content-length
int length=0;
String[] header = new String[ranges.size()];
@@ -820,20 +828,20 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
header[i]=ibr.toHeaderRangeString(content_length);
length+=
((i>0)?2:0)+
- 2+multi.getBoundary().length()+2+
- HttpHeaders.CONTENT_TYPE.length()+2+mimetype.length()+2+
- HttpHeaders.CONTENT_RANGE.length()+2+header[i].length()+2+
+ 2+multi.getBoundary().length()+2+
+ HttpHeaders.CONTENT_TYPE.length()+2+mimetype.length()+2+
+ HttpHeaders.CONTENT_RANGE.length()+2+header[i].length()+2+
2+
(ibr.getLast(content_length)-ibr.getFirst(content_length))+1;
}
length+=2+2+multi.getBoundary().length()+2+2;
response.setContentLength(length);
-
+
for (int i=0;i<ranges.size();i++)
{
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
multi.startPart(mimetype,new String[]{HttpHeaders.CONTENT_RANGE+": "+header[i]});
-
+
long start=ibr.getFirst(content_length);
long size=ibr.getSize(content_length);
if (in!=null)
@@ -856,7 +864,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
else
// Handle cached resource
(resource).writeTo(multi,start,size);
-
+
}
if (in!=null)
in.close();
@@ -864,20 +872,20 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
return;
}
-
+
/* ------------------------------------------------------------ */
protected void writeHeaders(HttpServletResponse response,HttpContent content,long count)
throws IOException
- {
+ {
if (content.getContentType()!=null && response.getContentType()==null)
response.setContentType(content.getContentType().toString());
-
+
if (response instanceof Response)
{
Response r=(Response)response;
HttpFields fields = r.getHttpFields();
- if (content.getLastModified()!=null)
+ if (content.getLastModified()!=null)
fields.put(HttpHeaders.LAST_MODIFIED_BUFFER,content.getLastModified(),content.getResource().lastModified());
else if (content.getResource()!=null)
{
@@ -885,7 +893,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (lml!=-1)
fields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER,lml);
}
-
+
if (count != -1)
r.setLongContentLength(count);
@@ -901,27 +909,27 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
if (count<Integer.MAX_VALUE)
response.setContentLength((int)count);
- else
- response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(count));
+ else
+ response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(count));
}
-
+
writeOptionHeaders(response);
}
}
/* ------------------------------------------------------------ */
protected void writeOptionHeaders(HttpFields fields) throws IOException
- {
+ {
if (_acceptRanges)
fields.put(HttpHeaders.ACCEPT_RANGES_BUFFER,HttpHeaderValues.BYTES_BUFFER);
if (_cacheControl!=null)
fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
}
-
+
/* ------------------------------------------------------------ */
protected void writeOptionHeaders(HttpServletResponse response) throws IOException
- {
+ {
if (_acceptRanges)
response.setHeader(HttpHeaders.ACCEPT_RANGES,"bytes");
@@ -930,7 +938,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see javax.servlet.Servlet#destroy()
*/
@Override
@@ -940,8 +948,6 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
if (_nioCache!=null)
_nioCache.stop();
- if (_bioCache!=null)
- _bioCache.stop();
}
catch(Exception e)
{
@@ -949,7 +955,19 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
finally
{
- super.destroy();
+ try
+ {
+ if (_bioCache!=null)
+ _bioCache.stop();
+ }
+ catch(Exception e)
+ {
+ Log.warn(Log.EXCEPTION,e);
+ }
+ finally
+ {
+ super.destroy();
+ }
}
}
@@ -959,12 +977,12 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
private class UnCachedContent implements HttpContent
{
Resource _resource;
-
+
UnCachedContent(Resource resource)
{
_resource=resource;
}
-
+
/* ------------------------------------------------------------ */
public Buffer getContentType()
{
@@ -1007,6 +1025,6 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
_resource.release();
_resource=null;
}
-
+
}
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
index 989b8b01b0..94d0515e8f 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlet;
@@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -30,34 +29,30 @@ import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
/** Error Page Error Handler
- *
+ *
* An ErrorHandler that maps exceptions and status codes to URIs for dispatch using
* the internal ERROR style of dispatch.
- *
+ *
*
*/
public class ErrorPageErrorHandler extends ErrorHandler
{
public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
-
+
protected ServletContext _servletContext;
protected Map _errorPages; // code or exception to URL
- protected List _errorPageList; // list of ErrorCode by range
+ protected List _errorPageList; // list of ErrorCode by range
/* ------------------------------------------------------------ */
- /**
- * @param context
- */
public ErrorPageErrorHandler()
{}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.handler.ErrorHandler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+ /**
+ * @see org.eclipse.jetty.server.handler.ErrorHandler#handle(String, Request, HttpServletRequest, HttpServletResponse)
*/
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
@@ -71,7 +66,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
{
String error_page= null;
Class exClass= (Class)request.getAttribute(Dispatcher.ERROR_EXCEPTION_TYPE);
-
+
if (ServletException.class.equals(exClass))
{
error_page= (String)_errorPages.get(exClass.getName());
@@ -84,20 +79,20 @@ public class ErrorPageErrorHandler extends ErrorHandler
exClass= th.getClass();
}
}
-
+
while (error_page == null && exClass != null )
{
error_page= (String)_errorPages.get(exClass.getName());
exClass= exClass.getSuperclass();
}
-
+
if (error_page == null)
{
// look for an exact code match
Integer code=(Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE);
if (code!=null)
{
- error_page= (String)_errorPages.get(TypeUtil.toString(code.intValue()));
+ error_page= (String)_errorPages.get(Integer.toString(code));
// if still not found
if ((error_page == null) && (_errorPageList != null))
@@ -106,7 +101,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
for (int i = 0; i < _errorPageList.size(); i++)
{
ErrorCodeRange errCode = (ErrorCodeRange) _errorPageList.get(i);
- if (errCode.isInRange(code.intValue()))
+ if (errCode.isInRange(code))
{
error_page = errCode.getUri();
break;
@@ -115,19 +110,19 @@ public class ErrorPageErrorHandler extends ErrorHandler
}
}
}
-
+
if (error_page!=null)
{
String old_error_page=(String)request.getAttribute(ERROR_PAGE);
if (old_error_page==null || !old_error_page.equals(error_page))
{
request.setAttribute(ERROR_PAGE, error_page);
-
+
Dispatcher dispatcher = (Dispatcher) _servletContext.getRequestDispatcher(error_page);
try
{
if(dispatcher!=null)
- {
+ {
dispatcher.error(request, response);
return;
}
@@ -144,7 +139,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
}
}
}
-
+
super.handle(target, baseRequest, request, response);
}
@@ -156,7 +151,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
{
return _errorPages;
}
-
+
/* ------------------------------------------------------------ */
/**
* @param errorPages The errorPages to set. A map of Exception class name or error code as a string to URI string
@@ -170,7 +165,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
/** Add Error Page mapping for an exception class
* This method is called as a result of an exception-type element in a web.xml file
* or may be called directly
- * @param code The class (or superclass) of the matching exceptions
+ * @param exception The exception
* @param uri The URI of the error page.
*/
public void addErrorPage(Class exception,String uri)
@@ -179,7 +174,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
_errorPages=new HashMap();
_errorPages.put(exception.getName(),uri);
}
-
+
/* ------------------------------------------------------------ */
/** Add Error Page mapping for a status code.
* This method is called as a result of an error-code element in a web.xml file
@@ -191,9 +186,9 @@ public class ErrorPageErrorHandler extends ErrorHandler
{
if (_errorPages==null)
_errorPages=new HashMap();
- _errorPages.put(TypeUtil.toString(code),uri);
+ _errorPages.put(Integer.toString(code),uri);
}
-
+
/* ------------------------------------------------------------ */
/** Add Error Page mapping for a status code range.
* This method is not available from web.xml and must be called
@@ -232,36 +227,36 @@ public class ErrorPageErrorHandler extends ErrorHandler
private int _from;
private int _to;
private String _uri;
-
+
ErrorCodeRange(int from, int to, String uri)
throws IllegalArgumentException
{
if (from > to)
throw new IllegalArgumentException("from>to");
-
+
_from = from;
_to = to;
_uri = uri;
}
-
+
boolean isInRange(int value)
{
if ((value >= _from) && (value <= _to))
{
return true;
}
-
+
return false;
}
-
+
String getUri()
{
return _uri;
}
-
+
public String toString()
{
return "from: " + _from + ",to: " + _to + ",uri: " + _uri;
}
- }
+ }
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
index 079c63787c..3ade48fb43 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
@@ -124,7 +124,7 @@ public class FilterHolder extends Holder<Filter>
Log.warn(e);
}
}
- if (!_instance)
+ if (!_extInstance)
_filter=null;
_config=null;
@@ -147,7 +147,7 @@ public class FilterHolder extends Holder<Filter>
public synchronized void setFilter(Filter filter)
{
_filter=filter;
- _instance=true;
+ _extInstance=true;
setHeldClass(filter.getClass());
if (getName()==null)
setName(filter.getClass().getName());
@@ -160,6 +160,7 @@ public class FilterHolder extends Holder<Filter>
}
/* ------------------------------------------------------------ */
+ @Override
public String toString()
{
return getName();
@@ -245,8 +246,3 @@ public class FilterHolder extends Holder<Filter>
}
}
}
-
-
-
-
-
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
index be57231330..a13ebfeafd 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
@@ -167,6 +167,20 @@ public class FilterMapping
/* ------------------------------------------------------------ */
/**
+ * @param dispatches The dispatches to set.
+ * @see #DEFAULT
+ * @see #REQUEST
+ * @see #ERROR
+ * @see #FORWARD
+ * @see #INCLUDE
+ */
+ public void setDispatches(int dispatches)
+ {
+ _dispatches = dispatches;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
* @param filterName The filterName to set.
*/
public void setFilterName(String filterName)
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
index bfa1b59e23..d1817bb793 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
@@ -37,20 +37,19 @@ import org.eclipse.jetty.util.log.Log;
public class Holder<T> extends AbstractLifeCycle
{
public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
-
final private Source _source;
-
protected transient Class<? extends T> _class;
+ protected final Map<String,String> _initParams=new HashMap<String,String>(3);
protected String _className;
protected String _displayName;
- protected Map<String,String> _initParams;
- protected boolean _instance;
- protected boolean _asyncSupported;
+ protected boolean _extInstance;
+ protected boolean _asyncSupported=true;
/* ---------------------------------------------------------------- */
protected String _name;
protected ServletHandler _servletHandler;
+ /* ---------------------------------------------------------------- */
protected Holder(Source source)
{
_source=source;
@@ -67,7 +66,7 @@ public class Holder<T> extends AbstractLifeCycle
*/
public boolean isInstance()
{
- return _instance;
+ return _extInstance;
}
/* ------------------------------------------------------------ */
@@ -99,7 +98,7 @@ public class Holder<T> extends AbstractLifeCycle
public void doStop()
throws Exception
{
- if (!_instance)
+ if (!_extInstance)
_class=null;
}
@@ -176,7 +175,7 @@ public class Holder<T> extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
- * @param className The className to set.
+ * @param held The class to hold
*/
public void setHeldClass(Class<? extends T> held)
{
@@ -198,15 +197,14 @@ public class Holder<T> extends AbstractLifeCycle
/* ------------------------------------------------------------ */
public void setInitParameter(String param,String value)
{
- if (_initParams==null)
- _initParams=new HashMap(3);
_initParams.put(param,value);
}
/* ---------------------------------------------------------------- */
- public void setInitParameters(Map map)
+ public void setInitParameters(Map<String,String> map)
{
- _initParams=map;
+ _initParams.clear();
+ _initParams.putAll(map);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
index 588d298f8d..f739b1dc3d 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
@@ -49,6 +49,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.server.handler.ScopedHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.Loader;
@@ -141,7 +142,6 @@ public class ServletContextHandler extends ContextHandler
else if (parent instanceof HandlerCollection)
((HandlerCollection)parent).addHandler(this);
}
-
/* ------------------------------------------------------------ */
@@ -248,7 +248,18 @@ public class ServletContextHandler extends ContextHandler
handler=_sessionHandler;
}
- setHandler(handler);
+ // skip any wrapped handlers
+ HandlerWrapper wrapper=this;
+ while (wrapper!=handler && wrapper.getHandler() instanceof HandlerWrapper)
+ wrapper=(HandlerWrapper)wrapper.getHandler();
+
+ // if we are not already linked
+ if (wrapper!=handler)
+ {
+ if (wrapper.getHandler()!=null )
+ throw new IllegalStateException("!ScopedHandler");
+ wrapper.setHandler(handler);
+ }
super.startContext();
@@ -398,7 +409,7 @@ public class ServletContextHandler extends ContextHandler
/* ------------------------------------------------------------ */
/**
- * @param securityHandler The {@link org.eclipse.jetty.server.handler.SecurityHandler} to set on this context.
+ * @param securityHandler The {@link SecurityHandler} to set on this context.
*/
public void setSecurityHandler(SecurityHandler securityHandler)
{
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 40c71bd05c..9c56b23b8c 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -68,9 +68,6 @@ import org.eclipse.jetty.util.log.Log;
*
* Unless run as part of a {@link ServletContextHandler} or derivative, the {@link #initialize()}
* method must be called manually after start().
- *
- * @see org.eclipse.jetty.webapp.WebAppContext
- *
*/
public class ServletHandler extends ScopedHandler
{
@@ -383,7 +380,7 @@ public class ServletHandler extends ScopedHandler
baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, ((ServletHolder.Registration)servlet_holder.getRegistration()).getMultipartConfig());
// start manual inline of nextScope(target,baseRequest,request,response);
- if (false)
+ if (never())
nextScope(target,baseRequest,request,response);
else if (_nextScope!=null)
_nextScope.doScope(target,baseRequest,request, response);
@@ -813,8 +810,8 @@ public class ServletHandler extends ScopedHandler
/** Convenience method to add a servlet with a servlet mapping.
* @param className
* @param pathSpec
- * @return
- * @deprecated
+ * @return the ServletHolder
+ * @deprecated use {@link #addServletWithMapping(Class, String)} instead
*/
public ServletHolder addServlet (String className, String pathSpec)
{
@@ -842,7 +839,7 @@ public class ServletHandler extends ScopedHandler
/* ------------------------------------------------------------ */
/**
- * @see {@link #newFilterHolder(Class)}
+ * @see #newFilterHolder(Class)
*/
public FilterHolder newFilterHolder(Holder.Source source)
{
@@ -857,7 +854,7 @@ public class ServletHandler extends ScopedHandler
/* ------------------------------------------------------------ */
- /** conveniance method to add a filter.
+ /** Convenience method to add a filter.
* @param filter class of filter to create
* @param pathSpec filter mappings for filter
* @param dispatches see {@link FilterMapping#setDispatches(int)}
@@ -873,7 +870,7 @@ public class ServletHandler extends ScopedHandler
}
/* ------------------------------------------------------------ */
- /** convenience method to add a filter.
+ /** Convenience method to add a filter.
* @param className of filter
* @param pathSpec filter mappings for filter
* @param dispatches see {@link FilterMapping#setDispatches(int)}
@@ -890,7 +887,7 @@ public class ServletHandler extends ScopedHandler
}
/* ------------------------------------------------------------ */
- /** conveniance method to add a filter.
+ /** Convenience method to add a filter.
* @param holder filter holder to add
* @param pathSpec filter mappings for filter
* @param dispatches see {@link FilterMapping#setDispatches(int)}
@@ -929,7 +926,8 @@ public class ServletHandler extends ScopedHandler
* @param className
* @param pathSpec
* @param dispatches
- * @return
+ * @return the filter holder created
+ * @deprecated use {@link #addFilterWithMapping(Class, String, int)} instead
*/
public FilterHolder addFilter (String className,String pathSpec,EnumSet<DispatcherType> dispatches)
{
@@ -1371,6 +1369,7 @@ public class ServletHandler extends ScopedHandler
b.append(indent);
b.append(" +-");
b.append(f);
+ b.append(f.getFilterHolder().getInitParameters());
b.append('\n');
}
}
@@ -1383,6 +1382,9 @@ public class ServletHandler extends ScopedHandler
b.append(indent);
b.append(" +-");
b.append(m);
+ ServletHolder h = getServlet(m.getServletName());
+ if (h!=null)
+ b.append(h.getInitParameters());
b.append('\n');
}
}
@@ -1396,6 +1398,7 @@ public class ServletHandler extends ScopedHandler
b.append(indent);
b.append(" +-[]==>");
b.append(h.getName());
+ b.append(h.getInitParameters());
b.append('\n');
}
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
index fc6a496a90..ec1f9cd940 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
@@ -120,7 +120,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
if (servlet==null || servlet instanceof SingleThreadModel)
throw new IllegalArgumentException();
- _instance=true;
+ _extInstance=true;
_servlet=servlet;
setHeldClass(servlet.getClass());
if (getName()==null)
@@ -263,7 +263,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
_servlet = new SingleThreadedWrapper();
- if (_instance || _initOnStartup)
+ if (_extInstance || _initOnStartup)
{
try
{
@@ -304,7 +304,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
}
}
- if (!_instance)
+ if (!_extInstance)
_servlet=null;
_config=null;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java
index 80e8d802c1..b0c908e737 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java
@@ -28,7 +28,7 @@ public class ServletMapping
/* ------------------------------------------------------------ */
/**
- * @return Returns the pathSpec.
+ * @return Returns the pathSpecs.
*/
public String[] getPathSpecs()
{
@@ -46,7 +46,7 @@ public class ServletMapping
/* ------------------------------------------------------------ */
/**
- * @param pathSpec The pathSpec to set.
+ * @param pathSpecs The pathSpecs to set.
*/
public void setPathSpecs(String[] pathSpecs)
{
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
index 2906a2635c..ce2f6f924a 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
@@ -5,26 +5,28 @@ import java.io.FileOutputStream;
import java.io.IOException;
import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
-public class DefaultServletTest extends TestCase
+public class DefaultServletTest
{
private boolean _runningOnWindows;
private Server server;
private LocalConnector connector;
private ServletContextHandler context;
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_runningOnWindows = System.getProperty( "os.name" ).startsWith( "Windows" );
- super.setUp();
-
server = new Server();
server.setSendServerVersion(false);
@@ -32,7 +34,7 @@ public class DefaultServletTest extends TestCase
context = new ServletContextHandler();
context.setContextPath("/context");
- context.setWelcomeFiles(new String[] {"index.html","index.jsp","index.htm"});
+ context.setWelcomeFiles(new String[] {"index.html","index.jsp","index.htm"});
server.setHandler(context);
server.addConnector(connector);
@@ -40,16 +42,14 @@ public class DefaultServletTest extends TestCase
server.start();
}
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
-
- if (server != null)
- {
- server.stop();
- }
+ server.stop();
+ server.join();
}
+ @Test
public void testListingWithSession() throws Exception
{
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/*");
@@ -57,15 +57,15 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("redirectWelcome","false");
defholder.setInitParameter("gzip","false");
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
/* create some content in the docroot */
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
- new File(resBase, "one").mkdir();
- new File(resBase, "two").mkdir();
- new File(resBase, "three").mkdir();
+ assertTrue(resBase.mkdirs());
+ assertTrue(new File(resBase, "one").mkdir());
+ assertTrue(new File(resBase, "two").mkdir());
+ assertTrue(new File(resBase, "three").mkdir());
String resBasePath = resBase.getAbsolutePath();
defholder.setInitParameter("resourceBase",resBasePath);
@@ -84,6 +84,7 @@ public class DefaultServletTest extends TestCase
assertResponseNotContains("<script>",response);
}
+ @Test
public void testListingXSS() throws Exception
{
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/*");
@@ -91,15 +92,15 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("redirectWelcome","false");
defholder.setInitParameter("gzip","false");
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
/* create some content in the docroot */
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
- new File(resBase, "one").mkdir();
- new File(resBase, "two").mkdir();
- new File(resBase, "three").mkdir();
+ assertTrue(resBase.mkdirs());
+ assertTrue(new File(resBase, "one").mkdir());
+ assertTrue(new File(resBase, "two").mkdir());
+ assertTrue(new File(resBase, "three").mkdir());
if ( !_runningOnWindows )
assertTrue("Creating dir 'f??r' (Might not work in Windows)", new File(resBase, "f??r").mkdir());
@@ -126,6 +127,7 @@ public class DefaultServletTest extends TestCase
assertResponseNotContains( "<script>", response );
}
+ @Test
public void testListingProperUrlEncoding() throws Exception
{
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/*");
@@ -133,18 +135,18 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("redirectWelcome","false");
defholder.setInitParameter("gzip","false");
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
/* create some content in the docroot */
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File wackyDir = new File(resBase, "dir;"); // this should not be double-encoded.
assertTrue(wackyDir.mkdirs());
- new File(wackyDir, "four").mkdir();
- new File(wackyDir, "five").mkdir();
- new File(wackyDir, "six").mkdir();
+ assertTrue(new File(wackyDir, "four").mkdir());
+ assertTrue(new File(wackyDir, "five").mkdir());
+ assertTrue(new File(wackyDir, "six").mkdir());
/* At this point we have the following
* testListingProperUrlEncoding/
@@ -163,7 +165,6 @@ public class DefaultServletTest extends TestCase
assertResponseContains("HTTP/1.1 404 Not Found", response);
-
// Now send request in proper, encoded format.
response = connector.getResponses("GET /context/dir%3B/ HTTP/1.0\r\n\r\n");
@@ -178,6 +179,7 @@ public class DefaultServletTest extends TestCase
assertResponseContains("/dir%3B/six/",response);
}
+ @Test
public void testListingContextBreakout() throws Exception
{
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/");
@@ -186,12 +188,12 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("gzip","false");
defholder.setInitParameter("aliases","true");
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
/* create some content in the docroot */
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File index = new File(resBase, "index.html");
createFile(index, "<h1>Hello Index</h1>");
@@ -207,7 +209,7 @@ public class DefaultServletTest extends TestCase
/* create some content outside of the docroot */
File sekret = new File(testDir, "sekret");
- sekret.mkdirs();
+ assertTrue(sekret.mkdirs());
File pass = new File(sekret, "pass");
createFile(pass, "Sssh, you shouldn't be seeing this");
@@ -286,17 +288,15 @@ public class DefaultServletTest extends TestCase
assertResponseNotContains("Sssh",response);
}
-
-
+ @Test
public void testWelcome() throws Exception
{
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File inde = new File(resBase, "index.htm");
File index = new File(resBase, "index.html");
-
String resBasePath = resBase.getAbsolutePath();
@@ -306,41 +306,39 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("welcomeServlets","false");
defholder.setInitParameter("gzip","false");
defholder.setInitParameter("resourceBase",resBasePath);
-
- ServletHolder jspholder = context.addServlet(NoJspServlet.class,"*.jsp");
- String response;
+ ServletHolder jspholder = context.addServlet(NoJspServlet.class,"*.jsp");
- response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
+ String response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("403",response);
createFile(index, "<h1>Hello Index</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
-
+
createFile(inde, "<h1>Hello Inde</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
- index.delete();
+ assertTrue(index.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Inde</h1>",response);
-
- inde.delete();
+
+ assertTrue(inde.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("403",response);
-
}
+ @Test
public void testWelcomeServlet() throws Exception
{
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File inde = new File(resBase, "index.htm");
File index = new File(resBase, "index.html");
-
+
String resBasePath = resBase.getAbsolutePath();
@@ -350,7 +348,7 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("welcomeServlets","true");
defholder.setInitParameter("gzip","false");
defholder.setInitParameter("resourceBase",resBasePath);
-
+
ServletHolder jspholder = context.addServlet(NoJspServlet.class,"*.jsp");
String response;
@@ -361,30 +359,29 @@ public class DefaultServletTest extends TestCase
createFile(index, "<h1>Hello Index</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
-
+
createFile(inde, "<h1>Hello Inde</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
- index.delete();
+ assertTrue(index.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Inde</h1>",response);
-
- inde.delete();
+
+ assertTrue(inde.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("JSP support not configured",response);
-
}
+ @Test
public void testWelcomeExactServlet() throws Exception
{
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File inde = new File(resBase, "index.htm");
File index = new File(resBase, "index.html");
-
String resBasePath = resBase.getAbsolutePath();
@@ -394,7 +391,7 @@ public class DefaultServletTest extends TestCase
defholder.setInitParameter("welcomeServlets","exact");
defholder.setInitParameter("gzip","false");
defholder.setInitParameter("resourceBase",resBasePath);
-
+
ServletHolder jspholder = context.addServlet(NoJspServlet.class,"*.jsp");
context.addServlet(jspholder,"/index.jsp");
@@ -406,46 +403,42 @@ public class DefaultServletTest extends TestCase
createFile(index, "<h1>Hello Index</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
-
+
createFile(inde, "<h1>Hello Inde</h1>");
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Index</h1>",response);
- index.delete();
+ assertTrue(index.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("<h1>Hello Inde</h1>",response);
-
- inde.delete();
+
+ assertTrue(inde.delete());
response= connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
assertResponseContains("JSP support not configured",response);
-
}
+ @Test
public void testRangeRequests() throws Exception
{
- File testDir = new File("target/tests/" + getName());
+ File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName());
prepareEmptyTestDir(testDir);
File resBase = new File(testDir, "docroot");
- resBase.mkdirs();
+ assertTrue(resBase.mkdirs());
File data = new File(resBase, "data.txt");
createFile(data,"01234567890123456789012345678901234567890123456789012345678901234567890123456789");
String resBasePath = resBase.getAbsolutePath();
-
-
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/");
defholder.setInitParameter("acceptRanges","true");
defholder.setInitParameter("resourceBase",resBasePath);
-
- String response;
- response= connector.getResponses(
- "GET /context/data.txt HTTP/1.1\r\n"+
- "Host: localhost\r\n"+
- "\r\n");
+ String response = connector.getResponses(
+ "GET /context/data.txt HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "\r\n");
assertResponseContains("200 OK",response);
assertResponseContains("Accept-Ranges: bytes",response);
-
+
response= connector.getResponses(
"GET /context/data.txt HTTP/1.1\r\n"+
"Host: localhost\r\n"+
@@ -486,7 +479,7 @@ public class DefaultServletTest extends TestCase
assertResponseContains("Content-Range: bytes 70-79/80",response);
assertResponseContains("Content-Length: "+body.length(),response);
assertTrue(body.endsWith(boundary+"--\r\n"));
-
+
response= connector.getResponses(
"GET /context/data.txt HTTP/1.1\r\n"+
"Host: localhost\r\n"+
@@ -503,10 +496,8 @@ public class DefaultServletTest extends TestCase
assertResponseContains("Content-Range: bytes 70-79/80",response);
assertResponseContains("Content-Length: "+body.length(),response);
assertTrue(body.endsWith(boundary+"--\r\n"));
-
}
-
private void createFile(File file, String str) throws IOException
{
FileOutputStream out = null;
@@ -527,7 +518,7 @@ public class DefaultServletTest extends TestCase
}
else
{
- testdir.mkdirs();
+ assertTrue(testdir.mkdirs());
}
assertTrue("test dir should exists",testdir.exists());
@@ -538,9 +529,7 @@ public class DefaultServletTest extends TestCase
private boolean isEmpty(File dir)
{
if (!dir.isDirectory())
- {
return true;
- }
return dir.list().length == 0;
}
@@ -548,10 +537,8 @@ public class DefaultServletTest extends TestCase
private void emptyDir(File dir)
{
File entries[] = dir.listFiles();
- for (int i = 0; i < entries.length; i++)
- {
- deletePath(entries[i]);
- }
+ for (File entry : entries)
+ deletePath(entry);
}
private void deletePath(File path)
@@ -559,10 +546,8 @@ public class DefaultServletTest extends TestCase
if (path.isDirectory())
{
File entries[] = path.listFiles();
- for (int i = 0; i < entries.length; i++)
- {
- deletePath(entries[i]);
- }
+ for (File entry : entries)
+ deletePath(entry);
}
assertTrue("Deleting: " + path.getAbsolutePath(),path.delete());
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
index 7c041fa71d..78a84a61ac 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
@@ -4,21 +4,19 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlet;
-
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
@@ -26,19 +24,24 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class DispatcherTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class DispatcherTest
{
- private Server _server = new Server();
+ private Server _server;
private LocalConnector _connector;
private ServletContextHandler _context;
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
_server = new Server();
_server.setSendServerVersion(false);
@@ -51,6 +54,14 @@ public class DispatcherTest extends TestCase
_server.start();
}
+ @After
+ public void destroy() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
+
+ @Test
public void testForward() throws Exception
{
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
@@ -63,10 +74,11 @@ public class DispatcherTest extends TestCase
"\r\n";
String responses = _connector.getResponses("GET /context/ForwardServlet?do=assertforward&do=more&test=1 HTTP/1.1\n" + "Host: localhost\n\n");
-
- assertEquals(expected, responses);
+
+ assertEquals(expected, responses);
}
-
+
+ @Test
public void testInclude() throws Exception
{
_context.addServlet(IncludeServlet.class, "/IncludeServlet/*");
@@ -78,10 +90,11 @@ public class DispatcherTest extends TestCase
"\r\n";
String responses = _connector.getResponses("GET /context/IncludeServlet?do=assertinclude&do=more&test=1 HTTP/1.1\n" + "Host: localhost\n\n");
-
- assertEquals(expected, responses);
+
+ assertEquals(expected, responses);
}
-
+
+ @Test
public void testForwardThenInclude() throws Exception
{
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
@@ -94,16 +107,17 @@ public class DispatcherTest extends TestCase
"\r\n";
String responses = _connector.getResponses("GET /context/ForwardServlet/forwardpath?do=include HTTP/1.1\n" + "Host: localhost\n\n");
-
+
assertEquals(expected, responses);
}
-
+
+ @Test
public void testIncludeThenForward() throws Exception
{
_context.addServlet(IncludeServlet.class, "/IncludeServlet/*");
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
_context.addServlet(AssertIncludeForwardServlet.class, "/AssertIncludeForwardServlet/*");
-
+
String expected=
"HTTP/1.1 200 OK\r\n"+
@@ -113,16 +127,16 @@ public class DispatcherTest extends TestCase
"\r\n";
String responses = _connector.getResponses("GET /context/IncludeServlet/includepath?do=forward HTTP/1.1\n" + "Host: localhost\n\n");
-
+
assertEquals(expected, responses);
}
-
- public static class ForwardServlet extends HttpServlet implements Servlet
+
+ public static class ForwardServlet extends HttpServlet implements Servlet
{
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
RequestDispatcher dispatcher = null;
-
+
if(request.getParameter("do").equals("include"))
dispatcher = getServletContext().getRequestDispatcher("/IncludeServlet/includepath?do=assertforwardinclude");
else if(request.getParameter("do").equals("assertincludeforward"))
@@ -130,15 +144,15 @@ public class DispatcherTest extends TestCase
else if(request.getParameter("do").equals("assertforward"))
dispatcher = getServletContext().getRequestDispatcher("/AssertForwardServlet?do=end&do=the");
dispatcher.forward(request, response);
- }
+ }
}
-
- public static class IncludeServlet extends HttpServlet implements Servlet
+
+ public static class IncludeServlet extends HttpServlet implements Servlet
{
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
RequestDispatcher dispatcher = null;
-
+
if(request.getParameter("do").equals("forward"))
dispatcher = getServletContext().getRequestDispatcher("/ForwardServlet/forwardpath?do=assertincludeforward");
else if(request.getParameter("do").equals("assertforwardinclude"))
@@ -146,7 +160,7 @@ public class DispatcherTest extends TestCase
else if(request.getParameter("do").equals("assertinclude"))
dispatcher = getServletContext().getRequestDispatcher("/AssertIncludeServlet?do=end&do=the");
dispatcher.include(request, response);
- }
+ }
}
public static class AssertForwardServlet extends HttpServlet implements Servlet
@@ -159,29 +173,24 @@ public class DispatcherTest extends TestCase
assertEquals( null, request.getAttribute(Dispatcher.FORWARD_PATH_INFO));
assertEquals( "do=assertforward&do=more&test=1", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING) );
-
- List expectedAttributeNames = Arrays.asList(new String[] {
- Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH,
- Dispatcher.FORWARD_SERVLET_PATH, Dispatcher.FORWARD_QUERY_STRING
- });
+ List expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH,
+ Dispatcher.FORWARD_SERVLET_PATH, Dispatcher.FORWARD_QUERY_STRING);
List requestAttributeNames = Collections.list(request.getAttributeNames());
assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
-
-
+
assertEquals(null, request.getPathInfo());
assertEquals(null, request.getPathTranslated());
assertEquals("do=end&do=the&test=1", request.getQueryString());
assertEquals("/context/AssertForwardServlet", request.getRequestURI());
assertEquals("/context", request.getContextPath());
assertEquals("/AssertForwardServlet", request.getServletPath());
-
+
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
-
}
}
- public static class AssertIncludeServlet extends HttpServlet implements Servlet
+ public static class AssertIncludeServlet extends HttpServlet implements Servlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
@@ -189,34 +198,28 @@ public class DispatcherTest extends TestCase
assertEquals( "/context", request.getAttribute(Dispatcher.INCLUDE_CONTEXT_PATH) );
assertEquals( "/AssertIncludeServlet", request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH));
assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_PATH_INFO));
- assertEquals( "do=end&do=the", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
-
- List expectedAttributeNames = Arrays.asList(new String[] {
- Dispatcher.INCLUDE_REQUEST_URI, Dispatcher.INCLUDE_CONTEXT_PATH,
- Dispatcher.INCLUDE_SERVLET_PATH, Dispatcher.INCLUDE_QUERY_STRING
- });
+ assertEquals( "do=end&do=the", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
+
+ List expectedAttributeNames = Arrays.asList(Dispatcher.INCLUDE_REQUEST_URI, Dispatcher.INCLUDE_CONTEXT_PATH,
+ Dispatcher.INCLUDE_SERVLET_PATH, Dispatcher.INCLUDE_QUERY_STRING);
List requestAttributeNames = Collections.list(request.getAttributeNames());
assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
-
-
assertEquals(null, request.getPathInfo());
assertEquals(null, request.getPathTranslated());
assertEquals("do=assertinclude&do=more&test=1", request.getQueryString());
assertEquals("/context/IncludeServlet", request.getRequestURI());
assertEquals("/context", request.getContextPath());
assertEquals("/IncludeServlet", request.getServletPath());
-
+
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
-
}
}
-
-
- public static class AssertForwardIncludeServlet extends HttpServlet implements Servlet
+
+ public static class AssertForwardIncludeServlet extends HttpServlet implements Servlet
{
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// include doesn't hide forward
assertEquals( "/context/ForwardServlet/forwardpath", request.getAttribute(Dispatcher.FORWARD_REQUEST_URI));
@@ -224,64 +227,56 @@ public class DispatcherTest extends TestCase
assertEquals( "/ForwardServlet", request.getAttribute(Dispatcher.FORWARD_SERVLET_PATH));
assertEquals( "/forwardpath", request.getAttribute(Dispatcher.FORWARD_PATH_INFO));
assertEquals( "do=include", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING) );
-
+
assertEquals( "/context/AssertForwardIncludeServlet/assertpath", request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI));
assertEquals( "/context", request.getAttribute(Dispatcher.INCLUDE_CONTEXT_PATH) );
assertEquals( "/AssertForwardIncludeServlet", request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH));
assertEquals( "/assertpath", request.getAttribute(Dispatcher.INCLUDE_PATH_INFO));
- assertEquals( "do=end", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
-
-
- List expectedAttributeNames = Arrays.asList(new String[] {
- Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
- Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING,
- Dispatcher.INCLUDE_REQUEST_URI, Dispatcher.INCLUDE_CONTEXT_PATH, Dispatcher.INCLUDE_SERVLET_PATH,
- Dispatcher.INCLUDE_PATH_INFO, Dispatcher.INCLUDE_QUERY_STRING
- });
+ assertEquals( "do=end", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
+
+ List expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
+ Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING,
+ Dispatcher.INCLUDE_REQUEST_URI, Dispatcher.INCLUDE_CONTEXT_PATH, Dispatcher.INCLUDE_SERVLET_PATH,
+ Dispatcher.INCLUDE_PATH_INFO, Dispatcher.INCLUDE_QUERY_STRING);
List requestAttributeNames = Collections.list(request.getAttributeNames());
- assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
-
-
+ assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
+
assertEquals("/includepath", request.getPathInfo());
assertEquals(null, request.getPathTranslated());
assertEquals("do=assertforwardinclude", request.getQueryString());
assertEquals("/context/IncludeServlet/includepath", request.getRequestURI());
assertEquals("/context", request.getContextPath());
assertEquals("/IncludeServlet", request.getServletPath());
-
+
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
- }
+ }
}
-
+
public static class AssertIncludeForwardServlet extends HttpServlet implements Servlet
{
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// forward hides include
assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI));
assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_CONTEXT_PATH) );
assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH));
assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_PATH_INFO));
- assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
+ assertEquals( null, request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
assertEquals( "/context/IncludeServlet/includepath", request.getAttribute(Dispatcher.FORWARD_REQUEST_URI));
assertEquals( "/context", request.getAttribute(Dispatcher.FORWARD_CONTEXT_PATH) );
assertEquals( "/IncludeServlet", request.getAttribute(Dispatcher.FORWARD_SERVLET_PATH));
assertEquals( "/includepath", request.getAttribute(Dispatcher.FORWARD_PATH_INFO));
assertEquals( "do=forward", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING) );
-
-
- List expectedAttributeNames = Arrays.asList(new String[] {
- Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
- Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING,
- });
+
+ List expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
+ Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING);
List requestAttributeNames = Collections.list(request.getAttributeNames());
assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
-
-
+
assertEquals("/assertpath", request.getPathInfo());
- assertEquals(null, request.getPathTranslated());
+ assertEquals(null, request.getPathTranslated());
assertEquals("do=end", request.getQueryString());
assertEquals("/context/AssertIncludeForwardServlet/assertpath", request.getRequestURI());
assertEquals("/context", request.getContextPath());
@@ -289,7 +284,6 @@ public class DispatcherTest extends TestCase
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
- }
+ }
}
-
}
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
index e08626e684..1456e80cb5 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
@@ -14,46 +14,54 @@
package org.eclipse.jetty.servlet;
import java.io.IOException;
-
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
/**
*
- *
*/
-public class InvokerTest extends TestCase
+public class InvokerTest
{
- Server _server;
- LocalConnector _connector;
- ServletContextHandler _context;
+ private Server _server;
+ private LocalConnector _connector;
- protected void setUp() throws Exception
+ @Before
+ public void init() throws Exception
{
- super.setUp();
_server = new Server();
_connector = new LocalConnector();
- _context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
_server.setSendServerVersion(false);
_server.addConnector(_connector);
- _server.setHandler(_context);
+ _server.setHandler(context);
- _context.setContextPath("/");
+ context.setContextPath("/");
- ServletHolder holder = _context.addServlet(Invoker.class, "/servlet/*");
+ ServletHolder holder = context.addServlet(Invoker.class, "/servlet/*");
holder.setInitParameter("nonContextServlets","true");
_server.start();
}
+ @After
+ public void destroy() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
+
+ @Test
public void testInvoker() throws Exception
{
String requestPath = "/servlet/"+TestServlet.class.getName();
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
index 12b55e7a51..7154d32aca 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
@@ -4,31 +4,31 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlet;
import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class StatisticsServletTest extends TestCase
+public class StatisticsServletTest
{
- Server server;
- LocalConnector connector;
- ServletContextHandler context;
-
- protected void setUp() throws Exception
- {
- super.setUp();
+ private Server server;
+ private LocalConnector connector;
+ private ServletContextHandler context;
+ @Before
+ public void init() throws Exception
+ {
server = new Server();
server.setSendServerVersion(false);
context = new ServletContextHandler();
@@ -37,25 +37,22 @@ public class StatisticsServletTest extends TestCase
holder.setServlet(new org.eclipse.jetty.servlet.StatisticsServlet());
holder.setInitParameter("restrictToLocalhost", "false");
context.addServlet(holder, "/stats");
-
+
server.setHandler(context);
connector = new LocalConnector();
server.addConnector(connector);
}
- protected void tearDown() throws Exception
+ @After
+ public void destroy() throws Exception
{
- super.tearDown();
-
- if (server != null)
- {
- server.stop();
- }
+ server.stop();
+ server.join();
}
-
-
+
+ @Test
public void testNoHandler () throws Exception
- {
+ {
server.start();
StringBuffer req1 = new StringBuffer();
@@ -64,25 +61,25 @@ public class StatisticsServletTest extends TestCase
req1.append("\n");
String response = connector.getResponses(req1.toString());
- assertResponseContains("503", response);
+ assertResponseContains("503", response);
}
-
+
+ @Test
public void testWithHandler () throws Exception
{
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(context);
server.setHandler(statsHandler);
server.start();
-
+
StringBuffer req1 = new StringBuffer();
req1.append("GET /stats HTTP/1.1\n");
req1.append("Host: localhost\n");
req1.append("\n");
-
+
String response = connector.getResponses(req1.toString());
- assertResponseContains("Statistics gathering started ", response);
+ assertResponseContains("Statistics gathering started ", response);
}
-
private void assertResponseContains(String expected, String response)
{
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index 32332a0831..ace6f655b8 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -39,11 +39,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.servlets.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -51,6 +52,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
index 7cf2859f75..694267d847 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -162,7 +162,7 @@ public class CrossOriginFilter implements Filter
{
String origin = request.getHeader(ORIGIN_HEADER);
// Is it a cross origin request ?
- if (origin != null)
+ if (origin != null && isEnabled(request))
{
if (originMatches(origin))
{
@@ -186,6 +186,18 @@ public class CrossOriginFilter implements Filter
chain.doFilter(request, response);
}
+ protected boolean isEnabled(HttpServletRequest request)
+ {
+ // WebSocket clients such as Chrome 5 implement a version of the WebSocket
+ // protocol that does not accept extra response headers on the upgrade response
+ if ("Upgrade".equalsIgnoreCase(request.getHeader("Connection")) &&
+ "WebSocket".equalsIgnoreCase(request.getHeader("Upgrade")))
+ {
+ return false;
+ }
+ return true;
+ }
+
private boolean originMatches(String origin)
{
if (anyOriginAllowed) return true;
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
index 5043905a51..a678441988 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
@@ -21,7 +21,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -38,12 +37,13 @@ import javax.servlet.http.HttpSessionBindingListener;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.Timeout;
/**
* Denial of Service filter
- *
+ *
* <p>
* This filter is based on the {@link QoSFilter}. it is useful for limiting
* exposure to abuse from request flooding, whether malicious, or as a result of
@@ -61,35 +61,53 @@ import org.eclipse.jetty.util.thread.Timeout;
* The {@link #extractUserId(ServletRequest request)} function should be
* implemented, in order to uniquely identify authenticated users.
* <p>
- * The following init parameters control the behavior of the filter:
- *
- * maxRequestsPerSec the maximum number of requests from a connection per
- * second. Requests in excess of this are first delayed,
- * then throttled.
- *
- * delayMs is the delay given to all requests over the rate limit,
- * before they are considered at all. -1 means just reject request,
- * 0 means no delay, otherwise it is the delay.
- *
- * maxWaitMs how long to blocking wait for the throttle semaphore.
- *
- * throttledRequests is the number of requests over the rate limit able to be
- * considered at once.
- *
- * throttleMs how long to async wait for semaphore.
+ * The following init parameters control the behavior of the filter:<dl>
+ *
+ * <dt>maxRequestsPerSec</dt>
+ * <dd>the maximum number of requests from a connection per
+ * second. Requests in excess of this are first delayed,
+ * then throttled.</dd>
+ *
+ * <dt>delayMs</dt>
+ * <dd>is the delay given to all requests over the rate limit,
+ * before they are considered at all. -1 means just reject request,
+ * 0 means no delay, otherwise it is the delay.</dd>
+ *
+ * <dt>maxWaitMs</dt>
+ * <dd>how long to blocking wait for the throttle semaphore.</dd>
+ *
+ * <dt>throttledRequests</dt>
+ * <dd>is the number of requests over the rate limit able to be
+ * considered at once.</dd>
+ *
+ * <dt>throttleMs</dt>
+ * <dd>how long to async wait for semaphore.</dd>
+ *
+ * <dt>maxRequestMs</dt>
+ * <dd>how long to allow this request to run.</dd>
+ *
+ * <dt>maxIdleTrackerMs</dt>
+ * <dd>how long to keep track of request rates for a connection,
+ * before deciding that the user has gone away, and discarding it</dd>
+ *
+ * <dt>insertHeaders</dt>
+ * <dd>if true , insert the DoSFilter headers into the response. Defaults to true.</dd>
+ *
+ * <dt>trackSessions</dt>
+ * <dd>if true, usage rate is tracked by session if a session exists. Defaults to true.</dd>
+ *
+ * <dt>remotePort</dt>
+ * <dd>if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.</dd>
+ *
+ * <dt>ipWhitelist</dt>
+ * <dd>a comma-separated list of IP addresses that will not be rate limited</dd>
*
- * maxRequestMs how long to allow this request to run.
- *
- * maxIdleTrackerMs how long to keep track of request rates for a connection,
- * before deciding that the user has gone away, and discarding it
- *
- * insertHeaders if true , insert the DoSFilter headers into the response. Defaults to true.
- *
- * trackSessions if true, usage rate is tracked by session if a session exists. Defaults to true.
- *
- * remotePort if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.
- *
- * ipWhitelist a comma-separated list of IP addresses that will not be rate limited
+ * <dt>managedAttr</dt>
+ * <dd>if set to true, then this servlet is set as a {@link ServletContext} attribute with the
+ * filter name as the attribute name. This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
+ * manage the configuration of the filter.</dd>
+ * </dl>
+ * </p>
*/
public class DoSFilter implements Filter
@@ -105,6 +123,7 @@ public class DoSFilter implements Filter
final static long __DEFAULT_MAX_REQUEST_MS_INIT_PARAM=30000L;
final static long __DEFAULT_MAX_IDLE_TRACKER_MS_INIT_PARAM=30000L;
+ final static String MANAGED_ATTR_INIT_PARAM="managedAttr";
final static String MAX_REQUESTS_PER_S_INIT_PARAM = "maxRequestsPerSec";
final static String DELAY_MS_INIT_PARAM = "delayMs";
final static String THROTTLED_REQUESTS_INIT_PARAM = "throttledRequests";
@@ -124,22 +143,25 @@ public class DoSFilter implements Filter
ServletContext _context;
+ protected String _name;
protected long _delayMs;
protected long _throttleMs;
- protected long _waitMs;
+ protected long _maxWaitMs;
protected long _maxRequestMs;
protected long _maxIdleTrackerMs;
protected boolean _insertHeaders;
protected boolean _trackSessions;
protected boolean _remotePort;
+ protected int _throttledRequests;
protected Semaphore _passes;
protected Queue<Continuation>[] _queue;
protected ContinuationListener[] _listener;
protected int _maxRequestsPerSec;
protected final ConcurrentHashMap<String, RateTracker> _rateTrackers=new ConcurrentHashMap<String, RateTracker>();
- private HashSet<String> _whitelist;
-
+ protected String _whitelistStr;
+ private final HashSet<String> _whitelist = new HashSet<String>();
+
private final Timeout _requestTimeoutQ = new Timeout();
private final Timeout _trackerTimeoutQ = new Timeout();
@@ -155,12 +177,13 @@ public class DoSFilter implements Filter
for (int p = 0; p < _queue.length; p++)
{
_queue[p] = new ConcurrentLinkedQueue<Continuation>();
-
+
final int priority=p;
_listener[p] = new ContinuationListener()
{
public void onComplete(Continuation continuation)
- {}
+ {
+ }
public void onTimeout(Continuation continuation)
{
@@ -169,6 +192,8 @@ public class DoSFilter implements Filter
};
}
+ _rateTrackers.clear();
+
int baseRateLimit = __DEFAULT_MAX_REQUESTS_PER_SEC;
if (filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM) != null)
baseRateLimit = Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM));
@@ -179,15 +204,16 @@ public class DoSFilter implements Filter
delay = Integer.parseInt(filterConfig.getInitParameter(DELAY_MS_INIT_PARAM));
_delayMs = delay;
- int passes = __DEFAULT_THROTTLE;
+ int throttledRequests = __DEFAULT_THROTTLE;
if (filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM) != null)
- passes = Integer.parseInt(filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM));
- _passes = new Semaphore(passes,true);
+ throttledRequests = Integer.parseInt(filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM));
+ _passes = new Semaphore(throttledRequests,true);
+ _throttledRequests = throttledRequests;
long wait = __DEFAULT_WAIT_MS;
if (filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM) != null)
wait = Integer.parseInt(filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM));
- _waitMs = wait;
+ _maxWaitMs = wait;
long suspend = __DEFAULT_THROTTLE_MS;
if (filterConfig.getInitParameter(THROTTLE_MS_INIT_PARAM) != null)
@@ -203,39 +229,27 @@ public class DoSFilter implements Filter
if (filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM) != null )
maxIdleTrackerMs = Long.parseLong(filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM));
_maxIdleTrackerMs = maxIdleTrackerMs;
-
- String whitelistString = "";
+
+ _whitelistStr = "";
if (filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM) !=null )
- whitelistString = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM);
-
- // empty
- if (whitelistString.length() == 0 )
- _whitelist = new HashSet<String>();
- else
- {
- StringTokenizer tokenizer = new StringTokenizer(whitelistString, ",");
- _whitelist = new HashSet<String>(tokenizer.countTokens());
- while (tokenizer.hasMoreTokens())
- _whitelist.add(tokenizer.nextToken().trim());
-
- Log.info("Whitelisted IP addresses: {}", _whitelist.toString());
- }
+ _whitelistStr = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM);
+ initWhitelist();
String tmp = filterConfig.getInitParameter(INSERT_HEADERS_INIT_PARAM);
- _insertHeaders = tmp==null || Boolean.parseBoolean(tmp);
-
+ _insertHeaders = tmp==null || Boolean.parseBoolean(tmp);
+
tmp = filterConfig.getInitParameter(TRACK_SESSIONS_INIT_PARAM);
_trackSessions = tmp==null || Boolean.parseBoolean(tmp);
-
+
tmp = filterConfig.getInitParameter(REMOTE_PORT_INIT_PARAM);
_remotePort = tmp!=null&& Boolean.parseBoolean(tmp);
_requestTimeoutQ.setNow();
_requestTimeoutQ.setDuration(_maxRequestMs);
-
+
_trackerTimeoutQ.setNow();
_trackerTimeoutQ.setDuration(_maxIdleTrackerMs);
-
+
_running=true;
_timerThread = (new Thread()
{
@@ -245,12 +259,15 @@ public class DoSFilter implements Filter
{
while (_running)
{
+ long now;
synchronized (_requestTimeoutQ)
{
- _requestTimeoutQ.setNow();
+ now = _requestTimeoutQ.setNow();
_requestTimeoutQ.tick();
-
- _trackerTimeoutQ.setNow(_requestTimeoutQ.getNow());
+ }
+ synchronized (_trackerTimeoutQ)
+ {
+ _trackerTimeoutQ.setNow(now);
_trackerTimeoutQ.tick();
}
try
@@ -270,26 +287,29 @@ public class DoSFilter implements Filter
}
});
_timerThread.start();
+
+ if (_context!=null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
+ _context.setAttribute(filterConfig.getFilterName(),this);
}
-
+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws IOException, ServletException
{
final HttpServletRequest srequest = (HttpServletRequest)request;
final HttpServletResponse sresponse = (HttpServletResponse)response;
-
+
final long now=_requestTimeoutQ.getNow();
-
+
// Look for the rate tracker for this request
RateTracker tracker = (RateTracker)request.getAttribute(__TRACKER);
if (tracker==null)
{
// This is the first time we have seen this request.
-
+
// get a rate tracker associated with this request, and record one hit
tracker = getRateTracker(request);
-
+
// Calculate the rate and check it is over the allowed limit
final boolean overRateLimit = tracker.isRateExceeded(now);
@@ -298,55 +318,66 @@ public class DoSFilter implements Filter
{
doFilterChain(filterchain,srequest,sresponse);
return;
- }
-
+ }
+
// We are over the limit.
Log.warn("DOS ALERT: ip="+srequest.getRemoteAddr()+",session="+srequest.getRequestedSessionId()+",user="+srequest.getUserPrincipal());
-
+
// So either reject it, delay it or throttle it
switch((int)_delayMs)
{
- case -1:
+ case -1:
{
// Reject this request
if (_insertHeaders)
((HttpServletResponse)response).addHeader("DoSFilter","unavailable");
+
((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
case 0:
{
- // fall through to throttle code
+ // fall through to throttle code
request.setAttribute(__TRACKER,tracker);
break;
}
default:
- {
+ {
// insert a delay before throttling the request
if (_insertHeaders)
((HttpServletResponse)response).addHeader("DoSFilter","delayed");
Continuation continuation = ContinuationSupport.getContinuation(request);
request.setAttribute(__TRACKER,tracker);
- continuation.setTimeout(_delayMs);
+ if (_delayMs > 0)
+ continuation.setTimeout(_delayMs);
+ continuation.addContinuationListener(new ContinuationListener()
+ {
+ public void onComplete(Continuation continuation)
+ {
+ }
+
+ public void onTimeout(Continuation continuation)
+ {
+ }
+ });
continuation.suspend();
return;
}
}
}
-
// Throttle the request
boolean accepted = false;
try
{
// check if we can afford to accept another request at this time
- accepted = _passes.tryAcquire(_waitMs,TimeUnit.MILLISECONDS);
+ accepted = _passes.tryAcquire(_maxWaitMs,TimeUnit.MILLISECONDS);
if (!accepted)
{
// we were not accepted, so either we suspend to wait,or if we were woken up we insist or we fail
final Continuation continuation = ContinuationSupport.getContinuation(request);
-
+
Boolean throttled = (Boolean)request.getAttribute(__THROTTLED);
if (throttled!=Boolean.TRUE && _throttleMs>0)
{
@@ -370,12 +401,12 @@ public class DoSFilter implements Filter
accepted = true;
}
}
-
+
// if we were accepted (either immediately or after throttle)
- if (accepted)
+ if (accepted)
// call the chain
doFilterChain(filterchain,srequest,sresponse);
- else
+ else
{
// fail the request
if (_insertHeaders)
@@ -388,6 +419,10 @@ public class DoSFilter implements Filter
_context.log("DoS",e);
((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
finally
{
if (accepted)
@@ -414,11 +449,11 @@ public class DoSFilter implements Filter
* @throws IOException
* @throws ServletException
*/
- protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response)
+ protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response)
throws IOException, ServletException
{
final Thread thread=Thread.currentThread();
-
+
final Timeout.Task requestTimeout = new Timeout.Task()
{
public void expired()
@@ -458,7 +493,7 @@ public class DoSFilter implements Filter
{
response.setHeader("Connection", "close");
}
- try
+ try
{
try
{
@@ -473,14 +508,14 @@ public class DoSFilter implements Filter
{
Log.warn(e);
}
-
+
// interrupt the handling thread
thread.interrupt();
}
-
+
/**
* Get priority for this request, based on user type
- *
+ *
* @param request
* @param tracker
* @return priority
@@ -507,39 +542,44 @@ public class DoSFilter implements Filter
* track of this connection's request rate. If this is not the first request
* from this connection, return the existing object with the stored stats.
* If it is the first request, then create a new request tracker.
- *
+ *
* Assumes that each connection has an identifying characteristic, and goes
* through them in order, taking the first that matches: user id (logged
* in), session id, client IP address. Unidentifiable connections are lumped
* into one.
- *
+ *
* When a session expires, its rate tracker is automatically deleted.
- *
+ *
* @param request
* @return the request rate tracker for the current connection
*/
public RateTracker getRateTracker(ServletRequest request)
{
HttpServletRequest srequest = (HttpServletRequest)request;
+ HttpSession session=srequest.getSession(false);
- String loadId;
+ String loadId = extractUserId(request);
final int type;
-
- loadId = extractUserId(request);
- HttpSession session=srequest.getSession(false);
- if (_trackSessions && session!=null && !session.isNew())
+ if (loadId != null)
{
- loadId=session.getId();
- type = USER_SESSION;
+ type = USER_AUTH;
}
else
{
- loadId = _remotePort?(request.getRemoteAddr()+request.getRemotePort()):request.getRemoteAddr();
- type = USER_IP;
+ if (_trackSessions && session!=null && !session.isNew())
+ {
+ loadId=session.getId();
+ type = USER_SESSION;
+ }
+ else
+ {
+ loadId = _remotePort?(request.getRemoteAddr()+request.getRemotePort()):request.getRemoteAddr();
+ type = USER_IP;
+ }
}
RateTracker tracker=_rateTrackers.get(loadId);
-
+
if (tracker==null)
{
RateTracker t;
@@ -551,11 +591,11 @@ public class DoSFilter implements Filter
{
t = new RateTracker(loadId,type,_maxRequestsPerSec);
}
-
+
tracker=_rateTrackers.putIfAbsent(loadId,t);
if (tracker==null)
tracker=t;
-
+
if (type == USER_IP)
{
// USER_IP expiration from _rateTrackers is handled by the _trackerTimeoutQ
@@ -579,14 +619,19 @@ public class DoSFilter implements Filter
synchronized (_requestTimeoutQ)
{
_requestTimeoutQ.cancelAll();
+ }
+ synchronized (_trackerTimeoutQ)
+ {
_trackerTimeoutQ.cancelAll();
}
+ _rateTrackers.clear();
+ _whitelist.clear();
}
/**
* Returns the user id, used to track this connection.
* This SHOULD be overridden by subclasses.
- *
+ *
* @param request
* @return a unique user id, if logged in; otherwise null.
*/
@@ -595,6 +640,281 @@ public class DoSFilter implements Filter
return null;
}
+ /* ------------------------------------------------------------ */
+ /**
+ * Initialize the IP address whitelist
+ */
+ protected void initWhitelist()
+ {
+ _whitelist.clear();
+ StringTokenizer tokenizer = new StringTokenizer(_whitelistStr, ",");
+ while (tokenizer.hasMoreTokens())
+ _whitelist.add(tokenizer.nextToken().trim());
+
+ Log.info("Whitelisted IP addresses: {}", _whitelist.toString());
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get maximum number of requests from a connection per
+ * second. Requests in excess of this are first delayed,
+ * then throttled.
+ *
+ * @return maximum number of requests
+ */
+ public int getMaxRequestsPerSec()
+ {
+ return _maxRequestsPerSec;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get maximum number of requests from a connection per
+ * second. Requests in excess of this are first delayed,
+ * then throttled.
+ *
+ * @param value maximum number of requests
+ */
+ public void setMaxRequestsPerSec(int value)
+ {
+ _maxRequestsPerSec = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get delay (in milliseconds) that is applied to all requests
+ * over the rate limit, before they are considered at all.
+ */
+ public long getDelayMs()
+ {
+ return _delayMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set delay (in milliseconds) that is applied to all requests
+ * over the rate limit, before they are considered at all.
+ *
+ * @param value delay (in milliseconds), 0 - no delay, -1 - reject request
+ */
+ public void setDelayMs(long value)
+ {
+ _delayMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get maximum amount of time (in milliseconds) the filter will
+ * blocking wait for the throttle semaphore.
+ *
+ * @return maximum wait time
+ */
+ public long getMaxWaitMs()
+ {
+ return _maxWaitMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set maximum amount of time (in milliseconds) the filter will
+ * blocking wait for the throttle semaphore.
+ *
+ * @param value maximum wait time
+ */
+ public void setMaxWaitMs(long value)
+ {
+ _maxWaitMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get number of requests over the rate limit able to be
+ * considered at once.
+ *
+ * @return number of requests
+ */
+ public long getThrottledRequests()
+ {
+ return _throttledRequests;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set number of requests over the rate limit able to be
+ * considered at once.
+ *
+ * @param value number of requests
+ */
+ public void setThrottledRequests(int value)
+ {
+ _passes = new Semaphore((value-_throttledRequests+_passes.availablePermits()), true);
+ _throttledRequests = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get amount of time (in milliseconds) to async wait for semaphore.
+ *
+ * @return wait time
+ */
+ public long getThrottleMs()
+ {
+ return _throttleMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set amount of time (in milliseconds) to async wait for semaphore.
+ *
+ * @param value wait time
+ */
+ public void setThrottleMs(long value)
+ {
+ _throttleMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get maximum amount of time (in milliseconds) to allow
+ * the request to process.
+ *
+ * @return maximum processing time
+ */
+ public long getMaxRequestMs()
+ {
+ return _maxRequestMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set maximum amount of time (in milliseconds) to allow
+ * the request to process.
+ *
+ * @param value maximum processing time
+ */
+ public void setMaxRequestMs(long value)
+ {
+ _maxRequestMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get maximum amount of time (in milliseconds) to keep track
+ * of request rates for a connection, before deciding that
+ * the user has gone away, and discarding it.
+ *
+ * @return maximum tracking time
+ */
+ public long getMaxIdleTrackerMs()
+ {
+ return _maxIdleTrackerMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set maximum amount of time (in milliseconds) to keep track
+ * of request rates for a connection, before deciding that
+ * the user has gone away, and discarding it.
+ *
+ * @param value maximum tracking time
+ */
+ public void setMaxIdleTrackerMs(long value)
+ {
+ _maxIdleTrackerMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Check flag to insert the DoSFilter headers into the response.
+ *
+ * @return value of the flag
+ */
+ public boolean isInsertHeaders()
+ {
+ return _insertHeaders;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set flag to insert the DoSFilter headers into the response.
+ *
+ * @param value value of the flag
+ */
+ public void setInsertHeaders(boolean value)
+ {
+ _insertHeaders = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get flag to have usage rate tracked by session if a session exists.
+ *
+ * @return value of the flag
+ */
+ public boolean isTrackSessions()
+ {
+ return _trackSessions;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set flag to have usage rate tracked by session if a session exists.
+ * @param value value of the flag
+ */
+ public void setTrackSessions(boolean value)
+ {
+ _trackSessions = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get flag to have usage rate tracked by IP+port (effectively connection)
+ * if session tracking is not used.
+ *
+ * @return value of the flag
+ */
+ public boolean isRemotePort()
+ {
+ return _remotePort;
+ }
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set flag to have usage rate tracked by IP+port (effectively connection)
+ * if session tracking is not used.
+ *
+ * @param value value of the flag
+ */
+ public void setRemotePort(boolean value)
+ {
+ _remotePort = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get a list of IP addresses that will not be rate limited.
+ *
+ * @return comma-separated whitelist
+ */
+ public String getWhitelist()
+ {
+ return _whitelistStr;
+ }
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set a list of IP addresses that will not be rate limited.
+ *
+ * @param value comma-separated whitelist
+ */
+ public void setWhitelist(String value)
+ {
+ _whitelistStr = value;
+ initWhitelist();
+ }
+
/**
* A RateTracker is associated with a connection, and stores request rate
* data.
@@ -605,7 +925,7 @@ public class DoSFilter implements Filter
protected final int _type;
protected final long[] _timestamps;
protected int _next;
-
+
public RateTracker(String id, int type,int maxRequestsPerSecond)
{
_id = id;
@@ -642,7 +962,7 @@ public class DoSFilter implements Filter
return _type;
}
-
+
public void valueBound(HttpSessionBindingEvent event)
{
}
@@ -651,14 +971,14 @@ public class DoSFilter implements Filter
{
_rateTrackers.remove(_id);
}
-
+
public void expired()
{
long now = _trackerTimeoutQ.getNow();
- int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length;
+ int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length;
long last=_timestamps[latestIndex];
boolean hasRecentRequest = last != 0 && (now-last)<1000L;
-
+
if (hasRecentRequest)
reschedule();
else
@@ -671,7 +991,7 @@ public class DoSFilter implements Filter
return "RateTracker/"+_id+"/"+_type;
}
}
-
+
class FixedRateTracker extends RateTracker
{
public FixedRateTracker(String id, int type, int numRecentRequestsTracked)
@@ -693,11 +1013,11 @@ public class DoSFilter implements Filter
return false;
}
-
+
@Override
public String toString()
{
return "Fixed"+super.toString();
}
}
-} \ No newline at end of file
+}
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
index 6193d79d57..1c98cf46ee 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
@@ -22,8 +22,12 @@ import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
@@ -43,10 +47,11 @@ import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.HostMap;
import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -54,7 +59,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
/**
* Asynchronous Proxy Servlet.
- *
+ *
* Forward requests to another server either as a standard web proxy (as defined by
* RFC2616) or as a transparent proxy.
* <p>
@@ -62,22 +67,22 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
* the web application.
* <p>
* To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger"
- * are set as context attributes prefixed with "org.eclipse.jetty.servlets."+name
- * (unless otherwise set with attrPrefix). This attribute prefix is also used for the
- * logger name.
+ * are set as context attributes prefixed with the servlet name.
* <p>
* The following init parameters may be used to configure the servlet: <ul>
* <li>name - Name of Proxy servlet (default: "ProxyServlet"
* <li>maxThreads - maximum threads
* <li>maxConnections - maximum connections per destination
* <li>HostHeader - Force the host header to a particular value
- * </ul>
+ * <li>whiteList - comma-separated list of allowed proxy destinations
+ * <li>blackList - comma-separated list of forbidden proxy destinations
+ * </ul>
*/
public class ProxyServlet implements Servlet
{
- protected Logger _log;
- HttpClient _client;
- String _hostHeader;
+ protected Logger _log;
+ protected HttpClient _client;
+ protected String _hostHeader;
protected HashSet<String> _DontProxyHeaders = new HashSet<String>();
{
@@ -94,7 +99,8 @@ public class ProxyServlet implements Servlet
protected ServletConfig _config;
protected ServletContext _context;
- protected String _name="ProxyServlet";
+ protected HostMap<PathMap> _white = new HostMap<PathMap>();
+ protected HostMap<PathMap> _black = new HostMap<PathMap>();
/* ------------------------------------------------------------ */
/* (non-Javadoc)
@@ -107,35 +113,43 @@ public class ProxyServlet implements Servlet
_client=new HttpClient();
_client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
-
+
_hostHeader=config.getInitParameter("HostHeader");
-
-
+
+
try
{
- String t = config.getInitParameter("attrPrefix");
- if (t!=null)
- _name=t;
- _log= Log.getLogger("org.eclipse.jetty.servlets."+_name);
+ _log= Log.getLogger("org.eclipse.jetty.servlets."+config.getServletName());
- t = config.getInitParameter("maxThreads");
+ String t = config.getInitParameter("maxThreads");
if (t!=null)
_client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
else
_client.setThreadPool(new QueuedThreadPool());
- ((QueuedThreadPool)_client.getThreadPool()).setName(_name.substring(_name.lastIndexOf('.')+1));
-
+ ((QueuedThreadPool)_client.getThreadPool()).setName(config.getServletName());
+
t = config.getInitParameter("maxConnections");
if (t!=null)
_client.setMaxConnectionsPerAddress(Integer.parseInt(t));
-
+
_client.start();
-
+
if (_context!=null)
{
- _context.setAttribute("org.eclipse.jetty.servlets."+_name+".Logger",_log);
- _context.setAttribute("org.eclipse.jetty.servlets."+_name+".ThreadPool",_client.getThreadPool());
- _context.setAttribute("org.eclipse.jetty.servlets."+_name+".HttpClient",_client);
+ _context.setAttribute(config.getServletName()+".Logger",_log);
+ _context.setAttribute(config.getServletName()+".ThreadPool",_client.getThreadPool());
+ _context.setAttribute(config.getServletName()+".HttpClient",_client);
+ }
+
+ String white = config.getInitParameter("whiteList");
+ if (white != null)
+ {
+ parseList(white, _white);
+ }
+ String black = config.getInitParameter("blackList");
+ if (black != null)
+ {
+ parseList(black, _black);
}
}
catch (Exception e)
@@ -145,6 +159,95 @@ public class ProxyServlet implements Servlet
}
/* ------------------------------------------------------------ */
+ /**
+ * Helper function to process a parameter value containing a list
+ * of new entries and initialize the specified host map.
+ *
+ * @param list comma-separated list of new entries
+ * @param hostMap target host map
+ */
+ private void parseList(String list, HostMap<PathMap> hostMap)
+ {
+ if (list != null && list.length() > 0)
+ {
+ int idx;
+ String entry;
+
+ StringTokenizer entries = new StringTokenizer(list, ",");
+ while(entries.hasMoreTokens())
+ {
+ entry = entries.nextToken();
+ idx = entry.indexOf('/');
+
+ String host = idx > 0 ? entry.substring(0,idx) : entry;
+ String path = idx > 0 ? entry.substring(idx) : "/*";
+
+ host = host.trim();
+ PathMap pathMap = hostMap.get(host);
+ if (pathMap == null)
+ {
+ pathMap = new PathMap(true);
+ hostMap.put(host,pathMap);
+ }
+ if (path != null)
+ {
+ pathMap.put(path,path);
+ }
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Check the request hostname and path against white- and blacklist.
+ *
+ * @param host hostname to check
+ * @param path path to check
+ * @return true if request is allowed to be proxied
+ */
+ public boolean validateDestination(String host, String path)
+ {
+ if (_white.size()>0)
+ {
+ boolean match = false;
+
+ Object whiteObj = _white.getLazyMatches(host);
+ if (whiteObj != null)
+ {
+ List whiteList = (whiteObj instanceof List) ? (List)whiteObj : Collections.singletonList(whiteObj);
+
+ for (Object entry: whiteList)
+ {
+ PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
+ if (match = (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null)))
+ break;
+ }
+ }
+
+ if (!match)
+ return false;
+ }
+
+ if (_black.size() > 0)
+ {
+ Object blackObj = _black.getLazyMatches(host);
+ if (blackObj != null)
+ {
+ List blackList = (blackObj instanceof List) ? (List)blackObj : Collections.singletonList(blackObj);
+
+ for (Object entry: blackList)
+ {
+ PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
+ if (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null))
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.Servlet#getServletConfig()
*/
@@ -153,7 +256,7 @@ public class ProxyServlet implements Servlet
return _config;
}
-
+
/* ------------------------------------------------------------ */
/** Get the hostHeader.
* @return the hostHeader
@@ -180,7 +283,7 @@ public class ProxyServlet implements Servlet
IOException
{
final int debug=_log.isDebugEnabled()?req.hashCode():0;
-
+
final HttpServletRequest request = (HttpServletRequest)req;
final HttpServletResponse response = (HttpServletResponse)res;
if ("CONNECT".equalsIgnoreCase(request.getMethod()))
@@ -193,7 +296,7 @@ public class ProxyServlet implements Servlet
final OutputStream out=response.getOutputStream();
final Continuation continuation = ContinuationSupport.getContinuation(request);
-
+
if (!continuation.isInitial())
response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
else
@@ -206,10 +309,10 @@ public class ProxyServlet implements Servlet
request.getServerName(),
request.getServerPort(),
uri);
-
+
if (debug!=0)
_log.debug(debug+" proxy "+uri+"-->"+url);
-
+
if (url==null)
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
@@ -248,7 +351,7 @@ public class ProxyServlet implements Servlet
{
if (debug!=0)
_log.debug(debug+" "+version+" "+status+" "+reason);
-
+
if (reason!=null && reason.length()>0)
response.setStatus(status,reason.toString());
else
@@ -264,7 +367,7 @@ public class ProxyServlet implements Servlet
{
if (debug!=0)
_log.debug(debug+" "+name+": "+value);
-
+
response.addHeader(name.toString(),value.toString());
}
else if (debug!=0)
@@ -303,7 +406,7 @@ public class ProxyServlet implements Servlet
exchange.setMethod(request.getMethod());
exchange.setURL(url.toString());
exchange.setVersion(request.getProtocol());
-
+
if (debug!=0)
_log.debug(debug+" "+request.getMethod()+" "+url+" "+request.getProtocol());
@@ -320,7 +423,7 @@ public class ProxyServlet implements Servlet
// force host
if (_hostHeader!=null)
exchange.setRequestHeader("Host",_hostHeader);
-
+
// copy headers
boolean xForwardedFor=false;
boolean hasContent=false;
@@ -344,7 +447,7 @@ public class ProxyServlet implements Servlet
else if ("content-length".equals(lhdr))
{
contentLength=request.getContentLength();
- exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(contentLength));
+ exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(contentLength));
if (contentLength>0)
hasContent=true;
}
@@ -373,8 +476,8 @@ public class ProxyServlet implements Servlet
if (hasContent)
exchange.setRequestContentSource(in);
-
- continuation.suspend(response);
+
+ continuation.suspend(response);
_client.send(exchange);
}
@@ -431,6 +534,9 @@ public class ProxyServlet implements Servlet
protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri)
throws MalformedURLException
{
+ if (!validateDestination(serverName, uri))
+ return null;
+
return new HttpURI(scheme+"://"+serverName+":"+serverPort+uri);
}
@@ -450,17 +556,17 @@ public class ProxyServlet implements Servlet
{
}
-
+
/**
* Transparent Proxy.
- *
- * This convenience extension to ProxyServlet configures the servlet as a transparent proxy.
+ *
+ * This convenience extension to ProxyServlet configures the servlet as a transparent proxy.
* The servlet is configured with init parameters:
* <ul>
* <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
* <li>Prefix - a URI prefix that is striped from the start of the forwarded URI.
* </ul>
- * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context
+ * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context
* and the Prefix was /foo, then the request would be proxied to http://host:80/context/bar
*
*/
@@ -515,7 +621,7 @@ public class ProxyServlet implements Servlet
if (!_prefix.startsWith("/"))
throw new UnavailableException("Prefix parameter must start with a '/'.");
- _log.info(_name + " @ " + _prefix + " to " + _proxyTo);
+ _log.info(config.getServletName()+" @ " + _prefix + " to " + _proxyTo);
}
@Override
@@ -525,8 +631,13 @@ public class ProxyServlet implements Servlet
{
if (!uri.startsWith(_prefix))
return null;
+
+ URI dstUri = new URI(_proxyTo + uri.substring(_prefix.length())).normalize();
+
+ if (!validateDestination(dstUri.getHost(),dstUri.getPath()))
+ return null;
- return new HttpURI(new URI(_proxyTo + uri.substring(_prefix.length())).normalize().toString());
+ return new HttpURI(dstUri.toString());
}
catch (URISyntaxException ex)
{
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java
index ecaac08ede..858428a9fc 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java
@@ -60,6 +60,7 @@ public class PutFilter implements Filter
Set<String> _operations = new HashSet<String>();
protected ConcurrentMap<String,String> _hidden = new ConcurrentHashMap<String, String>();
+ protected String _options;
protected ServletContext _context;
protected String _baseURI;
@@ -87,10 +88,12 @@ public class PutFilter implements Filter
_operations.add(__OPTIONS);
_operations.add(__PUT);
+ _options="GET,HEAD,POST,OPTIONS,PUT";
if (_delAllowed)
{
_operations.add(__DELETE);
_operations.add(__MOVE);
+ _options+=",DELETE";
}
}
@@ -284,15 +287,13 @@ public class PutFilter implements Filter
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.flushBuffer();
-
-
}
/* ------------------------------------------------------------ */
public void handleOptions(HttpServletRequest request, HttpServletResponse response) throws IOException
{
- // TODO implement
- throw new UnsupportedOperationException("Not Implemented");
+ // TODO filter real options and add PUT & DELETE
+ response.setHeader("Allow", _options);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java
index a726412b30..cf3a97dea5 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java
@@ -33,21 +33,23 @@ import javax.servlet.http.HttpSession;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.server.handler.ContextHandler;
/**
* Quality of Service Filter.
+ *
* This filter limits the number of active requests to the number set by the "maxRequests" init parameter (default 10).
* If more requests are received, they are suspended and placed on priority queues. Priorities are determined by
* the {@link #getPriority(ServletRequest)} method and are a value between 0 and the value given by the "maxPriority"
* init parameter (default 10), with higher values having higher priority.
- * <p>
+ * </p><p>
* This filter is ideal to prevent wasting threads waiting for slow/limited
* resources such as a JDBC connection pool. It avoids the situation where all of a
* containers thread pool may be consumed blocking on such a slow resource.
* By limiting the number of active threads, a smaller thread pool may be used as
* the threads are not wasted waiting. Thus more memory may be available for use by
* the active threads.
- * <p>
+ * </p><p>
* Furthermore, this filter uses a priority when resuming waiting requests. So that if
* a container is under load, and there are many requests waiting for resources,
* the {@link #getPriority(ServletRequest)} method is used, so that more important
@@ -55,12 +57,16 @@ import org.eclipse.jetty.continuation.ContinuationSupport;
* maxRequest limit slightly smaller than the containers thread pool and a high priority
* allocated to admin users. Thus regardless of load, admin users would always be
* able to access the web application.
- * <p>
+ * </p><p>
* The maxRequest limit is policed by a {@link Semaphore} and the filter will wait a short while attempting to acquire
* the semaphore. This wait is controlled by the "waitMs" init parameter and allows the expense of a suspend to be
* avoided if the semaphore is shortly available. If the semaphore cannot be obtained, the request will be suspended
* for the default suspend period of the container or the valued set as the "suspendMs" init parameter.
- *
+ * </p><p>
+ * If the "managedAttr" init parameter is set to true, then this servlet is set as a {@link ServletContext} attribute with the
+ * filter name as the attribute name. This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
+ * manage the configuration of the filter.
+ * </p>
*
*
*/
@@ -71,23 +77,31 @@ public class QoSFilter implements Filter
final static int __DEFAULT_WAIT_MS=50;
final static long __DEFAULT_TIMEOUT_MS = -1;
+ final static String MANAGED_ATTR_INIT_PARAM="managedAttr";
final static String MAX_REQUESTS_INIT_PARAM="maxRequests";
final static String MAX_PRIORITY_INIT_PARAM="maxPriority";
final static String MAX_WAIT_INIT_PARAM="waitMs";
final static String SUSPEND_INIT_PARAM="suspendMs";
ServletContext _context;
- long _waitMs;
- long _suspendMs;
- Semaphore _passes;
- Queue<Continuation>[] _queue;
- ContinuationListener[] _listener;
- String _suspended="QoSFilter@"+this.hashCode();
+
+ protected long _waitMs;
+ protected long _suspendMs;
+ protected int _maxRequests;
+ private Semaphore _passes;
+ private Queue<Continuation>[] _queue;
+ private ContinuationListener[] _listener;
+ private String _suspended="QoSFilter@"+this.hashCode();
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
public void init(FilterConfig filterConfig)
{
_context=filterConfig.getServletContext();
-
+
int max_priority=__DEFAULT_MAX_PRIORITY;
if (filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM)!=null)
max_priority=Integer.parseInt(filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM));
@@ -110,10 +124,11 @@ public class QoSFilter implements Filter
};
}
- int passes=__DEFAULT_PASSES;
+ int maxRequests=__DEFAULT_PASSES;
if (filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)!=null)
- passes=Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM));
- _passes=new Semaphore(passes,true);
+ maxRequests=Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM));
+ _passes=new Semaphore(maxRequests,true);
+ _maxRequests = maxRequests;
long wait = __DEFAULT_WAIT_MS;
if (filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM)!=null)
@@ -124,8 +139,15 @@ public class QoSFilter implements Filter
if (filterConfig.getInitParameter(SUSPEND_INIT_PARAM)!=null)
suspend=Integer.parseInt(filterConfig.getInitParameter(SUSPEND_INIT_PARAM));
_suspendMs=suspend;
+
+ if (_context!=null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
+ _context.setAttribute(filterConfig.getFilterName(),this);
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
@@ -220,7 +242,7 @@ public class QoSFilter implements Filter
* This method may be specialised to provide application specific priorities.
*
* @param request
- * @return
+ * @return the request priority
*/
protected int getPriority(ServletRequest request)
{
@@ -238,6 +260,83 @@ public class QoSFilter implements Filter
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
public void destroy(){}
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the (short) amount of time (in milliseconds) that the filter would wait
+ * for the semaphore to become available before suspending a request.
+ *
+ * @return wait time (in milliseconds)
+ */
+ public long getWaitMs()
+ {
+ return _waitMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the (short) amount of time (in milliseconds) that the filter would wait
+ * for the semaphore to become available before suspending a request.
+ *
+ * @param value wait time (in milliseconds)
+ */
+ public void setWaitMs(long value)
+ {
+ _waitMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the amount of time (in milliseconds) that the filter would suspend
+ * a request for while waiting for the semaphore to become available.
+ *
+ * @return suspend time (in milliseconds)
+ */
+ public long getSuspendMs()
+ {
+ return _suspendMs;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the amount of time (in milliseconds) that the filter would suspend
+ * a request for while waiting for the semaphore to become available.
+ *
+ * @param value suspend time (in milliseconds)
+ */
+ public void setSuspendMs(long value)
+ {
+ _suspendMs = value;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the maximum number of requests allowed to be processed
+ * at the same time.
+ *
+ * @return maximum number of requests
+ */
+ public int getMaxRequests()
+ {
+ return _maxRequests;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the maximum number of requests allowed to be processed
+ * at the same time.
+ *
+ * @param passes the _passes to set
+ */
+ public void setMaxRequests(int value)
+ {
+ _passes = new Semaphore((value-_maxRequests+_passes.availablePermits()), true);
+ _maxRequests = value;
+ }
+
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java
new file mode 100644
index 0000000000..34651edb09
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java
@@ -0,0 +1,344 @@
+package org.eclipse.jetty.servlets;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.EnumSet;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.testing.ServletTester;
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public abstract class AbstractDoSFilterTest
+{
+ private static ServletTester _tester;
+ private static String _host;
+ private static int _port;
+ private static long _requestMaxTime = 200;
+ private static FilterHolder _dosFilter;
+ private static FilterHolder _timeoutFilter;
+
+ public static void startServer(Class<? extends Filter> filter) throws Exception
+ {
+ _tester = new ServletTester();
+ HttpURI uri = new HttpURI(_tester.createChannelConnector(true));
+ _host = uri.getHost();
+ _port = uri.getPort();
+
+ _tester.setContextPath("/ctx");
+ _tester.addServlet(TestServlet.class, "/*");
+
+ _dosFilter = _tester.addFilter(filter, "/dos/*", EnumSet.allOf(DispatcherType.class));
+ _dosFilter.setInitParameter("maxRequestsPerSec", "4");
+ _dosFilter.setInitParameter("delayMs", "200");
+ _dosFilter.setInitParameter("throttledRequests", "1");
+ _dosFilter.setInitParameter("waitMs", "10");
+ _dosFilter.setInitParameter("throttleMs", "4000");
+ _dosFilter.setInitParameter("remotePort", "false");
+ _dosFilter.setInitParameter("insertHeaders", "true");
+
+ _timeoutFilter = _tester.addFilter(filter, "/timeout/*", EnumSet.allOf(DispatcherType.class));
+ _timeoutFilter.setInitParameter("maxRequestsPerSec", "4");
+ _timeoutFilter.setInitParameter("delayMs", "200");
+ _timeoutFilter.setInitParameter("throttledRequests", "1");
+ _timeoutFilter.setInitParameter("waitMs", "10");
+ _timeoutFilter.setInitParameter("throttleMs", "4000");
+ _timeoutFilter.setInitParameter("remotePort", "false");
+ _timeoutFilter.setInitParameter("insertHeaders", "true");
+ _timeoutFilter.setInitParameter("maxRequestMs", _requestMaxTime + "");
+
+ _tester.start();
+ }
+
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ _tester.stop();
+ }
+
+ @Before
+ public void startFilters() throws Exception
+ {
+ _dosFilter.start();
+ _timeoutFilter.start();
+ }
+
+ @After
+ public void stopFilters() throws Exception
+ {
+ _timeoutFilter.stop();
+ _dosFilter.stop();
+ }
+
+ private String doRequests(String requests, int loops, long pause0, long pause1, String request) throws Exception
+ {
+ Socket socket = new Socket(_host, _port);
+ socket.setSoTimeout(30000);
+
+ for (int i=loops;i-->0;)
+ {
+ socket.getOutputStream().write(requests.getBytes("UTF-8"));
+ socket.getOutputStream().flush();
+ if (i>0 && pause0>0)
+ Thread.sleep(pause0);
+ }
+ if (pause1>0)
+ Thread.sleep(pause1);
+ socket.getOutputStream().write(request.getBytes("UTF-8"));
+ socket.getOutputStream().flush();
+
+
+ String response;
+ if (requests.contains("/unresponsive"))
+ {
+ // don't read in anything, forcing the request to time out
+ Thread.sleep(_requestMaxTime * 2);
+ response = IO.toString(socket.getInputStream(),"UTF-8");
+ }
+ else
+ {
+ response = IO.toString(socket.getInputStream(),"UTF-8");
+ }
+ socket.close();
+ return response;
+ }
+
+ private int count(String responses,String substring)
+ {
+ int count=0;
+ int i=responses.indexOf(substring);
+ while (i>=0)
+ {
+ count++;
+ i=responses.indexOf(substring,i+substring.length());
+ }
+
+ return count;
+ }
+
+ @Test
+ public void testEvenLowRateIP() throws Exception
+ {
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request,11,300,300,last);
+ assertEquals(12,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(0,count(responses,"DoSFilter:"));
+ }
+
+ @Test
+ public void testBurstLowRateIP() throws Exception
+ {
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request,2,1100,1100,last);
+
+ assertEquals(9,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(0,count(responses,"DoSFilter:"));
+ }
+
+ @Test
+ public void testDelayedIP() throws Exception
+ {
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request+request,2,1100,1100,last);
+
+ assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(2,count(responses,"DoSFilter: delayed"));
+ }
+
+ @Test
+ public void testThrottledIP() throws Exception
+ {
+ Thread other = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ // Cause a delay, then sleep while holding pass
+ String request="GET /ctx/dos/sleeper HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/sleeper?sleep=3000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request,1,0,0,last);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+ other.start();
+ Thread.sleep(1500);
+
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request,1,0,0,last);
+ //System.out.println("responses are " + responses);
+ assertEquals("200 OK responses", 5,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals("delayed responses", 1,count(responses,"DoSFilter: delayed"));
+ assertEquals("throttled responses", 1,count(responses,"DoSFilter: throttled"));
+ assertEquals("unavailable responses", 0,count(responses,"DoSFilter: unavailable"));
+
+ other.join();
+ }
+
+ @Test
+ public void testUnavailableIP() throws Exception
+ {
+ Thread other = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ // Cause a delay, then sleep while holding pass
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test?sleep=5000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request,1,0,0,last);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+ other.start();
+ Thread.sleep(500);
+
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests(request+request+request+request,1,0,0,last);
+
+ assertEquals(4,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(1,count(responses,"HTTP/1.1 503"));
+ assertEquals(1,count(responses,"DoSFilter: delayed"));
+ assertEquals(1,count(responses,"DoSFilter: throttled"));
+ assertEquals(1,count(responses,"DoSFilter: unavailable"));
+
+ other.join();
+ }
+
+ @Test
+ public void testSessionTracking() throws Exception
+ {
+ // get a session, first
+ String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String response=doRequests("",1,0,0,requestSession);
+ String sessionId=response.substring(response.indexOf("Set-Cookie: ")+12, response.indexOf(";"));
+
+ // all other requests use this session
+ String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId + "\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId + "\r\n\r\n";
+ String responses = doRequests(request+request+request+request+request,2,1100,1100,last);
+
+ assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(2,count(responses,"DoSFilter: delayed"));
+ }
+
+ @Test
+ public void testMultipleSessionTracking() throws Exception
+ {
+ // get some session ids, first
+ String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\n\r\n";
+ String closeRequest="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String response=doRequests(requestSession+requestSession,1,0,0,closeRequest);
+
+ String[] sessions = response.split("\r\n\r\n");
+
+ String sessionId1=sessions[0].substring(sessions[0].indexOf("Set-Cookie: ")+12, sessions[0].indexOf(";"));
+ String sessionId2=sessions[1].substring(sessions[1].indexOf("Set-Cookie: ")+12, sessions[1].indexOf(";"));
+
+ // alternate between sessions
+ String request1="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId1 + "\r\n\r\n";
+ String request2="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId2 + "\r\n\r\n";
+ String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId2 + "\r\n\r\n";
+
+ // ensure the sessions are new
+ String responses = doRequests(request1+request2,1,1100,1100,last);
+ Thread.sleep(1000);
+
+ responses = doRequests(request1+request2+request1+request2+request1,2,1100,1100,last);
+
+ assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
+ assertEquals(0,count(responses,"DoSFilter: delayed"));
+
+ // alternate between sessions
+ responses = doRequests(request1+request2+request1+request2+request1,2,550,550,last);
+
+ assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
+ int delayedRequests = count(responses,"DoSFilter: delayed");
+ assertTrue(delayedRequests >= 2 && delayedRequests <= 3);
+ }
+
+ @Test
+ public void testUnresponsiveClient() throws Exception
+ {
+ int numRequests = 1000;
+
+ String last="GET /ctx/timeout/unresponsive?lines="+numRequests+" HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
+ String responses = doRequests("",0,0,0,last);
+ // was expired, and stopped before reaching the end of the requests
+ int responseLines = count(responses, "Line:");
+ assertTrue(responses.contains("DoSFilter: timeout"));
+ assertTrue(responseLines > 0 && responseLines < numRequests);
+ }
+
+ public static class TestServlet extends HttpServlet implements Servlet
+ {
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ if (request.getParameter("session")!=null)
+ request.getSession(true);
+ if (request.getParameter("sleep")!=null)
+ {
+ try
+ {
+ Thread.sleep(Long.parseLong(request.getParameter("sleep")));
+ }
+ catch(InterruptedException e)
+ {
+ }
+ }
+
+ if (request.getParameter("lines")!=null)
+ {
+ int count = Integer.parseInt(request.getParameter("lines"));
+ for(int i = 0; i < count; ++i)
+ {
+ response.getWriter().append("Line: " + i+"\n");
+ response.flushBuffer();
+
+ try
+ {
+ Thread.sleep(10);
+ }
+ catch(InterruptedException e)
+ {
+ }
+
+ }
+ }
+
+ response.setContentType("text/plain");
+ }
+ }
+}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
index 0768969fd0..95defdd12a 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
@@ -4,75 +4,44 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
-import java.util.EnumSet;
-import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpURI;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.util.log.Log;
+import org.junit.BeforeClass;
-public class CloseableDoSFilterTest extends DoSFilterTest
+public class CloseableDoSFilterTest extends AbstractDoSFilterTest
{
- protected void setUp() throws Exception
+ @BeforeClass
+ public static void setUp() throws Exception
{
- _tester = new ServletTester();
- HttpURI uri=new HttpURI(_tester.createSocketConnector(true));
- _host=uri.getHost();
- _port=uri.getPort();
-
- _tester.setContextPath("/ctx");
- _tester.addServlet(TestServlet.class, "/*");
-
- FilterHolder dos=_tester.addFilter(CloseableDoSFilter2.class,"/dos/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
- dos.setInitParameter("maxRequestsPerSec","4");
- dos.setInitParameter("delayMs","200");
- dos.setInitParameter("throttledRequests","1");
- dos.setInitParameter("waitMs","10");
- dos.setInitParameter("throttleMs","4000");
- dos.setInitParameter("remotePort", "false");
- dos.setInitParameter("insertHeaders", "true");
-
- FilterHolder quickTimeout = _tester.addFilter(CloseableDoSFilter2.class,"/timeout/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
- quickTimeout.setInitParameter("maxRequestsPerSec","4");
- quickTimeout.setInitParameter("delayMs","200");
- quickTimeout.setInitParameter("throttledRequests","1");
- quickTimeout.setInitParameter("waitMs","10");
- quickTimeout.setInitParameter("throttleMs","4000");
- quickTimeout.setInitParameter("remotePort", "false");
- quickTimeout.setInitParameter("insertHeaders", "true");
- quickTimeout.setInitParameter("maxRequestMs", _maxRequestMs + "");
-
- _tester.start();
-
+ startServer(CloseableDoSFilter2.class);
}
-
+
public static class CloseableDoSFilter2 extends CloseableDoSFilter
- {
+ {
public void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread)
{
- try
- {
- response.getWriter().append("DoSFilter: timeout");
- response.flushBuffer();
- super.closeConnection(request,response,thread);
- }
- catch (Exception e)
- {
- Log.warn(e);
- }
- }
+ try
+ {
+ response.getWriter().append("DoSFilter: timeout");
+ response.flushBuffer();
+ super.closeConnection(request, response, thread);
+ }
+ catch (Exception e)
+ {
+ Log.warn(e);
+ }
}
+ }
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java
index 1cfb0bee32..d7a2b31bd0 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java
@@ -3,7 +3,7 @@
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
+// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,340 +14,26 @@
package org.eclipse.jetty.servlets;
-import java.io.IOException;
-import java.net.Socket;
-import java.util.EnumSet;
-
-import javax.servlet.DispatcherType;
-import javax.servlet.FilterChain;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
-import org.eclipse.jetty.http.HttpURI;
-import org.eclipse.jetty.server.AsyncContinuation;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.testing.ServletTester;
-import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
+import org.junit.BeforeClass;
-public class DoSFilterTest extends TestCase
+public class DoSFilterTest extends AbstractDoSFilterTest
{
- protected ServletTester _tester;
- protected String _host;
- protected int _port;
-
- protected int _maxRequestMs = 200;
- protected void setUp() throws Exception
- {
- _tester = new ServletTester();
- HttpURI uri=new HttpURI(_tester.createChannelConnector(true));
- _host=uri.getHost();
- _port=uri.getPort();
-
- _tester.setContextPath("/ctx");
- _tester.addServlet(TestServlet.class, "/*");
-
- FilterHolder dos=_tester.addFilter(DoSFilter2.class,"/dos/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
- dos.setInitParameter("maxRequestsPerSec","4");
- dos.setInitParameter("delayMs","200");
- dos.setInitParameter("throttledRequests","1");
- dos.setInitParameter("waitMs","10");
- dos.setInitParameter("throttleMs","4000");
- dos.setInitParameter("remotePort", "false");
- dos.setInitParameter("insertHeaders", "true");
- dos.setAsyncSupported(true);
-
- FilterHolder quickTimeout = _tester.addFilter(DoSFilter2.class,"/timeout/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
- quickTimeout.setInitParameter("maxRequestsPerSec","4");
- quickTimeout.setInitParameter("delayMs","200");
- quickTimeout.setInitParameter("throttledRequests","1");
- quickTimeout.setInitParameter("waitMs","10");
- quickTimeout.setInitParameter("throttleMs","4000");
- quickTimeout.setInitParameter("remotePort", "false");
- quickTimeout.setInitParameter("insertHeaders", "true");
- quickTimeout.setInitParameter("maxRequestMs", _maxRequestMs + "");
- quickTimeout.setAsyncSupported(true);
-
- _tester.start();
-
- }
-
- protected void tearDown() throws Exception
+ @BeforeClass
+ public static void setUp() throws Exception
{
- _tester.stop();
+ startServer(DoSFilter2.class);
}
-
- private String doRequests(String requests, int loops, long pause0,long pause1,String request)
- throws Exception
- {
- Socket socket = new Socket(_host,_port);
- socket.setSoTimeout(300000);
-
- for (int i=loops;i-->0;)
- {
- socket.getOutputStream().write(requests.getBytes("UTF-8"));
- socket.getOutputStream().flush();
- if (i>0 && pause0>0)
- Thread.sleep(pause0);
- }
- if (pause1>0)
- Thread.sleep(pause1);
- socket.getOutputStream().write(request.getBytes("UTF-8"));
- socket.getOutputStream().flush();
-
-
- String response = "";
- if (requests.contains("/unresponsive"))
- {
- // don't read in anything, forcing the request to time out
- Thread.sleep(_maxRequestMs * 2);
- response = IO.toString(socket.getInputStream(),"UTF-8");
- }
- else
- {
- response = IO.toString(socket.getInputStream(),"UTF-8");
- }
- socket.close();
- return response;
- }
-
- private int count(String responses,String substring)
- {
- int count=0;
- int i=responses.indexOf(substring);
- while (i>=0)
- {
- count++;
- i=responses.indexOf(substring,i+substring.length());
- }
-
- return count;
- }
-
- public void testEvenLowRateIP()
- throws Exception
- {
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request,11,300,300,last);
- assertEquals(12,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(0,count(responses,"DoSFilter:"));
- }
-
- public void testBurstLowRateIP()
- throws Exception
- {
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request+request+request+request,2,1100,1100,last);
-
- assertEquals(9,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(0,count(responses,"DoSFilter:"));
- }
-
- public void testDelayedIP()
- throws Exception
- {
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
-
- String responses = doRequests(request+request+request+request+request,2,1100,1100,last);
-
- assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(2,count(responses,"DoSFilter: delayed"));
- }
-
- public void testThrottledIP()
- throws Exception
- {
- Thread other = new Thread()
- {
- public void run()
- {
- try
- {
- // Cause a delay, then sleep while holding pass
- String request="GET /ctx/dos/sleeper HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/sleeper?sleep=3000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request+request+request+request,1,0,0,last);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
- };
- other.start();
- Thread.sleep(1500);
-
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request+request+request+request,1,0,0,last);
- assertEquals(5,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(1,count(responses,"DoSFilter: delayed"));
- assertEquals(1,count(responses,"DoSFilter: throttled"));
- assertEquals(0,count(responses,"DoSFilter: unavailable"));
-
- other.join();
- }
-
- public void testUnavailableIP()
- throws Exception
- {
- Thread other = new Thread()
- {
- public void run()
- {
- try
- {
- // Cause a delay, then sleep while holding pass
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test?sleep=5000 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request+request+request+request,1,0,0,last);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
- };
- other.start();
- Thread.sleep(500);
-
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests(request+request+request+request,1,0,0,last);
-
- assertEquals(4,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(1,count(responses,"HTTP/1.1 503"));
- assertEquals(1,count(responses,"DoSFilter: delayed"));
- assertEquals(1,count(responses,"DoSFilter: throttled"));
- assertEquals(1,count(responses,"DoSFilter: unavailable"));
-
- other.join();
- }
-
- public void testSessionTracking()
- throws Exception
- {
- // get a session, first
- String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String response=doRequests("",1,0,0,requestSession);
- String sessionId=response.substring(response.indexOf("Set-Cookie: ")+12, response.indexOf(";"));
-
- // all other requests use this session
- String request="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId + "\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId + "\r\n\r\n";
- String responses = doRequests(request+request+request+request+request,2,1100,1100,last);
-
- assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(2,count(responses,"DoSFilter: delayed"));
- }
-
- public void testMultipleSessionTracking()
- throws Exception
- {
- // get some session ids, first
- String requestSession="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\n\r\n";
- String closeRequest="GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String response=doRequests(requestSession+requestSession,1,0,0,closeRequest);
-
- String[] sessions = response.split("\r\n\r\n");
-
- String sessionId1=sessions[0].substring(sessions[0].indexOf("Set-Cookie: ")+12, sessions[0].indexOf(";"));
- String sessionId2=sessions[1].substring(sessions[1].indexOf("Set-Cookie: ")+12, sessions[1].indexOf(";"));
-
- // alternate between sessions
- String request1="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId1 + "\r\n\r\n";
- String request2="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId2 + "\r\n\r\n";
- String last="GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId2 + "\r\n\r\n";
-
- // ensure the sessions are new
- String responses = doRequests(request1+request2,1,1100,1100,last);
- Thread.sleep(1000);
-
- responses = doRequests(request1+request2+request1+request2+request1,2,1100,1100,last);
-
- assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
- assertEquals(0,count(responses,"DoSFilter: delayed"));
-
- // alternate between sessions
- responses = doRequests(request1+request2+request1+request2+request1,2,550,550,last);
-
- assertEquals(11,count(responses,"HTTP/1.1 200 OK"));
- int delayedRequests = count(responses,"DoSFilter: delayed");
- assertTrue(delayedRequests >= 2 && delayedRequests <= 3);
- }
-
- public void testUnresponsiveClient()
- throws Exception
- {
- int numRequests = 1000;
-
- String last="GET /ctx/timeout/unresponsive?lines="+numRequests+" HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
- String responses = doRequests("",0,0,0,last);
- // was expired, and stopped before reaching the end of the requests
- int responseLines = count(responses, "Line:");
- assertTrue(responses.contains("DoSFilter: timeout"));
- assertTrue(responseLines > 0 && responseLines < numRequests);
- }
-
- public static class TestServlet extends HttpServlet implements Servlet
- {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- if (request.getParameter("session")!=null)
- request.getSession(true);
- if (request.getParameter("sleep")!=null)
- {
- try
- {
- long sleep=Long.parseLong(request.getParameter("sleep"));
- Thread.sleep(sleep);
- }
- catch(InterruptedException e)
- {
- e.printStackTrace();
- }
- }
-
- if (request.getParameter("lines")!=null)
- {
- int count = Integer.parseInt(request.getParameter("lines"));
- for(int i = 0; i < count; ++i)
- {
- response.getWriter().append("Line: " + i+"\n");
- response.flushBuffer();
-
- try
- {
- Thread.sleep(10);
- }
- catch(InterruptedException e)
- {
- }
-
- }
- }
-
- response.setContentType("text/plain");
-
- }
- }
-
public static class DoSFilter2 extends DoSFilter
{
public void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread)
{
- try {
+ try
+ {
response.getWriter().append("DoSFilter: timeout");
super.closeConnection(request,response,thread);
}
@@ -356,5 +42,5 @@ public class DoSFilterTest extends TestCase
Log.warn(e);
}
}
- }
+ }
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
index b1f815b0cc..a0469f4854 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
@@ -19,31 +19,34 @@ import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.util.EnumSet;
-
import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class PutFilterTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class PutFilterTest
{
- File _dir;
- ServletTester tester;
-
- protected void setUp() throws Exception
+ private File _dir;
+ private ServletTester tester;
+
+ @Before
+ public void setUp() throws Exception
{
_dir = File.createTempFile("testPutFilter",null);
- _dir.delete();
- _dir.mkdir();
+ assertTrue(_dir.delete());
+ assertTrue(_dir.mkdir());
_dir.deleteOnExit();
assertTrue(_dir.isDirectory());
-
- super.setUp();
+
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(_dir.getCanonicalPath());
@@ -51,21 +54,21 @@ public class PutFilterTest extends TestCase
FilterHolder holder = tester.addFilter(PutFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
holder.setInitParameter("delAllowed","true");
tester.start();
-
-
}
- protected void tearDown() throws Exception
+ @After
+ public void tearDown() throws Exception
{
- super.tearDown();
+ tester.stop();
}
+ @Test
public void testHandlePut() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
-
+
// test GET
request.setMethod("GET");
request.setVersion("HTTP/1.0");
@@ -84,7 +87,7 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_CREATED,response.getStatus());
-
+
File file=new File(_dir,"file.txt");
assertTrue(file.exists());
assertEquals(data0,IO.toString(new FileInputStream(file)));
@@ -108,12 +111,10 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-
+
file=new File(_dir,"file.txt");
assertTrue(file.exists());
assertEquals(data1,IO.toString(new FileInputStream(file)));
-
-
// test PUT2
request.setMethod("PUT");
@@ -144,7 +145,7 @@ public class PutFilterTest extends TestCase
out.write(to_send.substring(l-5).getBytes());
out.flush();
String in=IO.toString(socket.getInputStream());
-
+
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
@@ -153,10 +154,9 @@ public class PutFilterTest extends TestCase
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
assertEquals(data2,response.getContent());
-
-
}
+ @Test
public void testHandleDelete() throws Exception
{
// generated and parsed test
@@ -174,20 +174,18 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_CREATED,response.getStatus());
-
+
File file=new File(_dir,"file.txt");
assertTrue(file.exists());
FileInputStream fis = new FileInputStream(file);
assertEquals(data1,IO.toString(fis));
fis.close();
-
request.setMethod("DELETE");
request.setURI("/context/file.txt");
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_NO_CONTENT,response.getStatus());
-
assertTrue(!file.exists());
@@ -196,10 +194,9 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
-
-
}
+ @Test
public void testHandleMove() throws Exception
{
// generated and parsed test
@@ -217,13 +214,12 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_CREATED,response.getStatus());
-
+
File file=new File(_dir,"file.txt");
assertTrue(file.exists());
FileInputStream fis = new FileInputStream(file);
assertEquals(data1,IO.toString(fis));
fis.close();
-
request.setMethod("MOVE");
request.setURI("/context/file.txt");
@@ -231,22 +227,22 @@ public class PutFilterTest extends TestCase
response.parse(tester.getResponses(request.generate()));
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_NO_CONTENT,response.getStatus());
-
+
assertTrue(!file.exists());
File n_file=new File(_dir,"blah.txt");
assertTrue(n_file.exists());
-
}
+ @Test
public void testHandleOptions()
{
// TODO implement
}
+ @Test
public void testPassConditionalHeaders()
{
// TODO implement
}
-
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
index 391c76e63a..acf14cfb58 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
@@ -4,21 +4,19 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
import java.io.IOException;
-import java.io.InputStream;
import java.net.URL;
import java.util.EnumSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-
import javax.servlet.DispatcherType;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
@@ -27,16 +25,20 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.util.log.Log;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-public class QoSFilterTest extends TestCase
+public class QoSFilterTest
{
private ServletTester _tester;
private LocalConnector[] _connectors;
@@ -44,42 +46,46 @@ public class QoSFilterTest extends TestCase
private final int NUM_CONNECTIONS = 8;
private final int NUM_LOOPS = 6;
private final int MAX_QOS = 4;
-
- protected void setUp() throws Exception
+
+ @Before
+ public void setUp() throws Exception
{
_tester = new ServletTester();
_tester.setContextPath("/context");
_tester.addServlet(TestServlet.class, "/test");
TestServlet.__maxSleepers=0;
TestServlet.__sleepers=0;
-
+
_connectors = new LocalConnector[NUM_CONNECTIONS];
for(int i = 0; i < _connectors.length; ++i)
_connectors[i] = _tester.createLocalConnector();
-
+
_doneRequests = new CountDownLatch(NUM_CONNECTIONS*NUM_LOOPS);
-
+
_tester.start();
}
-
- protected void tearDown() throws Exception
+
+ @After
+ public void tearDown() throws Exception
{
_tester.stop();
}
+ @Test
public void testNoFilter() throws Exception
- {
+ {
for(int i = 0; i < NUM_CONNECTIONS; ++i )
{
new Thread(new Worker(i)).start();
}
-
+
_doneRequests.await(10,TimeUnit.SECONDS);
-
+
assertFalse("TEST WAS NOT PARALLEL ENOUGH!",TestServlet.__maxSleepers<=MAX_QOS);
assertTrue(TestServlet.__maxSleepers<=NUM_CONNECTIONS);
}
+ @Test
public void testBlockingQosFilter() throws Exception
{
FilterHolder holder = new FilterHolder(QoSFilter2.class);
@@ -97,23 +103,23 @@ public class QoSFilterTest extends TestCase
assertTrue(TestServlet.__maxSleepers==MAX_QOS);
}
+ @Test
public void testQosFilter() throws Exception
- {
+ {
FilterHolder holder = new FilterHolder(QoSFilter2.class);
holder.setAsyncSupported(true);
holder.setInitParameter(QoSFilter.MAX_REQUESTS_INIT_PARAM, ""+MAX_QOS);
_tester.getContext().getServletHandler().addFilterWithMapping(holder,"/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
-
for(int i = 0; i < NUM_CONNECTIONS; ++i )
{
new Thread(new Worker2(i)).start();
}
-
+
_doneRequests.await(20,TimeUnit.SECONDS);
assertFalse("TEST WAS NOT PARALLEL ENOUGH!",TestServlet.__maxSleepers<MAX_QOS);
assertTrue(TestServlet.__maxSleepers<=MAX_QOS);
}
-
+
class Worker implements Runnable {
private int _num;
public Worker(int num)
@@ -126,7 +132,6 @@ public class QoSFilterTest extends TestCase
for (int i=0;i<NUM_LOOPS;i++)
{
HttpTester request = new HttpTester();
- HttpTester response = new HttpTester();
request.setMethod("GET");
request.setHeader("host", "tester");
@@ -135,22 +140,14 @@ public class QoSFilterTest extends TestCase
try
{
String responseString = _tester.getResponses(request.generate(), _connectors[_num]);
- int index=-1;
- if((index = responseString.indexOf("HTTP", index+1))!=-1)
+ if(responseString.indexOf("HTTP")!=-1)
{
- responseString = response.parse(responseString);
_doneRequests.countDown();
}
}
- catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (Exception e)
+ catch (Exception x)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ assertTrue(false);
}
}
}
@@ -173,25 +170,24 @@ public class QoSFilterTest extends TestCase
{
url=new URL(addr+"/context/test?priority="+(_num%QoSFilter.__DEFAULT_MAX_PRIORITY)+"&n="+_num+"&l="+i);
// System.err.println(_num+"-"+i+" Try "+url);
- InputStream in = (InputStream)url.getContent();
+ url.getContent();
_doneRequests.countDown();
// System.err.println(_num+"-"+i+" Got "+IO.toString(in)+" "+_doneRequests.getCount());
}
}
catch(Exception e)
{
- Log.warn(url.toString());
+ Log.warn(String.valueOf(url));
Log.debug(e);
}
}
}
-
+
public static class TestServlet extends HttpServlet implements Servlet
{
- private int _count;
private static int __sleepers;
private static int __maxSleepers;
-
+
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
@@ -214,25 +210,24 @@ public class QoSFilterTest extends TestCase
}
response.setContentType("text/plain");
- response.getWriter().println("DONE!");
+ response.getWriter().println("DONE!");
}
catch (InterruptedException e)
{
e.printStackTrace();
response.sendError(500);
- }
+ }
}
}
-
+
public static class QoSFilter2 extends QoSFilter
{
public int getPriority(ServletRequest request)
{
- String p = ((HttpServletRequest)request).getParameter("priority");
+ String p = request.getParameter("priority");
if (p!=null)
return Integer.parseInt(p);
return 0;
}
}
-
}
diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml
index 7db1492776..9979d03167 100644
--- a/jetty-start/pom.xml
+++ b/jetty-start/pom.xml
@@ -20,6 +20,13 @@
</archive>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.start.*</onlyAnalyze>
+ </configuration>
+ </plugin>
</plugins>
</build>
<properties>
@@ -29,6 +36,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Config.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Config.java
index 61a369bb90..3fb06a8561 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Config.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Config.java
@@ -422,7 +422,7 @@ public class Config
* Get the classpath for the named section
*
* @param sectionId
- * @return
+ * @return the classpath for the specified section id
*/
public Classpath getSectionClasspath(String sectionId)
{
@@ -432,7 +432,7 @@ public class Config
/**
* Get the list of section Ids.
*
- * @return
+ * @return the set of unique section ids
*/
public Set<String> getSectionIds()
{
@@ -517,7 +517,7 @@ public class Config
/**
* Parse the configuration
*
- * @param buf
+ * @param stream the stream to read from
* @throws IOException
*/
public void parse(InputStream stream) throws IOException
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
index 435b008417..a067dd5e44 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
@@ -13,17 +13,18 @@
package org.eclipse.jetty.start;
import java.io.BufferedReader;
+import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
-import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ConnectException;
@@ -33,12 +34,11 @@ import java.security.Policy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.TimeZone;
-import org.eclipse.jetty.start.log.RedirectedStreamLogger;
/*-------------------------------------------*/
/**
@@ -49,21 +49,28 @@ import org.eclipse.jetty.start.log.RedirectedStreamLogger;
*
* <p>
* The behaviour of Main is controlled by the parsing of the {@link Config} "org/eclipse/start/start.config" file
- * obtained as a resource or file. This can be overridden with the START system property.
+ * obtained as a resource or file.
* </p>
*/
public class Main
{
+ private static final int EXIT_USAGE = 1;
+ private static final int ERR_LOGGING = -1;
+ private static final int ERR_INVOKE_MAIN = -2;
+ private static final int ERR_SECURITY = -3;
+ private static final int ERR_NOT_STOPPED = -4;
+ private static final int ERR_UNKNOWN = -5;
private boolean _showUsage = false;
private boolean _dumpVersions = false;
+ private boolean _listConfig = false;
private boolean _listOptions = false;
private boolean _dryRun = false;
private boolean _exec = false;
private boolean _secure = false;
- private boolean _fromDaemon = false;
private final Config _config = new Config();
private Set<String> _sysProps = new HashSet<String>();
- private List<String> _xArgs = new ArrayList<String>();
+ private List<String> _jvmArgs = new ArrayList<String>();
+ private String _startConfig = null;
private String _jettyHome;
@@ -77,6 +84,7 @@ public class Main
catch (Throwable t)
{
t.printStackTrace(System.err);
+ System.exit(ERR_UNKNOWN);
}
}
@@ -86,16 +94,43 @@ public class Main
{
List<String> arguments = new ArrayList<String>();
- arguments.addAll(loadStartIni()); // Add Arguments from start.ini (if it exists)
- if (args.length>0)
- arguments.addAll(Arrays.asList(args)); // Add Arguments on Command Line
+ // add the command line args and look for start.ini args
+ boolean ini=false;
+ for (String arg : args)
+ {
+ if (arg.startsWith("--ini=")||arg.equals("--ini"))
+ {
+ ini=true;
+ if (arg.length()>6)
+ {
+ arguments.addAll(loadStartIni(arg.substring(6)));
+ continue;
+ }
+ }
+ else if (arg.startsWith("--config="))
+ {
+ _startConfig=arg.substring(9);
+ }
+ else
+ {
+ arguments.add(arg);
+ }
+ }
+
+ // if no non-option inis, add the start.ini
+ if (!ini)
+ {
+ arguments.addAll(0,loadStartIni(null));
+ }
// The XML Configuration Files to initialize with
List<String> xmls = new ArrayList<String>();
+ // Process the arguments
+ int startup=0;
for (String arg : arguments)
{
- if ("--help".equals(arg))
+ if ("--help".equals(arg) || "-?".equals(arg))
{
_showUsage = true;
continue;
@@ -103,8 +138,8 @@ public class Main
if ("--stop".equals(arg))
{
- int port = Integer.parseInt(_config.getProperty("STOP.KEY",System.getProperty("STOP.PORT","-1")));
- String key = _config.getProperty("STOP.KETY",System.getProperty("STOP.KEY",null));
+ int port = Integer.parseInt(_config.getProperty("STOP.PORT",System.getProperty("STOP.PORT","-1")));
+ String key = _config.getProperty("STOP.KEY",System.getProperty("STOP.KEY",null));
stop(port,key);
return;
}
@@ -121,6 +156,12 @@ public class Main
continue;
}
+ if ("--list-config".equals(arg))
+ {
+ _listConfig=true;
+ continue;
+ }
+
if ("--exec-print".equals(arg)||"--dry-run".equals(arg))
{
_dryRun = true;
@@ -134,12 +175,31 @@ public class Main
}
// Special internal indicator that jetty was started by the jetty.sh Daemon
- if ("--fromDaemon".equals(arg))
+ if ("--daemon".equals(arg))
{
- _fromDaemon = true;
- PrintStream logger = new PrintStream(new RedirectedStreamLogger("daemon_yyyy_mm_dd.log",false,90,TimeZone.getTimeZone("GMT")));
+ File startDir = new File(System.getProperty("jetty.logs","logs"));
+ if (!startDir.exists() || !startDir.canWrite() )
+ startDir = new File(".");
+ File startLog = new File(startDir,"start.log");
+ if (!startLog.exists() && !startLog.createNewFile())
+ {
+ // Output about error is lost in majority of cases.
+ System.err.println("Unable to create: " + startLog.getAbsolutePath());
+ // Toss a unique exit code indicating this failure.
+ System.exit(ERR_LOGGING);
+ }
+
+ if (!startLog.canWrite())
+ {
+ // Output about error is lost in majority of cases.
+ System.err.println("Unable to write to: " + startLog.getAbsolutePath());
+ // Toss a unique exit code indicating this failure.
+ System.exit(ERR_LOGGING);
+ }
+ PrintStream logger = new PrintStream(new FileOutputStream(startLog,false));
System.setOut(logger);
System.setErr(logger);
+ System.out.println("Establishing start.log on " + new Date());
continue;
}
@@ -149,9 +209,9 @@ public class Main
continue;
}
- if (arg.startsWith("-X"))
+ if (arg.startsWith("--pre="))
{
- _xArgs.add(arg);
+ xmls.add(startup++,arg.substring(6));
continue;
}
@@ -173,15 +233,30 @@ public class Main
continue;
}
+ if (arg.startsWith("-"))
+ {
+ _jvmArgs.add(arg);
+ continue;
+ }
+
// Is this a Property?
- else if (arg.indexOf('=') >= 0)
+ if (arg.indexOf('=') >= 0)
{
String[] assign = arg.split("=",2);
switch(assign.length)
{
case 2:
- this._config.setProperty(assign[0],assign[1]);
+ if ("OPTIONS".equals(assign[0]))
+ {
+ String opts[] = assign[1].split(",");
+ for (String opt : opts)
+ _config.addActiveOption(opt);
+ }
+ else
+ {
+ this._config.setProperty(assign[0],assign[1]);
+ }
break;
case 1:
this._config.setProperty(assign[0],null);
@@ -189,21 +264,13 @@ public class Main
default:
break;
}
+
continue;
}
-
+
// Anything else is considered an XML file.
xmls.add(arg);
}
-
- // Special case for OPTIONS property
- String options = _config.getProperty("OPTIONS");
- if (options!=null)
- {
- String ids[] = options.split(",");
- for (String id : ids)
- _config.addActiveOption(id);
- }
start(xmls);
}
@@ -211,18 +278,23 @@ public class Main
{
t.printStackTrace(System.err);
System.out.println("Use java -jar start.jar --help for usage information.");
+ System.exit(ERR_UNKNOWN);
}
}
/**
* If a start.ini is present in the CWD, then load it into the argument list.
*/
- private List<String> loadStartIni()
+ private List<String> loadStartIni(String ini)
{
String jettyHome=System.getProperty("jetty.home");
- File startIniFile = (jettyHome!=null)? new File(jettyHome,"start.ini"):new File("start.ini");
+ File startIniFile = ini==null?((jettyHome!=null)? new File(jettyHome,"start.ini"):new File("start.ini")):new File(ini);
if (!startIniFile.exists() || !startIniFile.canRead())
{
+ if (ini != null)
+ {
+ System.err.println("Warning - can't find ini file: " + ini);
+ }
// No start.ini found, skip load.
return Collections.emptyList();
}
@@ -239,15 +311,18 @@ public class Main
String arg;
while ((arg = buf.readLine()) != null)
{
- arg=arg.trim();
- if (arg.length()==0 || arg.startsWith("#"))
+ arg = arg.trim();
+ if (arg.length() == 0 || arg.startsWith("#"))
+ {
continue;
+ }
args.add(arg);
}
}
catch (IOException e)
{
- e.printStackTrace();
+ e.printStackTrace(System.err);
+ System.exit(ERR_UNKNOWN);
}
finally
{
@@ -267,7 +342,7 @@ public class Main
{
System.err.println("Usage: java -jar start.jar [options] [properties] [configs]");
System.err.println("ERROR: detailed usage resource unavailable");
- System.exit(1);
+ System.exit(EXIT_USAGE);
}
BufferedReader buf = null;
@@ -278,61 +353,81 @@ public class Main
while ((line = buf.readLine()) != null)
{
- if (line.startsWith("@OPTIONS@"))
+ if (line.endsWith("@") && line.indexOf('@')!=line.lastIndexOf('@'))
{
- List<String> sortedOptions = new ArrayList<String>();
- sortedOptions.addAll(_config.getSectionIds());
- Collections.sort(sortedOptions);
-
- System.err.println(" Available OPTIONS: ");
+ String indent=line.substring(0,line.indexOf("@"));
+ String info=line.substring(line.indexOf('@'),line.lastIndexOf('@'));
- for (String option : sortedOptions)
- {
- System.err.println(" [" + option + "]");
- }
- }
- else if (line.startsWith("@CONFIGS@"))
- {
- System.err.println(" Configurations Available in ${jetty.home}/etc/: ");
- File etc = new File(System.getProperty("jetty.home","."),"etc");
- if (!etc.exists())
+ if (info.equals("@OPTIONS"))
{
- System.err.println(" Unable to find " + etc);
- continue;
- }
+ List<String> sortedOptions = new ArrayList<String>();
+ sortedOptions.addAll(_config.getSectionIds());
+ Collections.sort(sortedOptions);
- if (!etc.isDirectory())
- {
- System.err.println(" Unable list dir " + etc);
- continue;
+ for (String option : sortedOptions)
+ {
+ if ("*".equals(option) || option.trim().length()==0)
+ continue;
+ System.out.print(indent);
+ System.out.println(option);
+ }
}
-
- File configs[] = etc.listFiles(new FileFilter()
+ else if (info.equals("@CONFIGS"))
{
- public boolean accept(File path)
+ File etc = new File(System.getProperty("jetty.home","."),"etc");
+ if (!etc.exists() || !etc.isDirectory())
+ {
+ System.out.print(indent);
+ System.out.println("Unable to find/list " + etc);
+ continue;
+ }
+
+ File configs[] = etc.listFiles(new FileFilter()
{
- if (!path.isFile())
+ public boolean accept(File path)
{
- return false;
- }
+ if (!path.isFile())
+ {
+ return false;
+ }
- String name = path.getName().toLowerCase();
- return (name.startsWith("jetty") && name.endsWith(".xml"));
- }
- });
+ String name = path.getName().toLowerCase();
+ return (name.startsWith("jetty") && name.endsWith(".xml"));
+ }
+ });
- List<File> configFiles = new ArrayList<File>();
- configFiles.addAll(Arrays.asList(configs));
- Collections.sort(configFiles);
+ List<File> configFiles = new ArrayList<File>();
+ configFiles.addAll(Arrays.asList(configs));
+ Collections.sort(configFiles);
- for (File configFile : configFiles)
+ for (File configFile : configFiles)
+ {
+ System.out.print(indent);
+ System.out.print("etc/");
+ System.out.println(configFile.getName());
+ }
+ }
+ else if (info.equals("@STARTINI"))
{
- System.err.println(" etc/" + configFile.getName());
+ List<String> ini = loadStartIni(null);
+ if (ini!=null && ini.size()>0)
+ {
+ for (String a : ini)
+ {
+ System.out.print(indent);
+ System.out.println(a);
+ }
+ }
+ else
+ {
+ System.out.print(indent);
+ System.out.println("none");
+ }
}
}
else
{
- System.err.println(line);
+ System.out.println(line);
}
}
}
@@ -342,19 +437,9 @@ public class Main
}
finally
{
- if (buf != null)
- {
- try
- {
- buf.close();
- }
- catch (IOException ignore)
- {
- /* ignore */
- }
- }
+ close(buf);
}
- System.exit(1);
+ System.exit(EXIT_USAGE);
}
public void invokeMain(ClassLoader classloader, String classname, List<String> args) throws IllegalAccessException, InvocationTargetException,
@@ -374,13 +459,19 @@ public class Main
if (Config.isDebug() || invoked_class == null)
{
if (invoked_class == null)
+ {
System.err.println("ClassNotFound: " + classname);
+ }
else
+ {
System.err.println(classname + " " + invoked_class.getPackage().getImplementationVersion());
+ }
if (invoked_class == null)
{
- usage();
+ System.err.println("Usage: java -jar start.jar [options] [properties] [configs]");
+ System.err.println(" java -jar start.jar --help # for more information");
+ System.exit(ERR_INVOKE_MAIN);
return;
}
}
@@ -395,36 +486,19 @@ public class Main
}
/* ------------------------------------------------------------ */
- public static void close(Reader reader)
+ public static void close(Closeable c)
{
- if (reader == null)
+ if (c == null)
{
return;
}
try
{
- reader.close();
+ c.close();
}
catch (IOException e)
{
- e.printStackTrace();
- }
- }
-
- /* ------------------------------------------------------------ */
- public static void close(InputStream stream)
- {
- if (stream == null)
- {
- return;
- }
- try
- {
- stream.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
}
@@ -443,12 +517,6 @@ public class Main
throw new FileNotFoundException("No XML configuration files specified in start.config or command line.");
}
- // Add required logging if executed via the daemon.
- if (_fromDaemon)
- {
- configuredXmls.add("etc/jetty-logging.xml");
- }
-
// Add mandatory options for secure mode
if (_secure)
{
@@ -496,6 +564,12 @@ public class Main
showAllOptionsWithVersions(classpath);
return;
}
+
+ if (_listConfig)
+ {
+ listConfig();
+ return;
+ }
// Show Command Line to execute Jetty
if (_dryRun)
@@ -516,8 +590,10 @@ public class Main
return;
}
- if (_xArgs.size()>0 || _sysProps.size()>0)
+ if (_jvmArgs.size() > 0 || _sysProps.size() > 0)
+ {
System.err.println("WARNING: System properties and/or JVM args set. Consider using --dry-run or --exec");
+ }
// Set current context class loader to what is selected.
Thread.currentThread().setContextClassLoader(cl);
@@ -534,12 +610,16 @@ public class Main
// Check for override of start class (via "jetty.server" property)
String mainClass = System.getProperty("jetty.server");
if (mainClass != null)
+ {
classname = mainClass;
+ }
// Check for override of start class (via "main.class" property)
mainClass = System.getProperty("main.class");
if (mainClass != null)
+ {
classname = mainClass;
+ }
Config.debug("main.class=" + classname);
@@ -547,7 +627,8 @@ public class Main
}
catch (Exception e)
{
- e.printStackTrace();
+ e.printStackTrace(System.err);
+ System.exit(ERR_INVOKE_MAIN);
}
}
@@ -609,18 +690,18 @@ public class Main
{
StringBuilder cmd = new StringBuilder();
cmd.append(findJavaBin());
- for (String x:_xArgs)
+ for (String x:_jvmArgs)
cmd.append(' ').append(x);
cmd.append(" -Djetty.home=").append(_jettyHome);
for (String p:_sysProps)
{
- cmd.append(" -D").append(p);
+ cmd.append(" -D").append(p);
String v=System.getProperty(p);
- if (v!=null)
+ if (v!=null && v.length()>0)
cmd.append('=').append(v);
}
- cmd.append(" -cp ").append(classpath.toString());
- cmd.append(' ').append(_config.getMainClassname());
+ cmd.append(" -cp ").append(classpath.toString());
+ cmd.append(" ").append(_config.getMainClassname());
for (String xml : xmls)
{
cmd.append(' ').append(xml);
@@ -785,28 +866,23 @@ public class Main
}
catch (SecurityException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
catch (NoSuchMethodException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
catch (IllegalArgumentException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
catch (IllegalAccessException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
catch (InvocationTargetException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ e.printStackTrace(System.err);
}
}
}
@@ -861,12 +937,15 @@ public class Main
{
Policy policy = Policy.getPolicy();
if (policy != null)
+ {
policy.refresh();
+ }
}
}
catch (Exception e)
{
- e.printStackTrace();
+ e.printStackTrace(System.err);
+ System.exit(ERR_SECURITY);
}
}
@@ -881,6 +960,34 @@ public class Main
return ret;
}
+ private void listConfig()
+ {
+ InputStream cfgstream = null;
+ try
+ {
+ cfgstream=getConfigStream();
+ byte[] buf=new byte[4096];
+
+ int len=0;
+
+ while (len>=0)
+ {
+ len=cfgstream.read(buf);
+ if (len>0)
+ System.out.write(buf,0,len);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ System.exit(ERR_UNKNOWN);
+ }
+ finally
+ {
+ close(cfgstream);
+ }
+ }
+
/**
* Load Configuration.
*
@@ -898,18 +1005,9 @@ public class Main
{
// Pass in xmls.size into Config so that conditions based on "nargs" work.
_config.setArgCount(xmls.size());
-
- // What start.config should we use?
- String cfgName = System.getProperty("START","org/eclipse/jetty/start/start.config");
- Config.debug("config=" + cfgName);
-
- // Look up config as resource first.
- cfgstream = getClass().getClassLoader().getResourceAsStream(cfgName);
-
- // resource not found, try filesystem next
- if (cfgstream == null)
- cfgstream = new FileInputStream(cfgName);
-
+
+ cfgstream=getConfigStream();
+
// parse the config
_config.parse(cfgstream);
@@ -937,8 +1035,8 @@ public class Main
catch (Exception e)
{
e.printStackTrace();
- System.exit(1);
- return null; // never executed (just to satisfy javac compiler)
+ System.exit(ERR_UNKNOWN);
+ return null; // never executed (just here to satisfy javac compiler)
}
finally
{
@@ -946,10 +1044,32 @@ public class Main
}
}
+ private InputStream getConfigStream() throws FileNotFoundException
+ {
+ String config=_startConfig;
+ if (config == null || config.length() == 0)
+ {
+ config = System.getProperty("START","org/eclipse/jetty/start/start.config");
+ }
+
+ Config.debug("config=" + config);
+
+ // Look up config as resource first.
+ InputStream cfgstream = getClass().getClassLoader().getResourceAsStream(config);
+
+ // resource not found, try filesystem next
+ if (cfgstream == null)
+ {
+ cfgstream = new FileInputStream(config);
+ }
+
+ return cfgstream;
+ }
+
private void startMonitor()
{
- int port = Integer.parseInt(System.getProperty("STOP.PORT","-1"));
- String key = System.getProperty("STOP.KEY",null);
+ int port = Integer.parseInt(_config.getProperty("STOP.PORT",System.getProperty("STOP.PORT","-1")));
+ String key = _config.getProperty("STOP.KEY",System.getProperty("STOP.KEY",null));
Monitor.monitor(port,key);
}
@@ -965,7 +1085,9 @@ public class Main
try
{
if (_port <= 0)
+ {
System.err.println("STOP.PORT system property must be specified");
+ }
if (_key == null)
{
_key = "";
@@ -974,18 +1096,26 @@ public class Main
}
Socket s = new Socket(InetAddress.getByName("127.0.0.1"),_port);
- OutputStream out = s.getOutputStream();
- out.write((_key + "\r\nstop\r\n").getBytes());
- out.flush();
- s.close();
+ try
+ {
+ OutputStream out = s.getOutputStream();
+ out.write((_key + "\r\nstop\r\n").getBytes());
+ out.flush();
+ }
+ finally
+ {
+ s.close();
+ }
}
catch (ConnectException e)
{
System.err.println("ERROR: Not running!");
+ System.exit(ERR_NOT_STOPPED);
}
catch (Exception e)
{
- e.printStackTrace();
+ e.printStackTrace(System.err);
+ System.exit(ERR_UNKNOWN);
}
}
}
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/log/RedirectedStreamLogger.java b/jetty-start/src/main/java/org/eclipse/jetty/start/log/RedirectedStreamLogger.java
deleted file mode 100644
index 65ba90f2b1..0000000000
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/log/RedirectedStreamLogger.java
+++ /dev/null
@@ -1,299 +0,0 @@
-package org.eclipse.jetty.start.log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-import java.util.Timer;
-import java.util.TimerTask;
-
-public class RedirectedStreamLogger extends FilterOutputStream
-{
- private static Timer __rollover;
-
- final static String YYYY_MM_DD = "yyyy_mm_dd";
- final static String ROLLOVER_FILE_DATE_FORMAT = "yyyy_MM_dd";
- final static String ROLLOVER_FILE_BACKUP_FORMAT = "HHmmssSSS";
- final static int ROLLOVER_FILE_RETAIN_DAYS = 31;
-
- private RollTask _rollTask;
- private SimpleDateFormat _fileBackupFormat;
- private SimpleDateFormat _fileDateFormat;
-
- private String _filename;
- private File _file;
- private boolean _append;
- private int _retainDays;
-
- /* ------------------------------------------------------------ */
- /**
- * @param filename
- * The filename must include the string "yyyy_mm_dd", which is replaced with the actual date when
- * creating and rolling over the file.
- * @throws IOException
- */
- public RedirectedStreamLogger(String filename) throws IOException
- {
- this(filename,true,ROLLOVER_FILE_RETAIN_DAYS);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param filename
- * The filename must include the string "yyyy_mm_dd", which is replaced with the actual date when
- * creating and rolling over the file.
- * @param append
- * If true, existing files will be appended to.
- * @throws IOException
- */
- public RedirectedStreamLogger(String filename, boolean append) throws IOException
- {
- this(filename,append,ROLLOVER_FILE_RETAIN_DAYS);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param filename
- * The filename must include the string "yyyy_mm_dd", which is replaced with the actual date when
- * creating and rolling over the file.
- * @param append
- * If true, existing files will be appended to.
- * @param retainDays
- * The number of days to retain files before deleting them. 0 to retain forever.
- * @throws IOException
- */
- public RedirectedStreamLogger(String filename, boolean append, int retainDays) throws IOException
- {
- this(filename,append,retainDays,TimeZone.getDefault());
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param filename
- * The filename must include the string "yyyy_mm_dd", which is replaced with the actual date when
- * creating and rolling over the file.
- * @param append
- * If true, existing files will be appended to.
- * @param retainDays
- * The number of days to retain files before deleting them. 0 to retain forever.
- * @throws IOException
- */
- public RedirectedStreamLogger(String filename, boolean append, int retainDays, TimeZone zone) throws IOException
- {
- this(filename,append,retainDays,zone,null,null);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param filename
- * The filename must include the string "yyyy_mm_dd", which is replaced with the actual date when
- * creating and rolling over the file.
- * @param append
- * If true, existing files will be appended to.
- * @param retainDays
- * The number of days to retain files before deleting them. 0 to retain forever.
- * @param dateFormat
- * The format for the date file substitution. The default is "yyyy_MM_dd".
- * @param backupFormat
- * The format for the file extension of backup files. The default is "HHmmssSSS".
- * @throws IOException
- */
- public RedirectedStreamLogger(String filename, boolean append, int retainDays, TimeZone zone, String dateFormat, String backupFormat) throws IOException
- {
- super(null);
-
- if (dateFormat == null)
- dateFormat = ROLLOVER_FILE_DATE_FORMAT;
- _fileDateFormat = new SimpleDateFormat(dateFormat);
-
- if (backupFormat == null)
- backupFormat = ROLLOVER_FILE_BACKUP_FORMAT;
- _fileBackupFormat = new SimpleDateFormat(backupFormat);
-
- _fileBackupFormat.setTimeZone(zone);
- _fileDateFormat.setTimeZone(zone);
-
- if (filename != null)
- {
- filename = filename.trim();
- if (filename.length() == 0)
- filename = null;
- }
- if (filename == null)
- throw new IllegalArgumentException("Invalid filename");
-
- _filename = filename;
- _append = append;
- _retainDays = retainDays;
- setFile();
-
- synchronized (RedirectedStreamLogger.class)
- {
- if (__rollover == null)
- __rollover = new Timer(RedirectedStreamLogger.class.getName(),true);
-
- _rollTask = new RollTask();
-
- Calendar now = Calendar.getInstance();
- now.setTimeZone(zone);
-
- GregorianCalendar midnight = new GregorianCalendar(now.get(Calendar.YEAR),now.get(Calendar.MONTH),now.get(Calendar.DAY_OF_MONTH),23,0);
- midnight.setTimeZone(zone);
- midnight.add(Calendar.HOUR,1);
- __rollover.scheduleAtFixedRate(_rollTask,midnight.getTime(),1000L * 60 * 60 * 24);
- }
- }
-
- /* ------------------------------------------------------------ */
- public String getFilename()
- {
- return _filename;
- }
-
- /* ------------------------------------------------------------ */
- public String getDatedFilename()
- {
- if (_file == null)
- return null;
- return _file.toString();
- }
-
- /* ------------------------------------------------------------ */
- public int getRetainDays()
- {
- return _retainDays;
- }
-
- /* ------------------------------------------------------------ */
- private synchronized void setFile() throws IOException
- {
- // Check directory
- File file = new File(_filename);
- _filename = file.getCanonicalPath();
- file = new File(_filename);
- File dir = new File(file.getParent());
- if (!dir.isDirectory() || !dir.canWrite())
- throw new IOException("Cannot write log directory " + dir);
-
- Date now = new Date();
-
- // Is this a rollover file?
- String filename = file.getName();
- int i = filename.toLowerCase().indexOf(YYYY_MM_DD);
- if (i >= 0)
- {
- file = new File(dir,filename.substring(0,i) + _fileDateFormat.format(now) + filename.substring(i + YYYY_MM_DD.length()));
- }
-
- if (file.exists() && !file.canWrite())
- throw new IOException("Cannot write log file " + file);
-
- // Do we need to change the output stream?
- if (out == null || !file.equals(_file))
- {
- // Yep
- _file = file;
- if (!_append && file.exists())
- file.renameTo(new File(file.toString() + "." + _fileBackupFormat.format(now)));
- OutputStream oldOut = out;
- out = new FileOutputStream(file.toString(),_append);
- if (oldOut != null)
- oldOut.close();
- //if(log.isDebugEnabled())log.debug("Opened "+_file);
- }
- }
-
- /* ------------------------------------------------------------ */
- private void removeOldFiles()
- {
- if (_retainDays > 0)
- {
- long now = System.currentTimeMillis();
-
- File file = new File(_filename);
- File dir = new File(file.getParent());
- String fn = file.getName();
- int s = fn.toLowerCase().indexOf(YYYY_MM_DD);
- if (s < 0)
- return;
- String prefix = fn.substring(0,s);
- String suffix = fn.substring(s + YYYY_MM_DD.length());
-
- String[] logList = dir.list();
- for (int i = 0; i < logList.length; i++)
- {
- fn = logList[i];
- if (fn.startsWith(prefix) && fn.indexOf(suffix,prefix.length()) >= 0)
- {
- File f = new File(dir,fn);
- long date = f.lastModified();
- if (((now - date) / (1000 * 60 * 60 * 24)) > _retainDays)
- f.delete();
- }
- }
- }
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void write(byte[] buf) throws IOException
- {
- out.write(buf);
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void write(byte[] buf, int off, int len) throws IOException
- {
- out.write(buf,off,len);
- }
-
- /* ------------------------------------------------------------ */
- /**
- */
- @Override
- public void close() throws IOException
- {
- synchronized (RedirectedStreamLogger.class)
- {
- try
- {
- super.close();
- }
- finally
- {
- out = null;
- _file = null;
- }
-
- _rollTask.cancel();
- }
- }
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- private class RollTask extends TimerTask
- {
- @Override
- public void run()
- {
- try
- {
- RedirectedStreamLogger.this.setFile();
- RedirectedStreamLogger.this.removeOldFiles();
-
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config
index 38b51c91dc..94d2609611 100644
--- a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config
+++ b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config
@@ -139,16 +139,20 @@ $(jetty.home)/lib/setuid/**
$(jetty.home)/lib/jetty-policy-$(version).jar ! available org.eclipse.jetty.policy.JettyPolicy
$(jetty.home)/lib/policy/jetty.policy
-[All,client]
+[All,Client,client]
$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser
$(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient
[All,websocket]
$(jetty.home)/lib/jetty-websocket-$(version).jar ! available org.eclipse.jetty.websocket.WebSocket
+[Client]
+$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser
+
[All,websocket]
$(jetty.home)/lib/jetty-websocket-$(version).jar ! available org.eclipse.jetty.websocket.WebSocket
-
+
+
# Add ext if it exists
[Server,All,default,ext]
$(jetty.home)/lib/ext/**
diff --git a/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt b/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt
index 18a0e3b495..7371be3f99 100644
--- a/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt
+++ b/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt
@@ -1,58 +1,75 @@
-Usage: java -jar start.jar [options] [properties] [configs]
+Usage: java -jar start.jar [options...] [properties...] [configs...]
The start.jar builds a classpath and executes a main java class with
a classloader built from that classpath. By default the start.jar
mechanism is configured to start the jetty server, but it can be
configured to start any java main class.
-Common Options:
+Command Line Options:
--help This help / usage information.
- --version Print the version information for Jetty, then exit.
- --stop Stop the running Jetty instance.
-
-Advanced Options:
-
- --list-options List available options, then exit.
- (see OPTION property in section below)
+
+ --version Print the version information for Jetty and
+ dependent jars, then exit.
+ --list-options List the details of each classpath OPTION
+
+ --list-config List the start.config file.
+
--dry-run Print the command line that the start.jar generates,
then exit. This may be used to generate command lines
when the start.ini includes -X or -D arguments.
- On unix, the resulting command line can be run with
- eval $(java -jar start.jar --dry-run)
- This is more efficient than the --exec option, which
- creates a second JVM instance
--exec Run the generated command line (see --dry-run) in
a sub processes. This can be used when start.ini
contains -X or -D arguments, but creates an extra
JVM instance.
+
+ --stop Stop the running Jetty instance.
+
+ --daemon Start in daemon mode with stderr and stdout
+ redirected to ${jetty.log}/start.log
+
+ --config=<file> Specify an alternate start.config file.
+ The default is the start.config file inside
+ the start.jar. The default can also be specified
+ with the START system property.
+
+ --ini=<file> Load command line arguments from a file. If
+ no --ini options are specified, then the
+ start.ini file will be read if it exists.
+ A --ini option with no file indicates that
+ start.ini should not be read.
- --secure Enable Security:
- * JVM Security Manager
- * Security Policies
- * Secure Logging
- * Audit Logging
-
- If the file start.ini exists in the working directory, then it's each line
- of it's contents is prepended to the as an argument to the command line.
+ --pre=<file> Specify a configuration file that is to be processed
+ before any configuration files listed in start.ini
System Properties:
These are set with a command line like "java -Dname=value ..." and are
accessible via the java.lang.System#getProperty(String) API.
Some key system properties are:
+
org.eclipse.jetty.util.log.class=[class]
A Low Level Jetty Logger Implementation to use
(default: org.eclipse.jetty.util.log.Slf4jLog)
+
org.eclipse.jetty.util.log.DEBUG=[boolean]
Debug logging for the stderr and javautil Loggers. Slf4j
and other loggers must be separately configured for debug.
(default: false)
+
org.eclipse.jetty.util.log.IGNORED=[boolean]
Ignored exceptions are logged, independent of DEBUG settings
(default: false)
-Start Properties:
+ org.eclipse.jetty.util.log.SOURCE=[boolean]
+ The source location of logs is logged in the stderr Logger.
+ (default: false)
+
+ com.sun.management.jmxremote
+ Enable remote JMX management in Sun JVMS.
+
+
+Properties:
These are set with a command line like "java -jar start.jar name=value"
and only affect the start mechanism. Some of these are defined in the
default start.config and will not be available if another configuration
@@ -61,29 +78,46 @@ Start Properties:
path=[directory]
An additional class path element to add to the started class path. Typically
this is used to add directories of classes and/or resources
+
lib=[directory]
An additional library directory to add to the started class path. This must
be a (deep) directory of jars
+
STOP.PORT=[number]
The port to use to stop the running Jetty server.
Required along with STOP.KEY if you want to use the --stop option above.
+
STOP.KEY=[alphanumeric]
The passphrase defined to stop the server.
Requried along with STOP.PORT if you want to use the --stop option above.
+
DEBUG=true
Enable debug on the start mechanism and sets the
org.eclipse.jetty.util.log.stderr.DEBUG system property to true.
(default: false)
- OPTIONS=[option,option,...]
- Classpath Options to use. By convention, option names starting with capitals
- will include associated options (eg Server includes jetty-server, jetty-webapp,
- jetty-deploy, etc). An option starting with a lowercase letter includes
- just the direct dependencies of the option (eg jsp includes just jetty-jsp
- module and it's dependencies).
- (default: "default,*")
-@OPTIONS@
+ OPTIONS=[option,option,...]
+ Enable classpath OPTIONS. Each options represents one or more jars
+ to be added to the classpath. The options are defined in
+ the start.config file and can be listed with --help or --list-options.
+ By convention, options starting with a capital letter (eg Server)
+ are aggregations of other available options. Available OPTIONS:
+
+ @OPTIONS@
+
+
+Available Configurations:
+ By convention, configuration files are kept in $JETTY_HOME/etc.
+ The known configuration files are:
+
+ @CONFIGS@
+
+
+Defaults:
+ A start.ini file may be used to specify default arguments to start.jar,
+ which are used if no command line arguments are provided and override
+ the defaults in the start.config file. If --ini options are provided on
+ the command line, then start.ini will no be read. The current start.ini
+ arguments are:
-Configs:
- XML Configurations to use.
-@CONFIGS@
+ @STARTINI@
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigTest.java
index d3d3557b6f..fcd591bea1 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigTest.java
@@ -5,13 +5,13 @@
// 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
+// 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.apache.org/licenses/LICENSE-2.0.txt
//
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.start;
@@ -25,31 +25,29 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
-public class ConfigTest extends TestCase
+public class ConfigTest
{
- private File jettyHomeDir;
- private File resourcesDir;
-
private void assertEquals(String msg, Classpath expected, Classpath actual)
{
- assertNotNull(msg + " : expected classpath should not be null",expected);
- assertNotNull(msg + " : actual classpath should not be null",actual);
- assertTrue(msg + " : expected should have an entry",expected.count() >= 1);
- assertTrue(msg + " : actual should have an entry",actual.count() >= 1);
+ Assert.assertNotNull(msg + " : expected classpath should not be null",expected);
+ Assert.assertNotNull(msg + " : actual classpath should not be null",actual);
+ Assert.assertTrue(msg + " : expected should have an entry",expected.count() >= 1);
+ Assert.assertTrue(msg + " : actual should have an entry",actual.count() >= 1);
if (expected.count() != actual.count())
{
expected.dump(System.err);
actual.dump(System.err);
- assertEquals(msg + " : count",expected.count(),actual.count());
+ Assert.assertEquals(msg + " : count",expected.count(),actual.count());
}
List<File> actualEntries = Arrays.asList(actual.getElements());
List<File> expectedEntries = Arrays.asList(expected.getElements());
int len = expectedEntries.size();
-
+
for (int i = 0; i < len; i++)
{
File expectedFile = expectedEntries.get(i);
@@ -58,18 +56,18 @@ public class ConfigTest extends TestCase
{
expected.dump(System.err);
actual.dump(System.err);
- assertEquals(msg + ": entry [" + i + "]",expectedEntries.get(i),actualEntries.get(i));
+ Assert.assertEquals(msg + ": entry [" + i + "]",expectedEntries.get(i),actualEntries.get(i));
}
}
}
private void assertEquals(String msg, Collection<String> expected, Collection<String> actual)
{
- assertTrue(msg + " : expected should have an entry",expected.size() >= 1);
- assertEquals(msg + " : size",expected.size(),actual.size());
+ Assert.assertTrue(msg + " : expected should have an entry",expected.size() >= 1);
+ Assert.assertEquals(msg + " : size",expected.size(),actual.size());
for (String expectedVal : expected)
{
- assertTrue(msg + " : should contain <" + expectedVal + ">",actual.contains(expectedVal));
+ Assert.assertTrue(msg + " : should contain <" + expectedVal + ">",actual.contains(expectedVal));
}
}
@@ -81,12 +79,7 @@ public class ConfigTest extends TestCase
private File getJettyHomeDir()
{
- if (jettyHomeDir == null)
- {
- jettyHomeDir = new File(getTestResourcesDir(),"jetty.home");
- }
-
- return jettyHomeDir;
+ return new File(getTestResourcesDir(),"jetty.home");
}
private String getTestableJettyHome()
@@ -96,19 +89,15 @@ public class ConfigTest extends TestCase
private File getTestResourcesDir()
{
- if (resourcesDir == null)
- {
- File src = new File(System.getProperty("user.dir"),"src");
- File test = new File(src,"test");
- resourcesDir = new File(test,"resources");
- }
-
- return resourcesDir;
+ File src = new File(System.getProperty("user.dir"),"src");
+ File test = new File(src,"test");
+ return new File(test,"resources");
}
- /**
+ /*
* Test for SUBJECT "/=" for assign canonical path
*/
+ @Test
public void testSubjectAssignCanonicalPath() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -117,12 +106,13 @@ public class ConfigTest extends TestCase
Config cfg = new Config();
cfg.parse(buf);
- assertEquals(getTestResourcesDir().getCanonicalPath(),cfg.getProperty("test.resources.dir"));
+ Assert.assertEquals(getTestResourcesDir().getCanonicalPath(),cfg.getProperty("test.resources.dir"));
}
- /**
+ /*
* Test for SUBJECT "~=" for assigning Start Properties
*/
+ @Test
public void testSubjectAssignStartProperty() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -132,13 +122,14 @@ public class ConfigTest extends TestCase
Config options = new Config();
options.parse(buf);
- assertEquals("foo",options.getProperty("test.jetty.start.text"));
- assertEquals("Eatagramovabits",options.getProperty("test.jetty.start.quote"));
+ Assert.assertEquals("foo",options.getProperty("test.jetty.start.text"));
+ Assert.assertEquals("Eatagramovabits",options.getProperty("test.jetty.start.quote"));
}
- /**
+ /*
* Test for SUBJECT "=" for assigning System Properties
*/
+ @Test
public void testSubjectAssignSystemProperty() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -148,13 +139,14 @@ public class ConfigTest extends TestCase
Config options = new Config();
options.parse(buf);
- assertEquals("foo",System.getProperty("test.jetty.start.text"));
- assertEquals("Eatagramovabits",System.getProperty("test.jetty.start.quote"));
+ Assert.assertEquals("foo",System.getProperty("test.jetty.start.text"));
+ Assert.assertEquals("Eatagramovabits",System.getProperty("test.jetty.start.quote"));
}
- /**
+ /*
* Test for SUBJECT ending with "/**", all jar and zip components in dir (deep, recursive)
*/
+ @Test
public void testSubjectComponentDirDeep() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -191,9 +183,10 @@ public class ConfigTest extends TestCase
assertEquals("Components (Deep)",expected,actual);
}
- /**
+ /*
* Test for SUBJECT ending with "/*", all jar and zip components in dir (shallow, no recursion)
*/
+ @Test
public void testSubjectComponentDirShallow() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -225,9 +218,10 @@ public class ConfigTest extends TestCase
assertEquals("Components (Shallow)",expected,actual);
}
- /**
+ /*
* Test for SUBJECT ending with ".class", a Main Class
*/
+ @Test
public void testSubjectMainClass() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -236,12 +230,13 @@ public class ConfigTest extends TestCase
Config options = new Config();
options.parse(buf);
- assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
+ Assert.assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
}
- /**
+ /*
* Test for SUBJECT ending with ".class", a Main Class
*/
+ @Test
public void testSubjectMainClassConditionalPropertySet() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -252,12 +247,13 @@ public class ConfigTest extends TestCase
options.setProperty("start.class","net.company.server.Start");
options.parse(buf);
- assertEquals("net.company.server.Start",options.getMainClassname());
+ Assert.assertEquals("net.company.server.Start",options.getMainClassname());
}
- /**
+ /*
* Test for SUBJECT ending with ".class", a Main Class
*/
+ @Test
public void testSubjectMainClassConditionalPropertyUnset() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -268,12 +264,13 @@ public class ConfigTest extends TestCase
// The "start.class" property is unset.
options.parse(buf);
- assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
+ Assert.assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
}
- /**
+ /*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
+ @Test
public void testSubjectSimpleComponent() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -293,9 +290,10 @@ public class ConfigTest extends TestCase
assertEquals("Simple Component",expected,actual);
}
- /**
+ /*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
+ @Test
public void testSubjectSimpleComponentMultiple() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -317,9 +315,10 @@ public class ConfigTest extends TestCase
assertEquals("Simple Component",expected,actual);
}
- /**
+ /*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
+ @Test
public void testSubjectSimpleComponentNotExists() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -340,9 +339,10 @@ public class ConfigTest extends TestCase
assertEquals("Simple Component",expected,actual);
}
- /**
+ /*
* Test for SUBJECT ending with ".xml", an XML Configuration File
*/
+ @Test
public void testSubjectXmlConfigAlt() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -359,13 +359,14 @@ public class ConfigTest extends TestCase
List<String> actual = options.getXmlConfigs();
String expected = new File("src/test/resources/test-alt.xml").getAbsolutePath();
- assertEquals("XmlConfig.size",1,actual.size());
- assertEquals(expected,actual.get(0));
+ Assert.assertEquals("XmlConfig.size",1,actual.size());
+ Assert.assertEquals(expected,actual.get(0));
}
- /**
+ /*
* Test for SUBJECT ending with ".xml", an XML Configuration File
*/
+ @Test
public void testSubjectXmlConfigDefault() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -380,13 +381,14 @@ public class ConfigTest extends TestCase
List<String> actual = options.getXmlConfigs();
String expected = getJettyEtcFile("test-jetty.xml");
- assertEquals("XmlConfig.size",1,actual.size());
- assertEquals(expected,actual.get(0));
+ Assert.assertEquals("XmlConfig.size",1,actual.size());
+ Assert.assertEquals(expected,actual.get(0));
}
- /**
+ /*
* Test for SUBJECT ending with ".xml", an XML Configuration File.
*/
+ @Test
public void testSubjectXmlConfigMultiple() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -409,9 +411,10 @@ public class ConfigTest extends TestCase
assertEquals("Multiple XML Configs",expected,actual);
}
- /**
+ /*
* Test Section Handling
*/
+ @Test
public void testSectionClasspathSingle() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -426,12 +429,12 @@ public class ConfigTest extends TestCase
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
- assertNotNull("Default Classpath should not be null",defaultClasspath);
+ Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("Foo");
- assertNull("Foo Classpath should not exist",foocp);
+ Assert.assertNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
- assertNotNull("Classpath section 'All' should exist",allcp);
+ Assert.assertNotNull("Classpath section 'All' should exist",allcp);
File lib = new File(getJettyHomeDir(),"lib");
@@ -441,10 +444,11 @@ public class ConfigTest extends TestCase
assertEquals("Single Classpath Section",expected,allcp);
}
-
- /**
+
+ /*
* Test Section Handling
*/
+ @Test
public void testSectionClasspathAvailable() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -459,12 +463,12 @@ public class ConfigTest extends TestCase
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
- assertNotNull("Default Classpath should not be null",defaultClasspath);
+ Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("Foo");
- assertNull("Foo Classpath should not exist",foocp);
+ Assert.assertNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
- assertNotNull("Classpath section 'All' should exist",allcp);
+ Assert.assertNotNull("Classpath section 'All' should exist",allcp);
File lib = new File(getJettyHomeDir(),"lib");
@@ -475,9 +479,10 @@ public class ConfigTest extends TestCase
assertEquals("Single Classpath Section",expected,allcp);
}
- /**
+ /*
* Test Section Handling, with multiple defined sections.
*/
+ @Test
public void testSectionClasspathMultiples() throws IOException
{
StringBuffer buf = new StringBuffer();
@@ -506,10 +511,10 @@ public class ConfigTest extends TestCase
cfg.parse(buf);
Classpath defaultClasspath = cfg.getClasspath();
- assertNotNull("Default Classpath should not be null",defaultClasspath);
+ Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = cfg.getSectionClasspath("Foo");
- assertNull("Foo Classpath should not exist",foocp);
+ Assert.assertNull("Foo Classpath should not exist",foocp);
// Test if entire section list can be fetched
Set<String> sections = cfg.getSectionIds();
@@ -527,7 +532,7 @@ public class ConfigTest extends TestCase
// Test fetch of specific section by name works
Classpath cpAll = cfg.getSectionClasspath("All");
- assertNotNull("Classpath section 'All' should exist",cpAll);
+ Assert.assertNotNull("Classpath section 'All' should exist",cpAll);
File lib = new File(getJettyHomeDir(),"lib");
@@ -539,14 +544,14 @@ public class ConfigTest extends TestCase
expectedAll.addComponent(new File(lib,"LOGGING.JAR"));
assertEquals("Classpath 'All' Section",expectedAll,cpAll);
-
+
// Test combined classpath fetch of multiple sections works
List<String> activated = new ArrayList<String>();
activated.add("server");
activated.add("logging");
-
+
Classpath cpCombined = cfg.getCombinedClasspath(activated);
-
+
Classpath expectedCombined = new Classpath();
// from default
expectedCombined.addComponent(new File(lib,"spec.zip"));
@@ -559,17 +564,16 @@ public class ConfigTest extends TestCase
// from '*'
expectedCombined.addComponent(new File(lib,"io.jar"));
expectedCombined.addComponent(new File(lib,"util.jar"));
-
+
assertEquals("Classpath combined 'server,logging'",expectedCombined,cpCombined);
}
-
-
+ @Test
public void testDynamicSection() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All,default,=$(jetty.home)/lib/*]\n");
-
+
String jettyHome = getTestableJettyHome();
Config options = new Config();
@@ -577,32 +581,31 @@ public class ConfigTest extends TestCase
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
- assertNotNull("Default Classpath should not be null",defaultClasspath);
+ Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("foo");
- assertNotNull("Foo Classpath should not exist",foocp);
+ Assert.assertNotNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
- assertNotNull("Classpath section 'All' should exist",allcp);
-
+ Assert.assertNotNull("Classpath section 'All' should exist",allcp);
+
Classpath extcp = options.getSectionClasspath("ext");
- assertNotNull("Classpath section 'ext' should exist", extcp);
+ Assert.assertNotNull("Classpath section 'ext' should exist", extcp);
- assertEquals("Deep Classpath Section",0,foocp.count());
+ Assert.assertEquals("Deep Classpath Section",0,foocp.count());
- Classpath expected = new Classpath();
File lib = new File(getJettyHomeDir(),"lib");
File ext = new File(lib, "ext");
- expected = new Classpath();
+ Classpath expected = new Classpath();
expected.addComponent(new File(ext,"custom-impl.jar"));
assertEquals("Single Classpath Section",expected,extcp);
-
}
-
+
+ @Test
public void testDeepDynamicSection() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All,default,=$(jetty.home)/lib/**]\n");
-
+
String jettyHome = getTestableJettyHome();
@@ -611,15 +614,15 @@ public class ConfigTest extends TestCase
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
- assertNotNull("Default Classpath should not be null",defaultClasspath);
+ Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("foo");
- assertNotNull("Foo Classpath should not exist",foocp);
+ Assert.assertNotNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
- assertNotNull("Classpath section 'All' should exist",allcp);
-
+ Assert.assertNotNull("Classpath section 'All' should exist",allcp);
+
Classpath extcp = options.getSectionClasspath("ext");
- assertNotNull("Classpath section 'ext' should exist", extcp);
+ Assert.assertNotNull("Classpath section 'ext' should exist", extcp);
File lib = new File(getJettyHomeDir(),"lib");
@@ -628,11 +631,10 @@ public class ConfigTest extends TestCase
File bar = new File(foo, "bar");
expected.addComponent(new File(bar,"foobar.jar"));
assertEquals("Deep Classpath Section",expected,foocp);
-
+
File ext = new File(lib, "ext");
expected = new Classpath();
expected.addComponent(new File(ext,"custom-impl.jar"));
assertEquals("Single Classpath Section",expected,extcp);
-
}
}
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java
index 63643e806d..f3a8fee032 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java
@@ -5,27 +5,31 @@
// 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
+// 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.apache.org/licenses/LICENSE-2.0.txt
//
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.start;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class VersionTest extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class VersionTest
{
+ @Test
public void testDefaultVersion()
{
Version version = new Version();
-
assertEquals("Default version difference to 0.0.0",0,version.compare(new Version("0.0.0")));
}
-
+
+ @Test
public void testNewerVersion() {
assertIsNewer("0.0.0", "0.0.1");
assertIsNewer("0.1.0", "0.1.1");
@@ -33,6 +37,7 @@ public class VersionTest extends TestCase
// assertIsNewer("1.6.0_12", "1.6.0_16"); // JDK version spec?
}
+ @Test
public void testOlderVersion() {
assertIsOlder("0.0.1", "0.0.0");
assertIsOlder("0.1.1", "0.1.0");
@@ -43,7 +48,6 @@ public class VersionTest extends TestCase
{
Version vbase = new Version(basever);
Version vtest = new Version(testver);
-
assertTrue("Version [" + testver + "] should be older than [" + basever + "]",
vtest.compare(vbase) == -1);
}
@@ -52,7 +56,6 @@ public class VersionTest extends TestCase
{
Version vbase = new Version(basever);
Version vtest = new Version(testver);
-
assertTrue("Version [" + testver + "] should be newer than [" + basever + "]",
vtest.compare(vbase) == 1);
}
diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml
index 6a3f9c5aab..e8801c32a3 100644
--- a/jetty-util/pom.xml
+++ b/jetty-util/pom.xml
@@ -25,7 +25,7 @@
</goals>
<configuration>
<instructions>
- <Import-Package>org.slf4j;version="[1.5,1.6)";resolution:=optional,*</Import-Package>
+ <Import-Package>org.slf4j;version="[1.5,1.7)";resolution:=optional,*</Import-Package>
</instructions>
</configuration>
</execution>
@@ -60,18 +60,20 @@
</execution>
</executions>
</plugin>
- <!-- Always create the source bundle. the configuration is inherited by the parent pom. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.util.*</onlyAnalyze>
+ </configuration>
</plugin>
-
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/jetty-util/src/main/config/etc/jetty-logging.xml b/jetty-util/src/main/config/etc/jetty-logging.xml
index 09b590abe6..f6e47e6057 100644
--- a/jetty-util/src/main/config/etc/jetty-logging.xml
+++ b/jetty-util/src/main/config/etc/jetty-logging.xml
@@ -13,7 +13,7 @@
<New id="ServerLog" class="java.io.PrintStream">
<Arg>
<New class="org.eclipse.jetty.util.RolloverFileOutputStream">
- <Arg><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.stderrout.log</Arg>
+ <Arg><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.stderrout.log</Arg>
<Arg type="boolean">false</Arg>
<Arg type="int">90</Arg>
<Arg><Call class="java.util.TimeZone" name="getTimeZone"><Arg>GMT</Arg></Call></Arg>
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java
index 829b4ef938..aaba131ea3 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java
@@ -20,10 +20,8 @@ import java.util.Queue;
/* ------------------------------------------------------------ */
/** Queue backed by circular array.
*
- * This partial Queue implementation (also with {@link #pop()} for stack operation)
+ * This partial Queue implementation (also with {@link #remove()} for stack operation)
* is backed by a growable circular array.
- *
- *
*
* @param <E>
*/
@@ -214,7 +212,7 @@ public class ArrayQueue<E> extends AbstractList<E> implements Queue<E>
/* ------------------------------------------------------------ */
/**
* Get without synchronization or bounds checking.
- * @see get(int)
+ * @see #get(int)
*/
public E getUnsafe(int index)
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
index d433996e7c..ce23e549c8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
@@ -40,7 +40,8 @@ public class AttributesMap implements Attributes
{
_map=map;
}
-
+
+ /* ------------------------------------------------------------ */
public AttributesMap(AttributesMap map)
{
_map=new HashMap<String,Object>(map._map);
@@ -117,7 +118,13 @@ public class AttributesMap implements Attributes
{
_map.clear();
}
-
+
+ /* ------------------------------------------------------------ */
+ public int size()
+ {
+ return _map.size();
+ }
+
/* ------------------------------------------------------------ */
@Override
public String toString()
@@ -130,5 +137,16 @@ public class AttributesMap implements Attributes
{
return _map.keySet();
}
+
+ /* ------------------------------------------------------------ */
+ public void addAll(Attributes attributes)
+ {
+ Enumeration<String> e = attributes.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ String name=e.nextElement();
+ setAttribute(name,attributes.getAttribute(name));
+ }
+ }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/HostMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/HostMap.java
new file mode 100644
index 0000000000..768171561e
--- /dev/null
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/HostMap.java
@@ -0,0 +1,101 @@
+// ========================================================================
+// Copyright (c) 2010 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.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/* ------------------------------------------------------------ */
+/**
+ */
+public class HostMap<TYPE> extends HashMap<String, TYPE>
+{
+ /* --------------------------------------------------------------- */
+ /** Construct empty HostMap.
+ */
+ public HostMap()
+ {
+ super(11);
+ }
+
+ /* --------------------------------------------------------------- */
+ /** Construct empty HostMap.
+ *
+ * @param capacity initial capacity
+ */
+ public HostMap(int capacity)
+ {
+ super (capacity);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public TYPE put(String host, TYPE object)
+ throws IllegalArgumentException
+ {
+ return super.put(host, object);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see java.util.HashMap#get(java.lang.Object)
+ */
+ @Override
+ public TYPE get(Object key)
+ {
+ return super.get(key);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve a lazy list of map entries associated with specified
+ * hostname by taking into account the domain suffix matches.
+ *
+ * @param host hostname
+ * @return lazy list of map entries
+ */
+ public Object getLazyMatches(String host)
+ {
+ if (host == null)
+ return LazyList.getList(super.entrySet());
+
+ int idx = 0;
+ String domain = host.trim();
+ HashSet<String> domains = new HashSet<String>();
+ do {
+ domains.add(domain);
+ if ((idx = domain.indexOf('.')) > 0)
+ {
+ domain = domain.substring(idx+1);
+ }
+ } while (idx > 0);
+
+ Object entries = null;
+ for(Map.Entry<String, TYPE> entry: super.entrySet())
+ {
+ if (domains.contains(entry.getKey()))
+ {
+ entries = LazyList.add(entries,entry);
+ }
+ }
+
+ return entries;
+ }
+
+}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java
new file mode 100644
index 0000000000..dc9f82e687
--- /dev/null
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java
@@ -0,0 +1,358 @@
+// ========================================================================
+// Copyright (c) 2010 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.util;
+
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Internet address map to object
+ * <p>
+ * Internet addresses may be specified as absolute address or as a combination of
+ * four octet wildcard specifications (a.b.c.d) that are defined as follows.
+ * </p>
+ * <pre>
+ * nnn - an absolute value (0-255)
+ * mmm-nnn - an inclusive range of absolute values,
+ * with following shorthand notations:
+ * nnn- => nnn-255
+ * -nnn => 0-nnn
+ * - => 0-255
+ * a,b,... - a list of wildcard specifications
+ * </pre>
+ */
+public class IPAddressMap<TYPE> extends HashMap<String, TYPE>
+{
+ private final HashMap<String,IPAddrPattern> _patterns = new HashMap<String,IPAddrPattern>();
+
+ /* --------------------------------------------------------------- */
+ /** Construct empty IPAddressMap.
+ */
+ public IPAddressMap()
+ {
+ super(11);
+ }
+
+ /* --------------------------------------------------------------- */
+ /** Construct empty IPAddressMap.
+ *
+ * @param capacity initial capacity
+ */
+ public IPAddressMap(int capacity)
+ {
+ super (capacity);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Insert a new internet address into map
+ *
+ * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public TYPE put(String addrSpec, TYPE object)
+ throws IllegalArgumentException
+ {
+ if (addrSpec == null || addrSpec.trim().length() == 0)
+ throw new IllegalArgumentException("Invalid IP address pattern: "+addrSpec);
+
+ String spec = addrSpec.trim();
+ if (_patterns.get(spec) == null)
+ _patterns.put(spec,new IPAddrPattern(spec));
+
+ return super.put(spec, object);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the object mapped to the specified internet address literal
+ *
+ * @see java.util.HashMap#get(java.lang.Object)
+ */
+ @Override
+ public TYPE get(Object key)
+ {
+ return super.get(key);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the first object that is associated with the specified
+ * internet address by taking into account the wildcard specifications.
+ *
+ * @param addr internet address
+ * @return associated object
+ */
+ public TYPE match(String addr)
+ {
+ Map.Entry<String, TYPE> entry = getMatch(addr);
+ return entry==null ? null : entry.getValue();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve the first map entry that is associated with the specified
+ * internet address by taking into account the wildcard specifications.
+ *
+ * @param addr internet address
+ * @return map entry associated
+ */
+ public Map.Entry<String, TYPE> getMatch(String addr)
+ {
+ if (addr != null)
+ {
+ for(Map.Entry<String, TYPE> entry: super.entrySet())
+ {
+ if (_patterns.get(entry.getKey()).match(addr))
+ {
+ return entry;
+ }
+ }
+ }
+ return null;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Retrieve a lazy list of map entries associated with specified
+ * internet address by taking into account the wildcard specifications.
+ *
+ * @param addr internet address
+ * @return lazy list of map entries
+ */
+ public Object getLazyMatches(String addr)
+ {
+ if (addr == null)
+ return LazyList.getList(super.entrySet());
+
+ Object entries = null;
+ for(Map.Entry<String, TYPE> entry: super.entrySet())
+ {
+ if (_patterns.get(entry.getKey()).match(addr))
+ {
+ entries = LazyList.add(entries,entry);
+ }
+ }
+ return entries;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * IPAddrPattern
+ *
+ * Represents internet address wildcard.
+ * Matches the wildcard to provided internet address.
+ */
+ private static class IPAddrPattern
+ {
+ private final OctetPattern[] _octets = new OctetPattern[4];
+ /* ------------------------------------------------------------ */
+ /**
+ * Create new IPAddrPattern
+ *
+ * @param value internet address wildcard specification
+ * @throws IllegalArgumentException if wildcard specification is invalid
+ */
+ public IPAddrPattern(String value)
+ throws IllegalArgumentException
+ {
+ if (value == null || value.trim().length() == 0)
+ throw new IllegalArgumentException("Invalid IP address pattern: "+value);
+
+ try
+ {
+ StringTokenizer parts = new StringTokenizer(value, ".");
+
+ String part;
+ for (int idx=0; idx<4; idx++)
+ {
+ part = parts.hasMoreTokens() ? parts.nextToken().trim() : "0-255";
+
+ int len = part.length();
+ if (len == 0 && parts.hasMoreTokens())
+ throw new IllegalArgumentException("Invalid IP address pattern: "+value);
+
+ _octets[idx] = new OctetPattern(len==0 ? "0-255" : part);
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IllegalArgumentException("Invalid IP address pattern: "+value, ex);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Match the specified internet address against the wildcard
+ *
+ * @param value internet address
+ * @return true if specified internet address matches wildcard specification
+ *
+ * @throws IllegalArgumentException if specified internet address is invalid
+ */
+ public boolean match(String value)
+ throws IllegalArgumentException
+ {
+ if (value == null || value.trim().length() == 0)
+ throw new IllegalArgumentException("Invalid IP address: "+value);
+
+ try
+ {
+ StringTokenizer parts = new StringTokenizer(value, ".");
+
+ boolean result = true;
+ for (int idx=0; idx<4; idx++)
+ {
+ if (!parts.hasMoreTokens())
+ throw new IllegalArgumentException("Invalid IP address: "+value);
+
+ if (!(result &= _octets[idx].match(parts.nextToken())))
+ break;
+ }
+ return result;
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IllegalArgumentException("Invalid IP address: "+value, ex);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * OctetPattern
+ *
+ * Represents a single octet wildcard.
+ * Matches the wildcard to the specified octet value.
+ */
+ private static class OctetPattern extends BitSet
+ {
+ private final BitSet _mask = new BitSet(256);
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Create new OctetPattern
+ *
+ * @param octetSpec octet wildcard specification
+ * @throws IllegalArgumentException if wildcard specification is invalid
+ */
+ public OctetPattern(String octetSpec)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ if (octetSpec != null)
+ {
+ String spec = octetSpec.trim();
+ if(spec.length() == 0)
+ {
+ _mask.set(0,255);
+ }
+ else
+ {
+ StringTokenizer parts = new StringTokenizer(spec,",");
+ while (parts.hasMoreTokens())
+ {
+ String part = parts.nextToken().trim();
+ if (part.length() > 0)
+ {
+ if (part.indexOf('-') < 0)
+ {
+ Integer value = Integer.valueOf(part);
+ _mask.set(value);
+ }
+ else
+ {
+ int low = 0, high = 255;
+
+ String[] bounds = part.split("-",-2);
+ if (bounds.length != 2)
+ {
+ throw new IllegalArgumentException("Invalid octet spec: "+octetSpec);
+ }
+
+ if (bounds[0].length() > 0)
+ {
+ low = Integer.parseInt(bounds[0]);
+ }
+ if (bounds[1].length() > 0)
+ {
+ high = Integer.parseInt(bounds[1]);
+ }
+
+ if (low > high)
+ {
+ throw new IllegalArgumentException("Invalid octet spec: "+octetSpec);
+ }
+
+ _mask.set(low, high+1);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new IllegalArgumentException("Invalid octet spec: "+octetSpec, ex);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Match specified octet value against the wildcard
+ *
+ * @param value octet value
+ * @return true if specified octet value matches the wildcard
+ * @throws IllegalArgumentException if specified octet value is invalid
+ */
+ public boolean match(String value)
+ throws IllegalArgumentException
+ {
+ if (value == null || value.trim().length() == 0)
+ throw new IllegalArgumentException("Invalid octet: "+value);
+
+ try
+ {
+ int number = Integer.parseInt(value);
+ return match(number);
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new IllegalArgumentException("Invalid octet: "+value);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Match specified octet value against the wildcard
+ *
+ * @param number octet value
+ * @return true if specified octet value matches the wildcard
+ * @throws IllegalArgumentException if specified octet value is invalid
+ */
+ public boolean match(int number)
+ throws IllegalArgumentException
+ {
+ if (number < 0 || number > 255)
+ throw new IllegalArgumentException("Invalid octet: "+number);
+
+ return _mask.get(number);
+ }
+ }
+} \ No newline at end of file
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java b/jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java
index 6156b9df16..56d16275e6 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java
@@ -51,7 +51,6 @@ import java.util.ListIterator;
* An ArrayList of default size is used as the initial LazyList.
*
* @see java.util.List
- *
*/
public class LazyList
implements Cloneable, Serializable
@@ -283,7 +282,7 @@ public class LazyList
/** Convert a lazylist to an array
* @param list The list to convert
* @param clazz The class of the array, which may be a primitive type
- * @return
+ * @return array of the lazylist entries passed in
*/
@SuppressWarnings("unchecked")
public static Object toArray(Object list,Class<?> clazz)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java
index f464dc4c97..6eb82e4951 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java
@@ -283,7 +283,7 @@ public class MultiPartInputStream
*/
public MultiPartInputStream (InputStream in, String contentType, MultipartConfigElement config)
{
- _in = in;
+ _in = new BufferedInputStream(in);
_contentType = contentType;
_config = config;
if (_config == null)
@@ -463,11 +463,14 @@ public class MultiPartInputStream
// this is not a boundary
if(cr)
part.write(13);
+
if(lf)
- part.write(10);
+ part.write(10);
+
cr=lf=false;
if(b>0)
part.write(byteBoundary,0,b);
+
b=-1;
part.write(c);
}
@@ -477,8 +480,10 @@ public class MultiPartInputStream
{
if(cr)
part.write(13);
+
if(lf)
part.write(10);
+
cr=lf=false;
part.write(byteBoundary,0,b);
b=-1;
@@ -494,9 +499,11 @@ public class MultiPartInputStream
}
// handle CR LF
if(cr)
- part.write(13);
+ part.write(13);
+
if(lf)
part.write(10);
+
cr=(c==13);
lf=(c==10||state==10);
if(state==10)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/PatternMatcher.java b/jetty-util/src/main/java/org/eclipse/jetty/util/PatternMatcher.java
index 3d8522e451..d573906979 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/PatternMatcher.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/PatternMatcher.java
@@ -32,8 +32,8 @@ public abstract class PatternMatcher
* Will iterate over the jar names, matching
* all those starting with "aaa-" first, then "bbb-".
*
- * @param pattern
- * @param loader
+ * @param pattern the pattern
+ * @param uris the uris to test the pattern against
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
* @throws Exception
*/
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java b/jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java
index 90729a14f1..dfa66bf03e 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.util;
+import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -266,7 +267,7 @@ public class QuotedStringTokenizer
* @param s The string to quote.
* @return quoted string
*/
- public static String quote(String s, String delim)
+ public static String quoteIfNeeded(String s, String delim)
{
if (s==null)
return null;
@@ -309,162 +310,19 @@ public class QuotedStringTokenizer
}
-
/* ------------------------------------------------------------ */
- /** Quote a string into a StringBuffer.
+ /** Quote a string into an Appendable.
* The characters ", \, \n, \r, \t, \f and \b are escaped
- * @param buf The StringBuffer
+ * @param buf The Appendable
* @param s The String to quote.
*/
- public static void quote(StringBuffer buf, String s)
+ public static void quote(Appendable buf, String s)
{
- synchronized(buf)
+ try
{
buf.append('"');
-
- int i=0;
- loop:
- for (;i<s.length();i++)
- {
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- buf.append(s,0,i);
- buf.append("\\\"");
- break loop;
- case '\\':
- buf.append(s,0,i);
- buf.append("\\\\");
- break loop;
- case '\n':
- buf.append(s,0,i);
- buf.append("\\n");
- break loop;
- case '\r':
- buf.append(s,0,i);
- buf.append("\\r");
- break loop;
- case '\t':
- buf.append(s,0,i);
- buf.append("\\t");
- break loop;
- case '\f':
- buf.append(s,0,i);
- buf.append("\\f");
- break loop;
- case '\b':
- buf.append(s,0,i);
- buf.append("\\b");
- break loop;
-
- default:
- continue;
- }
- }
- if (i==s.length())
- buf.append(s);
- else
- {
- i++;
- for (;i<s.length();i++)
- {
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- buf.append("\\\"");
- continue;
- case '\\':
- buf.append("\\\\");
- continue;
- case '\n':
- buf.append("\\n");
- continue;
- case '\r':
- buf.append("\\r");
- continue;
- case '\t':
- buf.append("\\t");
- continue;
- case '\f':
- buf.append("\\f");
- continue;
- case '\b':
- buf.append("\\b");
- continue;
-
- default:
- buf.append(c);
- continue;
- }
- }
- }
-
- buf.append('"');
- }
-
-
-
- }
-
-
- /* ------------------------------------------------------------ */
- /** Quote a string into a StringBuffer.
- * The characters ", \, \n, \r, \t, \f and \b are escaped
- * @param buf The StringBuffer
- * @param s The String to quote.
- */
- public static void quote(StringBuilder buf, String s)
- {
- buf.append('"');
-
- int i=0;
- loop:
- for (;i<s.length();i++)
- {
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- buf.append(s,0,i);
- buf.append("\\\"");
- break loop;
- case '\\':
- buf.append(s,0,i);
- buf.append("\\\\");
- break loop;
- case '\n':
- buf.append(s,0,i);
- buf.append("\\n");
- break loop;
- case '\r':
- buf.append(s,0,i);
- buf.append("\\r");
- break loop;
- case '\t':
- buf.append(s,0,i);
- buf.append("\\t");
- break loop;
- case '\f':
- buf.append(s,0,i);
- buf.append("\\f");
- break loop;
- case '\b':
- buf.append(s,0,i);
- buf.append("\\b");
- break loop;
- default:
- continue;
- }
- }
- if (i==s.length())
- buf.append(s);
- else
- {
- i++;
- for (;i<s.length();i++)
+ for (int i=0;i<s.length();i++)
{
char c = s.charAt(i);
switch(c)
@@ -492,187 +350,60 @@ public class QuotedStringTokenizer
continue;
default:
- buf.append(c);
- continue;
- }
- }
- }
-
- buf.append('"');
- }
-
-
-
-
-
- /* ------------------------------------------------------------ */
- /** Quote a string into a StringBuffer.
- * The characters ", \, \n, \r, \t, \f, \b are escaped.
- * Quotes are forced if any escaped characters are present or there
- * is a ", ', space, +, =, ; or % character.
- *
- * @param buf The StringBuffer
- * @param s The String to quote.
- */
- public static void quoteIfNeeded(StringBuffer buf, String s)
- {
- synchronized(buf)
- {
- int e=-1;
-
- search: for (int i=0;i<s.length();i++)
- {
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- case '\\':
- case '\n':
- case '\r':
- case '\t':
- case '\f':
- case '\b':
- case '%':
- case '+':
- case ' ':
- case ';':
- case '=':
- e=i;
- buf.append('"');
- // TODO when 1.4 support is dropped: buf.append(s,0,e);
- for (int j=0;j<e;j++)
- buf.append(s.charAt(j));
- break search;
-
- default:
- continue;
- }
- }
-
- if (e<0)
- {
- buf.append(s);
- return;
- }
-
- for (int i=e;i<s.length();i++)
- {
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- buf.append("\\\"");
- continue;
- case '\\':
- buf.append("\\\\");
- continue;
- case '\n':
- buf.append("\\n");
- continue;
- case '\r':
- buf.append("\\r");
- continue;
- case '\t':
- buf.append("\\t");
- continue;
- case '\f':
- buf.append("\\f");
- continue;
- case '\b':
- buf.append("\\b");
- continue;
-
- default:
- buf.append(c);
+ if (c<0x10)
+ {
+ buf.append("\\u000");
+ buf.append(Integer.toString(c,16));
+ }
+ else if (c<=0x1f)
+ {
+ buf.append("\\u00");
+ buf.append(Integer.toString(c,16));
+ }
+ else
+ buf.append(c);
continue;
}
}
+
buf.append('"');
+ }
+ catch(IOException e)
+ {
+ throw new RuntimeException(e);
}
}
/* ------------------------------------------------------------ */
- /** Quote a string into a StringBuffer.
- * The characters ", \, \n, \r, \t, \f, \b are escaped.
- * Quotes are forced if any escaped characters are present or there
- * is a ", ', space, + or % character.
+ /** Quote a string into a StringBuffer only if needed.
+ * Quotes are forced if any delim characters are present.
*
- * @param buf The StringBuilder
+ * @param buf The StringBuffer
* @param s The String to quote.
+ * @param delim String of characters that must be quoted.
+ * @return true if quoted;
*/
- public static void quoteIfNeeded(StringBuilder buf, String s)
+ public static boolean quoteIfNeeded(Appendable buf, String s,String delim)
{
- int e=-1;
-
- search: for (int i=0;i<s.length();i++)
+ for (int i=0;i<s.length();i++)
{
char c = s.charAt(i);
- switch(c)
+ if (delim.indexOf(c)>=0)
{
- case '"':
- case '\\':
- case '\n':
- case '\r':
- case '\t':
- case '\f':
- case '\b':
- case '%':
- case '+':
- case ' ':
- case ';':
- case '=':
- e=i;
- buf.append('"');
- // TODO when 1.4 support is dropped: buf.append(s,0,e);
- for (int j=0;j<e;j++)
- buf.append(s.charAt(j));
- break search;
-
- default:
- continue;
+ quote(buf,s);
+ return true;
}
}
-
- if (e<0)
+
+ try
{
buf.append(s);
- return;
+ return false;
}
-
- for (int i=e;i<s.length();i++)
+ catch(IOException e)
{
- char c = s.charAt(i);
- switch(c)
- {
- case '"':
- buf.append("\\\"");
- continue;
- case '\\':
- buf.append("\\\\");
- continue;
- case '\n':
- buf.append("\\n");
- continue;
- case '\r':
- buf.append("\\r");
- continue;
- case '\t':
- buf.append("\\t");
- continue;
- case '\f':
- buf.append("\\f");
- continue;
- case '\b':
- buf.append("\\b");
- continue;
-
- default:
- buf.append(c);
- continue;
- }
+ throw new RuntimeException(e);
}
- buf.append('"');
-
}
/* ------------------------------------------------------------ */
@@ -720,6 +451,15 @@ public class QuotedStringTokenizer
case 'b':
b.append('\b');
break;
+ case '\\':
+ b.append('\\');
+ break;
+ case '/':
+ b.append('/');
+ break;
+ case '"':
+ b.append('"');
+ break;
case 'u':
b.append((char)(
(TypeUtil.convertHexDigit((byte)s.charAt(i++))<<24)+
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java
index 77dc44664e..0cacc83b11 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java
@@ -120,7 +120,7 @@ public class Scanner
/**
* Get the location of the directory to scan
- * @return
+ * @return the first directory (of {@link #getScanDirs()} being scanned)
* @deprecated use getScanDirs() instead
*/
@Deprecated
@@ -160,7 +160,7 @@ public class Scanner
/**
* Get any filter applied to files in the scan dir.
- * @return
+ * @return the filename filter
*/
public FilenameFilter getFilenameFilter ()
{
@@ -310,7 +310,6 @@ public class Scanner
/**
* Recursively scan all files in the designated directories.
- * @return Map of name of file to last modified time
*/
public synchronized void scanFiles ()
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java
index 5c508eb368..5c279c094c 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util;
@@ -25,20 +25,20 @@ import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
-/** TYPE Utilities.
+/**
+ * TYPE Utilities.
* Provides various static utiltiy methods for manipulating types and their
* string representations.
*
* @since Jetty 4.1
- *
*/
public class TypeUtil
{
public static int CR = '\015';
public static int LF = '\012';
-
+
/* ------------------------------------------------------------ */
- private static final HashMap name2Class=new HashMap();
+ private static final HashMap<String, Class> name2Class=new HashMap<String, Class>();
static
{
name2Class.put("boolean",java.lang.Boolean.TYPE);
@@ -50,7 +50,7 @@ public class TypeUtil
name2Class.put("long",java.lang.Long.TYPE);
name2Class.put("short",java.lang.Short.TYPE);
name2Class.put("void",java.lang.Void.TYPE);
-
+
name2Class.put("java.lang.Boolean.TYPE",java.lang.Boolean.TYPE);
name2Class.put("java.lang.Byte.TYPE",java.lang.Byte.TYPE);
name2Class.put("java.lang.Character.TYPE",java.lang.Character.TYPE);
@@ -84,9 +84,9 @@ public class TypeUtil
name2Class.put("String",java.lang.String.class);
name2Class.put("java.lang.String",java.lang.String.class);
}
-
+
/* ------------------------------------------------------------ */
- private static final HashMap class2Name=new HashMap();
+ private static final HashMap<Class, String> class2Name=new HashMap<Class, String>();
static
{
class2Name.put(java.lang.Boolean.TYPE,"boolean");
@@ -107,19 +107,19 @@ public class TypeUtil
class2Name.put(java.lang.Integer.class,"java.lang.Integer");
class2Name.put(java.lang.Long.class,"java.lang.Long");
class2Name.put(java.lang.Short.class,"java.lang.Short");
-
+
class2Name.put(null,"void");
class2Name.put(java.lang.String.class,"java.lang.String");
}
-
+
/* ------------------------------------------------------------ */
- private static final HashMap class2Value=new HashMap();
+ private static final HashMap<Class, Method> class2Value=new HashMap<Class, Method>();
static
{
try
{
Class[] s ={java.lang.String.class};
-
+
class2Value.put(java.lang.Boolean.TYPE,
java.lang.Boolean.class.getMethod("valueOf",s));
class2Value.put(java.lang.Byte.TYPE,
@@ -157,53 +157,15 @@ public class TypeUtil
}
/* ------------------------------------------------------------ */
- private static Class[] stringArg = { java.lang.String.class };
-
- /* ------------------------------------------------------------ */
- private static int intCacheSize = 600;
- private static Integer[] integerCache = new Integer[intCacheSize];
- private static String[] integerStrCache = new String[intCacheSize];
- private static Integer minusOne = new Integer(-1);
- private static int longCacheSize = 64;
- private static Long[] longCache = new Long[longCacheSize];
- private static Long minusOneL = new Long(-1);
-
- public static void setIntCacheSize(int size)
- {
- if (size > intCacheSize) {
- Integer[] intCache = new Integer[size];
- System.arraycopy(integerCache,0,intCache,0,intCacheSize);
-
- String [] strCache = new String[size];
- System.arraycopy(integerStrCache,0,strCache,0,intCacheSize);
-
- intCacheSize = size;
- integerCache = intCache;
- integerStrCache = strCache;
- }
- }
-
- public static void setLongCacheSize(int size)
- {
- if (size > longCacheSize) {
- Long[] lnCache = new Long[size];
- System.arraycopy(longCache,0,lnCache,0,longCacheSize);
-
- longCacheSize = size;
- longCache = lnCache;
- }
- }
-
- /* ------------------------------------------------------------ */
/** Class from a canonical name for a type.
* @param name A class or type name.
* @return A class , which may be a primitive TYPE field..
*/
public static Class fromName(String name)
{
- return (Class)name2Class.get(name);
+ return name2Class.get(name);
}
-
+
/* ------------------------------------------------------------ */
/** Canonical name for a type.
* @param type A class , which may be a primitive TYPE field.
@@ -211,9 +173,9 @@ public class TypeUtil
*/
public static String toName(Class type)
{
- return (String)class2Name.get(type);
+ return class2Name.get(type);
}
-
+
/* ------------------------------------------------------------ */
/** Convert String value to instance.
* @param type The class of the instance, which may be a primitive TYPE field.
@@ -226,17 +188,17 @@ public class TypeUtil
{
if (type.equals(java.lang.String.class))
return value;
-
- Method m = (Method)class2Value.get(type);
+
+ Method m = class2Value.get(type);
if (m!=null)
- return m.invoke(null,new Object[] {value});
+ return m.invoke(null, value);
if (type.equals(java.lang.Character.TYPE) ||
type.equals(java.lang.Character.class))
return new Character(value.charAt(0));
- Constructor c = type.getConstructor(stringArg);
- return c.newInstance(new Object[] {value});
+ Constructor c = type.getConstructor(java.lang.String.class);
+ return c.newInstance(value);
}
catch(NoSuchMethodException e)
{
@@ -258,7 +220,7 @@ public class TypeUtil
}
return null;
}
-
+
/* ------------------------------------------------------------ */
/** Convert String value to instance.
* @param type classname or type (eg int)
@@ -269,72 +231,6 @@ public class TypeUtil
{
return valueOf(fromName(type),value);
}
-
- /* ------------------------------------------------------------ */
- /** Convert int to Integer using cache.
- */
- public static Integer newInteger(int i)
- {
- if (i>=0 && i<intCacheSize)
- {
- if (integerCache[i]==null)
- integerCache[i]=new Integer(i);
- return integerCache[i];
- }
- else if (i==-1)
- return minusOne;
- return new Integer(i);
- }
-
- /* ------------------------------------------------------------ */
- /** Convert int to Integer using cache.
- */
- public static Long newLong(long i)
- {
- if (i>=0 && i<longCacheSize)
- {
- if (longCache[(int)i]==null)
- longCache[(int)i]=new Long(i);
- return longCache[(int)i];
- }
- else if (i==-1)
- return minusOneL;
- return new Long(i);
- }
-
-
- /* ------------------------------------------------------------ */
- /** Convert int to String using cache.
- */
- public static String toString(int i)
- {
- if (i>=0 && i<intCacheSize)
- {
- if (integerStrCache[i]==null)
- integerStrCache[i]=Integer.toString(i);
- return integerStrCache[i];
- }
- else if (i==-1)
- return "-1";
- return Integer.toString(i);
- }
-
- /* ------------------------------------------------------------ */
- /** Convert long to String using cache.
- */
- public static String toString(long i)
- {
- if (i>=0 && i<intCacheSize)
- {
- if (integerStrCache[(int)i]==null)
- integerStrCache[(int)i]=Long.toString(i);
- return integerStrCache[(int)i];
- }
- else if (i==-1)
- return "-1";
- return Long.toString(i);
- }
-
/* ------------------------------------------------------------ */
/** Parse an int from a substring.
@@ -343,7 +239,8 @@ public class TypeUtil
* @param offset Offset within string
* @param length Length of integer or -1 for remainder of string
* @param base base of the integer
- * @exception NumberFormatException
+ * @return the parsed integer
+ * @throws NumberFormatException if the string cannot be parsed
*/
public static int parseInt(String s, int offset, int length, int base)
throws NumberFormatException
@@ -356,7 +253,7 @@ public class TypeUtil
for (int i=0;i<length;i++)
{
char c=s.charAt(offset+i);
-
+
int digit=c-'0';
if (digit<0 || digit>=base || digit>=10)
{
@@ -378,7 +275,8 @@ public class TypeUtil
* @param offset Offset within string
* @param length Length of integer or -1 for remainder of string
* @param base base of the integer
- * @exception NumberFormatException
+ * @return the parsed integer
+ * @throws NumberFormatException if the array cannot be parsed into an integer
*/
public static int parseInt(byte[] b, int offset, int length, int base)
throws NumberFormatException
@@ -391,7 +289,7 @@ public class TypeUtil
for (int i=0;i<length;i++)
{
char c=(char)(0xff&b[offset+i]);
-
+
int digit=c-'0';
if (digit<0 || digit>=base || digit>=10)
{
@@ -419,9 +317,9 @@ public class TypeUtil
public static String toString(byte[] bytes, int base)
{
StringBuilder buf = new StringBuilder();
- for (int i=0;i<bytes.length;i++)
+ for (byte b : bytes)
{
- int bi=0xff&bytes[i];
+ int bi=0xff&b;
int c='0'+(bi/base)%base;
if (c>'9')
c= 'a'+(c-'0'-10);
@@ -435,7 +333,7 @@ public class TypeUtil
}
/* ------------------------------------------------------------ */
- /**
+ /**
* @param b An ASCII encoded character 0-9 a-f A-F
* @return The byte value of the character 0-16.
*/
@@ -448,41 +346,35 @@ public class TypeUtil
}
/* ------------------------------------------------------------ */
- public static void toHex(byte b,StringBuilder buf)
- {
- int bi=0xff&b;
- int c='0'+(bi/16)%16;
- if (c>'9')
- c= 'A'+(c-'0'-10);
- buf.append((char)c);
- c='0'+bi%16;
- if (c>'9')
- c= 'A'+(c-'0'-10);
- buf.append((char)c);
- }
-
- /* ------------------------------------------------------------ */
- public static String toHexString(byte[] b)
- {
- StringBuilder buf = new StringBuilder();
- for (int i=0;i<b.length;i++)
+ public static void toHex(byte b,Appendable buf)
+ {
+ try
{
- int bi=0xff&b[i];
+ int bi=0xff&b;
int c='0'+(bi/16)%16;
if (c>'9')
c= 'A'+(c-'0'-10);
buf.append((char)c);
c='0'+bi%16;
if (c>'9')
- c= 'a'+(c-'0'-10);
+ c= 'A'+(c-'0'-10);
buf.append((char)c);
}
- return buf.toString();
+ catch(IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public static String toHexString(byte[] b)
+ {
+ return toHexString(b, 0, b.length);
}
-
+
/* ------------------------------------------------------------ */
public static String toHexString(byte[] b,int offset,int length)
- {
+ {
StringBuilder buf = new StringBuilder();
for (int i=offset;i<offset+length;i++)
{
@@ -498,10 +390,10 @@ public class TypeUtil
}
return buf.toString();
}
-
+
/* ------------------------------------------------------------ */
public static byte[] fromHexString(String s)
- {
+ {
if (s.length()%2!=0)
throw new IllegalArgumentException(s);
byte[] array = new byte[s.length()/2];
@@ -509,10 +401,10 @@ public class TypeUtil
{
int b = Integer.parseInt(s.substring(i*2,i*2+2),16);
array[i]=(byte)(0xff&b);
- }
+ }
return array;
}
-
+
public static void dump(Class c)
{
@@ -529,31 +421,31 @@ public class TypeUtil
cl = cl.getParent();
}
}
-
+
/* ------------------------------------------------------------ */
public static byte[] readLine(InputStream in) throws IOException
{
byte[] buf = new byte[256];
-
+
int i=0;
int loops=0;
int ch=0;
-
+
while (true)
{
ch=in.read();
if (ch<0)
break;
loops++;
-
+
// skip a leading LF's
if (loops==1 && ch==LF)
continue;
-
+
if (ch==CR || ch==LF)
break;
-
+
if (i>=buf.length)
{
byte[] old_buf=buf;
@@ -562,10 +454,10 @@ public class TypeUtil
}
buf[i++]=(byte)ch;
}
-
+
if (ch==-1 && i==0)
return null;
-
+
// skip a trailing LF if it exists
if (ch==CR && in.available()>=1 && in.markSupported())
{
@@ -578,10 +470,10 @@ public class TypeUtil
byte[] old_buf=buf;
buf=new byte[i];
System.arraycopy(old_buf, 0, buf, 0, i);
-
+
return buf;
}
-
+
public static URL jarFor(String className)
{
try
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java
index 37f8486b33..6b5729363c 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java
@@ -39,7 +39,6 @@ import java.util.Map;
* get operations are not protected from concurrent updates.
*
* @see java.net.URLEncoder
- *
*/
public class UrlEncoded extends MultiMap
{
@@ -239,7 +238,10 @@ public class UrlEncoded extends MultiMap
/* -------------------------------------------------------------- */
/** Decoded parameters to Map.
- * @param data the byte[] containing the encoded parameters
+ * @param raw the byte[] containing the encoded parameters
+ * @param offset the offset within raw to decode from
+ * @param length the length of the section to decode
+ * @param map the {@link MultiMap} to populate
*/
public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map)
{
@@ -248,7 +250,11 @@ public class UrlEncoded extends MultiMap
/* -------------------------------------------------------------- */
/** Decoded parameters to Map.
- * @param data the byte[] containing the encoded parameters
+ * @param raw the byte[] containing the encoded parameters
+ * @param offset the offset within raw to decode from
+ * @param length the length of the section to decode
+ * @param map the {@link MultiMap} to populate
+ * @param buffer the buffer to decode into
*/
public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map,Utf8StringBuilder buffer)
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java
index 6cb9a8d40a..7c9a15371c 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.ajax;
@@ -31,10 +31,14 @@ import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
-/** JSON Parser and Generator.
- *
- * <p>This class provides some static methods to convert POJOs to and from JSON
- * notation. The mapping from JSON to java is:<pre>
+/**
+ * JSON Parser and Generator.
+ *
+ * <p>
+ * This class provides some static methods to convert POJOs to and from JSON
+ * notation. The mapping from JSON to java is:
+ *
+ * <pre>
* object ==> Map
* array ==> Object[]
* number ==> Double or Long
@@ -42,8 +46,12 @@ import org.eclipse.jetty.util.log.Log;
* null ==> null
* bool ==> Boolean
* </pre>
- * </p><p>
- * The java to JSON mapping is:<pre>
+ *
+ * </p>
+ * <p>
+ * The java to JSON mapping is:
+ *
+ * <pre>
* String --> string
* Number --> number
* Map --> object
@@ -53,36 +61,43 @@ import org.eclipse.jetty.util.log.Log;
* Boolean--> boolean
* Object --> string (dubious!)
* </pre>
- * </p><p>
- * The interface {@link JSON.Convertible} may be implemented by classes that wish to externalize and
- * initialize specific fields to and from JSON objects. Only directed acyclic graphs of objects are supported.
+ *
* </p>
* <p>
- * The interface {@link JSON.Generator} may be implemented by classes that know how to render themselves as JSON and
- * the {@link #toString(Object)} method will use {@link JSON.Generator#addJSON(StringBuffer)} to generate the JSON.
- * The class {@link JSON.Literal} may be used to hold pre-gnerated JSON object.
+ * The interface {@link JSON.Convertible} may be implemented by classes that
+ * wish to externalize and initialize specific fields to and from JSON objects.
+ * Only directed acyclic graphs of objects are supported.
+ * </p>
* <p>
- * The interface {@link Convertor} may be implemented to provide static convertors for objects that may be registered
- * with {@link #registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor)}. These convertors are looked up by class, interface and
- * super class by {@link #getConvertor(Class)}.
+ * The interface {@link JSON.Generator} may be implemented by classes that know
+ * how to render themselves as JSON and the {@link #toString(Object)} method
+ * will use {@link JSON.Generator#addJSON(Appendable)} to generate the JSON.
+ * The class {@link JSON.Literal} may be used to hold pre-generated JSON object.
+ * <p>
+ * The interface {@link JSON.Convertor} may be implemented to provide static
+ * convertors for objects that may be registered with
+ * {@link #registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor)}
+ * . These convertors are looked up by class, interface and super class by
+ * {@link #getConvertor(Class)}.
* </p>
- *
+ *
*
*/
public class JSON
{
public final static JSON DEFAULT = new JSON();
- private Map<String,Convertor> _convertors=new ConcurrentHashMap<String,Convertor>();
- private int _stringBufferSize=256;
-
+ private Map<String, Convertor> _convertors = new ConcurrentHashMap<String, Convertor>();
+ private int _stringBufferSize = 1024;
+
public JSON()
{
}
-
+
/* ------------------------------------------------------------ */
/**
- * @return the initial stringBuffer size to use when creating JSON strings (default 256)
+ * @return the initial stringBuffer size to use when creating JSON strings
+ * (default 1024)
*/
public int getStringBufferSize()
{
@@ -91,18 +106,23 @@ public class JSON
/* ------------------------------------------------------------ */
/**
- * @param stringBufferSize the initial stringBuffer size to use when creating JSON strings (default 256)
+ * @param stringBufferSize
+ * the initial stringBuffer size to use when creating JSON
+ * strings (default 1024)
*/
public void setStringBufferSize(int stringBufferSize)
{
- _stringBufferSize=stringBufferSize;
+ _stringBufferSize = stringBufferSize;
}
/* ------------------------------------------------------------ */
/**
* Register a {@link Convertor} for a class or interface.
- * @param forClass The class or interface that the convertor applies to
- * @param convertor the convertor
+ *
+ * @param forClass
+ * The class or interface that the convertor applies to
+ * @param convertor
+ * the convertor
*/
public static void registerConvertor(Class forClass, Convertor convertor)
{
@@ -124,39 +144,31 @@ public class JSON
/* ------------------------------------------------------------ */
public static String toString(Object object)
{
- StringBuffer buffer=new StringBuffer(DEFAULT.getStringBufferSize());
- synchronized (buffer)
- {
- DEFAULT.append(buffer,object);
- return buffer.toString();
- }
+ StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+ DEFAULT.append(buffer,object);
+ return buffer.toString();
}
/* ------------------------------------------------------------ */
public static String toString(Map object)
{
- StringBuffer buffer=new StringBuffer(DEFAULT.getStringBufferSize());
- synchronized (buffer)
- {
- DEFAULT.appendMap(buffer,object);
- return buffer.toString();
- }
+ StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+ DEFAULT.appendMap(buffer,object);
+ return buffer.toString();
}
/* ------------------------------------------------------------ */
public static String toString(Object[] array)
{
- StringBuffer buffer=new StringBuffer(DEFAULT.getStringBufferSize());
- synchronized (buffer)
- {
- DEFAULT.appendArray(buffer,array);
- return buffer.toString();
- }
+ StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+ DEFAULT.appendArray(buffer,array);
+ return buffer.toString();
}
/* ------------------------------------------------------------ */
/**
- * @param s String containing JSON object or array.
+ * @param s
+ * String containing JSON object or array.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
public static Object parse(String s)
@@ -166,8 +178,10 @@ public class JSON
/* ------------------------------------------------------------ */
/**
- * @param s String containing JSON object or array.
- * @param stripOuterComment If true, an outer comment around the JSON is ignored.
+ * @param s
+ * String containing JSON object or array.
+ * @param stripOuterComment
+ * If true, an outer comment around the JSON is ignored.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
public static Object parse(String s, boolean stripOuterComment)
@@ -177,7 +191,8 @@ public class JSON
/* ------------------------------------------------------------ */
/**
- * @param in Reader containing JSON object or array.
+ * @param in
+ * Reader containing JSON object or array.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
public static Object parse(Reader in) throws IOException
@@ -187,8 +202,10 @@ public class JSON
/* ------------------------------------------------------------ */
/**
- * @param s Stream containing JSON object or array.
- * @param stripOuterComment If true, an outer comment around the JSON is ignored.
+ * @param in
+ * Reader containing JSON object or array.
+ * @param stripOuterComment
+ * If true, an outer comment around the JSON is ignored.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
public static Object parse(Reader in, boolean stripOuterComment) throws IOException
@@ -199,7 +216,8 @@ public class JSON
/* ------------------------------------------------------------ */
/**
* @deprecated use {@link #parse(Reader)}
- * @param in Reader containing JSON object or array.
+ * @param in
+ * Reader containing JSON object or array.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
@Deprecated
@@ -211,8 +229,10 @@ public class JSON
/* ------------------------------------------------------------ */
/**
* @deprecated use {@link #parse(Reader, boolean)}
- * @param s Stream containing JSON object or array.
- * @param stripOuterComment If true, an outer comment around the JSON is ignored.
+ * @param in
+ * Stream containing JSON object or array.
+ * @param stripOuterComment
+ * If true, an outer comment around the JSON is ignored.
* @return A Map, Object array or primitive array parsed from the JSON.
*/
@Deprecated
@@ -222,23 +242,26 @@ public class JSON
}
/* ------------------------------------------------------------ */
- /** Convert Object to JSON
- * @param object The object to convert
+ /**
+ * Convert Object to JSON
+ *
+ * @param object
+ * The object to convert
* @return The JSON String
*/
public String toJSON(Object object)
{
- StringBuffer buffer=new StringBuffer(getStringBufferSize());
- synchronized (buffer)
- {
- append(buffer,object);
- return buffer.toString();
- }
+ StringBuilder buffer = new StringBuilder(getStringBufferSize());
+ append(buffer,object);
+ return buffer.toString();
}
/* ------------------------------------------------------------ */
- /** Convert JSON to Object
- * @param json The json to convert
+ /**
+ * Convert JSON to Object
+ *
+ * @param json
+ * The json to convert
* @return The object
*/
public Object fromJSON(String json)
@@ -247,53 +270,90 @@ public class JSON
return parse(source);
}
+ @Deprecated
+ public void append(StringBuffer buffer, Object object)
+ {
+ append((Appendable)buffer,object);
+ }
+
/* ------------------------------------------------------------ */
/**
* Append object as JSON to string buffer.
+ *
* @param buffer
+ * the buffer to append to
* @param object
+ * the object to append
*/
- public void append(StringBuffer buffer, Object object)
+ public void append(Appendable buffer, Object object)
{
- if (object==null)
- buffer.append("null");
- else if (object instanceof Convertible)
- appendJSON(buffer,(Convertible)object);
- else if (object instanceof Generator)
- appendJSON(buffer,(Generator)object);
- else if (object instanceof Map)
- appendMap(buffer,(Map)object);
- else if (object instanceof Collection)
- appendArray(buffer,(Collection)object);
- else if (object.getClass().isArray())
- appendArray(buffer,object);
- else if (object instanceof Number)
- appendNumber(buffer,(Number)object);
- else if (object instanceof Boolean)
- appendBoolean(buffer,(Boolean)object);
- else if (object instanceof Character)
- appendString(buffer,object.toString());
- else if (object instanceof String)
- appendString(buffer,(String)object);
- else
+ try
{
- Convertor convertor=getConvertor(object.getClass());
- if (convertor!=null)
- appendJSON(buffer,convertor,object);
- else
+ if (object == null)
+ buffer.append("null");
+ else if (object instanceof Convertible)
+ appendJSON(buffer,(Convertible)object);
+ else if (object instanceof Generator)
+ appendJSON(buffer,(Generator)object);
+ else if (object instanceof Map)
+ appendMap(buffer,(Map)object);
+ else if (object instanceof Collection)
+ appendArray(buffer,(Collection)object);
+ else if (object.getClass().isArray())
+ appendArray(buffer,object);
+ else if (object instanceof Number)
+ appendNumber(buffer,(Number)object);
+ else if (object instanceof Boolean)
+ appendBoolean(buffer,(Boolean)object);
+ else if (object instanceof Character)
appendString(buffer,object.toString());
+ else if (object instanceof String)
+ appendString(buffer,(String)object);
+ else
+ {
+ Convertor convertor = getConvertor(object.getClass());
+ if (convertor != null)
+ appendJSON(buffer,convertor,object);
+ else
+ appendString(buffer,object.toString());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
}
}
/* ------------------------------------------------------------ */
+ @Deprecated
public void appendNull(StringBuffer buffer)
{
- buffer.append("null");
+ appendNull((Appendable)buffer);
}
/* ------------------------------------------------------------ */
+ public void appendNull(Appendable buffer)
+ {
+ try
+ {
+ buffer.append("null");
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ @Deprecated
public void appendJSON(final StringBuffer buffer, final Convertor convertor, final Object object)
{
+ appendJSON((Appendable)buffer,convertor,object);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void appendJSON(final Appendable buffer, final Convertor convertor, final Object object)
+ {
appendJSON(buffer,new Convertible()
{
public void fromJSON(Map object)
@@ -308,183 +368,206 @@ public class JSON
}
/* ------------------------------------------------------------ */
+ @Deprecated
public void appendJSON(final StringBuffer buffer, Convertible converter)
{
- final char[] c=
- { '{' };
- converter.toJSON(new Output()
- {
- public void add(Object obj)
- {
- if (c[0]==0)
- throw new IllegalStateException();
- append(buffer,obj);
- c[0]=0;
- }
+ appendJSON((StringBuffer)buffer,converter);
+ }
- public void addClass(Class type)
- {
- if (c[0]==0)
- throw new IllegalStateException();
- buffer.append(c);
- buffer.append("\"class\":");
- append(buffer,type.getName());
- c[0]=',';
- }
+ /* ------------------------------------------------------------ */
+ public void appendJSON(final Appendable buffer, Convertible converter)
+ {
+ ConvertableOutput out=new ConvertableOutput(buffer);
+ converter.toJSON(out);
+ out.complete();
+ }
- public void add(String name, Object value)
- {
- if (c[0]==0)
- throw new IllegalStateException();
- buffer.append(c);
- QuotedStringTokenizer.quote(buffer,name);
- buffer.append(':');
- append(buffer,value);
- c[0]=',';
- }
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void appendJSON(StringBuffer buffer, Generator generator)
+ {
+ generator.addJSON(buffer);
+ }
- public void add(String name, double value)
- {
- if (c[0]==0)
- throw new IllegalStateException();
- buffer.append(c);
- QuotedStringTokenizer.quote(buffer,name);
- buffer.append(':');
- appendNumber(buffer,new Double(value));
- c[0]=',';
- }
+ /* ------------------------------------------------------------ */
+ public void appendJSON(Appendable buffer, Generator generator)
+ {
+ generator.addJSON(buffer);
+ }
- public void add(String name, long value)
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void appendMap(StringBuffer buffer, Map<?,?> map)
+ {
+ appendMap((Appendable)buffer,map);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void appendMap(Appendable buffer, Map<?,?> map)
+ {
+ try
+ {
+ if (map == null)
{
- if (c[0]==0)
- throw new IllegalStateException();
- buffer.append(c);
- QuotedStringTokenizer.quote(buffer,name);
- buffer.append(':');
- appendNumber(buffer,TypeUtil.newLong(value));
- c[0]=',';
+ appendNull(buffer);
+ return;
}
- public void add(String name, boolean value)
+ buffer.append('{');
+ Iterator<?> iter = map.entrySet().iterator();
+ while (iter.hasNext())
{
- if (c[0]==0)
- throw new IllegalStateException();
- buffer.append(c);
- QuotedStringTokenizer.quote(buffer,name);
+ Map.Entry<?,?> entry = (Map.Entry<?,?>)iter.next();
+ QuotedStringTokenizer.quote(buffer,entry.getKey().toString());
buffer.append(':');
- appendBoolean(buffer,value?Boolean.TRUE:Boolean.FALSE);
- c[0]=',';
+ append(buffer,entry.getValue());
+ if (iter.hasNext())
+ buffer.append(',');
}
- });
- if (c[0]=='{')
- buffer.append("{}");
- else if (c[0]!=0)
- buffer.append("}");
+ buffer.append('}');
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
}
/* ------------------------------------------------------------ */
- public void appendJSON(StringBuffer buffer, Generator generator)
+ @Deprecated
+ public void appendArray(StringBuffer buffer, Collection collection)
{
- generator.addJSON(buffer);
+ appendArray((Appendable)buffer,collection);
}
/* ------------------------------------------------------------ */
- public void appendMap(StringBuffer buffer, Map object)
+ public void appendArray(Appendable buffer, Collection collection)
{
- if (object==null)
+ try
{
- appendNull(buffer);
- return;
- }
+ if (collection == null)
+ {
+ appendNull(buffer);
+ return;
+ }
+
+ buffer.append('[');
+ Iterator iter = collection.iterator();
+ boolean first = true;
+ while (iter.hasNext())
+ {
+ if (!first)
+ buffer.append(',');
- buffer.append('{');
- Iterator iter=object.entrySet().iterator();
- while (iter.hasNext())
+ first = false;
+ append(buffer,iter.next());
+ }
+
+ buffer.append(']');
+ }
+ catch (IOException e)
{
- Map.Entry entry=(Map.Entry)iter.next();
- QuotedStringTokenizer.quote(buffer,entry.getKey().toString());
- buffer.append(':');
- append(buffer,entry.getValue());
- if (iter.hasNext())
- buffer.append(',');
+ throw new RuntimeException(e);
}
+ }
- buffer.append('}');
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void appendArray(StringBuffer buffer, Object array)
+ {
+ appendArray((Appendable)buffer,array);
}
/* ------------------------------------------------------------ */
- public void appendArray(StringBuffer buffer, Collection collection)
+ public void appendArray(Appendable buffer, Object array)
{
- if (collection==null)
+ try
{
- appendNull(buffer);
- return;
- }
+ if (array == null)
+ {
+ appendNull(buffer);
+ return;
+ }
- buffer.append('[');
- Iterator iter=collection.iterator();
- boolean first=true;
- while (iter.hasNext())
- {
- if (!first)
- buffer.append(',');
+ buffer.append('[');
+ int length = Array.getLength(array);
- first=false;
- append(buffer,iter.next());
+ for (int i = 0; i < length; i++)
+ {
+ if (i != 0)
+ buffer.append(',');
+ append(buffer,Array.get(array,i));
+ }
+
+ buffer.append(']');
}
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
- buffer.append(']');
+ /* ------------------------------------------------------------ */
+ @Deprecated
+ public void appendBoolean(StringBuffer buffer, Boolean b)
+ {
+ appendBoolean((Appendable)buffer,b);
}
/* ------------------------------------------------------------ */
- public void appendArray(StringBuffer buffer, Object array)
+ public void appendBoolean(Appendable buffer, Boolean b)
{
- if (array==null)
+ try
{
- appendNull(buffer);
- return;
+ if (b == null)
+ {
+ appendNull(buffer);
+ return;
+ }
+ buffer.append(b.booleanValue()?"true":"false");
}
-
- buffer.append('[');
- int length=Array.getLength(array);
-
- for (int i=0; i<length; i++)
+ catch (IOException e)
{
- if (i!=0)
- buffer.append(',');
- append(buffer,Array.get(array,i));
+ throw new RuntimeException(e);
}
-
- buffer.append(']');
}
/* ------------------------------------------------------------ */
- public void appendBoolean(StringBuffer buffer, Boolean b)
+ @Deprecated
+ public void appendNumber(StringBuffer buffer, Number number)
{
- if (b==null)
- {
- appendNull(buffer);
- return;
- }
- buffer.append(b.booleanValue()?"true":"false");
+ appendNumber((Appendable)buffer,number);
}
/* ------------------------------------------------------------ */
- public void appendNumber(StringBuffer buffer, Number number)
+ public void appendNumber(Appendable buffer, Number number)
{
- if (number==null)
+ try
{
- appendNull(buffer);
- return;
+ if (number == null)
+ {
+ appendNull(buffer);
+ return;
+ }
+ buffer.append(String.valueOf(number));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
}
- buffer.append(number);
}
/* ------------------------------------------------------------ */
+ @Deprecated
public void appendString(StringBuffer buffer, String string)
{
- if (string==null)
+ appendString((Appendable)buffer,string);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void appendString(Appendable buffer, String string)
+ {
+ if (string == null)
{
appendNull(buffer);
return;
@@ -492,19 +575,19 @@ public class JSON
QuotedStringTokenizer.quote(buffer,string);
}
-
+
// Parsing utilities
/* ------------------------------------------------------------ */
- protected String toString(char[] buffer,int offset,int length)
+ protected String toString(char[] buffer, int offset, int length)
{
return new String(buffer,offset,length);
}
/* ------------------------------------------------------------ */
- protected Map<String,Object> newMap()
+ protected Map<String, Object> newMap()
{
- return new HashMap<String,Object>();
+ return new HashMap<String, Object>();
}
/* ------------------------------------------------------------ */
@@ -526,13 +609,13 @@ public class JSON
}
/* ------------------------------------------------------------ */
- protected Object convertTo(Class type,Map map)
+ protected Object convertTo(Class type, Map map)
{
- if (type!=null&&Convertible.class.isAssignableFrom(type))
+ if (type != null && Convertible.class.isAssignableFrom(type))
{
try
{
- Convertible conv=(Convertible)type.newInstance();
+ Convertible conv = (Convertible)type.newInstance();
conv.fromJSON(map);
return conv;
}
@@ -542,20 +625,22 @@ public class JSON
}
}
- Convertor convertor=getConvertor(type);
- if (convertor!=null)
+ Convertor convertor = getConvertor(type);
+ if (convertor != null)
{
return convertor.fromJSON(map);
}
return map;
}
-
/* ------------------------------------------------------------ */
/**
* Register a {@link Convertor} for a class or interface.
- * @param forClass The class or interface that the convertor applies to
- * @param convertor the convertor
+ *
+ * @param forClass
+ * The class or interface that the convertor applies to
+ * @param convertor
+ * the convertor
*/
public void addConvertor(Class forClass, Convertor convertor)
{
@@ -566,28 +651,31 @@ public class JSON
/**
* Lookup a convertor for a class.
* <p>
- * If no match is found for the class, then the interfaces for the class are tried. If still no
- * match is found, then the super class and it's interfaces are tried recursively.
- * @param forClass The class
- * @return a {@link Convertor} or null if none were found.
+ * If no match is found for the class, then the interfaces for the class are
+ * tried. If still no match is found, then the super class and it's
+ * interfaces are tried recursively.
+ *
+ * @param forClass
+ * The class
+ * @return a {@link JSON.Convertor} or null if none were found.
*/
protected Convertor getConvertor(Class forClass)
{
- Class cls=forClass;
- Convertor convertor=_convertors.get(cls.getName());
- if (convertor==null && this!=DEFAULT)
- convertor=DEFAULT.getConvertor(cls);
-
- while (convertor==null&&cls!=null&&cls!=Object.class)
+ Class cls = forClass;
+ Convertor convertor = _convertors.get(cls.getName());
+ if (convertor == null && this != DEFAULT)
+ convertor = DEFAULT.getConvertor(cls);
+
+ while (convertor == null && cls != null && cls != Object.class)
{
- Class[] ifs=cls.getInterfaces();
- int i=0;
- while (convertor==null&&ifs!=null&&i<ifs.length)
- convertor=_convertors.get(ifs[i++].getName());
- if (convertor==null)
+ Class[] ifs = cls.getInterfaces();
+ int i = 0;
+ while (convertor == null && ifs != null && i < ifs.length)
+ convertor = _convertors.get(ifs[i++].getName());
+ if (convertor == null)
{
- cls=cls.getSuperclass();
- convertor=_convertors.get(cls.getName());
+ cls = cls.getSuperclass();
+ convertor = _convertors.get(cls.getName());
}
}
return convertor;
@@ -595,92 +683,96 @@ public class JSON
/* ------------------------------------------------------------ */
/**
- * Register a {@link Convertor} for a named class or interface.
- * @param name name of a class or an interface that the convertor applies to
- * @param convertor the convertor
+ * Register a {@link JSON.Convertor} for a named class or interface.
+ *
+ * @param name
+ * name of a class or an interface that the convertor applies to
+ * @param convertor
+ * the convertor
*/
public void addConvertorFor(String name, Convertor convertor)
{
_convertors.put(name,convertor);
- }
+ }
/* ------------------------------------------------------------ */
/**
* Lookup a convertor for a named class.
*
- * @param name name of the class
- * @return a {@link Convertor} or null if none were found.
+ * @param name
+ * name of the class
+ * @return a {@link JSON.Convertor} or null if none were found.
*/
public Convertor getConvertorFor(String name)
{
- String clsName=name;
- Convertor convertor=_convertors.get(clsName);
- if (convertor==null && this!=DEFAULT)
- convertor=DEFAULT.getConvertorFor(clsName);
+ String clsName = name;
+ Convertor convertor = _convertors.get(clsName);
+ if (convertor == null && this != DEFAULT)
+ convertor = DEFAULT.getConvertorFor(clsName);
return convertor;
- }
+ }
/* ------------------------------------------------------------ */
public Object parse(Source source, boolean stripOuterComment)
{
- int comment_state=0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
+ int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
if (!stripOuterComment)
return parse(source);
-
- int strip_state=1; // 0=no strip, 1=wait for /*, 2= wait for */
- Object o=null;
+ int strip_state = 1; // 0=no strip, 1=wait for /*, 2= wait for */
+
+ Object o = null;
while (source.hasNext())
{
- char c=source.peek();
+ char c = source.peek();
// handle // or /* comment
- if (comment_state==1)
+ if (comment_state == 1)
{
switch (c)
{
case '/':
- comment_state=-1;
+ comment_state = -1;
break;
case '*':
- comment_state=2;
- if (strip_state==1)
+ comment_state = 2;
+ if (strip_state == 1)
{
- comment_state=0;
- strip_state=2;
+ comment_state = 0;
+ strip_state = 2;
}
}
}
// handle /* */ comment
- else if (comment_state>1)
+ else if (comment_state > 1)
{
switch (c)
{
case '*':
- comment_state=3;
+ comment_state = 3;
break;
case '/':
- if (comment_state==3)
+ if (comment_state == 3)
{
- comment_state=0;
- if (strip_state==2)
+ comment_state = 0;
+ if (strip_state == 2)
return o;
}
else
- comment_state=2;
+ comment_state = 2;
break;
default:
- comment_state=2;
+ comment_state = 2;
}
}
// handle // comment
- else if (comment_state<0)
+ else if (comment_state < 0)
{
switch (c)
{
case '\r':
case '\n':
- comment_state=0;
+ comment_state = 0;
default:
break;
}
@@ -690,72 +782,71 @@ public class JSON
{
if (!Character.isWhitespace(c))
{
- if (c=='/')
- comment_state=1;
- else if (c=='*')
- comment_state=3;
- else if (o==null)
+ if (c == '/')
+ comment_state = 1;
+ else if (c == '*')
+ comment_state = 3;
+ else if (o == null)
{
- o=parse(source);
+ o = parse(source);
continue;
}
}
}
-
+
source.next();
}
return o;
}
-
/* ------------------------------------------------------------ */
public Object parse(Source source)
{
- int comment_state=0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
+ int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
while (source.hasNext())
{
- char c=source.peek();
+ char c = source.peek();
// handle // or /* comment
- if (comment_state==1)
+ if (comment_state == 1)
{
switch (c)
{
case '/':
- comment_state=-1;
+ comment_state = -1;
break;
case '*':
- comment_state=2;
+ comment_state = 2;
}
}
// handle /* */ comment
- else if (comment_state>1)
+ else if (comment_state > 1)
{
switch (c)
{
case '*':
- comment_state=3;
+ comment_state = 3;
break;
case '/':
- if (comment_state==3)
- comment_state=0;
+ if (comment_state == 3)
+ comment_state = 0;
else
- comment_state=2;
+ comment_state = 2;
break;
default:
- comment_state=2;
+ comment_state = 2;
}
}
// handle // comment
- else if (comment_state<0)
+ else if (comment_state < 0)
{
switch (c)
{
case '\r':
case '\n':
- comment_state=0;
+ comment_state = 0;
break;
default:
break;
@@ -790,9 +881,9 @@ public class JSON
case 'N':
complete("NaN",source);
return null;
-
+
case '/':
- comment_state=1;
+ comment_state = 1;
break;
default:
@@ -800,7 +891,7 @@ public class JSON
return parseNumber(source);
else if (Character.isWhitespace(c))
break;
- return handleUnknown(source, c);
+ return handleUnknown(source,c);
}
}
source.next();
@@ -812,47 +903,47 @@ public class JSON
/* ------------------------------------------------------------ */
protected Object handleUnknown(Source source, char c)
{
- throw new IllegalStateException("unknown char '"+c+"'("+(int)c+") in "+source);
+ throw new IllegalStateException("unknown char '" + c + "'(" + (int)c + ") in " + source);
}
/* ------------------------------------------------------------ */
protected Object parseObject(Source source)
{
- if (source.next()!='{')
+ if (source.next() != '{')
throw new IllegalStateException();
- Map<String,Object> map=newMap();
+ Map<String, Object> map = newMap();
- char next=seekTo("\"}",source);
+ char next = seekTo("\"}",source);
while (source.hasNext())
{
- if (next=='}')
+ if (next == '}')
{
source.next();
break;
}
- String name=parseString(source);
+ String name = parseString(source);
seekTo(':',source);
source.next();
- Object value=contextFor(name).parse(source);
+ Object value = contextFor(name).parse(source);
map.put(name,value);
seekTo(",}",source);
- next=source.next();
- if (next=='}')
+ next = source.next();
+ if (next == '}')
break;
else
- next=seekTo("\"}",source);
+ next = seekTo("\"}",source);
}
- String classname=(String)map.get("class");
- if (classname!=null)
+ String classname = (String)map.get("class");
+ if (classname != null)
{
try
{
- Class c=Loader.loadClass(JSON.class,classname);
+ Class c = Loader.loadClass(JSON.class,classname);
return convertTo(c,map);
}
catch (ClassNotFoundException e)
@@ -862,26 +953,26 @@ public class JSON
}
return map;
}
-
+
/* ------------------------------------------------------------ */
protected Object parseArray(Source source)
{
- if (source.next()!='[')
+ if (source.next() != '[')
throw new IllegalStateException();
- int size=0;
- ArrayList list=null;
- Object item=null;
- boolean coma=true;
+ int size = 0;
+ ArrayList list = null;
+ Object item = null;
+ boolean coma = true;
while (source.hasNext())
{
- char c=source.peek();
+ char c = source.peek();
switch (c)
{
case ']':
source.next();
- switch(size)
+ switch (size)
{
case 0:
return newArray(0);
@@ -896,7 +987,7 @@ public class JSON
case ',':
if (coma)
throw new IllegalStateException();
- coma=true;
+ coma = true;
source.next();
break;
@@ -905,22 +996,22 @@ public class JSON
source.next();
else
{
- coma=false;
- if (size++==0)
- item=contextForArray().parse(source);
- else if (list==null)
+ coma = false;
+ if (size++ == 0)
+ item = contextForArray().parse(source);
+ else if (list == null)
{
- list=new ArrayList();
+ list = new ArrayList();
list.add(item);
- item=contextForArray().parse(source);
+ item = contextForArray().parse(source);
list.add(item);
- item=null;
+ item = null;
}
else
{
- item=contextForArray().parse(source);
+ item = contextForArray().parse(source);
list.add(item);
- item=null;
+ item = null;
}
}
}
@@ -929,169 +1020,160 @@ public class JSON
throw new IllegalStateException("unexpected end of array");
}
-
/* ------------------------------------------------------------ */
protected String parseString(Source source)
{
- if (source.next()!='"')
+ if (source.next() != '"')
throw new IllegalStateException();
- boolean escape=false;
+ boolean escape = false;
+
+ StringBuilder b = null;
+ final char[] scratch = source.scratchBuffer();
- StringBuffer b=null;
- final char[] scratch=source.scratchBuffer();
-
- if (scratch!=null)
+ if (scratch != null)
{
- int i=0;
+ int i = 0;
while (source.hasNext())
{
- if(i>=scratch.length)
+ if (i >= scratch.length)
{
// we have filled the scratch buffer, so we must
// use the StringBuffer for a large string
- b=new StringBuffer(scratch.length*2);
+ b = new StringBuilder(scratch.length * 2);
b.append(scratch,0,i);
break;
}
- char c=source.next();
+ char c = source.next();
if (escape)
{
- escape=false;
+ escape = false;
switch (c)
{
case '"':
- scratch[i++]='"';
+ scratch[i++] = '"';
break;
case '\\':
- scratch[i++]='\\';
+ scratch[i++] = '\\';
break;
case '/':
- scratch[i++]='/';
+ scratch[i++] = '/';
break;
case 'b':
- scratch[i++]='\b';
+ scratch[i++] = '\b';
break;
case 'f':
- scratch[i++]='\f';
+ scratch[i++] = '\f';
break;
case 'n':
- scratch[i++]='\n';
+ scratch[i++] = '\n';
break;
case 'r':
- scratch[i++]='\r';
+ scratch[i++] = '\r';
break;
case 't':
- scratch[i++]='\t';
+ scratch[i++] = '\t';
break;
case 'u':
- char uc=(char)((TypeUtil.convertHexDigit((byte)source.next())<<12)+
- (TypeUtil.convertHexDigit((byte)source.next())<<8)+
- (TypeUtil.convertHexDigit((byte)source.next())<<4)+
- (TypeUtil.convertHexDigit((byte)source.next())));
- scratch[i++]=uc;
+ char uc = (char)((TypeUtil.convertHexDigit((byte)source.next()) << 12) + (TypeUtil.convertHexDigit((byte)source.next()) << 8)
+ + (TypeUtil.convertHexDigit((byte)source.next()) << 4) + (TypeUtil.convertHexDigit((byte)source.next())));
+ scratch[i++] = uc;
break;
default:
- scratch[i++]=c;
+ scratch[i++] = c;
}
}
- else if (c=='\\')
+ else if (c == '\\')
{
- escape=true;
+ escape = true;
continue;
}
- else if (c=='\"')
+ else if (c == '\"')
{
// Return string that fits within scratch buffer
return toString(scratch,0,i);
}
else
- scratch[i++]=c;
+ scratch[i++] = c;
}
-
+
// Missing end quote, but return string anyway ?
- if (b==null)
+ if (b == null)
return toString(scratch,0,i);
}
else
- b=new StringBuffer(getStringBufferSize());
-
-
+ b = new StringBuilder(getStringBufferSize());
+
// parse large string into string buffer
- synchronized (b)
+ final StringBuilder builder=b;
+ while (source.hasNext())
{
- while (source.hasNext())
- {
- char c=source.next();
+ char c = source.next();
- if (escape)
- {
- escape=false;
- switch (c)
- {
- case '"':
- b.append('"');
- break;
- case '\\':
- b.append('\\');
- break;
- case '/':
- b.append('/');
- break;
- case 'b':
- b.append('\b');
- break;
- case 'f':
- b.append('\f');
- break;
- case 'n':
- b.append('\n');
- break;
- case 'r':
- b.append('\r');
- break;
- case 't':
- b.append('\t');
- break;
- case 'u':
- char uc=(char)((TypeUtil.convertHexDigit((byte)source.next())<<12)+
- (TypeUtil.convertHexDigit((byte)source.next())<<8)+
- (TypeUtil.convertHexDigit((byte)source.next())<<4)+
- (TypeUtil.convertHexDigit((byte)source.next())));
- b.append(uc);
- break;
- default:
- b.append(c);
- }
- }
- else if (c=='\\')
+ if (escape)
+ {
+ escape = false;
+ switch (c)
{
- escape=true;
- continue;
+ case '"':
+ builder.append('"');
+ break;
+ case '\\':
+ builder.append('\\');
+ break;
+ case '/':
+ builder.append('/');
+ break;
+ case 'b':
+ builder.append('\b');
+ break;
+ case 'f':
+ builder.append('\f');
+ break;
+ case 'n':
+ builder.append('\n');
+ break;
+ case 'r':
+ builder.append('\r');
+ break;
+ case 't':
+ builder.append('\t');
+ break;
+ case 'u':
+ char uc = (char)((TypeUtil.convertHexDigit((byte)source.next()) << 12) + (TypeUtil.convertHexDigit((byte)source.next()) << 8)
+ + (TypeUtil.convertHexDigit((byte)source.next()) << 4) + (TypeUtil.convertHexDigit((byte)source.next())));
+ builder.append(uc);
+ break;
+ default:
+ builder.append(c);
}
- else if (c=='\"')
- break;
- else
- b.append(c);
}
-
- return b.toString();
+ else if (c == '\\')
+ {
+ escape = true;
+ continue;
+ }
+ else if (c == '\"')
+ break;
+ else
+ builder.append(c);
}
+ return builder.toString();
}
/* ------------------------------------------------------------ */
public Number parseNumber(Source source)
{
- boolean minus=false;
- long number=0;
- StringBuilder buffer=null;
+ boolean minus = false;
+ long number = 0;
+ StringBuilder buffer = null;
longLoop: while (source.hasNext())
{
- char c=source.peek();
+ char c = source.peek();
switch (c)
{
case '0':
@@ -1104,68 +1186,66 @@ public class JSON
case '7':
case '8':
case '9':
- number=number*10+(c-'0');
+ number = number * 10 + (c - '0');
source.next();
break;
case '-':
case '+':
- if (number!=0)
+ if (number != 0)
throw new IllegalStateException("bad number");
- minus=true;
+ minus = true;
source.next();
break;
case '.':
case 'e':
case 'E':
- buffer=new StringBuilder(16);
- if(minus)
+ buffer = new StringBuilder(16);
+ if (minus)
buffer.append('-');
buffer.append(number);
buffer.append(c);
source.next();
break longLoop;
-
default:
break longLoop;
}
}
- if (buffer==null)
- return TypeUtil.newLong(minus?-1*number:number);
-
+ if (buffer == null)
+ return minus ? -1 * number : number;
- doubleLoop: while (source.hasNext())
+ doubleLoop: while (source.hasNext())
+ {
+ char c = source.peek();
+ switch (c)
{
- char c=source.peek();
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- case '.':
- case '+':
- case 'e':
- case 'E':
- buffer.append(c);
- source.next();
- break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '.':
+ case '+':
+ case 'e':
+ case 'E':
+ buffer.append(c);
+ source.next();
+ break;
- default:
- break doubleLoop;
- }
+ default:
+ break doubleLoop;
}
- return new Double(buffer.toString());
+ }
+ return new Double(buffer.toString());
}
@@ -1174,16 +1254,16 @@ public class JSON
{
while (source.hasNext())
{
- char c=source.peek();
- if (c==seek)
+ char c = source.peek();
+ if (c == seek)
return;
if (!Character.isWhitespace(c))
- throw new IllegalStateException("Unexpected '"+c+" while seeking '"+seek+"'");
+ throw new IllegalStateException("Unexpected '" + c + " while seeking '" + seek + "'");
source.next();
}
- throw new IllegalStateException("Expected '"+seek+"'");
+ throw new IllegalStateException("Expected '" + seek + "'");
}
/* ------------------------------------------------------------ */
@@ -1191,35 +1271,157 @@ public class JSON
{
while (source.hasNext())
{
- char c=source.peek();
- if (seek.indexOf(c)>=0)
+ char c = source.peek();
+ if (seek.indexOf(c) >= 0)
{
return c;
}
if (!Character.isWhitespace(c))
- throw new IllegalStateException("Unexpected '"+c+"' while seeking one of '"+seek+"'");
+ throw new IllegalStateException("Unexpected '" + c + "' while seeking one of '" + seek + "'");
source.next();
}
- throw new IllegalStateException("Expected one of '"+seek+"'");
+ throw new IllegalStateException("Expected one of '" + seek + "'");
}
/* ------------------------------------------------------------ */
protected static void complete(String seek, Source source)
{
- int i=0;
- while (source.hasNext()&&i<seek.length())
+ int i = 0;
+ while (source.hasNext() && i < seek.length())
{
- char c=source.next();
- if (c!=seek.charAt(i++))
- throw new IllegalStateException("Unexpected '"+c+" while seeking \""+seek+"\"");
+ char c = source.next();
+ if (c != seek.charAt(i++))
+ throw new IllegalStateException("Unexpected '" + c + " while seeking \"" + seek + "\"");
}
- if (i<seek.length())
- throw new IllegalStateException("Expected \""+seek+"\"");
+ if (i < seek.length())
+ throw new IllegalStateException("Expected \"" + seek + "\"");
}
+ private final class ConvertableOutput implements Output
+ {
+ private final Appendable _buffer;
+ char c = '{';
+
+ private ConvertableOutput(Appendable buffer)
+ {
+ _buffer = buffer;
+ }
+
+ public void complete()
+ {
+ try
+ {
+ if (c == '{')
+ _buffer.append("{}");
+ else if (c != 0)
+ _buffer.append("}");
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void add(Object obj)
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ append(_buffer,obj);
+ c = 0;
+ }
+
+ public void addClass(Class type)
+ {
+ try
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ _buffer.append(c);
+ _buffer.append("\"class\":");
+ append(_buffer,type.getName());
+ c = ',';
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void add(String name, Object value)
+ {
+ try
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ _buffer.append(c);
+ QuotedStringTokenizer.quote(_buffer,name);
+ _buffer.append(':');
+ append(_buffer,value);
+ c = ',';
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void add(String name, double value)
+ {
+ try
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ _buffer.append(c);
+ QuotedStringTokenizer.quote(_buffer,name);
+ _buffer.append(':');
+ appendNumber(_buffer,new Double(value));
+ c = ',';
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void add(String name, long value)
+ {
+ try
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ _buffer.append(c);
+ QuotedStringTokenizer.quote(_buffer,name);
+ _buffer.append(':');
+ appendNumber(_buffer, value);
+ c = ',';
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void add(String name, boolean value)
+ {
+ try
+ {
+ if (c == 0)
+ throw new IllegalStateException();
+ _buffer.append(c);
+ QuotedStringTokenizer.quote(_buffer,name);
+ _buffer.append(':');
+ appendBoolean(_buffer,value?Boolean.TRUE:Boolean.FALSE);
+ c = ',';
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
/* ------------------------------------------------------------ */
public interface Source
@@ -1229,7 +1431,7 @@ public class JSON
char next();
char peek();
-
+
char[] scratchBuffer();
}
@@ -1242,14 +1444,14 @@ public class JSON
public StringSource(String s)
{
- string=s;
+ string = s;
}
public boolean hasNext()
{
- if (index<string.length())
+ if (index < string.length())
return true;
- scratch=null;
+ scratch = null;
return false;
}
@@ -1262,17 +1464,17 @@ public class JSON
{
return string.charAt(index);
}
-
+
@Override
public String toString()
{
- return string.substring(0,index)+"|||"+string.substring(index);
+ return string.substring(0,index) + "|||" + string.substring(index);
}
public char[] scratchBuffer()
{
- if (scratch==null)
- scratch=new char[string.length()];
+ if (scratch == null)
+ scratch = new char[string.length()];
return scratch;
}
}
@@ -1281,26 +1483,26 @@ public class JSON
public static class ReaderSource implements Source
{
private Reader _reader;
- private int _next=-1;
+ private int _next = -1;
private char[] scratch;
public ReaderSource(Reader r)
{
- _reader=r;
+ _reader = r;
}
-
+
public void setReader(Reader reader)
{
- _reader=reader;
- _next=-1;
+ _reader = reader;
+ _next = -1;
}
public boolean hasNext()
{
getNext();
- if (_next<0)
+ if (_next < 0)
{
- scratch=null;
+ scratch = null;
return false;
}
return true;
@@ -1309,8 +1511,8 @@ public class JSON
public char next()
{
getNext();
- char c=(char)_next;
- _next=-1;
+ char c = (char)_next;
+ _next = -1;
return c;
}
@@ -1322,11 +1524,11 @@ public class JSON
private void getNext()
{
- if (_next<0)
+ if (_next < 0)
{
try
{
- _next=_reader.read();
+ _next = _reader.read();
}
catch (IOException e)
{
@@ -1337,15 +1539,15 @@ public class JSON
public char[] scratchBuffer()
{
- if (scratch==null)
- scratch=new char[1024];
+ if (scratch == null)
+ scratch = new char[1024];
return scratch;
}
}
/* ------------------------------------------------------------ */
- /**
+ /**
* JSON Output class for use by {@link Convertible}.
*/
public interface Output
@@ -1365,16 +1567,16 @@ public class JSON
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
- /** JSON Convertible object.
- * Object can implement this interface in a similar way to the
- * {@link Externalizable} interface is used to allow classes to
+ /**
+ * JSON Convertible object. Object can implement this interface in a similar
+ * way to the {@link Externalizable} interface is used to allow classes to
* provide their own serialization mechanism.
* <p>
- * A JSON.Convertible object may be written to a JSONObject
- * or initialized from a Map of field names to values.
+ * A JSON.Convertible object may be written to a JSONObject or initialized
+ * from a Map of field names to values.
* <p>
- * If the JSON is to be convertible back to an Object, then
- * the method {@link Output#addClass(Class)} must be called from within toJSON()
+ * If the JSON is to be convertible back to an Object, then the method
+ * {@link Output#addClass(Class)} must be called from within toJSON()
*
*/
public interface Convertible
@@ -1385,13 +1587,16 @@ public class JSON
}
/* ------------------------------------------------------------ */
- /** Static JSON Convertor.
+ /**
+ * Static JSON Convertor.
* <p>
- * may be implemented to provide static convertors for objects that may be registered
- * with {@link JSON#registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor).
- * These convertors are looked up by class, interface and
- * super class by {@link JSON#getConvertor(Class)}. Convertors should be used when the
- * classes to be converted cannot implement {@link Convertible} or {@link Generator}.
+ * may be implemented to provide static convertors for objects that may be
+ * registered with
+ * {@link JSON#registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor)}
+ * . These convertors are looked up by class, interface and super class by
+ * {@link JSON#getConvertor(Class)}. Convertors should be used when the
+ * classes to be converted cannot implement {@link Convertible} or
+ * {@link Generator}.
*/
public interface Convertor
{
@@ -1401,34 +1606,39 @@ public class JSON
}
/* ------------------------------------------------------------ */
- /** JSON Generator.
- * A class that can add it's JSON representation directly to a StringBuffer.
- * This is useful for object instances that are frequently converted and wish to
- * avoid multiple Conversions
+ /**
+ * JSON Generator. A class that can add it's JSON representation directly to
+ * a StringBuffer. This is useful for object instances that are frequently
+ * converted and wish to avoid multiple Conversions
*/
public interface Generator
{
- public void addJSON(StringBuffer buffer);
+ public void addJSON(Appendable buffer);
}
/* ------------------------------------------------------------ */
- /** A Literal JSON generator
- * A utility instance of {@link JSON.Generator} that holds a pre-generated string on JSON text.
+ /**
+ * A Literal JSON generator A utility instance of {@link JSON.Generator}
+ * that holds a pre-generated string on JSON text.
*/
public static class Literal implements Generator
{
private String _json;
/* ------------------------------------------------------------ */
- /** Construct a literal JSON instance for use by {@link JSON#toString(Object)}.
- * If {@link Log#isDebugEnabled()} is true, the JSON will be parsed to check validity
- * @param json A literal JSON string.
+ /**
+ * Construct a literal JSON instance for use by
+ * {@link JSON#toString(Object)}. If {@link Log#isDebugEnabled()} is
+ * true, the JSON will be parsed to check validity
+ *
+ * @param json
+ * A literal JSON string.
*/
public Literal(String json)
{
if (Log.isDebugEnabled())
parse(json);
- _json=json;
+ _json = json;
}
@Override
@@ -1437,9 +1647,16 @@ public class JSON
return _json;
}
- public void addJSON(StringBuffer buffer)
+ public void addJSON(Appendable buffer)
{
- buffer.append(_json);
+ try
+ {
+ buffer.append(_json);
+ }
+ catch(IOException e)
+ {
+ throw new RuntimeException(e);
+ }
}
}
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java
index dd657bb3cb..d9d21cbce1 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java
@@ -211,5 +211,12 @@ public abstract class AbstractLifeCycle implements LifeCycle
}
}
-
+ public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
+ {
+ public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
+ public void lifeCycleStarted(LifeCycle event) {}
+ public void lifeCycleStarting(LifeCycle event) {}
+ public void lifeCycleStopped(LifeCycle event) {}
+ public void lifeCycleStopping(LifeCycle event) {}
+ }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java
index eb2a13ef30..29681f30d6 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java
@@ -34,9 +34,6 @@ import org.eclipse.jetty.util.log.Log;
* this.bars=bars;
* }
* </pre>
- *
- *
- *
*/
public class Container
{
@@ -73,7 +70,7 @@ public class Container
* @param oldChild The previous value of the child. If this is non null and differs from <code>child</code>, then a remove event is generated.
* @param child The current child. If this is non null and differs from <code>oldChild</code>, then an add event is generated.
* @param relationship The name of the relationship
- * @param addRemoveBean If true add/remove is called for the new/old children as well as the relationships
+ * @param addRemove If true add/remove is called for the new/old children as well as the relationships
*/
public synchronized void update(Object parent, Object oldChild, final Object child, String relationship,boolean addRemove)
{
@@ -112,7 +109,7 @@ public class Container
* This array is modified and children that remain in the new children array are nulled out of the old children array.
* @param children The current array of children. An add event is generated for any child in this array but not in the <code>oldChildren</code> array.
* @param relationship The name of the relationship
- * @param addRemoveBean If true add/remove is called for the new/old children as well as the relationships
+ * @param addRemove If true add/remove is called for the new/old children as well as the relationships
*/
public synchronized void update(Object parent, Object[] oldChildren, final Object[] children, String relationship, boolean addRemove)
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java
index 99f6edf7ca..19ecf11039 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java
@@ -22,12 +22,12 @@ import java.util.logging.Level;
* <p>
* Implementation of Jetty {@link Logger} based on {@link java.util.logging.Logger}.
* </p>
- *
+ *
* <p>
* Honors the standard jetty system property <code>"org.eclipse.jetty.util.log.DEBUG"</code> to set logger into debug
* mode (defaults to false, set to "true" to enable)
* </p>
- *
+ *
* <p>
* You can also set the logger level using <a href="http://java.sun.com/j2se/1.5.0/docs/guide/logging/overview.html">
* standard java.util.logging configuration</a> against the name <code>"org.eclipse.jetty.util.log"</code>.
@@ -46,44 +46,42 @@ public class JavaUtilLog implements Logger
{
_logger = java.util.logging.Logger.getLogger(name);
if (Boolean.getBoolean("org.eclipse.jetty.util.log.DEBUG"))
- {
_logger.setLevel(Level.FINE);
- }
}
-
+
public String getName()
{
return _logger.getName();
}
- public void debug(String msg)
+ public void warn(String msg, Object... args)
{
- _logger.log(Level.FINE,msg);
+ _logger.log(Level.WARNING, format(msg, args));
}
- public void debug(String msg, Throwable th)
+ public void warn(Throwable thrown)
{
- _logger.log(Level.FINE,msg,th);
+ warn("", thrown);
}
- public void debug(String msg, Object arg0, Object arg1)
+ public void warn(String msg, Throwable thrown)
{
- _logger.log(Level.FINE,format(msg,arg0,arg1));
+ _logger.log(Level.WARNING, msg, thrown);
}
- public Logger getLogger(String name)
+ public void info(String msg, Object... args)
{
- return new JavaUtilLog(name);
+ _logger.log(Level.INFO, format(msg, args));
}
- public void info(String msg)
+ public void info(Throwable thrown)
{
- _logger.log(Level.INFO,msg);
+ info("", thrown);
}
- public void info(String msg, Object arg0, Object arg1)
+ public void info(String msg, Throwable thrown)
{
- _logger.log(Level.INFO,format(msg,arg0,arg1));
+ _logger.log(Level.INFO, msg, thrown);
}
public boolean isDebugEnabled()
@@ -96,30 +94,50 @@ public class JavaUtilLog implements Logger
_logger.setLevel(Level.FINE);
}
- public void warn(String msg)
+ public void debug(String msg, Object... args)
{
- _logger.log(Level.WARNING,msg);
+ _logger.log(Level.FINE, format(msg, args));
}
- public void warn(String msg, Object arg0, Object arg1)
+ public void debug(Throwable thrown)
{
- _logger.log(Level.WARNING,format(msg,arg0,arg1));
+ debug("", thrown);
}
- public void warn(String msg, Throwable th)
+ public void debug(String msg, Throwable thrown)
{
- _logger.log(Level.WARNING,msg,th);
+ _logger.log(Level.FINE, msg, thrown);
}
- private String format(String msg, Object arg0, Object arg1)
+ public Logger getLogger(String name)
{
- int i0 = msg.indexOf("{}");
- int i1 = i0 < 0?-1:msg.indexOf("{}",i0 + 2);
+ return new JavaUtilLog(name);
+ }
- if (arg1 != null && i1 >= 0)
- msg = msg.substring(0,i1) + arg1 + msg.substring(i1 + 2);
- if (arg0 != null && i0 >= 0)
- msg = msg.substring(0,i0) + arg0 + msg.substring(i0 + 2);
- return msg;
+ private String format(String msg, Object... args)
+ {
+ msg = String.valueOf(msg); // Avoids NPE
+ String braces = "{}";
+ StringBuilder builder = new StringBuilder();
+ int start = 0;
+ for (Object arg : args)
+ {
+ int bracesIndex = msg.indexOf(braces, start);
+ if (bracesIndex < 0)
+ {
+ builder.append(msg.substring(start));
+ builder.append(" ");
+ builder.append(arg);
+ start = msg.length();
+ }
+ else
+ {
+ builder.append(msg.substring(start, bracesIndex));
+ builder.append(String.valueOf(arg));
+ start = bracesIndex + braces.length();
+ }
+ }
+ builder.append(msg.substring(start));
+ return builder.toString();
}
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
index 775fcd54a1..2adca11192 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
@@ -4,25 +4,24 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.log;
+
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.jetty.util.Loader;
-
-
-/*-----------------------------------------------------------------------*/
-/** Logging.
- * This class provides a static logging interface. If an instance of the
+/**
+ * Logging.
+ * This class provides a static logging interface. If an instance of the
* org.slf4j.Logger class is found on the classpath, the static log methods
* are directed to a slf4j logger for "org.eclipse.log". Otherwise the logs
* are directed to stderr.
@@ -30,62 +29,55 @@ import org.eclipse.jetty.util.Loader;
* The "org.eclipse.jetty.util.log.class" system property can be used
* to select a specific logging implementation.
* <p>
- * If the system property org.eclipse.jetty.util.log.IGNORED is set,
+ * If the system property org.eclipse.jetty.util.log.IGNORED is set,
* then ignored exceptions are logged in detail.
- *
+ *
* @see StdErrLog
* @see Slf4jLog
*/
-public class Log
-{
- private static final String[] __nestedEx =
- {"getTargetException","getTargetError","getException","getRootCause"};
- /*-------------------------------------------------------------------*/
- private static final Class[] __noArgs=new Class[0];
+public class Log
+{
public final static String EXCEPTION= "EXCEPTION ";
public final static String IGNORED= "IGNORED";
- public final static String IGNORED_FMT= "IGNORED: {}";
- public final static String NOT_IMPLEMENTED= "NOT IMPLEMENTED ";
-
+
public static String __logClass;
public static boolean __ignored;
-
+
static
{
- AccessController.doPrivileged(new PrivilegedAction<Boolean>()
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
{
- public Boolean run()
- {
- __logClass = System.getProperty("org.eclipse.jetty.util.log.class","org.eclipse.jetty.util.log.Slf4jLog");
- __ignored = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.IGNORED","false"));
- return true;
- }
- });
+ __logClass = System.getProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.Slf4jLog");
+ __ignored = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.IGNORED", "false"));
+ return null;
+ }
+ });
}
-
+
private static Logger __log;
- private static boolean _initialized;
-
+ private static boolean __initialized;
+
public static boolean initialized()
{
- if (__log!=null)
+ if (__log != null)
return true;
-
+
synchronized (Log.class)
{
- if (_initialized)
- return __log!=null;
- _initialized=true;
+ if (__initialized)
+ return __log != null;
+ __initialized = true;
}
-
- Class log_class=null;
+
try
{
- log_class=Loader.loadClass(Log.class, __logClass);
- if (__log==null || !__log.getClass().equals(log_class))
+ Class log_class = Loader.loadClass(Log.class, __logClass);
+ if (__log == null || !__log.getClass().equals(log_class))
{
- __log=(Logger) log_class.newInstance();
- __log.info("Logging to {} via {}",__log,log_class.getName());
+ __log = (Logger)log_class.newInstance();
+ __log.debug("Logging to {} via {}", __log, log_class.getName());
}
}
catch(NoClassDefFoundError e)
@@ -97,34 +89,34 @@ public class Log
initStandardLogging(e);
}
- return __log!=null;
+ return __log != null;
}
- private static void initStandardLogging(Throwable e)
+ private static void initStandardLogging(Throwable e)
{
Class log_class;
if(e != null && __ignored)
e.printStackTrace();
- if (__log==null)
+ if (__log == null)
{
- log_class= StdErrLog.class;
- __log=new StdErrLog();
- __log.info("Logging to {} via {}",__log,log_class.getName());
+ log_class = StdErrLog.class;
+ __log = new StdErrLog();
+ __log.debug("Logging to {} via {}", __log, log_class.getName());
}
}
public static void setLog(Logger log)
{
- Log.__log=log;
+ Log.__log = log;
}
-
+
public static Logger getLog()
{
initialized();
return __log;
}
-
+
/**
* Set Log to parent Logger.
* <p>
@@ -132,12 +124,12 @@ public class Log
* call {@link #getLogger(String)} on it and construct a {@link LoggerLog} instance
* as this Log's Logger, so that logging is delegated to the parent Log.
* <p>
- * This should be used if a webapp is using Log, but wishes the logging to be
+ * This should be used if a webapp is using Log, but wishes the logging to be
* directed to the containers log.
* <p>
* If there is not parent Log, then this call is equivalent to<pre>
* Log.setLog(Log.getLogger(name));
- * </pre>
+ * </pre>
* @param name Logger name
*/
public static void setLogToParent(String name)
@@ -148,161 +140,137 @@ public class Log
try
{
Class<?> uberlog = loader.getParent().loadClass("org.eclipse.jetty.util.log.Log");
- Method getLogger=uberlog.getMethod("getLogger",new Class[]{String.class});
+ Method getLogger = uberlog.getMethod("getLogger", new Class[]{String.class});
Object logger = getLogger.invoke(null,name);
setLog(new LoggerLog(logger));
- return;
}
catch (Exception e)
{
e.printStackTrace();
- }
+ }
+ }
+ else
+ {
+ setLog(getLogger(name));
}
-
- setLog(getLogger(name));
}
-
+
public static void debug(Throwable th)
- {
+ {
if (!isDebugEnabled())
return;
- __log.debug(EXCEPTION,th);
- unwind(th);
+ __log.debug(EXCEPTION, th);
}
public static void debug(String msg)
{
if (!initialized())
return;
-
- __log.debug(msg,null,null);
+ __log.debug(msg);
}
-
- public static void debug(String msg,Object arg)
+
+ public static void debug(String msg, Object arg)
{
if (!initialized())
return;
- __log.debug(msg,arg,null);
+ __log.debug(msg, arg);
}
-
- public static void debug(String msg,Object arg0, Object arg1)
+
+ public static void debug(String msg, Object arg0, Object arg1)
{
if (!initialized())
return;
- __log.debug(msg,arg0,arg1);
+ __log.debug(msg, arg0, arg1);
}
-
- /* ------------------------------------------------------------ */
+
/**
* Ignore an exception unless trace is enabled.
* This works around the problem that log4j does not support the trace level.
+ * @param thrown the Throwable to ignore
*/
- public static void ignore(Throwable th)
+ public static void ignore(Throwable thrown)
{
if (!initialized())
return;
if (__ignored)
{
- __log.warn(IGNORED,th);
- unwind(th);
+ __log.warn(IGNORED, thrown);
}
}
-
+
public static void info(String msg)
{
if (!initialized())
return;
- __log.info(msg,null,null);
+ __log.info(msg);
}
-
- public static void info(String msg,Object arg)
+
+ public static void info(String msg, Object arg)
{
if (!initialized())
return;
- __log.info(msg,arg,null);
+ __log.info(msg, arg);
}
-
- public static void info(String msg,Object arg0, Object arg1)
+
+ public static void info(String msg, Object arg0, Object arg1)
{
if (!initialized())
return;
- __log.info(msg,arg0,arg1);
+ __log.info(msg, arg0, arg1);
}
-
+
public static boolean isDebugEnabled()
{
if (!initialized())
return false;
return __log.isDebugEnabled();
}
-
+
public static void warn(String msg)
{
if (!initialized())
return;
- __log.warn(msg,null,null);
+ __log.warn(msg);
}
-
- public static void warn(String msg,Object arg)
+
+ public static void warn(String msg, Object arg)
{
if (!initialized())
return;
- __log.warn(msg,arg,null);
+ __log.warn(msg, arg);
}
-
- public static void warn(String msg,Object arg0, Object arg1)
+
+ public static void warn(String msg, Object arg0, Object arg1)
{
if (!initialized())
return;
- __log.warn(msg,arg0,arg1);
+ __log.warn(msg, arg0, arg1);
}
-
+
public static void warn(String msg, Throwable th)
{
if (!initialized())
return;
- __log.warn(msg,th);
- unwind(th);
+ __log.warn(msg, th);
}
public static void warn(Throwable th)
{
if (!initialized())
return;
- __log.warn(EXCEPTION,th);
- unwind(th);
+ __log.warn(EXCEPTION, th);
}
- /** Obtain a named Logger.
+ /**
* Obtain a named Logger or the default Logger if null is passed.
+ * @param name the Logger name
+ * @return the Logger with the given name
*/
public static Logger getLogger(String name)
{
if (!initialized())
return null;
-
- if (name==null)
- return __log;
- return __log.getLogger(name);
- }
- private static void unwind(Throwable th)
- {
- if (th==null)
- return;
- for (int i=0;i<__nestedEx.length;i++)
- {
- try
- {
- Method get_target = th.getClass().getMethod(__nestedEx[i],__noArgs);
- Throwable th2=(Throwable)get_target.invoke(th,(Object[])null);
- if (th2!=null && th2!=th)
- warn("Nested in "+th+":",th2);
- }
- catch(Exception ignore){}
- }
+ return name == null ? __log : __log.getLogger(name);
}
-
-
}
-
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Logger.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Logger.java
index 72eab7dc9b..d96c04012a 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Logger.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Logger.java
@@ -4,39 +4,99 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.log;
-/** Logging Facade
- * A simple logging facade that is intended simply to capture the style
- * of logging as used by Jetty.
- *
+/**
+ * A simple logging facade that is intended simply to capture the style of logging as used by Jetty.
*/
public interface Logger
{
+ /**
+ * @return the name of this logger
+ */
+ public String getName();
+
+ /**
+ * Formats and logs at warn level.
+ * @param msg the formatting string
+ * @param args the optional arguments
+ */
+ public void warn(String msg, Object... args);
+
+ /**
+ * Logs the given Throwable information at warn level
+ * @param thrown the Throwable to log
+ */
+ public void warn(Throwable thrown);
+
+ /**
+ * Logs the given message at warn level, with Throwable information.
+ * @param msg the message to log
+ * @param thrown the Throwable to log
+ */
+ public void warn(String msg, Throwable thrown);
+
+ /**
+ * Formats and logs at info level.
+ * @param msg the formatting string
+ * @param args the optional arguments
+ */
+ public void info(String msg, Object... args);
+
+ /**
+ * Logs the given Throwable information at info level
+ * @param thrown the Throwable to log
+ */
+ public void info(Throwable thrown);
+
+ /**
+ * Logs the given message at info level, with Throwable information.
+ * @param msg the message to log
+ * @param thrown the Throwable to log
+ */
+ public void info(String msg, Throwable thrown);
+
+ /**
+ * @return whether the debug level is enabled
+ */
public boolean isDebugEnabled();
- /** Mutator used to turn debug on programatically.
- * Implementations operation in which case an appropriate
- * warning message shall be generated.
+ /**
+ * Mutator used to turn debug on programmatically.
+ * @param enabled whether to enable the debug level
*/
public void setDebugEnabled(boolean enabled);
- public void info(String msg);
- public void info(String msg,Object arg0, Object arg1);
- public void debug(String msg);
- public void debug(String msg,Throwable th);
- public void debug(String msg,Object arg0, Object arg1);
- public void warn(String msg);
- public void warn(String msg,Object arg0, Object arg1);
- public void warn(String msg, Throwable th);
+ /**
+ * Formats and logs at debug level.
+ * @param msg the formatting string
+ * @param args the optional arguments
+ */
+ public void debug(String msg, Object... args);
+
+ /**
+ * Logs the given Throwable information at debug level
+ * @param thrown the Throwable to log
+ */
+ public void debug(Throwable thrown);
+
+ /**
+ * Logs the given message at debug level, with Throwable information.
+ * @param msg the message to log
+ * @param thrown the Throwable to log
+ */
+ public void debug(String msg, Throwable thrown);
+
+ /**
+ * @param name the name of the logger
+ * @return a logger with the given name
+ */
public Logger getLogger(String name);
-
- public String getName();
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/LoggerLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/LoggerLog.java
index a476c16d67..6eef7bfa39 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/LoggerLog.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/LoggerLog.java
@@ -4,124 +4,106 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.log;
import java.lang.reflect.Method;
+/**
+ *
+ */
public class LoggerLog implements Logger
{
- boolean _debug;
- Object _logger;
- Method _debugMT;
- Method _debugMAA;
- Method _infoMAA;
- Method _warnMT;
- Method _warnMAA;
- Method _isDebugEnabled;
- Method _setDebugEnabledE;
- Method _getLoggerN;
-
+ private final Object _logger;
+ private final Method _debugMT;
+ private final Method _debugMAA;
+ private final Method _infoMT;
+ private final Method _infoMAA;
+ private final Method _warnMT;
+ private final Method _warnMAA;
+ private final Method _setDebugEnabledE;
+ private final Method _getLoggerN;
+ private final Method _getName;
+ private volatile boolean _debug;
+
public LoggerLog(Object logger)
{
try
{
- _logger=logger;
- Class<?> lc=logger.getClass();
- _debugMT=lc.getMethod("debug",new Class[]{String.class,Throwable.class});
- _debugMAA=lc.getMethod("debug",new Class[]{String.class,Object.class,Object.class});
- _infoMAA=lc.getMethod("info",new Class[]{String.class,Object.class,Object.class});
- _warnMT=lc.getMethod("warn",new Class[]{String.class,Throwable.class});
- _warnMAA=lc.getMethod("warn",new Class[]{String.class,Object.class,Object.class});
- _isDebugEnabled=lc.getMethod("isDebugEnabled",new Class[]{});
- _setDebugEnabledE=lc.getMethod("setDebugEnabled",new Class[]{Boolean.TYPE});
- _getLoggerN=lc.getMethod("getLogger",new Class[]{String.class});
-
- _debug=((Boolean)_isDebugEnabled.invoke(_logger,(Object[])null)).booleanValue();
- }
- catch(Exception e)
+ _logger = logger;
+ Class<?> lc = logger.getClass();
+ _debugMT = lc.getMethod("debug", new Class[]{String.class, Throwable.class});
+ _debugMAA = lc.getMethod("debug", new Class[]{String.class, Object[].class});
+ _infoMT = lc.getMethod("info", new Class[]{String.class, Throwable.class});
+ _infoMAA = lc.getMethod("info", new Class[]{String.class, Object[].class});
+ _warnMT = lc.getMethod("warn", new Class[]{String.class, Throwable.class});
+ _warnMAA = lc.getMethod("warn", new Class[]{String.class, Object[].class});
+ Method _isDebugEnabled = lc.getMethod("isDebugEnabled");
+ _setDebugEnabledE = lc.getMethod("setDebugEnabled", new Class[]{Boolean.TYPE});
+ _getLoggerN = lc.getMethod("getLogger", new Class[]{String.class});
+ _getName = lc.getMethod("getName");
+
+ _debug = (Boolean)_isDebugEnabled.invoke(_logger);
+ }
+ catch(Exception x)
{
- e.printStackTrace();
- throw new IllegalStateException(e);
+ throw new IllegalStateException(x);
}
}
-
public String getName()
{
- return _logger.toString();
- }
-
- public void debug(String msg, Throwable th)
- {
- if (_debug)
+ try
{
- try
- {
- _debugMT.invoke(_logger,msg,th);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
+ return (String)_getName.invoke(_logger);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return null;
}
}
- public void debug(String msg)
+ public void warn(String msg, Object... args)
{
- if (_debug)
+ try
{
- try
- {
- _debugMAA.invoke(_logger,msg,null,null);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
+ _warnMAA.invoke(_logger, args);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
}
}
- public void debug(String msg, Object arg0, Object arg1)
+ public void warn(Throwable thrown)
{
- if (_debug)
- {
- try
- {
- _debugMAA.invoke(_logger,msg,arg0,arg1);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
+ warn("", thrown);
}
- public Logger getLogger(String name)
+ public void warn(String msg, Throwable thrown)
{
try
{
- Object logger=_getLoggerN.invoke(_logger,name);
- return new LoggerLog(logger);
+ _warnMT.invoke(_logger, msg, thrown);
}
catch (Exception e)
{
e.printStackTrace();
}
- return this;
}
- public void info(String msg)
+ public void info(String msg, Object... args)
{
try
{
- _infoMAA.invoke(_logger,msg,null,null);
+ _infoMAA.invoke(_logger, args);
}
catch (Exception e)
{
@@ -129,11 +111,16 @@ public class LoggerLog implements Logger
}
}
- public void info(String msg, Object arg0, Object arg1)
+ public void info(Throwable thrown)
+ {
+ info("", thrown);
+ }
+
+ public void info(String msg, Throwable thrown)
{
try
{
- _infoMAA.invoke(_logger,msg,arg0,arg1);
+ _infoMT.invoke(_logger, msg, thrown);
}
catch (Exception e)
{
@@ -150,21 +137,23 @@ public class LoggerLog implements Logger
{
try
{
- _setDebugEnabledE.invoke(_logger,enabled);
- _debug=enabled;
+ _setDebugEnabledE.invoke(_logger, enabled);
+ _debug = enabled;
}
catch (Exception e)
{
e.printStackTrace();
}
-
}
- public void warn(String msg)
+ public void debug(String msg, Object... args)
{
+ if (!_debug)
+ return;
+
try
{
- _warnMAA.invoke(_logger,msg,null,null);
+ _debugMAA.invoke(_logger, args);
}
catch (Exception e)
{
@@ -172,11 +161,19 @@ public class LoggerLog implements Logger
}
}
- public void warn(String msg, Object arg0, Object arg1)
+ public void debug(Throwable thrown)
{
+ debug("", thrown);
+ }
+
+ public void debug(String msg, Throwable th)
+ {
+ if (!_debug)
+ return;
+
try
{
- _warnMAA.invoke(_logger,msg,arg0,arg1);
+ _debugMT.invoke(_logger, msg, th);
}
catch (Exception e)
{
@@ -184,16 +181,17 @@ public class LoggerLog implements Logger
}
}
- public void warn(String msg, Throwable th)
+ public Logger getLogger(String name)
{
try
{
- _warnMT.invoke(_logger,msg,th);
+ Object logger=_getLoggerN.invoke(_logger, name);
+ return new LoggerLog(logger);
}
catch (Exception e)
{
e.printStackTrace();
+ return this;
}
}
-
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java
index a62b62824b..7df5c9fd08 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java
@@ -4,144 +4,100 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.log;
-
-/* ------------------------------------------------------------ */
-/** Slf4jLog Logger
- *
+/**
+ * Slf4jLog Logger
*/
public class Slf4jLog implements Logger
{
- private org.slf4j.Logger _logger;
-
+ private final org.slf4j.Logger _logger;
public Slf4jLog() throws Exception
{
this("org.eclipse.jetty.util.log");
}
-
+
public Slf4jLog(String name)
{
_logger = org.slf4j.LoggerFactory.getLogger( name );
}
-
+
public String getName()
{
return _logger.getName();
}
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doDebug(java.lang.String)
- */
- public void debug(String msg)
+
+ public void warn(String msg, Object... args)
{
- _logger.debug(msg);
+ _logger.warn(msg, args);
}
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doDebug(java.lang.String, java.lang.Object, java.lang.Object)
- */
- public void debug(String msg, Object arg0, Object arg1)
+
+ public void warn(Throwable thrown)
{
- _logger.debug(msg, arg0, arg1);
+ warn("", thrown);
}
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doDebug(java.lang.String, java.lang.Throwable)
- */
- public void debug(String msg, Throwable th)
+ public void warn(String msg, Throwable thrown)
{
- _logger.debug(msg, th);
+ _logger.warn(msg, thrown);
}
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doDebugEnabled()
- */
- public boolean isDebugEnabled()
+ public void info(String msg, Object... args)
{
- return _logger.isDebugEnabled();
+ _logger.info(msg, args);
}
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doInfo(java.lang.String)
- */
- public void info(String msg)
+ public void info(Throwable thrown)
{
- _logger.info(msg);
+ info("", thrown);
}
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doInfo(java.lang.String, java.lang.Object, java.lang.Object)
- */
- public void info(String msg, Object arg0, Object arg1)
+
+ public void info(String msg, Throwable thrown)
{
- _logger.info(msg, arg0, arg1);
+ _logger.info(msg, thrown);
}
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doWarn(java.lang.String)
- */
- public void warn(String msg)
+ public void debug(String msg, Object... args)
{
- _logger.warn(msg);
+ _logger.debug(msg, args);
}
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doWarn(java.lang.String, java.lang.Object, java.lang.Object)
- */
- public void warn(String msg, Object arg0, Object arg1)
+
+ public void debug(Throwable thrown)
{
- _logger.warn(msg, arg0, arg1);
+ debug("", thrown);
}
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.log.Log#doWarn(java.lang.String, java.lang.Throwable)
- */
- public void warn(String msg, Throwable th)
+ public void debug(String msg, Throwable thrown)
{
+ _logger.debug(msg, thrown);
+ }
- if (th instanceof RuntimeException || th instanceof Error)
- _logger.error(msg, th);
- else
- _logger.warn(msg,th);
+ public boolean isDebugEnabled()
+ {
+ return _logger.isDebugEnabled();
+ }
+ public void setDebugEnabled(boolean enabled)
+ {
+ warn("setDebugEnabled not implemented",null,null);
}
- /* ------------------------------------------------------------ */
public Logger getLogger(String name)
{
return new Slf4jLog(name);
-
}
- /* ------------------------------------------------------------ */
@Override
public String toString()
{
return _logger.toString();
}
-
- /* ------------------------------------------------------------ */
- public void setDebugEnabled(boolean enabled)
- {
- warn("setDebugEnabled not implemented",null,null);
- }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java
index 58bf8df615..788bc081d8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.util.log;
@@ -17,76 +17,82 @@ import java.security.AccessControlException;
import org.eclipse.jetty.util.DateCache;
-/*-----------------------------------------------------------------------*/
-/** StdErr Logging.
- * This implementation of the Logging facade sends all logs to StdErr with minimal formatting.
- *
- * If the system property "org.eclipse.jetty.util.log.DEBUG" is set,
- * then debug logs are printed if stderr is being used.
+/**
+ * StdErr Logging. This implementation of the Logging facade sends all logs to
+ * StdErr with minimal formatting.
* <p>
- * For named debuggers, the system property name+".DEBUG" is checked. If it is not not set, then
+ * If the system property "org.eclipse.jetty.util.log.DEBUG" is set, then debug
+ * logs are printed if stderr is being used. For named debuggers, the system
+ * property name+".DEBUG" is checked. If it is not not set, then
* "org.eclipse.jetty.util.log.DEBUG" is used as the default.
+ * <p>
+ * If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the
+ * source method/file of a log is logged. For named debuggers, the system
+ * property name+".SOURCE" is checked. If it is not not set, then
+ * "org.eclipse.jetty.util.log.SOURCE" is used as the default.
*
*/
public class StdErrLog implements Logger
-{
+{
private static DateCache _dateCache;
-
- private final static String LN = System.getProperty("line.separator");
- private final static boolean __debug =
- Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.DEBUG",System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG","false")));
- private boolean _debug = __debug;
- private final String _name;
- private boolean _hideStacks=false;
- StringBuilder _buffer = new StringBuilder();
-
+
+ private final static boolean __debug = Boolean.parseBoolean(
+ System.getProperty("org.eclipse.jetty.util.log.DEBUG",
+ System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG", "false")));
+ private final static boolean __source = Boolean.parseBoolean(
+ System.getProperty("org.eclipse.jetty.util.log.SOURCE",
+ System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE", "false")));
+
static
{
try
{
- _dateCache=new DateCache("yyyy-MM-dd HH:mm:ss");
+ _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
}
- catch(Exception e)
+ catch (Exception x)
{
- e.printStackTrace();
+ x.printStackTrace();
}
-
}
-
+
+ private boolean _debug = __debug;
+ private boolean _source = __source;
+ private final String _name;
+ private boolean _hideStacks = false;
+
public StdErrLog()
{
this(null);
}
-
+
public StdErrLog(String name)
- {
- this._name=name==null?"":name;
+ {
+ this._name = name == null ? "" : name;
try
{
- _debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG",Boolean.toString(__debug)));
+ _debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG", Boolean.toString(_debug)));
}
catch (AccessControlException ace)
{
_debug = __debug;
}
+
+ try
+ {
+ _source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE", Boolean.toString(_source)));
+ }
+ catch (AccessControlException ace)
+ {
+ _source = __source;
+ }
}
-
+
public String getName()
{
return _name;
}
-
- public boolean isDebugEnabled()
- {
- return _debug;
- }
-
- public void setDebugEnabled(boolean enabled)
- {
- _debug=enabled;
- }
-
+
public boolean isHideStacks()
{
return _hideStacks;
@@ -97,227 +103,226 @@ public class StdErrLog implements Logger
_hideStacks = hideStacks;
}
- public void info(String msg)
+ /* ------------------------------------------------------------ */
+ /** Is the source of a log, logged
+ * @return true if the class, method, file and line number of a log is logged.
+ */
+ public boolean isSource()
{
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":INFO:");
- format(msg);
- System.err.println(_buffer.toString());
- }
+ return _source;
}
- public void info(String msg,Object arg0, Object arg1)
+ /* ------------------------------------------------------------ */
+ /** Set if a log source is logged.
+ * @param source true if the class, method, file and line number of a log is logged.
+ */
+ public void setSource(boolean source)
{
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":INFO:");
- format(msg,arg0,arg1);
- System.err.println(_buffer.toString());
- }
+ _source = source;
}
-
- public void debug(String msg,Throwable th)
+
+ public void warn(String msg, Object... args)
{
- if (_debug)
- {
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":DBUG:");
- format(msg);
- if (_hideStacks)
- format(th.toString());
- else
- format(th);
- System.err.println(_buffer.toString());
- }
- }
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":WARN:", msg, args);
+ System.err.println(buffer);
}
-
- public void debug(String msg)
+
+ public void warn(Throwable thrown)
{
- if (_debug)
- {
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":DBUG:");
- format(msg);
- System.err.println(_buffer.toString());
- }
- }
+ warn("", thrown);
}
-
- public void debug(String msg,Object arg0, Object arg1)
+
+ public void warn(String msg, Throwable thrown)
{
- if (_debug)
- {
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":DBUG:");
- format(msg,arg0,arg1);
- System.err.println(_buffer.toString());
- }
- }
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":WARN:", msg, thrown);
+ System.err.println(buffer);
}
-
- public void warn(String msg)
+
+ public void info(String msg, Object... args)
{
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":WARN:");
- format(msg);
- System.err.println(_buffer.toString());
- }
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":INFO:", msg, args);
+ System.err.println(buffer);
}
-
- public void warn(String msg,Object arg0, Object arg1)
+
+ public void info(Throwable thrown)
{
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":WARN:");
- format(msg,arg0,arg1);
- System.err.println(_buffer.toString());
- }
+ info("", thrown);
}
-
- public void warn(String msg, Throwable th)
+
+ public void info(String msg, Throwable thrown)
{
- String d=_dateCache.now();
- int ms=_dateCache.lastMs();
- synchronized(_buffer)
- {
- tag(d,ms,":WARN:");
- format(msg);
- if (_hideStacks)
- format(th.toString());
- else
- format(th);
- System.err.println(_buffer.toString());
- }
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":INFO:", msg, thrown);
+ System.err.println(buffer);
+ }
+
+ public boolean isDebugEnabled()
+ {
+ return _debug;
}
-
- private void tag(String d,int ms,String tag)
+ public void setDebugEnabled(boolean enabled)
{
- _buffer.setLength(0);
- _buffer.append(d);
- if (ms>99)
- _buffer.append('.');
- else if (ms>9)
- _buffer.append(".0");
+ _debug = enabled;
+ }
+
+ public void debug(String msg, Object... args)
+ {
+ if (!_debug)
+ return;
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":DBUG:", msg, args);
+ System.err.println(buffer);
+ }
+
+ public void debug(Throwable thrown)
+ {
+ debug("", thrown);
+ }
+
+ public void debug(String msg, Throwable thrown)
+ {
+ if (!_debug)
+ return;
+ StringBuilder buffer = new StringBuilder(64);
+ format(buffer, ":DBUG:", msg, thrown);
+ System.err.println(buffer);
+ }
+
+ private void format(StringBuilder buffer, String level, String msg, Object... args)
+ {
+ String d = _dateCache.now();
+ int ms = _dateCache.lastMs();
+ tag(buffer, d, ms, level);
+ format(buffer, msg, args);
+ }
+
+ private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
+ {
+ format(buffer, level, msg);
+ if (isHideStacks())
+ format(buffer, String.valueOf(thrown));
else
- _buffer.append(".00");
- _buffer.append(ms).append(tag).append(_name).append(':');
+ format(buffer, thrown);
}
-
- private void format(String msg, Object arg0, Object arg1)
+
+ private void tag(StringBuilder buffer, String d, int ms, String tag)
{
- int i0=msg==null?-1:msg.indexOf("{}");
- int i1=i0<0?-1:msg.indexOf("{}",i0+2);
-
- if (i0>=0)
+ buffer.setLength(0);
+ buffer.append(d);
+ if (ms > 99)
+ buffer.append('.');
+ else if (ms > 9)
+ buffer.append(".0");
+ else
+ buffer.append(".00");
+ buffer.append(ms).append(tag).append(_name).append(':');
+ if (_source)
{
- format(msg.substring(0,i0));
- format(String.valueOf(arg0==null?"null":arg0));
-
- if (i1>=0)
+ Throwable source = new Throwable();
+ StackTraceElement[] frames = source.getStackTrace();
+ for (int i=0;i<frames.length;i++)
{
- format(msg.substring(i0+2,i1));
- format(String.valueOf(arg1==null?"null":arg1));
- format(msg.substring(i1+2));
- }
- else
- {
- format(msg.substring(i0+2));
- if (arg1!=null)
- {
- _buffer.append(' ');
- format(String.valueOf(arg1));
- }
+ final StackTraceElement frame = frames[i];
+ String clazz = frame.getClassName();
+ if (clazz.equals(StdErrLog.class.getName())|| clazz.equals(Log.class.getName()))
+ continue;
+ if (clazz.startsWith("org.eclipse.jetty."))
+ buffer.append("o.e.j.").append(clazz,18,clazz.length());
+ else
+ buffer.append(clazz);
+ buffer.append('#').append(frame.getMethodName());
+ if (frame.getFileName()!=null)
+ buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
+ buffer.append(':');
+ break;
}
}
- else
+ }
+
+ private void format(StringBuilder builder, String msg, Object... args)
+ {
+ msg = String.valueOf(msg); // Avoids NPE
+ String braces = "{}";
+ int start = 0;
+ for (Object arg : args)
{
- format(msg);
- if (arg0!=null)
+ int bracesIndex = msg.indexOf(braces, start);
+ if (bracesIndex < 0)
{
- _buffer.append(' ');
- format(String.valueOf(arg0));
+ escape(builder, msg.substring(start));
+ builder.append(" ");
+ builder.append(arg);
+ start = msg.length();
}
- if (arg1!=null)
+ else
{
- _buffer.append(' ');
- format(String.valueOf(arg1));
+ escape(builder, msg.substring(start, bracesIndex));
+ builder.append(String.valueOf(arg));
+ start = bracesIndex + braces.length();
}
}
+ escape(builder, msg.substring(start));
}
-
- private void format(String msg)
+
+ private void escape(StringBuilder builder, String string)
{
- if (msg == null)
- _buffer.append("null");
- else
- for (int i=0;i<msg.length();i++)
+ for (int i = 0; i < string.length(); ++i)
+ {
+ char c = string.charAt(i);
+ if (Character.isISOControl(c))
{
- char c=msg.charAt(i);
- if (Character.isISOControl(c))
- {
- if (c=='\n')
- _buffer.append('|');
- else if (c=='\r')
- _buffer.append('<');
- else
- _buffer.append('?');
- }
+ if (c == '\n')
+ builder.append('|');
+ else if (c == '\r')
+ builder.append('<');
else
- _buffer.append(c);
+ builder.append('?');
}
+ else
+ builder.append(c);
+ }
}
-
- private void format(Throwable th)
+
+ private void format(StringBuilder buffer, Throwable thrown)
{
- if (th == null)
- _buffer.append("null");
+ if (thrown == null)
+ {
+ buffer.append("null");
+ }
else
{
- _buffer.append('\n');
- format(th.toString());
- StackTraceElement[] elements = th.getStackTrace();
- for (int i=0;elements!=null && i<elements.length;i++)
+ buffer.append('\n');
+ format(buffer, thrown.toString());
+ StackTraceElement[] elements = thrown.getStackTrace();
+ for (int i = 0; elements != null && i < elements.length; i++)
{
- _buffer.append("\n\tat ");
- format(elements[i].toString());
+ buffer.append("\n\tat ");
+ format(buffer, elements[i].toString());
+ }
+
+ Throwable cause = thrown.getCause();
+ if (cause!=null && cause!=thrown)
+ {
+ buffer.append("\nCaused by: ");
+ format(buffer,cause);
}
}
}
-
+
public Logger getLogger(String name)
{
- if ((name==null && this._name==null) ||
- (name!=null && name.equals(this._name)))
+ if ((name == null && this._name == null) || (name != null && name.equals(this._name)))
return this;
- return new StdErrLog(_name==null||_name.length()==0?name:_name+"."+name);
+ return new StdErrLog(_name == null || _name.length() == 0?name:_name + "." + name);
}
-
+
@Override
public String toString()
{
- return "StdErrLog:"+_name+":DEBUG="+_debug;
+ return "StdErrLog:" + _name + ":DEBUG=" + _debug;
}
-
}
-
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
index aa97c53505..dc933bafb7 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
@@ -315,7 +315,7 @@ class JarFileResource extends JarResource
* Take a Resource that possibly might use URLConnection caching
* and turn it into one that doesn't.
* @param resource
- * @return
+ * @return the non-caching resource
*/
public static Resource getNonCachingResource (Resource resource)
{
@@ -331,9 +331,9 @@ class JarFileResource extends JarResource
/**
* Check if this jar:file: resource is contained in the
- * named resource. Eg jar:file:///a/b/c/foo.jar!/x.html isContainedIn file:///a/b/c/foo.jar
+ * named resource. Eg <code>jar:file:///a/b/c/foo.jar!/x.html</code> isContainedIn <code>file:///a/b/c/foo.jar</code>
* @param resource
- * @return
+ * @return true if resource is contained in the named resource
* @throws MalformedURLException
*/
@Override
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
index 6c8b41695f..44e8ba6916 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
@@ -34,10 +34,8 @@ import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
-/** Abstract resource class.
- *
- *
- *
+/**
+ * Abstract resource class.
*/
public abstract class Resource implements Serializable
{
@@ -259,13 +257,13 @@ public abstract class Resource implements Serializable
/* ------------------------------------------------------------ */
/** Find a classpath resource.
- * The {@java.lang.Class#getResource} method is used to lookup the resource. If it is not
+ * The {@link java.lang.Class#getResource(String)} method is used to lookup the resource. If it is not
* found, then the {@link Loader#getResource(Class, String, boolean)} method is used.
* If it is still not found, then {@link ClassLoader#getSystemResource(String)} is used.
- * Unlike {@link #getSystemResource} this method does not check for normal resources.
- * @param name The relative name of the resouce
+ * Unlike {@link ClassLoader#getSystemResource(String)} this method does not check for normal resources.
+ * @param name The relative name of the resource
* @param useCaches True if URL caches are to be used.
- * @param checkParents True if forced searching of parent classloaders is performed to work around
+ * @param checkParents True if forced searching of parent Classloaders is performed to work around
* loaders with inverted priorities
* @return Resource or null
*/
@@ -491,7 +489,7 @@ public abstract class Resource implements Serializable
buf.append("\">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
}
- String defangedBase = defangURI(base);
+ String encodedBase = hrefEncodeURI(base);
DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM);
@@ -500,7 +498,7 @@ public abstract class Resource implements Serializable
Resource item = addPath(ls[i]);
buf.append("\n<TR><TD><A HREF=\"");
- String path=URIUtil.addPaths(defangedBase,URIUtil.encodePath(ls[i]));
+ String path=URIUtil.addPaths(encodedBase,URIUtil.encodePath(ls[i]));
buf.append(path);
@@ -524,38 +522,36 @@ public abstract class Resource implements Serializable
}
/**
- * Defang any characters that could break the URI string in an HREF.
+ * Encode any characters that could break the URI string in an HREF.
* Such as <a href="/path/to;<script>Window.alert("XSS"+'%20'+"here");</script>">Link</a>
*
* The above example would parse incorrectly on various browsers as the "<" or '"' characters
* would end the href attribute value string prematurely.
*
- * @param raw the raw text to defang.
+ * @param raw the raw text to encode.
* @return the defanged text.
*/
- private static String defangURI(String raw)
+ private static String hrefEncodeURI(String raw)
{
StringBuffer buf = null;
-
- if (buf==null)
+
+ loop:
+ for (int i=0;i<raw.length();i++)
{
- for (int i=0;i<raw.length();i++)
+ char c=raw.charAt(i);
+ switch(c)
{
- char c=raw.charAt(i);
- switch(c)
- {
- case '\'':
- case '"':
- case '<':
- case '>':
- buf=new StringBuffer(raw.length()<<1);
- break;
- }
+ case '\'':
+ case '"':
+ case '<':
+ case '>':
+ buf=new StringBuffer(raw.length()<<1);
+ break loop;
}
- if (buf==null)
- return raw;
}
-
+ if (buf==null)
+ return raw;
+
for (int i=0;i<raw.length();i++)
{
char c=raw.charAt(i);
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java
index 7ff50cfe63..8d55ee2f3f 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java
@@ -114,6 +114,10 @@ public class ResourceCollection extends Resource
throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
}
}
+ catch(IllegalArgumentException e)
+ {
+ throw e;
+ }
catch(Exception e)
{
throw new RuntimeException(e);
@@ -458,12 +462,9 @@ public class ResourceCollection extends Resource
public String toString()
{
if(_resources==null)
- return "";
+ return "[]";
- StringBuilder buffer = new StringBuilder();
- for(Resource r : _resources)
- buffer.append(r.toString()).append(';');
- return buffer.toString();
+ return String.valueOf(Arrays.asList(_resources));
}
/* ------------------------------------------------------------ */
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java
index 98006e5a6f..8c9b33d310 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java
@@ -46,7 +46,7 @@ public class CounterStatistic
/* ------------------------------------------------------------ */
/**
- * @param delta
+ * @param delta the amount to add to the count
*/
public void add(final long delta)
{
@@ -64,7 +64,7 @@ public class CounterStatistic
/* ------------------------------------------------------------ */
/**
- * @param delta
+ * @param delta the amount to subtract the count by.
*/
public void subtract(final long delta)
{
@@ -89,7 +89,7 @@ public class CounterStatistic
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return max value
*/
public long getMax()
{
@@ -98,7 +98,7 @@ public class CounterStatistic
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return current value
*/
public long getCurrent()
{
@@ -107,7 +107,7 @@ public class CounterStatistic
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return total value
*/
public long getTotal()
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java
index cc0edea8db..fbdb422b0b 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java
@@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicLong;
* deviation of continuous sequence of samples.
* <p>
* Calculates estimates of mean, variance, and standard deviation
- * characteristics of a sample using a non synchronised
+ * characteristics of a sample using a non synchronized
* approximation of the on-line algorithm presented
* in Donald Knuth's Art of Computer Programming, Volume 2,
* Seminumerical Algorithms, 3rd edition, page 232,
@@ -73,7 +73,7 @@ public class SampleStatistic
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the max value
*/
public long getMax()
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java
index 32bc92e1cf..c00a3cb1fe 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java
@@ -27,12 +27,10 @@ import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
-/** Jetty ThreadPool using java 5 ThreadPoolExecutor
+/**
+ * Jetty ThreadPool using java 5 ThreadPoolExecutor
* This class wraps a {@link ExecutorService} as a {@link ThreadPool} and
- * {@link LifeCycle} interfaces so that it may be used by the Jetty {@link org.eclipse.jetty.Server}
- *
- *
- *
+ * {@link LifeCycle} interfaces so that it may be used by the Jetty <code>org.eclipse.jetty.server.Server</code>
*/
public class ExecutorThreadPool extends AbstractLifeCycle implements ThreadPool, LifeCycle
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
index a543363130..6c89832e70 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
@@ -28,7 +28,6 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
-
public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, Executor
{
private final AtomicInteger _threadsStarted = new AtomicInteger();
@@ -47,7 +46,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
private int _maxStopTime=100;
/* ------------------------------------------------------------------- */
- /* Construct
+ /** Construct
*/
public QueuedThreadPool()
{
@@ -55,7 +54,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
}
/* ------------------------------------------------------------------- */
- /* Construct
+ /** Construct
*/
public QueuedThreadPool(int maxThreads)
{
@@ -64,7 +63,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
}
/* ------------------------------------------------------------------- */
- /* Construct
+ /** Construct
*/
public QueuedThreadPool(BlockingQueue<Runnable> jobQ)
{
@@ -508,7 +507,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
/**
* @param id The thread ID to stop.
* @return true if the thread was found and stopped.
- * @Deprecated Use {@link #interruptThread(long)} in preference
+ * @deprecated Use {@link #interruptThread(long)} in preference
*/
@SuppressWarnings("deprecation")
public boolean stopThread(long id)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java
index bae25570e6..ebf3096fff 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java
@@ -35,6 +35,7 @@ public class ShutdownThread extends Thread
{
private static final ShutdownThread _thread = new ShutdownThread();
+ private boolean _hooked;
private final List<LifeCycle> _lifeCycles = new CopyOnWriteArrayList<LifeCycle>();
/* ------------------------------------------------------------ */
@@ -45,14 +46,44 @@ public class ShutdownThread extends Thread
*/
private ShutdownThread()
{
- Runtime.getRuntime().addShutdownHook(this);
}
-
+
+ /* ------------------------------------------------------------ */
+ private synchronized void hook()
+ {
+ try
+ {
+ if (!_hooked)
+ Runtime.getRuntime().addShutdownHook(this);
+ _hooked=true;
+ }
+ catch(Exception e)
+ {
+ Log.ignore(e);
+ Log.info("shutdown already commenced");
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private synchronized void unhook()
+ {
+ try
+ {
+ _hooked=false;
+ Runtime.getRuntime().removeShutdownHook(this);
+ }
+ catch(Exception e)
+ {
+ Log.ignore(e);
+ Log.info("shutdown already commenced");
+ }
+ }
+
/* ------------------------------------------------------------ */
/**
* Returns the instance of the singleton
*
- * @return
+ * @return the singleton instance of the {@link ShutdownThread}
*/
public static ShutdownThread getInstance()
{
@@ -63,18 +94,24 @@ public class ShutdownThread extends Thread
public static synchronized void register(LifeCycle... lifeCycles)
{
_thread._lifeCycles.addAll(Arrays.asList(lifeCycles));
+ if (_thread._lifeCycles.size()>0)
+ _thread.hook();
}
/* ------------------------------------------------------------ */
public static synchronized void register(int index, LifeCycle... lifeCycles)
{
_thread._lifeCycles.addAll(index,Arrays.asList(lifeCycles));
+ if (_thread._lifeCycles.size()>0)
+ _thread.hook();
}
/* ------------------------------------------------------------ */
public static synchronized void deregister(LifeCycle lifeCycle)
{
_thread._lifeCycles.remove(lifeCycle);
+ if (_thread._lifeCycles.size()==0)
+ _thread.unhook();
}
/* ------------------------------------------------------------ */
@@ -93,11 +130,4 @@ public class ShutdownThread extends Thread
}
}
}
-
- /* ------------------------------------------------------------ */
- protected Object readResolve()
- throws ObjectStreamException
- {
- return _thread;
- }
-} \ No newline at end of file
+}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java
index e2220840c7..c1aabe11d1 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java
@@ -23,10 +23,7 @@ import org.eclipse.jetty.util.log.Log;
* is changed, this affects all scheduled tasks.
* <p>
* The nested class Task should be extended by users of this class to obtain call back notification of
- * expiries.
- *
- *
- *
+ * expires.
*/
public class Timeout
{
@@ -91,7 +88,7 @@ public class Timeout
* expired Task, but without calling it's {@link Task#expire()} or
* {@link Task#expired()} methods.
*
- * @returns the next expired task or null.
+ * @return the next expired task or null.
*/
public Task expired()
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ArrayQueueTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ArrayQueueTest.java
index f79c618564..028208bd32 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ArrayQueueTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ArrayQueueTest.java
@@ -13,11 +13,16 @@
package org.eclipse.jetty.util;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-public class ArrayQueueTest extends TestCase
+import org.junit.Test;
+
+
+public class ArrayQueueTest
{
-
+ @Test
public void testWrap() throws Exception
{
ArrayQueue<String> queue = new ArrayQueue<String>(3,3);
@@ -63,6 +68,7 @@ public class ArrayQueueTest extends TestCase
}
+ @Test
public void testRemove() throws Exception
{
ArrayQueue<String> queue = new ArrayQueue<String>(3,3);
@@ -82,6 +88,7 @@ public class ArrayQueueTest extends TestCase
assertEquals(i+"!",queue.get(i));
}
+ @Test
public void testGrow() throws Exception
{
ArrayQueue<String> queue = new ArrayQueue<String>(3,5);
@@ -123,10 +130,9 @@ public class ArrayQueueTest extends TestCase
for (int i=0;i<12;i++)
queue.add(""+('a'+i));
assertEquals(13,queue.getCapacity());
-
-
}
+ @Test
public void testFullEmpty() throws Exception
{
ArrayQueue<String> queue = new ArrayQueue<String>(2);
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java
index a7ae482adc..7daee8f5c5 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java
@@ -13,17 +13,22 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.util.HashSet;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
-import junit.framework.TestCase;
+import org.junit.Test;
+
-public class BlockingArrayQueueTest extends TestCase
+public class BlockingArrayQueueTest
{
+ @Test
public void testWrap() throws Exception
{
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3);
@@ -66,6 +71,7 @@ public class BlockingArrayQueueTest extends TestCase
}
+ @Test
public void testRemove() throws Exception
{
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3,3);
@@ -85,6 +91,7 @@ public class BlockingArrayQueueTest extends TestCase
assertEquals(i+"!",queue.get(i));
}
+ @Test
public void testGrow() throws Exception
{
BlockingArrayQueue<String> queue = new BlockingArrayQueue<String>(3,2);
@@ -128,11 +135,9 @@ public class BlockingArrayQueueTest extends TestCase
s+=2;
c+=2;
}
-
-
-
}
+ @Test
public void testTake() throws Exception
{
final String[] data=new String[4];
@@ -178,6 +183,7 @@ public class BlockingArrayQueueTest extends TestCase
volatile boolean _running;
+ @Test
public void testConcurrentAccess() throws Exception
{
final int THREADS=50;
@@ -306,9 +312,5 @@ public class BlockingArrayQueueTest extends TestCase
HashSet<Integer> consSet = new HashSet<Integer>(consumed);
assertEquals(prodSet,consSet);
-
-
-
-
}
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java
index e49eff036e..15284fd249 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java
@@ -13,37 +13,23 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.util.Locale;
import java.util.TimeZone;
-import junit.framework.TestSuite;
+import org.junit.Test;
/* ------------------------------------------------------------ */
/** Util meta Tests.
*
*/
-public class DateCacheTest extends junit.framework.TestCase
+public class DateCacheTest
{
- public DateCacheTest(String name)
- {
- super(name);
- }
-
- public static junit.framework.Test suite() {
- TestSuite suite = new TestSuite(DateCacheTest.class);
- return suite;
- }
-
- /* ------------------------------------------------------------ */
- /** main.
- */
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
/* ------------------------------------------------------------ */
+ @Test
public void testDateCache() throws Exception
{
//@WAS: Test t = new Test("org.eclipse.jetty.util.DateCache");
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/IPAddressMapTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/IPAddressMapTest.java
new file mode 100644
index 0000000000..f1ade99091
--- /dev/null
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/IPAddressMapTest.java
@@ -0,0 +1,172 @@
+// ========================================================================
+// Copyright (c) 2010 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.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+
+public class IPAddressMapTest
+{
+ @Test
+ public void testOneAddress()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("10.5.2.1","1");
+
+ assertNotNull(map.match("10.5.2.1"));
+
+ assertNull(map.match("101.5.2.1"));
+ assertNull(map.match("10.15.2.1"));
+ assertNull(map.match("10.5.22.1"));
+ assertNull(map.match("10.5.2.0"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testOneRange()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("1-15.16-31.32-63.64-127","1");
+
+ assertNotNull(map.match("7.23.39.71"));
+ assertNotNull(map.match("1.16.32.64"));
+ assertNotNull(map.match("15.31.63.127"));
+
+ assertNull(map.match("16.32.64.128"));
+ assertNull(map.match("1.16.32.63"));
+ assertNull(map.match("1.16.31.64"));
+ assertNull(map.match("1.15.32.64"));
+ assertNull(map.match("0.16.32.64"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testOneMissing()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("10.5.2.","1");
+
+ assertNotNull(map.match("10.5.2.0"));
+ assertNotNull(map.match("10.5.2.128"));
+ assertNotNull(map.match("10.5.2.255"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testTwoMissing()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("10.5.","1");
+
+ assertNotNull(map.match("10.5.2.0"));
+ assertNotNull(map.match("10.5.2.128"));
+ assertNotNull(map.match("10.5.2.255"));
+ assertNotNull(map.match("10.5.0.1"));
+ assertNotNull(map.match("10.5.128.1"));
+ assertNotNull(map.match("10.5.255.1"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testThreeMissing()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("10.","1");
+
+ assertNotNull(map.match("10.5.2.0"));
+ assertNotNull(map.match("10.5.2.128"));
+ assertNotNull(map.match("10.5.2.255"));
+ assertNotNull(map.match("10.5.0.1"));
+ assertNotNull(map.match("10.5.128.1"));
+ assertNotNull(map.match("10.5.255.1"));
+ assertNotNull(map.match("10.0.1.1"));
+ assertNotNull(map.match("10.128.1.1"));
+ assertNotNull(map.match("10.255.1.1"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testOneMixed()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("0-15,21.10,16-31.0-15,32-63.-95,128-","1");
+
+ assertNotNull(map.match("7.23.39.46"));
+ assertNotNull(map.match("10.20.10.150"));
+ assertNotNull(map.match("21.10.32.255"));
+ assertNotNull(map.match("21.10.15.0"));
+
+ assertNull(map.match("16.15.20.100"));
+ assertNull(map.match("15.10.63.100"));
+ assertNull(map.match("15.10.64.128"));
+ assertNull(map.match("15.11.32.95"));
+ assertNull(map.match("16.31.63.128"));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testManyMixed()
+ {
+ IPAddressMap<String> map = new IPAddressMap();
+
+ map.put("10.5.2.1","1");
+ map.put("1-15.16-31.32-63.64-127","2");
+ map.put("1-15,21.10,16-31.0-15,32-63.-55,195-","3");
+ map.put("44.99.99.","4");
+ map.put("55.99.","5");
+ map.put("66.","6");
+
+ assertEquals("1", map.match("10.5.2.1"));
+
+ assertEquals("2", map.match("7.23.39.71"));
+ assertEquals("2", map.match("1.16.32.64"));
+ assertEquals("2", map.match("15.31.63.127"));
+
+ assertEquals("3", map.match("7.23.39.46"));
+ assertEquals("3", map.match("10.20.10.200"));
+ assertEquals("3", map.match("21.10.32.255"));
+ assertEquals("3", map.match("21.10.15.0"));
+
+ assertEquals("4", map.match("44.99.99.0"));
+ assertEquals("5", map.match("55.99.128.1"));
+ assertEquals("6", map.match("66.255.1.1"));
+
+ assertNull(map.match("101.5.2.1"));
+ assertNull(map.match("10.15.2.1"));
+ assertNull(map.match("10.5.22.1"));
+ assertNull(map.match("10.5.2.0"));
+
+ assertNull(map.match("16.32.64.96"));
+ assertNull(map.match("1.16.32.194"));
+ assertNull(map.match("1.16.31.64"));
+ assertNull(map.match("1.15.32.64"));
+ assertNull(map.match("0.16.32.64"));
+
+ assertNull(map.match("16.15.20.100"));
+ assertNull(map.match("15.10.63.100"));
+ assertNull(map.match("15.10.64.128"));
+ assertNull(map.match("15.11.32.95"));
+ assertNull(map.match("16.31.63.128"));
+ }
+}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java
index 4f1613e6e4..93716a4a74 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java
@@ -13,32 +13,28 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
-import junit.framework.TestCase;
+import org.junit.Test;
+
/**
*
*
*/
-public class LazyListTest extends TestCase
+public class LazyListTest
{
-
- /**
- * Constructor for LazyListTest.
- * @param arg0
- */
- public LazyListTest(String arg0)
- {
- super(arg0);
- }
-
/*
* Test for Object add(Object, Object)
*/
+ @Test
public void testAddObjectObject()
{
Object list=null;
@@ -79,6 +75,7 @@ public class LazyListTest extends TestCase
/*
* Test for Object add(Object, int, Object)
*/
+ @Test
public void testAddObjectintObject()
{
Object list=null;
@@ -100,7 +97,7 @@ public class LazyListTest extends TestCase
assertTrue(list instanceof List);
}
-
+ @Test
public void testAddCollection()
{
ArrayList l=new ArrayList();
@@ -118,6 +115,7 @@ public class LazyListTest extends TestCase
assertEquals("b",LazyList.get(list,3));
}
+ @Test
public void testEnsureSize()
{
assertTrue(LazyList.ensureSize(null,10)!=null);
@@ -134,6 +132,7 @@ public class LazyListTest extends TestCase
/*
* Test for Object remove(Object, Object)
*/
+ @Test
public void testRemoveObjectObject()
{
Object list=null;
@@ -166,6 +165,7 @@ public class LazyListTest extends TestCase
/*
* Test for Object remove(Object, int)
*/
+ @Test
public void testRemoveObjectint()
{
Object list=null;
@@ -197,6 +197,7 @@ public class LazyListTest extends TestCase
/*
* Test for List getList(Object)
*/
+ @Test
public void testGetListObject()
{
assertEquals(0,LazyList.getList(null).size());
@@ -211,12 +212,14 @@ public class LazyListTest extends TestCase
/*
* Test for List getList(Object, boolean)
*/
+ @Test
public void testGetListObjectboolean()
{
assertEquals(0,LazyList.getList(null,false).size());
assertEquals(null,LazyList.getList(null,true));
}
+ @Test
public void testToStringArray()
{
assertEquals(0,LazyList.toStringArray(null).length);
@@ -237,6 +240,7 @@ public class LazyListTest extends TestCase
}
+ @Test
public void testSize()
{
ArrayList l=new ArrayList();
@@ -249,6 +253,7 @@ public class LazyListTest extends TestCase
assertEquals(2,LazyList.size(l));
}
+ @Test
public void testGet()
{
testAddObjectObject();
@@ -274,6 +279,7 @@ public class LazyListTest extends TestCase
}
}
+ @Test
public void testContains()
{
ArrayList l=new ArrayList();
@@ -289,8 +295,7 @@ public class LazyListTest extends TestCase
}
-
-
+ @Test
public void testIterator()
{
ArrayList l=new ArrayList();
@@ -312,6 +317,7 @@ public class LazyListTest extends TestCase
assertFalse(i.hasNext());
}
+ @Test
public void testListIterator()
{
ArrayList l=new ArrayList();
@@ -341,6 +347,7 @@ public class LazyListTest extends TestCase
assertEquals("a",i.previous());
}
+ @Test
public void testCloneToString()
{
ArrayList l=new ArrayList();
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 8bbc66aa99..7777a6779a 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
@@ -3,9 +3,16 @@ package org.eclipse.jetty.util;
import java.io.IOException;
import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-public class MultiExceptionTest extends TestCase
+import org.junit.Test;
+
+
+public class MultiExceptionTest
{
+ @Test
public void testEmpty() throws Exception
{
MultiException me = new MultiException();
@@ -16,6 +23,7 @@ public class MultiExceptionTest extends TestCase
me.ifExceptionThrowRuntime();
}
+ @Test
public void testOne() throws Exception
{
MultiException me = new MultiException();
@@ -69,6 +77,7 @@ public class MultiExceptionTest extends TestCase
}
}
+ @Test
public void testTwo() throws Exception
{
MultiException me = new MultiException();
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
index b3b4f1d392..b4835a48bd 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
@@ -34,16 +34,16 @@ public class MultiPartInputStreamTest extends TestCase
{
protected String _contentType = "multipart/form-data, boundary=AaB03x";
protected String _multi =
- "--AaB03x\n"+
- "content-disposition: form-data; name=\"field1\"\n"+
+ "--AaB03x\r\n"+
+ "content-disposition: form-data; name=\"field1\"\r\n"+
"\r\n"+
- "Joe Blow\n"+
- "--AaB03x\n"+
- "content-disposition: form-data; name=\"stuff\"; filename=\"stuff.txt\"\n"+
- "Content-Type: text/plain\n"+
+ "Joe Blow\r\n"+
+ "--AaB03x\r\n"+
+ "content-disposition: form-data; name=\"stuff\"; filename=\"stuff.txt\"\r\n"+
+ "Content-Type: text/plain\r\n"+
"\r\n"+
- "000000000000000000000000000000000000000000000000000\n"+
- "--AaB03x--";
+ "000000000000000000000000000000000000000000000000000\r\n"+
+ "--AaB03x--\r\n";
protected String _dirname = System.getProperty("java.io.tmpdir")+File.separator+"myfiles-"+System.currentTimeMillis();
@@ -112,7 +112,7 @@ public class MultiPartInputStreamTest extends TestCase
throws Exception
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
- MultiPartInputStream mpis = new MultiPartInputStream(new ByteArrayInputStream(_multi.getBytes()),
+ MultiPartInputStream mpis = new MultiPartInputStream(new ByteArrayInputStream(_multi.getBytes()),
_contentType,
config);
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java
index 8c2253163a..7048e9b1ee 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java
@@ -13,27 +13,23 @@
package org.eclipse.jetty.util;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
/**
*
*
*/
-public class QuotedStringTokenizerTest extends TestCase
+public class QuotedStringTokenizerTest
{
-
- /**
- * Constructor for QuotedStringTokenizerTest.
- * @param arg0
- */
- public QuotedStringTokenizerTest(String arg0)
- {
- super(arg0);
- }
-
/*
* Test for String nextToken()
*/
+ @Test
public void testTokenizer0()
{
QuotedStringTokenizer tok =
@@ -44,6 +40,7 @@ public class QuotedStringTokenizerTest extends TestCase
/*
* Test for String nextToken()
*/
+ @Test
public void testTokenizer1()
{
QuotedStringTokenizer tok =
@@ -55,6 +52,7 @@ public class QuotedStringTokenizerTest extends TestCase
/*
* Test for String nextToken()
*/
+ @Test
public void testTokenizer2()
{
QuotedStringTokenizer tok =
@@ -70,6 +68,7 @@ public class QuotedStringTokenizerTest extends TestCase
/*
* Test for String nextToken()
*/
+ @Test
public void testTokenizer3()
{
QuotedStringTokenizer tok;
@@ -91,6 +90,7 @@ public class QuotedStringTokenizerTest extends TestCase
checkTok(tok,true,true);
}
+ @Test
public void testQuote()
{
StringBuffer buf = new StringBuffer();
@@ -108,11 +108,11 @@ public class QuotedStringTokenizerTest extends TestCase
assertEquals("\"abcefg\\\"\"",buf.toString());
buf.setLength(0);
- QuotedStringTokenizer.quoteIfNeeded(buf,"abc \n efg");
+ QuotedStringTokenizer.quoteIfNeeded(buf,"abc \n efg","\"\\\n\r\t\f\b%+ ;=");
assertEquals("\"abc \\n efg\"",buf.toString());
buf.setLength(0);
- QuotedStringTokenizer.quoteIfNeeded(buf,"abcefg");
+ QuotedStringTokenizer.quoteIfNeeded(buf,"abcefg","\"\\\n\r\t\f\b%+ ;=");
assertEquals("abcefg",buf.toString());
}
@@ -120,6 +120,7 @@ public class QuotedStringTokenizerTest extends TestCase
/*
* Test for String nextToken()
*/
+ @Test
public void testTokenizer4()
{
QuotedStringTokenizer tok = new QuotedStringTokenizer("abc'def,ghi'jkl",",");
@@ -150,21 +151,24 @@ public class QuotedStringTokenizerTest extends TestCase
/*
* Test for String quote(String, String)
*/
+ @Test
public void testQuoteString()
{
- assertEquals("abc",QuotedStringTokenizer.quote("abc", " ,"));
- assertEquals("\"a c\"",QuotedStringTokenizer.quote("a c", " ,"));
- assertEquals("\"a'c\"",QuotedStringTokenizer.quote("a'c", " ,"));
- assertEquals("\"a\\n\\r\\t\"",QuotedStringTokenizer.quote("a\n\r\t"));
+ assertEquals("abc",QuotedStringTokenizer.quoteIfNeeded("abc", " ,"));
+ assertEquals("\"a c\"",QuotedStringTokenizer.quoteIfNeeded("a c", " ,"));
+ assertEquals("\"a'c\"",QuotedStringTokenizer.quoteIfNeeded("a'c", " ,"));
+ assertEquals("\"a\\n\\r\\t\"",QuotedStringTokenizer.quote("a\n\r\t"));
+ assertEquals("\"\\u0000\\u001f\"",QuotedStringTokenizer.quote("\u0000\u001f"));
}
-
+ @Test
public void testUnquote()
{
assertEquals("abc",QuotedStringTokenizer.unquote("abc"));
assertEquals("a\"c",QuotedStringTokenizer.unquote("\"a\\\"c\""));
assertEquals("a'c",QuotedStringTokenizer.unquote("\"a'c\""));
assertEquals("a\n\r\t",QuotedStringTokenizer.unquote("\"a\\n\\r\\t\""));
+ assertEquals("\u0000\u001f ",QuotedStringTokenizer.unquote("\"\u0000\u001f\u0020\""));
}
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/StringMapTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/StringMapTest.java
index ce27d67600..5f0c075f98 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/StringMapTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/StringMapTest.java
@@ -13,6 +13,10 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
@@ -20,37 +24,28 @@ import java.io.ObjectOutputStream;
import java.util.Map;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
/**
*
*
*/
-public class StringMapTest extends TestCase
+public class StringMapTest
{
StringMap m0;
StringMap m1;
StringMap m5;
StringMap m5i;
- /**
- * Constructor for StringMapTest.
- * @param arg0
- */
- public StringMapTest(String arg0)
- {
- super(arg0);
- }
-
/*
* @see TestCase#setUp()
*/
- @Override
- protected void setUp() throws Exception
+
+ @Before
+ public void setUp() throws Exception
{
- super.setUp();
-
m0=new StringMap();
m1=new StringMap(false);
m1.put("abc", "0");
@@ -70,15 +65,7 @@ public class StringMapTest extends TestCase
m5i.put("bbb", null);
}
- /*
- * @see TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
+ @Test
public void testSize()
{
assertEquals(0, m0.size());
@@ -96,6 +83,7 @@ public class StringMapTest extends TestCase
assertEquals(5, m5i.size());
}
+ @Test
public void testIsEmpty()
{
assertTrue(m0.isEmpty());
@@ -104,6 +92,7 @@ public class StringMapTest extends TestCase
assertFalse(m5i.isEmpty());
}
+ @Test
public void testClear()
{
m0.clear();
@@ -123,6 +112,7 @@ public class StringMapTest extends TestCase
/*
* Test for Object put(Object, Object)
*/
+ @Test
public void testPutGet()
{
assertEquals("2",m5.get("abc"));
@@ -146,11 +136,10 @@ public class StringMapTest extends TestCase
}
-
-
/*
* Test for Map.Entry getEntry(String, int, int)
*/
+ @Test
public void testGetEntryStringintint()
{
Map.Entry entry;
@@ -187,6 +176,7 @@ public class StringMapTest extends TestCase
/*
* Test for Map.Entry getEntry(char[], int, int)
*/
+ @Test
public void testGetEntrycharArrayintint()
{
char[] xabcyz = {'x','a','b','c','y','z'};
@@ -210,6 +200,7 @@ public class StringMapTest extends TestCase
/*
* Test for Object remove(Object)
*/
+ @Test
public void testRemove()
{
m0.remove("abc");
@@ -230,10 +221,10 @@ public class StringMapTest extends TestCase
assertEquals(null,m5i.get(null));
}
-
/*
* Test for Set entrySet()
*/
+ @Test
public void testEntrySet()
{
Set es0=m0.entrySet();
@@ -247,6 +238,7 @@ public class StringMapTest extends TestCase
/*
* Test for boolean containsKey(Object)
*/
+ @Test
public void testContainsKey()
{
assertTrue(m5.containsKey("abc"));
@@ -260,6 +252,7 @@ public class StringMapTest extends TestCase
assertTrue(m5i.containsKey("ABC"));
}
+ @Test
public void testWriteExternal()
throws Exception
{
@@ -288,6 +281,7 @@ public class StringMapTest extends TestCase
}
+ @Test
public void testToString()
{
assertEquals("{}",m0.toString());
@@ -295,7 +289,7 @@ public class StringMapTest extends TestCase
assertTrue(m5.toString().indexOf("abc=2")>0);
}
-
+ @Test
public void testIgnoreCase()
{
StringMap map = new StringMap(true);
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java
index 10d2a51bdb..52d9f8fb9a 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java
@@ -13,43 +13,20 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
-import junit.framework.TestCase;
/**
*
*
*/
-public class StringUtilTest extends TestCase
+public class StringUtilTest
{
-
- /**
- * Constructor for StringUtilTest.
- * @param arg0
- */
- public StringUtilTest(String arg0)
- {
- super(arg0);
- }
-
- /*
- * @see TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- /*
- * @see TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
+ @Test
public void testAsciiToLowerCase()
{
String lc="\u0690bc def 1\u06903";
@@ -57,6 +34,7 @@ public class StringUtilTest extends TestCase
assertTrue(StringUtil.asciiToLowerCase(lc)==lc);
}
+ @Test
public void testStartsWithIgnoreCase()
{
@@ -74,6 +52,7 @@ public class StringUtilTest extends TestCase
assertFalse(StringUtil.startsWithIgnoreCase("\u0690", "xyz"));
}
+ @Test
public void testEndsWithIgnoreCase()
{
assertTrue(StringUtil.endsWithIgnoreCase("\u0690bcd\u0690f\u0690", "\u0690f\u0690"));
@@ -90,6 +69,7 @@ public class StringUtilTest extends TestCase
assertFalse(StringUtil.endsWithIgnoreCase("\u0690", "xyz"));
}
+ @Test
public void testIndexFrom()
{
assertEquals(StringUtil.indexFrom("\u0690bcd", "xyz"),-1);
@@ -98,6 +78,7 @@ public class StringUtilTest extends TestCase
assertEquals(StringUtil.indexFrom("\u0690bcd", "dxy"),3);
}
+ @Test
public void testReplace()
{
String s="\u0690bc \u0690bc \u0690bc";
@@ -109,6 +90,7 @@ public class StringUtilTest extends TestCase
}
+ @Test
public void testUnquote()
{
String uq =" not quoted ";
@@ -120,6 +102,7 @@ public class StringUtilTest extends TestCase
}
+ @Test
public void testNonNull()
{
String nn="";
@@ -130,12 +113,14 @@ public class StringUtilTest extends TestCase
/*
* Test for boolean equals(String, char[], int, int)
*/
+ @Test
public void testEqualsStringcharArrayintint()
{
assertTrue(StringUtil.equals("\u0690bc", new char[] {'x','\u0690','b','c','z'},1,3));
assertFalse(StringUtil.equals("axc", new char[] {'x','a','b','c','z'},1,3));
}
+ @Test
public void testAppend()
{
StringBuilder buf = new StringBuilder();
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java b/jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java
index 91ed6f3acf..e85ee76a16 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java
@@ -13,35 +13,40 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import junit.framework.TestCase;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
/**
* TestInjection
*
*
*/
-public class TestIntrospectionUtil extends TestCase
+public class TestIntrospectionUtil
{
- public final Class[] __INTEGER_ARG = new Class[] {Integer.class};
- Field privateAField;
- Field protectedAField;
- Field publicAField;
- Field defaultAField;
- Field privateBField;
- Field protectedBField;
- Field publicBField;
- Field defaultBField;
- Method privateCMethod;
- Method protectedCMethod;
- Method publicCMethod;
- Method defaultCMethod;
- Method privateDMethod;
- Method protectedDMethod;
- Method publicDMethod;
- Method defaultDMethod;
+ public final static Class[] __INTEGER_ARG = new Class[] {Integer.class};
+ static Field privateAField;
+ static Field protectedAField;
+ static Field publicAField;
+ static Field defaultAField;
+ static Field privateBField;
+ static Field protectedBField;
+ static Field publicBField;
+ static Field defaultBField;
+ static Method privateCMethod;
+ static Method protectedCMethod;
+ static Method publicCMethod;
+ static Method defaultCMethod;
+ static Method privateDMethod;
+ static Method protectedDMethod;
+ static Method publicDMethod;
+ static Method defaultDMethod;
public class ServletA
{
@@ -75,8 +80,8 @@ public class TestIntrospectionUtil extends TestCase
void setDefaultD(Integer d) {}
}
- @Override
- public void setUp()
+ @BeforeClass
+ public static void setUp()
throws Exception
{
privateAField = ServletA.class.getDeclaredField("privateA");
@@ -97,7 +102,7 @@ public class TestIntrospectionUtil extends TestCase
defaultDMethod = ServletD.class.getDeclaredMethod("setDefaultD", __INTEGER_ARG);
}
-
+ @Test
public void testFieldPrivate ()
throws Exception
{
@@ -117,6 +122,7 @@ public class TestIntrospectionUtil extends TestCase
}
}
+ @Test
public void testFieldProtected()
throws Exception
{
@@ -129,6 +135,7 @@ public class TestIntrospectionUtil extends TestCase
assertEquals(f, protectedAField);
}
+ @Test
public void testFieldPublic()
throws Exception
{
@@ -141,6 +148,7 @@ public class TestIntrospectionUtil extends TestCase
assertEquals(f, publicAField);
}
+ @Test
public void testFieldDefault()
throws Exception
{
@@ -153,6 +161,7 @@ public class TestIntrospectionUtil extends TestCase
assertEquals(f, defaultAField);
}
+ @Test
public void testMethodPrivate ()
throws Exception
{
@@ -172,6 +181,7 @@ public class TestIntrospectionUtil extends TestCase
}
}
+ @Test
public void testMethodProtected ()
throws Exception
{
@@ -184,6 +194,7 @@ public class TestIntrospectionUtil extends TestCase
assertEquals(m, protectedCMethod);
}
+ @Test
public void testMethodPublic ()
throws Exception
{
@@ -196,6 +207,7 @@ public class TestIntrospectionUtil extends TestCase
assertEquals(m, publicCMethod);
}
+ @Test
public void testMethodDefault ()
throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/URITest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/URITest.java
index 80624ebf07..79f350ff1c 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/URITest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/URITest.java
@@ -13,34 +13,19 @@
package org.eclipse.jetty.util;
-import junit.framework.TestSuite;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
/* ------------------------------------------------------------ */
/** Util meta Tests.
*
*/
-public class URITest extends junit.framework.TestCase
+public class URITest
{
- public URITest(String name)
- {
- super(name);
- }
-
- public static junit.framework.Test suite() {
- TestSuite suite = new TestSuite(URITest.class);
- return suite;
- }
-
- /* ------------------------------------------------------------ */
- /** main.
- */
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
/* ------------------------------------------------------------ */
+ @Test
public void testEncodePath()
{
// test basic encode/decode
@@ -63,6 +48,7 @@ public class URITest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testDecodePath()
{
assertEquals("foo%23;,:=b a r",URIUtil.decodePath("foo%2523%3b%2c:%3db%20a%20r"));
@@ -72,6 +58,7 @@ public class URITest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testAddPaths()
{
assertEquals("null+null", URIUtil.addPaths(null,null),null);
@@ -161,6 +148,7 @@ public class URITest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testCompactPath()
{
assertEquals("/foo/bar", URIUtil.compactPath("/foo/bar"));
@@ -174,6 +162,7 @@ public class URITest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testParentPath()
{
assertEquals("parent /aaa/bbb/","/aaa/", URIUtil.parentPath("/aaa/bbb/"));
@@ -186,6 +175,7 @@ public class URITest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testCanonicalPath()
{
String[][] canonical =
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java
index 43d7a5d9f1..bee8052f4d 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java
@@ -13,38 +13,23 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
-import junit.framework.TestSuite;
+import org.junit.Test;
/* ------------------------------------------------------------ */
/** Util meta Tests.
*
*/
-public class URLEncodedTest extends junit.framework.TestCase
+public class URLEncodedTest
{
- public URLEncodedTest(String name)
- {
- super(name);
- }
-
- public static junit.framework.Test suite() {
- TestSuite suite = new TestSuite(URLEncodedTest.class);
- return suite;
- }
-
- /* ------------------------------------------------------------ */
- /** main.
- */
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
-
/* -------------------------------------------------------------- */
+ @Test
public void testUrlEncoded() throws UnsupportedEncodingException
{
@@ -147,6 +132,7 @@ public class URLEncodedTest extends junit.framework.TestCase
/* -------------------------------------------------------------- */
+ @Test
public void testUrlEncodedStream()
throws Exception
{
@@ -185,6 +171,7 @@ public class URLEncodedTest extends junit.framework.TestCase
}
/* -------------------------------------------------------------- */
+ @Test
public void testUtf8()
throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBufferTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBufferTest.java
index 2b65d76185..8601e6205f 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBufferTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBufferTest.java
@@ -13,10 +13,14 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
-public class Utf8StringBufferTest extends junit.framework.TestCase
-{
+public class Utf8StringBufferTest
+{
public void testUtfStringBuffer()
throws Exception
{
@@ -30,6 +34,7 @@ public class Utf8StringBufferTest extends junit.framework.TestCase
}
+ @Test
public void testShort()
throws Exception
{
@@ -49,6 +54,7 @@ public class Utf8StringBufferTest extends junit.framework.TestCase
}
}
+ @Test
public void testLong()
throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBuilderTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBuilderTest.java
index 4a20865f4b..6240218945 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBuilderTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8StringBuilderTest.java
@@ -13,10 +13,15 @@
package org.eclipse.jetty.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
-public class Utf8StringBuilderTest extends junit.framework.TestCase
-{
+public class Utf8StringBuilderTest
+{
+ @Test
public void testUtfStringBuilder()
throws Exception
{
@@ -29,6 +34,7 @@ public class Utf8StringBuilderTest extends junit.framework.TestCase
assertTrue(buffer.toString().endsWith("jetty"));
}
+ @Test
public void testShort()
throws Exception
{
@@ -48,6 +54,7 @@ public class Utf8StringBuilderTest extends junit.framework.TestCase
}
}
+ @Test
public void testLong()
throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java
index aea0c8f8c3..c4d78105c3 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java
@@ -13,14 +13,18 @@
package org.eclipse.jetty.util.ajax;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
/**
* Test to convert POJOs to JSON and vice versa with automatic convertor creation.
*/
-public class JSONPojoConvertorFactoryTest extends TestCase {
-
+public class JSONPojoConvertorFactoryTest
+{
+ @Test
public void testFoo()
{
JSON jsonOut = new JSON();
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java
index 3f193ba280..4fdd24cbda 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java
@@ -13,15 +13,20 @@
package org.eclipse.jetty.util.ajax;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+
/**
* Test to converts POJOs to JSON and vice versa.
- *
- *
- *
*/
-public class JSONPojoConvertorTest extends TestCase
+public class JSONPojoConvertorTest
{
+ @Test
public void testFoo()
{
JSON json = new JSON();
@@ -66,6 +71,7 @@ public class JSONPojoConvertorTest extends TestCase
assertEquals(Color.Green,br.getColor());
}
+ @Test
public void testExclude()
{
JSON json = new JSON();
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java
index 0b77acc962..851e729fdf 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java
@@ -12,6 +12,10 @@
// ========================================================================
package org.eclipse.jetty.util.ajax;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.StringReader;
import java.lang.reflect.Array;
import java.math.BigDecimal;
@@ -21,12 +25,13 @@ import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.util.DateCache;
import org.eclipse.jetty.util.ajax.JSON.Output;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
-public class JSONTest extends TestCase
+public class JSONTest
{
String test="\n\n\n\t\t "+
"// ignore this ,a [ \" \n"+
@@ -45,6 +50,17 @@ public class JSONTest extends TestCase
"\"undefined\": undefined," +
"}";
+ /* ------------------------------------------------------------ */
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ @BeforeClass
+ public static void setUp() throws Exception
+ {
+ JSON.registerConvertor(Gadget.class,new JSONObjectConvertor(false));
+ }
+
+ @Test
public void testToString()
{
HashMap map = new HashMap();
@@ -94,26 +110,16 @@ public class JSONTest extends TestCase
gadget.setWoggles(new Woggle[]{w0,w1});
s = JSON.toString(new Gadget[]{gadget});
+ System.out.println(s);
assertTrue(s.startsWith("["));
assertTrue(s.indexOf("\"modulated\":false")>=0);
assertTrue(s.indexOf("\"shields\":42")>=0);
assertTrue(s.indexOf("\"name\":\"woggle0\"")>=0);
assertTrue(s.indexOf("\"name\":\"woggle1\"")>=0);
-
- }
-
-
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception
- {
- JSON.registerConvertor(Gadget.class,new JSONObjectConvertor(false));
}
/* ------------------------------------------------------------ */
+ @Test
public void testParse()
{
Map map = (Map)JSON.parse(test);
@@ -134,6 +140,7 @@ public class JSONTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testParseReader() throws Exception
{
Map map = (Map)JSON.parse(new StringReader(test));
@@ -149,6 +156,7 @@ public class JSONTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testStripComment()
{
String test="\n\n\n\t\t "+
@@ -171,6 +179,7 @@ public class JSONTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testQuote()
{
String test="\"abc123|\\\"|\\\\|\\/|\\b|\\f|\\n|\\r|\\t|\\uaaaa|\"";
@@ -180,6 +189,7 @@ public class JSONTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testBigDecimal()
{
Object obj = JSON.parse("1.0E7");
@@ -189,6 +199,16 @@ public class JSONTest extends TestCase
obj = Array.get(JSON.parse(string),0);
assertTrue(obj instanceof Double);
}
+
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testZeroByte()
+ {
+ String withzero="\u0000";
+ String json = JSON.toString(withzero);
+ System.err.println(json);
+ }
/* ------------------------------------------------------------ */
public static class Gadget
@@ -247,6 +267,7 @@ public class JSONTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testConvertor()
{
// test case#1 - force timezone to GMT
@@ -316,6 +337,7 @@ public class JSONTest extends TestCase
enum Color { Red, Green, Blue };
+ @Test
public void testEnumConvertor()
{
JSON json = new JSON();
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java
index 528c9241d3..9bc149c1f5 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java
@@ -13,34 +13,20 @@
package org.eclipse.jetty.util.component;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
+import org.junit.Test;
-public class LifeCycleListenerTest extends TestCase
+
+public class LifeCycleListenerTest
{
static Exception cause = new Exception("expected test exception");
- public LifeCycleListenerTest(String name)
- {
- super(name);
- }
-
- public static void main(String[] args)
- {
- TestRunner.run(suite());
- }
-
- public static Test suite()
- {
- TestSuite suite = new TestSuite(LifeCycleListenerTest.class);
- return suite;
- }
-
+ @Test
public void testStart() throws Exception
{
TestLifeCycle lifecycle = new TestLifeCycle();
@@ -78,6 +64,7 @@ public class LifeCycleListenerTest extends TestCase
assertTrue("The lifecycle state is not started",lifecycle.isStarted());
}
+ @Test
public void testStop() throws Exception
{
TestLifeCycle lifecycle = new TestLifeCycle();
@@ -126,6 +113,7 @@ public class LifeCycleListenerTest extends TestCase
}
+ @Test
public void testRemoveLifecycleListener ()
throws Exception
{
@@ -178,7 +166,7 @@ public class LifeCycleListenerTest extends TestCase
- private class TestListener implements LifeCycle.Listener
+ private class TestListener extends AbstractLifeCycle.AbstractLifeCycleListener
{
private boolean failure = false;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
index a200721ffb..957eaee595 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
@@ -13,26 +13,31 @@
package org.eclipse.jetty.util.log;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
-import junit.framework.TestCase;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
-public class LogTest extends TestCase
+public class LogTest
{
- PrintStream _orig= System.err;
- ByteArrayOutputStream _out = new ByteArrayOutputStream();
- PrintStream _pout = new PrintStream(_out);
+ static PrintStream _orig= System.err;
+ static ByteArrayOutputStream _out = new ByteArrayOutputStream();
+ static PrintStream _pout = new PrintStream(_out);
- @Override
- public void setUp()
+ @BeforeClass
+ public static void setUp()
{
System.setErr(_pout);
}
- @Override
- public void tearDown()
+ @AfterClass
+ public static void tearDown()
{
System.setErr(_orig);
}
@@ -64,6 +69,7 @@ public class LogTest extends TestCase
assertTrue(false);
}
+ @Test
public void testStdErrLogFormat()
{
StdErrLog log = new StdErrLog("test");
@@ -90,6 +96,7 @@ public class LogTest extends TestCase
logContains("INFO:test:testing");
}
+ @Test
public void testStdErrLogDebug()
{
StdErrLog log = new StdErrLog("xxx");
@@ -109,6 +116,7 @@ public class LogTest extends TestCase
logNotContains("YOU SHOULD NOT SEE THIS!");
}
+ @Test
public void testStdErrLogName()
{
StdErrLog log = new StdErrLog("test");
@@ -119,6 +127,7 @@ public class LogTest extends TestCase
}
+ @Test
public void testStdErrThrowable()
{
Throwable th = new Throwable("Message");
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
index bdda51facd..2a0ffcf005 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
@@ -4,7 +4,7 @@
// 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
+// 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
@@ -18,43 +18,44 @@ import junit.framework.TestCase;
/**
* @author mgorovoy
* */
-public class StdErrLogTest extends TestCase
+public class StdErrLogTest extends TestCase
{
public void testNullValues()
{
StdErrLog log = new StdErrLog();
log.setDebugEnabled(true);
-
+ log.setHideStacks(true);
+
try {
log.info("Testing info(msg,null,null) - {} {}",null,null);
log.info("Testing info(msg,null,null) - {}",null,null);
log.info("Testing info(msg,null,null)",null,null);
log.info(null,"- Testing","info(null,arg0,arg1)");
log.info(null,null,null);
-
+
log.debug("Testing debug(msg,null,null) - {} {}",null,null);
log.debug("Testing debug(msg,null,null) - {}",null,null);
log.debug("Testing debug(msg,null,null)",null,null);
log.debug(null,"- Testing","debug(null,arg0,arg1)");
log.debug(null,null,null);
-
- log.debug("Testing debug(msg,null)",null);
+
+ log.debug("Testing debug(msg,null)");
log.debug(null,new Throwable("IGNORE::Testing debug(null,thrw)").fillInStackTrace());
-
+
log.warn("Testing warn(msg,null,null) - {} {}",null,null);
log.warn("Testing warn(msg,null,null) - {}",null,null);
log.warn("Testing warn(msg,null,null)",null,null);
log.warn(null,"- Testing","warn(msg,arg0,arg1)");
log.warn(null,null,null);
-
- log.warn("Testing warn(msg,null)",null);
+
+ log.warn("Testing warn(msg,null)");
log.warn(null,new Throwable("IGNORE::Testing warn(msg,thrw)").fillInStackTrace());
}
catch (NullPointerException npe)
{
- assertTrue("NullPointerException in StdErrLog.", false);
System.err.println(npe);
npe.printStackTrace();
+ assertTrue("NullPointerException in StdErrLog.", false);
}
}
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java
index 9317e51c39..7bc940bbac 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java
@@ -18,10 +18,20 @@ import java.io.File;
import java.io.InputStreamReader;
import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-public class ResourceCollectionTest extends TestCase
+import org.junit.Test;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+
+public class ResourceCollectionTest
{
+ @Test
public void testMutlipleSources1() throws Exception
{
ResourceCollection rc1 = new ResourceCollection(new String[]{
@@ -47,6 +57,7 @@ public class ResourceCollectionTest extends TestCase
System.err.println(s);
}
+ @Test
public void testMergedDir() throws Exception
{
ResourceCollection rc = new ResourceCollection(new String[]{
@@ -63,6 +74,7 @@ public class ResourceCollectionTest extends TestCase
assertEquals("3 - three", getContent(rc, "3.txt"));
}
+ @Test
public void testCopyTo() throws Exception
{
ResourceCollection rc = new ResourceCollection(new String[]{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
index 19f505efc4..6eadcb76c4 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
@@ -13,6 +13,10 @@
package org.eclipse.jetty.util.resource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FilePermission;
@@ -24,8 +28,11 @@ import java.util.jar.JarInputStream;
import junit.framework.TestSuite;
import org.eclipse.jetty.util.IO;
+import org.junit.BeforeClass;
+import org.junit.Test;
-public class ResourceTest extends junit.framework.TestCase
+
+public class ResourceTest
{
public static String __userDir = System.getProperty("basedir", ".");
@@ -36,7 +43,7 @@ public class ResourceTest extends junit.framework.TestCase
private static final boolean DIR=true;
private static final boolean EXISTS=true;
- class Data
+ static class Data
{
Resource resource;
String test;
@@ -93,27 +100,10 @@ public class ResourceTest extends junit.framework.TestCase
}
public static Data[] data;
-
- public ResourceTest(String name)
- {
- super(name);
- }
-
- /* ------------------------------------------------------------ */
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
- /* ------------------------------------------------------------ */
- public static junit.framework.Test suite()
- {
- return new TestSuite(ResourceTest.class);
- }
/* ------------------------------------------------------------ */
- @Override
- protected void setUp()
+ @BeforeClass
+ public static void setUp()
throws Exception
{
if (data!=null)
@@ -189,16 +179,8 @@ public class ResourceTest extends junit.framework.TestCase
}
-
- /* ------------------------------------------------------------ */
- @Override
- protected void tearDown()
- throws Exception
- {
- }
-
-
/* ------------------------------------------------------------ */
+ @Test
public void testResourceExists()
{
for (int i=0;i<data.length;i++)
@@ -211,6 +193,7 @@ public class ResourceTest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testResourceDir()
{
for (int i=0;i<data.length;i++)
@@ -223,6 +206,7 @@ public class ResourceTest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testResourceContent()
throws Exception
{
@@ -238,6 +222,7 @@ public class ResourceTest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testEncoding() throws Exception
{
Resource r =Resource.newResource("/tmp/a file with,spe#ials/");
@@ -246,6 +231,7 @@ public class ResourceTest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testJarFile()
throws Exception
{
@@ -256,9 +242,9 @@ public class ResourceTest extends junit.framework.TestCase
JarInputStream jin = new JarInputStream(is);
assertNotNull(is);
assertNotNull(jin);
-
}
+ @Test
public void testJarFileIsContainedIn ()
throws Exception
{
@@ -276,6 +262,7 @@ public class ResourceTest extends junit.framework.TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testJarFileCopyToDirectoryTraversal () throws Exception
{
String s = "jar:"+__userURL+"TestData/extract.zip!/";
@@ -333,6 +320,7 @@ public class ResourceTest extends junit.framework.TestCase
/**
* Test a class path resource for existence.
*/
+ @Test
public void testClassPathResourceClassRelative()
{
final String classPathName="Resource.class";
@@ -351,6 +339,7 @@ public class ResourceTest extends junit.framework.TestCase
/**
* Test a class path resource for existence.
*/
+ @Test
public void testClassPathResourceClassAbsolute()
{
final String classPathName="/org/eclipse/jetty/util/resource/Resource.class";
@@ -369,6 +358,7 @@ public class ResourceTest extends junit.framework.TestCase
/**
* Test a class path resource for directories.
*/
+ @Test
public void testClassPathResourceDirectory() throws Exception
{
final String classPathName="/";
@@ -390,6 +380,7 @@ public class ResourceTest extends junit.framework.TestCase
/**
* Test a class path resource for a file.
*/
+ @Test
public void testClassPathResourceFile() throws Exception
{
final String fileName="resource.txt";
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java
index 3031aefcb8..14be1dd65f 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java
@@ -1,12 +1,13 @@
package org.eclipse.jetty.util.statistic;
-import org.eclipse.jetty.util.statistic.SampleStatistic;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-import junit.framework.TestCase;
+import org.junit.Test;
/* ------------------------------------------------------------ */
-public class SampleStatisticTest extends TestCase
+public class SampleStatisticTest
{
private static long[][] data =
{
@@ -26,6 +27,7 @@ public class SampleStatisticTest extends TestCase
};
+ @Test
public void testData()
throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java
index a8910eb342..59cd536b9f 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java
@@ -11,14 +11,17 @@
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-
package org.eclipse.jetty.util.thread;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.util.concurrent.atomic.AtomicInteger;
-import junit.framework.TestCase;
+import org.junit.Test;
+
-public class QueuedThreadPoolTest extends TestCase
+public class QueuedThreadPoolTest
{
final AtomicInteger _jobs=new AtomicInteger();
volatile long _sleep=100;
@@ -44,6 +47,7 @@ public class QueuedThreadPoolTest extends TestCase
+ @Test
public void testThreadPool() throws Exception
{
_sleep=100;
@@ -129,6 +133,7 @@ public class QueuedThreadPoolTest extends TestCase
tp.stop();
}
+ @Test
public void testShrink() throws Exception
{
Runnable job = new Runnable()
@@ -184,6 +189,7 @@ public class QueuedThreadPoolTest extends TestCase
}
+ @Test
public void testMaxStopTime() throws Exception
{
_sleep=100;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/TimeoutTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/TimeoutTest.java
index 11eccd5b15..ceca63281b 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/TimeoutTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/TimeoutTest.java
@@ -13,11 +13,15 @@
package org.eclipse.jetty.util.thread;
+import static org.junit.Assert.assertEquals;
+
import java.util.concurrent.atomic.AtomicIntegerArray;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
-public class TimeoutTest extends TestCase
+public class TimeoutTest
{
private boolean _stress=Boolean.getBoolean("STRESS");
@@ -29,11 +33,9 @@ public class TimeoutTest extends TestCase
/*
* @see junit.framework.TestCase#setUp()
*/
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void setUp() throws Exception
{
- super.setUp();
-
timeout=new Timeout(lock);
tasks= new Timeout.Task[10];
@@ -47,17 +49,7 @@ public class TimeoutTest extends TestCase
}
/* ------------------------------------------------------------ */
- /*
- * @see junit.framework.TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- }
-
-
- /* ------------------------------------------------------------ */
+ @Test
public void testExpiry()
{
timeout.setDuration(200);
@@ -71,6 +63,7 @@ public class TimeoutTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testCancel()
{
timeout.setDuration(200);
@@ -89,6 +82,7 @@ public class TimeoutTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testTouch()
{
timeout.setDuration(200);
@@ -112,6 +106,7 @@ public class TimeoutTest extends TestCase
/* ------------------------------------------------------------ */
+ @Test
public void testDelay()
{
Timeout.Task task = new Timeout.Task();
@@ -134,6 +129,7 @@ public class TimeoutTest extends TestCase
}
/* ------------------------------------------------------------ */
+ @Test
public void testStress() throws Exception
{
if ( !_stress )
diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml
index cde62c1de1..1ae874368b 100644
--- a/jetty-webapp/pom.xml
+++ b/jetty-webapp/pom.xml
@@ -13,32 +13,22 @@
</properties>
<build>
<resources>
- <resource><directory>src/main/resources</directory></resource>
- <resource><directory>target/generated-resources</directory></resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/config/etc</directory>
+ <targetPath>org/eclipse/jetty/webapp</targetPath>
+ <filtering>false</filtering>
+ <includes>
+ <include>webdefault.xml</include>
+ </includes>
+ </resource>
</resources>
<plugins>
<plugin>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>run</goal>
- </goals>
- <configuration>
- <tasks>
- <copy failonerror="true" file="${basedir}/src/main/config/etc/webdefault.xml" toFile="${project.build.directory}/generated-resources/org/eclipse/jetty/webapp/webdefault.xml" />
- </tasks>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins
- </groupId>
- <artifactId>maven-assembly-plugin
- </artifactId>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
@@ -71,8 +61,7 @@
<!--
Required for OSGI
-->
- <groupId>org.apache.maven.plugins
- </groupId>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
@@ -82,10 +71,12 @@
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.webapp.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -98,12 +89,13 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlet</artifactId>
- <version>${project.version}</version>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
</project>
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java
new file mode 100644
index 0000000000..a7c2185fb6
--- /dev/null
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java
@@ -0,0 +1,262 @@
+// ========================================================================
+// Copyright (c) 2009-2009 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.webapp;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * ClasspathPattern performs sequential pattern matching of a class name
+ * against an internal array of classpath pattern entries.
+ *
+ * When an entry starts with '-' (minus), reverse matching is performed.
+ * When an entry ends with '.' (period), prefix matching is performed.
+ *
+ * When class is initialized from a classpath pattern string, entries
+ * in this string should be separated by ':' (semicolon) or ',' (comma).
+ */
+
+public class ClasspathPattern
+{
+ private class Entry
+ {
+ public String classpath = null;
+ public boolean result = false;
+ public boolean partial = false;
+ }
+
+ private ArrayList<String> _patterns = null;
+ private ArrayList<Entry> _entries = null;
+
+ public ClasspathPattern(String[] patterns)
+ {
+ setPatterns(patterns);
+ }
+
+ public ClasspathPattern(String pattern)
+ {
+ setPattern(pattern);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Create a new instance from a String array of classpath patterns
+ *
+ * @param patterns array of classpath patterns
+ * @return new instance
+ */
+ public static ClasspathPattern fromArray(String[] patterns)
+ {
+ return new ClasspathPattern(patterns);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Create a new instance from a classpath pattern sring
+ *
+ * @param patterns classpath pattern string
+ * @return new instance
+ */
+ public static ClasspathPattern fromString(String patterns)
+ {
+ return new ClasspathPattern(patterns);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Initialize the matcher by parsing each classpath pattern in an array
+ *
+ * @param patterns array of classpath patterns
+ */
+ private void setPatterns(String[] patterns)
+ {
+ if (patterns == null)
+ {
+ _patterns = null;
+ _entries = null;
+ }
+ else
+ {
+ _patterns = new ArrayList<String>();
+ _entries = new ArrayList<Entry>();
+ }
+
+ if (_patterns != null) {
+ Entry entry = null;
+ for (String pattern : patterns)
+ {
+ entry = createEntry(pattern);
+ if (entry != null) {
+ _patterns.add(pattern);
+ _entries.add(entry);
+ }
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Initialize the matcher by parsing each classpath pattern in an array
+ *
+ * @param patterns array of classpath patterns
+ */
+ private void addPatterns(String[] patterns)
+ {
+ if (patterns != null)
+ {
+ if (_patterns == null)
+ {
+ setPatterns(patterns);
+ }
+ else
+ {
+ Entry entry = null;
+ for (String pattern : patterns)
+ {
+ entry = createEntry(pattern);
+ if (entry != null) {
+ _patterns.add(pattern);
+ _entries.add(entry);
+ }
+ }
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Create an entry object containing information about
+ * a single classpath pattern
+ *
+ * @param pattern single classpath pattern
+ * @return corresponding Entry object
+ */
+ private Entry createEntry(String pattern)
+ {
+ Entry entry = null;
+
+ if (pattern != null)
+ {
+ String item = pattern.trim();
+ if (item.length() > 0)
+ {
+ entry = new Entry();
+ entry.result = !item.startsWith("-");
+ entry.partial = item.endsWith(".");
+ entry.classpath = entry.result ? item : item.substring(1).trim();
+ }
+ }
+ return entry;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Initialize the matcher by parsing a classpath pattern string
+ *
+ * @param pattern classpath pattern string
+ */
+ public void setPattern(String pattern)
+ {
+ ArrayList<String> patterns = new ArrayList<String>();
+ StringTokenizer entries = new StringTokenizer(pattern, ":,");
+ while (entries.hasMoreTokens())
+ {
+ patterns.add(entries.nextToken());
+ }
+
+ setPatterns((String[])patterns.toArray());
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Parse a classpath pattern string and appending the result
+ * to the existing configuration.
+ *
+ * @param pattern classpath pattern string
+ */
+ public void addPattern(String pattern)
+ {
+ ArrayList<String> patterns = new ArrayList<String>();
+ StringTokenizer entries = new StringTokenizer(pattern, ":,");
+ while (entries.hasMoreTokens())
+ {
+ patterns.add(entries.nextToken());
+ }
+
+ addPatterns((String[])patterns.toArray());
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return array of classpath patterns
+ */
+ public String[] getPatterns()
+ {
+ String[] patterns = null;
+
+ if (_patterns!=null)
+ {
+ patterns = _patterns.toArray(new String[_patterns.size()]);
+ }
+
+ return patterns;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Match the class name against the pattern
+ *
+ * @param name name of the class to match
+ * @return true if class matches the pattern
+ */
+ public boolean match(String name)
+ {
+ boolean result=false;
+
+ if (_entries != null)
+ {
+ int startIdx = 0;
+ name = name.replace('/','.');
+ name = name.replaceFirst("^[.]+","");
+
+ for (Entry entry : _entries)
+ {
+ if (entry != null)
+ {
+ if (entry.partial)
+ {
+ if (name.startsWith(entry.classpath))
+ {
+ result = entry.result;
+ break;
+ }
+ }
+ else
+ {
+ if (name.equals(entry.classpath))
+ {
+ result = entry.result;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java
index 70c9a51ccd..e7331f6972 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java
@@ -22,7 +22,7 @@ import org.eclipse.jetty.util.resource.Resource;
*/
public class DefaultsDescriptor extends Descriptor
{
- public DefaultsDescriptor(Resource xml, WebXmlProcessor processor)
+ public DefaultsDescriptor(Resource xml, MetaData processor)
{
super(xml, processor);
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java
index 8e3458589a..e6aca3c819 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java
@@ -23,8 +23,6 @@ import javax.servlet.Servlet;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebXmlProcessor.AbsoluteOrdering;
-import org.eclipse.jetty.webapp.WebXmlProcessor.Ordering;
import org.eclipse.jetty.xml.XmlParser;
@@ -35,37 +33,121 @@ import org.eclipse.jetty.xml.XmlParser;
* A web descriptor (web.xml/web-defaults.xml/web-overrides.xml).
*/
public class Descriptor
-{
+{
+ protected static XmlParser _parser;
public enum MetaDataComplete {NotSet, True, False};
protected Resource _xml;
protected XmlParser.Node _root;
protected MetaDataComplete _metaDataComplete;
protected int _majorVersion = 3; //default to container version
protected int _minorVersion = 0;
- protected ArrayList<String> _classNames;
+ protected ArrayList<String> _classNames = new ArrayList<String>();
protected boolean _distributable;
protected boolean _validating;
- protected WebXmlProcessor _processor;
+ protected MetaData _metaData;
protected boolean _isOrdered = false;
protected List<String> _ordering = new ArrayList<String>();
+
+ public static XmlParser newParser()
+ throws ClassNotFoundException
+ {
+ XmlParser xmlParser=new XmlParser();
+ //set up cache of DTDs and schemas locally
+ URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
+ URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
+ URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
+ URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
+ URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
+ URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
+ URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
+ URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
+ URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
+ URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
+ URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
+ URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
+ URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
+
+ URL jsp20xsd = null;
+ URL jsp21xsd = null;
+
+ try
+ {
+ Class jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
+ jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
+ jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
+ }
+ catch (Exception e)
+ {
+ Log.ignore(e);
+ }
+ finally
+ {
+ if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
+ if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
+ }
+
+ redirect(xmlParser,"web-app_2_2.dtd",dtd22);
+ redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
+ redirect(xmlParser,"web.dtd",dtd23);
+ redirect(xmlParser,"web-app_2_3.dtd",dtd23);
+ redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
+ redirect(xmlParser,"XMLSchema.dtd",schemadtd);
+ redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
+ redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
+ redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
+ redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
+ redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
+ redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
+ redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
+ redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd);
+ redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd);
+ redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd);
+ redirect(xmlParser,"xml.xsd",xmlxsd);
+ redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
+ redirect(xmlParser,"datatypes.dtd",datatypesdtd);
+ redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
+ redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
+ redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
+ redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
+ redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
+ return xmlParser;
+ }
+
- public Descriptor (Resource xml, WebXmlProcessor processor)
+ protected static void redirect(XmlParser parser, String resource, URL source)
+ {
+ if (source != null) parser.redirectEntity(resource, source);
+ }
+
+
+
+ public Descriptor (Resource xml, MetaData md)
{
_xml = xml;
- _processor = processor;
+ _metaData = md;
}
public void parse ()
throws Exception
{
+ if (_parser == null)
+ _parser = newParser();
+
if (_root == null)
{
//boolean oldValidating = _processor.getParser().getValidating();
//_processor.getParser().setValidating(_validating);
- _root = _processor.getParser().parse(_xml.getURL().toString());
+ _root = _parser.parse(_xml.getURL().toString());
processVersion();
processOrdering();
//_processor.getParser().setValidating(oldValidating);
@@ -98,6 +180,11 @@ public class Descriptor
return _xml;
}
+ public MetaData getMetaData()
+ {
+ return _metaData;
+ }
+
public void processVersion ()
{
String version = _root.getAttribute("version", "DTD");
@@ -105,7 +192,7 @@ public class Descriptor
{
_majorVersion = 2;
_minorVersion = 3;
- String dtd = _processor.getParser().getDTD();
+ String dtd = _parser.getDTD();
if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
{
_majorVersion = 2;
@@ -141,7 +228,7 @@ public class Descriptor
//Process the web.xml's optional <absolute-ordering> element
XmlParser.Node ordering = _root.get("absolute-ordering");
if (ordering == null)
- return; // could be a RelativeOrdering if we find any <ordering> clauses in web-fragments
+ return;
_isOrdered = true;
//If an absolute-ordering was already set, then ignore it in favour of this new one
@@ -163,37 +250,11 @@ public class Descriptor
_ordering.add(node.toString(false,true));
}
}
-
- public void processClassNames ()
+
+ public void addClassName (String className)
{
- _classNames = new ArrayList<String>();
- Iterator iter = _root.iterator();
-
- while (iter.hasNext())
- {
- Object o = iter.next();
- if (!(o instanceof XmlParser.Node)) continue;
- XmlParser.Node node = (XmlParser.Node) o;
- String name = node.getTag();
- if ("servlet".equals(name))
- {
- String className = node.getString("servlet-class", false, true);
- if (className != null)
- _classNames.add(className);
- }
- else if ("filter".equals(name))
- {
- String className = node.getString("filter-class", false, true);
- if (className != null)
- _classNames.add(className);
- }
- else if ("listener".equals(name))
- {
- String className = node.getString("listener-class", false, true);
- if (className != null)
- _classNames.add(className);
- }
- }
+ if (!_classNames.contains(className))
+ _classNames.add(className);
}
public ArrayList<String> getClassNames ()
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java
new file mode 100644
index 0000000000..2e1a1535b1
--- /dev/null
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java
@@ -0,0 +1,68 @@
+// ========================================================================
+// Copyright (c) 2010 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.webapp;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+
+/**
+ * DiscoveredAnnotation
+ *
+ * Represents an annotation that has been discovered
+ * by scanning source code of WEB-INF/classes and WEB-INF/lib jars.
+ *
+ */
+public abstract class DiscoveredAnnotation
+{
+ protected WebAppContext _context;
+ protected String _className;
+ protected Class _clazz;
+
+ public abstract void apply();
+
+ public DiscoveredAnnotation (WebAppContext context, String className)
+ {
+ _context = context;
+ _className = className;
+ }
+
+
+ public Class getTargetClass()
+ {
+ if (_clazz != null)
+ return _clazz;
+
+ loadClass();
+
+ return _clazz;
+ }
+
+ private void loadClass ()
+ {
+ if (_clazz != null)
+ return;
+
+ if (_className == null)
+ return;
+
+ try
+ {
+ _clazz = Loader.loadClass(null, _className);
+ }
+ catch (Exception e)
+ {
+ Log.warn(e);
+ }
+ }
+}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java
index 8a2781d6ef..4828738c94 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java
@@ -21,7 +21,7 @@ import org.eclipse.jetty.util.resource.Resource;
/**
* FragmentConfiguration
*
- * This configuration supports some Servlet 3.0 features in jetty-7.
+ *
*
* Process web-fragments in jars
*/
@@ -33,16 +33,13 @@ public class FragmentConfiguration implements Configuration
{
if (!context.isConfigurationDiscovered())
return;
-
- WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (processor == null)
- {
- processor = new WebXmlProcessor (context);
- context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
- }
-
- //parse web-fragment.xmls
- parseWebFragments(context, processor);
+
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException("No metadata");
+
+ //find all web-fragment.xmls
+ findWebFragments(context, metaData);
}
@@ -51,18 +48,12 @@ public class FragmentConfiguration implements Configuration
if (!context.isConfigurationDiscovered())
return;
- WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (processor == null)
- {
- processor = new WebXmlProcessor (context);
- context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
- }
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException("No metadata");
- //order the fragments first
- processor.orderFragments();
-
- //process the fragments
- processor.processFragments();
+ //order the fragments
+ metaData.orderFragments();
}
public void deconfigure(WebAppContext context) throws Exception
@@ -77,18 +68,18 @@ public class FragmentConfiguration implements Configuration
/* ------------------------------------------------------------------------------- */
/**
- * Look for any web.xml fragments in META-INF of jars in WEB-INF/lib
+ * Look for any web-fragment.xml fragments in META-INF of jars in WEB-INF/lib
*
* @throws Exception
*/
- public void parseWebFragments (final WebAppContext context, final WebXmlProcessor processor) throws Exception
+ public void findWebFragments (final WebAppContext context, final MetaData metaData) throws Exception
{
List<Resource> frags = (List<Resource>)context.getAttribute(FRAGMENT_RESOURCES);
if (frags!=null)
{
for (Resource frag : frags)
{
- processor.parseFragment(Resource.newResource("jar:"+frag.getURL()+"!/META-INF/web-fragment.xml"));
+ metaData.addFragment(frag, Resource.newResource("jar:"+frag.getURL()+"!/META-INF/web-fragment.xml"));
}
}
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Fragment.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java
index fafb28a5e3..75c36de57a 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Fragment.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java
@@ -27,13 +27,12 @@ import org.eclipse.jetty.xml.XmlParser;
*
* A web-fragment.xml descriptor.
*/
-public class Fragment extends Descriptor
+public class FragmentDescriptor extends Descriptor
{
public static final String NAMELESS = "@@-NAMELESS-@@"; //prefix for nameless Fragments
public enum OtherType {None, Before, After};
protected int _counter = 0;
- protected boolean _hasOther = false;
protected OtherType _otherType = OtherType.None;
@@ -42,7 +41,7 @@ public class Fragment extends Descriptor
protected String _name;
- public Fragment (Resource xml, WebXmlProcessor processor)
+ public FragmentDescriptor (Resource xml, MetaData processor)
throws Exception
{
super (xml, processor);
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java
index d90ff804f5..fd1507649e 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java
@@ -31,8 +31,8 @@ public abstract class IterativeDescriptorProcessor implements DescriptorProcesso
{
public static final Class[] __signature = new Class[]{Descriptor.class, XmlParser.Node.class};
protected Map<String, Method> _visitors = new HashMap<String, Method>();
- public abstract void start();
- public abstract void end();
+ public abstract void start(Descriptor descriptor);
+ public abstract void end(Descriptor descriptor);
/**
* Register a method to be called back when visiting the node with the given name.
@@ -56,7 +56,7 @@ public abstract class IterativeDescriptorProcessor implements DescriptorProcesso
if (descriptor == null)
return;
- start();
+ start(descriptor);
XmlParser.Node root = descriptor.getRoot();
Iterator iter = root.iterator();
@@ -69,7 +69,7 @@ public abstract class IterativeDescriptorProcessor implements DescriptorProcesso
visit(descriptor, node);
}
- end();
+ end(descriptor);
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JarScanner.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JarScanner.java
index c51c50a87f..02fde5d614 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JarScanner.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JarScanner.java
@@ -65,7 +65,7 @@ public abstract class JarScanner extends org.eclipse.jetty.util.PatternMatcher
* all those starting with "aaa-" first, then "bbb-".
*
* @param pattern
- * @param loader
+ * @param uris
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
* @throws Exception
*/
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java
index 1fe03ff4da..05c6c5cd24 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java
@@ -13,6 +13,9 @@
package org.eclipse.jetty.webapp;
+import java.util.HashMap;
+import java.util.Map;
+
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlConfiguration;
@@ -29,6 +32,11 @@ import org.eclipse.jetty.xml.XmlConfiguration;
*/
public class JettyWebXmlConfiguration implements Configuration
{
+ /** The value of this property points to the WEB-INF directory of
+ * the web-app currently installed.
+ * it is passed as a property to the jetty-web.xml file */
+ public static final String PROPERTY_THIS_WEB_INF_URL = "this.web-inf.url";
+
public void preConfigure(WebAppContext context) throws Exception
{
// TODO Auto-generated method stub
@@ -74,6 +82,7 @@ public class JettyWebXmlConfiguration implements Configuration
if(Log.isDebugEnabled())
Log.debug("Configure: "+jetty);
XmlConfiguration jetty_config=new XmlConfiguration(jetty.getURL());
+ setupXmlConfiguration(jetty_config, web_inf);
jetty_config.configure(context);
}
finally
@@ -85,6 +94,22 @@ public class JettyWebXmlConfiguration implements Configuration
}
}
+ /**
+ * Configures some well-known properties before the XmlConfiguration reads
+ * the configuration.
+ * @param jetty_config The configuration object.
+ */
+ private void setupXmlConfiguration(XmlConfiguration jetty_config, Resource web_inf)
+ {
+ Map<Object,Object> props = jetty_config.getProperties();
+ if (props == null)
+ {
+ props = new HashMap<Object, Object>();
+ jetty_config.setProperties(props);
+ }
+ props.put(PROPERTY_THIS_WEB_INF_URL, web_inf.getURL());
+ }
+
public void postConfigure(WebAppContext context) throws Exception
{
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java
new file mode 100644
index 0000000000..07b306e63b
--- /dev/null
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java
@@ -0,0 +1,911 @@
+// ========================================================================
+// Copyright (c) 2009 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.webapp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+
+
+
+
+/**
+ * MetaData
+ *
+ *
+ */
+public class MetaData
+{
+ public static final String METADATA = "org.eclipse.jetty.metaData";
+ public static final String METADATA_COMPLETE = "org.eclipse.jetty.metadataComplete";
+ public static final String WEBXML_MAJOR_VERSION = "org.eclipse.jetty.webXmlMajorVersion";
+ public static final String WEBXML_MINOR_VERSION = "org.eclipse.jetty.webXmlMinorVersion";
+ public static final String WEBXML_CLASSNAMES = "org.eclipse.jetty.webXmlClassNames";
+
+ public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation};
+
+ protected WebAppContext _context;
+ protected Map<String, OriginInfo> _origins = new HashMap<String,OriginInfo>();
+ protected Descriptor _webDefaultsRoot;
+ protected Descriptor _webXmlRoot;
+ protected Descriptor _webOverrideRoot;
+ protected List<DiscoveredAnnotation> _annotations = new ArrayList<DiscoveredAnnotation>();
+ protected List<DescriptorProcessor> _descriptorProcessors = new ArrayList<DescriptorProcessor>();
+ protected List<FragmentDescriptor> _webFragmentRoots = new ArrayList<FragmentDescriptor>();
+ protected Map<String,FragmentDescriptor> _webFragmentNameMap = new HashMap<String,FragmentDescriptor>();
+ protected Map<Resource, FragmentDescriptor> _webFragmentResourceMap = new HashMap<Resource, FragmentDescriptor>();
+ protected Map<Resource, List<DiscoveredAnnotation>> _webFragmentAnnotations = new HashMap<Resource, List<DiscoveredAnnotation>>();
+ protected List<Resource> _orderedResources;
+ protected Ordering _ordering;//can be set to RelativeOrdering by web-default.xml, web.xml, web-override.xml
+ protected StandardDescriptorProcessor _standardDescriptorProcessor;
+
+
+ public static class OriginInfo
+ {
+ protected String name;
+ protected Origin origin;
+ protected Descriptor descriptor;
+
+ public OriginInfo (String n, Descriptor d)
+ {
+ name = n;
+ descriptor = d;
+ if (d == null)
+ throw new IllegalArgumentException("No descriptor");
+ if (d instanceof FragmentDescriptor)
+ origin = Origin.WebFragment;
+ if (d instanceof OverrideDescriptor)
+ origin = Origin.WebOverride;
+ if (d instanceof DefaultsDescriptor)
+ origin = Origin.WebDefaults;
+ origin = Origin.WebXml;
+ }
+
+ public OriginInfo (String n)
+ {
+ name = n;
+ origin = Origin.Annotation;
+ }
+
+ public OriginInfo(String n, Origin o)
+ {
+ name = n;
+ origin = o;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public Origin getOriginType()
+ {
+ return origin;
+ }
+
+ public Descriptor getDescriptor()
+ {
+ return descriptor;
+ }
+ }
+
+ /**
+ * Ordering
+ *
+ *
+ */
+ public interface Ordering
+ {
+ public List<Resource> order(List<Resource> fragments);
+ public boolean isAbsolute ();
+ public boolean hasOther();
+ }
+
+ /**
+ * AbsoluteOrdering
+ *
+ * An <absolute-order> element in web.xml
+ */
+ public class AbsoluteOrdering implements Ordering
+ {
+ public static final String OTHER = "@@-OTHER-@@";
+ protected List<String> _order = new ArrayList<String>();
+ protected boolean _hasOther = false;
+
+ /**
+ * Order the list of jars in WEB-INF/lib according to the ordering declarations in the descriptors
+ * @see org.eclipse.jetty.webapp.MetaData.Ordering#order(java.util.List)
+ */
+ public List<Resource> order(List<Resource> jars)
+ {
+ List<Resource> orderedList = new ArrayList<Resource>();
+ List<Resource> tmp = new ArrayList<Resource>(jars);
+
+ //1. put everything into the list of named others, and take the named ones out of there,
+ //assuming we will want to use the <other> clause
+ Map<String,FragmentDescriptor> others = new HashMap(getNamedFragments());
+
+ //2. for each name, take out of the list of others, add to tail of list
+ int index = -1;
+ for (String item:_order)
+ {
+ if (!item.equals(OTHER))
+ {
+ FragmentDescriptor f = others.remove(item);
+ if (f != null)
+ {
+ Resource jar = getJarForFragment(item);
+ orderedList.add(jar); //take from others and put into final list in order, ignoring duplicate names
+ //remove resource from list for resource matching name of descriptor
+ tmp.remove(jar);
+ }
+ }
+ else
+ index = orderedList.size(); //remember the index at which we want to add in all the others
+ }
+
+ //3. if <other> was specified, insert rest of the fragments
+ if (_hasOther)
+ {
+ orderedList.addAll((index < 0? 0: index), tmp);
+ }
+
+ return orderedList;
+ }
+
+ public boolean isAbsolute()
+ {
+ return true;
+ }
+
+ public void add (String name)
+ {
+ _order.add(name);
+ }
+
+ public void addOthers ()
+ {
+ if (_hasOther)
+ throw new IllegalStateException ("Duplicate <other> element in absolute ordering");
+
+ _hasOther = true;
+ _order.add(OTHER);
+ }
+
+ public boolean hasOther ()
+ {
+ return _hasOther;
+ }
+ }
+
+
+ /**
+ * RelativeOrdering
+ *
+ * A set of <order> elements in web-fragment.xmls.
+ */
+ public class RelativeOrdering implements Ordering
+ {
+ protected LinkedList<Resource> _beforeOthers = new LinkedList<Resource>();
+ protected LinkedList<Resource> _afterOthers = new LinkedList<Resource>();
+ protected LinkedList<Resource> _noOthers = new LinkedList<Resource>();
+
+ /**
+ * Order the list of jars according to the ordering declared
+ * in the various web-fragment.xml files.
+ * @see org.eclipse.jetty.webapp.MetaData.Ordering#order(java.util.List)
+ */
+ public List<Resource> order(List<Resource> jars)
+ {
+ //for each jar, put it into the ordering according to the fragment ordering
+ for (Resource jar:jars)
+ {
+ //check if the jar has a fragment descriptor
+ FragmentDescriptor descriptor = _webFragmentResourceMap.get(jar);
+ if (descriptor != null)
+ {
+ switch (descriptor.getOtherType())
+ {
+ case None:
+ {
+ ((RelativeOrdering)_ordering).addNoOthers(jar);
+ break;
+ }
+ case Before:
+ {
+ ((RelativeOrdering)_ordering).addBeforeOthers(jar);
+ break;
+ }
+ case After:
+ {
+ ((RelativeOrdering)_ordering).addAfterOthers(jar);
+ break;
+ }
+ }
+ }
+ else
+ {
+ //jar fragment has no descriptor, but there is a relative ordering in place, so it must be part of the others
+ ((RelativeOrdering)_ordering).addNoOthers(jar);
+ }
+ }
+
+ //now apply the ordering
+ List<Resource> orderedList = new ArrayList<Resource>();
+ int maxIterations = 2;
+ boolean done = false;
+ do
+ {
+ //1. order the before-others according to any explicit before/after relationships
+ boolean changesBefore = orderList(_beforeOthers);
+
+ //2. order the after-others according to any explicit before/after relationships
+ boolean changesAfter = orderList(_afterOthers);
+
+ //3. order the no-others according to their explicit before/after relationships
+ boolean changesNone = orderList(_noOthers);
+
+ //we're finished on a clean pass through with no ordering changes
+ done = (!changesBefore && !changesAfter && !changesNone);
+ }
+ while (!done && (--maxIterations >0));
+
+ //4. merge before-others + no-others +after-others
+ if (!done)
+ throw new IllegalStateException("Circular references for fragments");
+
+ for (Resource r: _beforeOthers)
+ orderedList.add(r);
+ for (Resource r: _noOthers)
+ orderedList.add(r);
+ for(Resource r: _afterOthers)
+ orderedList.add(r);
+
+ return orderedList;
+ }
+
+ public boolean isAbsolute ()
+ {
+ return false;
+ }
+
+ public boolean hasOther ()
+ {
+ return !_beforeOthers.isEmpty() || !_afterOthers.isEmpty();
+ }
+
+ public void addBeforeOthers (Resource r)
+ {
+ _beforeOthers.addLast(r);
+ }
+
+ public void addAfterOthers (Resource r)
+ {
+ _afterOthers.addLast(r);
+ }
+
+ public void addNoOthers (Resource r)
+ {
+ _noOthers.addLast(r);
+ }
+
+ protected boolean orderList (LinkedList<Resource> list)
+ {
+ //Take a copy of the list so we can iterate over it and at the same time do random insertions
+ boolean changes = false;
+ List<Resource> iterable = new ArrayList(list);
+ Iterator<Resource> itor = iterable.iterator();
+
+ while (itor.hasNext())
+ {
+ Resource r = itor.next();
+ FragmentDescriptor f = getFragment(r);
+ if (f == null)
+ {
+ //no fragment for this resource so cannot have any ordering directives
+ continue;
+ }
+
+ //Handle any explicit <before> relationships for the fragment we're considering
+ List<String> befores = f.getBefores();
+ if (befores != null && !befores.isEmpty())
+ {
+ for (String b: befores)
+ {
+ //Fragment we're considering must be before b
+ //Check that we are already before it, if not, move us so that we are.
+ //If the name does not exist in our list, then get it out of the no-other list
+ if (!isBefore(list, f.getName(), b))
+ {
+ //b is not already before name, move it so that it is
+ int idx1 = getIndexOf(list, f.getName());
+ int idx2 = getIndexOf(list, b);
+
+ //if b is not in the same list
+ if (idx2 < 0)
+ {
+ changes = true;
+ // must be in the noOthers list or it would have been an error
+ Resource bResource = getJarForFragment(b);
+ if (bResource != null)
+ {
+ //If its in the no-others list, insert into this list so that we are before it
+ if (_noOthers.remove(bResource))
+ {
+ insert(list, idx1+1, b);
+
+ }
+ }
+ }
+ else
+ {
+ //b is in the same list but b is before name, so swap it around
+ list.remove(idx1);
+ insert(list, idx2, f.getName());
+ changes = true;
+ }
+ }
+ }
+ }
+
+ //Handle any explicit <after> relationships
+ List<String> afters = f.getAfters();
+ if (afters != null && !afters.isEmpty())
+ {
+ for (String a: afters)
+ {
+ //Check that fragment we're considering is after a, moving it if possible if its not
+ if (!isAfter(list, f.getName(), a))
+ {
+ //name is not after a, move it
+ int idx1 = getIndexOf(list, f.getName());
+ int idx2 = getIndexOf(list, a);
+
+ //if a is not in the same list as name
+ if (idx2 < 0)
+ {
+ changes = true;
+ //take it out of the noOthers list and put it in the right place in this list
+ Resource aResource = getJarForFragment(a);
+ if (aResource != null)
+ {
+ if (_noOthers.remove(aResource))
+ {
+ insert(list,idx1, aResource);
+ }
+ }
+ }
+ else
+ {
+ //a is in the same list as name, but in the wrong place, so move it
+ list.remove(idx2);
+ insert(list,idx1, a);
+ changes = true;
+ }
+ }
+ //Name we're considering must be after this name
+ //Check we're already after it, if not, move us so that we are.
+ //If the name does not exist in our list, then get it out of the no-other list
+ }
+ }
+ }
+
+ return changes;
+ }
+
+ /**
+ * Is fragment with name a before fragment with name b?
+ * @param list
+ * @param fragNameA
+ * @param fragNameB
+ * @return
+ */
+ protected boolean isBefore (List<Resource> list, String fragNameA, String fragNameB)
+ {
+ //check if a and b are already in the same list, and b is already
+ //before a
+ int idxa = getIndexOf(list, fragNameA);
+ int idxb = getIndexOf(list, fragNameB);
+
+
+ if (idxb >=0 && idxb < idxa)
+ {
+ //a and b are in the same list but a is not before b
+ return false;
+ }
+
+ if (idxb < 0)
+ {
+ //a and b are not in the same list, but it is still possible that a is before
+ //b, depending on which list we're examining
+ if (list == _beforeOthers)
+ {
+ //The list we're looking at is the beforeOthers.If b is in the _afterOthers or the _noOthers, then by
+ //definition a is before it
+ return true;
+ }
+ else if (list == _afterOthers)
+ {
+ //The list we're looking at is the afterOthers, then a will be the tail of
+ //the final list. If b is in the beforeOthers list, then b will be before a and an error.
+ if (_beforeOthers.contains(fragNameB))
+ throw new IllegalStateException("Incorrect relationship: "+fragNameA+" before "+fragNameB);
+ else
+ return false; //b could be moved to the list
+ }
+ }
+
+ //a and b are in the same list and a is already before b
+ return true;
+ }
+
+
+ /**
+ * Is fragment name "a" after fragment name "b"?
+ * @param list
+ * @param fragNameA
+ * @param fragNameB
+ * @return
+ */
+ protected boolean isAfter(List<Resource> list, String fragNameA, String fragNameB)
+ {
+ int idxa = getIndexOf(list, fragNameA);
+ int idxb = getIndexOf(list, fragNameB);
+
+ if (idxb >=0 && idxa < idxb)
+ {
+ //a and b are both in the same list, but a is before b
+ return false;
+ }
+
+ if (idxb < 0)
+ {
+ //a and b are in different lists. a could still be after b depending on which list it is in.
+
+ if (list == _afterOthers)
+ {
+ //The list we're looking at is the afterOthers. If b is in the beforeOthers or noOthers then
+ //by definition a is after b because a is in the afterOthers list.
+ return true;
+ }
+ else if (list == _beforeOthers)
+ {
+ //The list we're looking at is beforeOthers, and contains a and will be before
+ //everything else in the final ist. If b is in the afterOthers list, then a cannot be before b.
+ if (_afterOthers.contains(fragNameB))
+ throw new IllegalStateException("Incorrect relationship: "+fragNameB+" after "+fragNameA);
+ else
+ return false; //b could be moved from noOthers list
+ }
+ }
+
+ return true; //a and b in the same list, a is after b
+ }
+
+ /**
+ * Insert the resource matching the fragName into the list of resources
+ * at the location indicated by index.
+ *
+ * @param list
+ * @param index
+ * @param fragName
+ */
+ protected void insert(List<Resource> list, int index, String fragName)
+ {
+ Resource jar = getJarForFragment(fragName);
+ if (jar == null)
+ throw new IllegalStateException("No jar for insertion");
+
+ insert(list, index, jar);
+ }
+
+ protected void insert(List<Resource> list, int index, Resource resource)
+ {
+ if (list == null)
+ throw new IllegalStateException("List is null for insertion");
+
+ //add it at the end
+ if (index > list.size())
+ list.add(resource);
+ else
+ list.add(index, resource);
+ }
+
+ protected void remove (List<Resource> resources, Resource r)
+ {
+ if (resources == null)
+ return;
+ resources.remove(r);
+ }
+
+ protected int getIndexOf(List<Resource> resources, String fragmentName)
+ {
+ FragmentDescriptor fd = getFragment(fragmentName);
+ if (fd == null)
+ return -1;
+
+
+ Resource r = getJarForFragment(fragmentName);
+ if (r == null)
+ return -1;
+
+ return resources.indexOf(r);
+ }
+ }
+
+
+
+ public MetaData (WebAppContext context) throws ClassNotFoundException
+ {
+ _context = context;
+
+ }
+
+ public WebAppContext getContext()
+ {
+ return _context;
+ }
+
+
+
+ public void setDefaults (Resource webDefaults)
+ throws Exception
+ {
+ _webDefaultsRoot = new DefaultsDescriptor(webDefaults, this);
+ _webDefaultsRoot.parse();
+ if (_webDefaultsRoot.isOrdered())
+ {
+ if (_ordering == null)
+ _ordering = new AbsoluteOrdering();
+
+ List<String> order = _webDefaultsRoot.getOrdering();
+ for (String s:order)
+ {
+ if (s.equalsIgnoreCase("others"))
+ ((AbsoluteOrdering)_ordering).addOthers();
+ else
+ ((AbsoluteOrdering)_ordering).add(s);
+ }
+ }
+ }
+
+ public void setWebXml (Resource webXml)
+ throws Exception
+ {
+ _webXmlRoot = new Descriptor(webXml, this);
+ _webXmlRoot.parse();
+ if (_webXmlRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.True)
+ _context.setAttribute(METADATA_COMPLETE, Boolean.TRUE);
+ else
+ _context.setAttribute(METADATA_COMPLETE, Boolean.FALSE);
+ _context.getServletContext().setEffectiveMajorVersion(_webXmlRoot.getMajorVersion());
+ _context.getServletContext().setEffectiveMinorVersion(_webXmlRoot.getMinorVersion());
+ _context.setAttribute(WEBXML_CLASSNAMES, _webXmlRoot.getClassNames());
+
+ if (_webXmlRoot.isOrdered())
+ {
+ if (_ordering == null)
+ _ordering = new AbsoluteOrdering();
+
+ List<String> order = _webXmlRoot.getOrdering();
+ for (String s:order)
+ {
+ if (s.equalsIgnoreCase("others"))
+ ((AbsoluteOrdering)_ordering).addOthers();
+ else
+ ((AbsoluteOrdering)_ordering).add(s);
+ }
+ }
+ }
+
+ public void setOverride (Resource override)
+ throws Exception
+ {
+ _webOverrideRoot = new OverrideDescriptor(override, this);
+ _webOverrideRoot.setValidating(false);
+ _webOverrideRoot.parse();
+ if (_webOverrideRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.True)
+ _context.setAttribute(METADATA_COMPLETE, Boolean.TRUE);
+ else if (_webOverrideRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.False)
+ _context.setAttribute(METADATA_COMPLETE, Boolean.FALSE);
+
+ if (_webOverrideRoot.isOrdered())
+ {
+ if (_ordering == null)
+ _ordering = new AbsoluteOrdering();
+
+ List<String> order = _webOverrideRoot.getOrdering();
+ for (String s:order)
+ {
+ if (s.equalsIgnoreCase("others"))
+ ((AbsoluteOrdering)_ordering).addOthers();
+ else
+ ((AbsoluteOrdering)_ordering).add(s);
+ }
+ }
+ }
+
+
+ /**
+ * Add a web-fragment.xml
+ *
+ * @param jarResource the jar the fragment is contained in
+ * @param xmlResource the resource representing the xml file
+ * @throws Exception
+ */
+ public void addFragment (Resource jarResource, Resource xmlResource)
+ throws Exception
+ {
+ Boolean metaComplete = (Boolean)_context.getAttribute(METADATA_COMPLETE);
+ if (metaComplete != null && metaComplete.booleanValue())
+ return; //do not process anything else if web.xml/web-override.xml set metadata-complete
+
+ //Metadata-complete is not set, or there is no web.xml
+ FragmentDescriptor descriptor = new FragmentDescriptor(xmlResource, this);
+ _webFragmentResourceMap.put(jarResource, descriptor);
+ _webFragmentRoots.add(descriptor);
+
+ descriptor.parse();
+
+ if (descriptor.getName() != null)
+ _webFragmentNameMap.put(descriptor.getName(), descriptor);
+
+ //If web.xml has specified an absolute ordering, ignore any relative ordering in the fragment
+ if (_ordering != null && _ordering.isAbsolute())
+ return;
+
+ if (_ordering == null && descriptor.isOrdered())
+ _ordering = new RelativeOrdering();
+ }
+
+ /**
+ * Annotations not associated with a WEB-INF/lib fragment jar.
+ * These are from WEB-INF/classes or the ??container path??
+ * @param annotations
+ */
+ public void addDiscoveredAnnotations(List<DiscoveredAnnotation> annotations)
+ {
+ _annotations.addAll(annotations);
+ }
+
+ public void addDiscoveredAnnotations(Resource resource, List<DiscoveredAnnotation> annotations)
+ {
+ _webFragmentAnnotations.put(resource, new ArrayList<DiscoveredAnnotation>(annotations));
+ }
+
+ public void addDescriptorProcessor(DescriptorProcessor p)
+ {
+ _descriptorProcessors.add(p);
+ }
+
+ public void orderFragments ()
+ {
+ //if we have already ordered them don't do it again
+ if (_orderedResources != null)
+ return;
+
+ if (_ordering != null)
+ {
+ //Get the jars in WEB-INF/lib according to the order specified
+ _orderedResources = _ordering.order((List<Resource>)_context.getAttribute(WebInfConfiguration.WEB_INF_JAR_RESOURCES));
+
+ _context.setAttribute(WebInfConfiguration.WEB_INF_ORDERED_JAR_RESOURCES, _orderedResources);
+ List<String> orderedJars = new ArrayList<String>();
+
+ for (Resource webInfJar:_orderedResources)
+ {
+ //get just the name of the jar file
+ String fullname = webInfJar.getName();
+ int i = fullname.indexOf(".jar");
+ int j = fullname.lastIndexOf("/", i);
+ orderedJars.add(fullname.substring(j+1,i+4));
+ }
+
+ _context.setAttribute(ServletContext.ORDERED_LIBS, orderedJars);
+ }
+ else
+ _orderedResources = new ArrayList<Resource>((List<Resource>)_context.getAttribute(WebInfConfiguration.WEB_INF_JAR_RESOURCES));
+ }
+
+
+ /**
+ * Resolve all servlet/filter/listener metadata from all sources: descriptors and annotations.
+ *
+ */
+ public void resolve ()
+ throws Exception
+ {
+ //TODO - apply all descriptors and annotations in order:
+ //apply descriptorProcessors to web-defaults.xml
+ //apply descriptorProcessors to web.xml
+ //apply descriptorProcessors to web-override.xml
+ //apply discovered annotations from container path
+ //apply discovered annotations from WEB-INF/classes
+ //for the ordering of the jars in WEB-INF/lib:
+ // +apply descriptorProcessors to web-fragment.xml
+ // +apply discovered annotations
+
+ for (DescriptorProcessor p:_descriptorProcessors)
+ {
+ p.process(getWebDefault());
+ p.process(getWebXml());
+ p.process(getOverrideWeb());
+ }
+
+ for (DiscoveredAnnotation a:_annotations)
+ a.apply();
+
+
+ List<Resource> resources = getOrderedResources();
+ for (Resource r:resources)
+ {
+ FragmentDescriptor fd = _webFragmentResourceMap.get(r);
+ if (fd != null)
+ {
+ for (DescriptorProcessor p:_descriptorProcessors)
+ {
+ p.process(fd);
+ }
+ }
+
+ List<DiscoveredAnnotation> fragAnnotations = _webFragmentAnnotations.get(r);
+ if (fragAnnotations != null)
+ {
+ for (DiscoveredAnnotation a:fragAnnotations)
+ a.apply();
+ }
+ }
+ }
+
+ public boolean isDistributable ()
+ {
+ boolean distributable = (
+ (_webDefaultsRoot != null && _webDefaultsRoot.isDistributable())
+ || (_webXmlRoot != null && _webXmlRoot.isDistributable())
+ || (_webOverrideRoot != null && _webOverrideRoot.isDistributable()));
+
+ List<Resource> orderedResources = getOrderedResources();
+ for (Resource r: orderedResources)
+ {
+ FragmentDescriptor d = _webFragmentResourceMap.get(r);
+ if (d!=null)
+ distributable = distributable && d.isDistributable();
+ }
+ return distributable;
+ }
+
+
+ public Descriptor getWebXml ()
+ {
+ return _webXmlRoot;
+ }
+
+ public Descriptor getOverrideWeb ()
+ {
+ return _webOverrideRoot;
+ }
+
+ public Descriptor getWebDefault ()
+ {
+ return _webDefaultsRoot;
+ }
+
+ public List<FragmentDescriptor> getFragments ()
+ {
+ return _webFragmentRoots;
+ }
+
+ public List<Resource> getOrderedResources ()
+ {
+ return _orderedResources;
+ }
+
+ public List<FragmentDescriptor> getOrderedFragments ()
+ {
+ List<FragmentDescriptor> list = new ArrayList<FragmentDescriptor>();
+ if (_orderedResources == null)
+ return list;
+
+ for (Resource r:_orderedResources)
+ {
+ FragmentDescriptor fd = _webFragmentResourceMap.get(r);
+ if (fd != null)
+ list.add(fd);
+ }
+ return list;
+ }
+
+ public Ordering getOrdering()
+ {
+ return _ordering;
+ }
+
+ public void setOrdering (Ordering o)
+ {
+ _ordering = o;
+ }
+
+ public FragmentDescriptor getFragment (Resource jar)
+ {
+ return _webFragmentResourceMap.get(jar);
+ }
+
+ public FragmentDescriptor getFragment(String name)
+ {
+ return _webFragmentNameMap.get(name);
+ }
+
+ public Resource getJarForFragment (String name)
+ {
+ FragmentDescriptor f = getFragment(name);
+ if (f == null)
+ return null;
+
+ Resource jar = null;
+ for (Resource r: _webFragmentResourceMap.keySet())
+ {
+ if (_webFragmentResourceMap.get(r).equals(f))
+ jar = r;
+ }
+ return jar;
+ }
+
+ public Map<String,FragmentDescriptor> getNamedFragments ()
+ {
+ return Collections.unmodifiableMap(_webFragmentNameMap);
+ }
+
+
+ public Origin getOrigin (String name)
+ {
+ OriginInfo x = _origins.get(name);
+ if (x == null)
+ return Origin.NotSet;
+
+ return x.getOriginType();
+ }
+
+
+ public Descriptor getOriginDescriptor (String name)
+ {
+ OriginInfo o = _origins.get(name);
+ if (o == null)
+ return null;
+ return o.getDescriptor();
+ }
+
+ public void setOrigin (String name, Descriptor d)
+ {
+ OriginInfo x = new OriginInfo (name, d);
+ _origins.put(name, x);
+ }
+
+ public void setOrigin (String name)
+ {
+ if (name == null)
+ return;
+
+ OriginInfo x = new OriginInfo (name, Origin.Annotation);
+ _origins.put(name, x);
+ }
+}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java
index adcbf43342..fe7adb3599 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java
@@ -22,7 +22,7 @@ import org.eclipse.jetty.util.resource.Resource;
*/
public class OverrideDescriptor extends Descriptor
{
- public OverrideDescriptor(Resource xml, WebXmlProcessor processor)
+ public OverrideDescriptor(Resource xml, MetaData processor)
{
super(xml, processor);
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
index 67e2d11275..d8de387c00 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
@@ -49,7 +49,7 @@ import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebXmlProcessor.Origin;
+import org.eclipse.jetty.webapp.MetaData.Origin;
import org.eclipse.jetty.xml.XmlParser;
/**
@@ -59,6 +59,7 @@ import org.eclipse.jetty.xml.XmlParser;
*/
public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{
+ public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
protected WebAppContext _context;
//the shared configuration operated on by web-default.xml, web.xml, web-override.xml and all web-fragment.xml
@@ -72,20 +73,19 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
protected Object _listenerClassNames;
protected Object _welcomeFiles;
protected Set<String> _roles = new HashSet<String>();
- protected Object _constraintMappings;
+ protected List<ConstraintMapping> _constraintMappings = new ArrayList<ConstraintMapping>();
protected Map _errorPages;
protected boolean _hasJSP;
protected String _jspServletName;
protected String _jspServletClass;
protected boolean _defaultWelcomeFileList;
- protected WebXmlProcessor _processor;
+ protected MetaData _metaData;
+
-
- public StandardDescriptorProcessor (WebXmlProcessor processor)
+ public StandardDescriptorProcessor ()
{
- _processor = processor;
- _context = _processor.getContext();
+
try
{
registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature));
@@ -118,8 +118,11 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
/**
* @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start()
*/
- public void start()
+ public void start(Descriptor descriptor)
{
+ _metaData = descriptor.getMetaData();
+ _context = _metaData.getContext();
+
//Get the current objects from the context
_servletHandler = _context.getServletHandler();
_securityHandler = (SecurityHandler)_context.getSecurityHandler();
@@ -131,8 +134,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
_welcomeFiles = LazyList.array2List(_context.getWelcomeFiles());
if (_securityHandler instanceof ConstraintAware)
{
- _constraintMappings = LazyList.array2List(((ConstraintAware) _securityHandler).getConstraintMappings());
-
+ _constraintMappings.addAll(((ConstraintAware) _securityHandler).getConstraintMappings());
if (((ConstraintAware) _securityHandler).getRoles() != null)
{
_roles.addAll(((ConstraintAware) _securityHandler).getRoles());
@@ -146,7 +148,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
/**
* @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end()
*/
- public void end()
+ public void end(Descriptor descriptor)
{
//Set the context with the results of the processing
_servletHandler.setFilters((FilterHolder[]) LazyList.toArray(_filters, FilterHolder.class));
@@ -158,28 +160,33 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
// TODO jaspi check this
if (_securityHandler instanceof ConstraintAware)
{
- ((ConstraintAware) _securityHandler).setConstraintMappings((ConstraintMapping[]) LazyList.toArray(_constraintMappings,
- ConstraintMapping.class),
- _roles);
+ for (ConstraintMapping m:_constraintMappings)
+ ((ConstraintAware) _securityHandler).addConstraintMapping(m);
+ for (String r:_roles)
+ ((ConstraintAware) _securityHandler).addRole(r);
}
if (_errorPages != null && _context.getErrorHandler() instanceof ErrorPageErrorHandler)
((ErrorPageErrorHandler)_context.getErrorHandler()).setErrorPages(_errorPages);
-
+
+ _roles.clear();
+ _constraintMappings.clear();
+ _metaData = null;
+ _context = null;
}
public void visitContextParam (Descriptor descriptor, XmlParser.Node node)
{
String name = node.getString("param-name", false, true);
String value = node.getString("param-value", false, true);
- Origin o = _processor.getOrigin("context-param."+name);
+ Origin o = _metaData.getOrigin("context-param."+name);
switch (o)
{
case NotSet:
{
//just set it
_context.getInitParams().put(name, value);
- _processor.setOrigin("context-param."+name, descriptor);
+ _metaData.setOrigin("context-param."+name, descriptor);
break;
}
case WebXml:
@@ -187,17 +194,17 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//previously set by a web xml, allow other web xml files to override
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getInitParams().put(name, value);
- _processor.setOrigin("context-param."+name, descriptor);
+ _metaData.setOrigin("context-param."+name, descriptor);
}
break;
}
case WebFragment:
{
//previously set by a web-fragment, this fragment's value must be the same
- if (descriptor instanceof Fragment)
+ if (descriptor instanceof FragmentDescriptor)
{
if (!((String)_context.getInitParams().get(name)).equals(value))
throw new IllegalStateException("Conflicting context-param "+name+"="+value+" in "+descriptor.getResource());
@@ -214,10 +221,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
protected void visitDisplayName(Descriptor descriptor, XmlParser.Node node)
{
//Servlet Spec 3.0 p. 74 Ignore from web-fragments
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.setDisplayName(node.toString(false, true));
- _processor.setOrigin("display-name", descriptor);
+ _metaData.setOrigin("display-name", descriptor);
}
}
@@ -248,14 +255,16 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String pname = paramNode.getString("param-name", false, true);
String pvalue = paramNode.getString("param-value", false, true);
- Origin origin = _processor.getOrigin(servlet_name+"servlet.init-param."+pname);
+ Origin origin = _metaData.getOrigin(servlet_name+".servlet.init-param."+pname);
+
switch (origin)
{
case NotSet:
{
//init-param not already set, so set it
+
registration.setInitParameter(pname, pvalue);
- _processor.setOrigin(servlet_name+"servlet.init-param."+pname, descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
break;
}
case WebXml:
@@ -264,10 +273,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{
//previously set by a web xml descriptor, if we're parsing another web xml descriptor allow override
//otherwise just ignore it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
registration.setInitParameter(pname, pvalue);
- _processor.setOrigin(servlet_name+"servlet.init-param."+pname, descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
}
break;
}
@@ -324,14 +333,16 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
//Set the servlet-class
if (servlet_class != null)
{
- Origin o = _processor.getOrigin(servlet_name+".servlet-class");
+ descriptor.addClassName(servlet_class);
+
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.servlet-class");
switch (o)
{
case NotSet:
{
//the class of the servlet has not previously been set, so set it
holder.setClassName(servlet_class);
- _processor.setOrigin(servlet_name+".servlet-class", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.servlet-class", descriptor);
break;
}
case WebXml:
@@ -339,10 +350,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//the class of the servlet was set by a web xml file, only allow web-override/web-default to change it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
holder.setClassName(servlet_class);
- _processor.setOrigin(servlet_name+".servlet-class", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.servlet-class", descriptor);
}
break;
}
@@ -388,14 +399,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
}
- Origin o = _processor.getOrigin(servlet_name+".load-on-startup");
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.load-on-startup");
switch (o)
{
case NotSet:
{
//not already set, so set it now
registration.setLoadOnStartup(order);
- _processor.setOrigin(servlet_name+".load-on-startup", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
break;
}
case WebXml:
@@ -403,10 +414,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//if it was already set by a web xml descriptor and we're parsing another web xml descriptor, then override it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
registration.setLoadOnStartup(order);
- _processor.setOrigin(servlet_name+".load-on-startup", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
}
break;
}
@@ -429,14 +440,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
{
if (Log.isDebugEnabled()) Log.debug("link role " + roleName + " to " + roleLink + " for " + this);
- Origin o = _processor.getOrigin(servlet_name+".role-name."+roleName);
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.role-name."+roleName);
switch (o)
{
case NotSet:
{
//set it
holder.setUserRoleLink(roleName, roleLink);
- _processor.setOrigin(servlet_name+".role-name."+roleName, descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
break;
}
case WebXml:
@@ -444,10 +455,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//only another web xml descriptor (web-default,web-override web.xml) can override an already set value
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
holder.setUserRoleLink(roleName, roleLink);
- _processor.setOrigin(servlet_name+".role-name."+roleName, descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
}
break;
}
@@ -473,14 +484,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (roleName != null)
{
- Origin o = _processor.getOrigin(servlet_name+".run-as");
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.run-as");
switch (o)
{
case NotSet:
{
//run-as not set, so set it
registration.setRunAsRole(roleName);
- _processor.setOrigin(servlet_name+".run-as", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.run-as", descriptor);
break;
}
case WebXml:
@@ -488,10 +499,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//run-as was set by a web xml, only allow it to be changed if we're currently parsing another web xml(override/default)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
registration.setRunAsRole(roleName);
- _processor.setOrigin(servlet_name+".run-as", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.run-as", descriptor);
}
break;
}
@@ -510,14 +521,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (async!=null)
{
boolean val = async.length()==0||Boolean.valueOf(async);
- Origin o =_processor.getOrigin(servlet_name+"servlet.async-supported");
+ Origin o =_metaData.getOrigin(servlet_name+".servlet.async-supported");
switch (o)
{
case NotSet:
{
//set it
registration.setAsyncSupported(val);
- _processor.setOrigin(servlet_name+"servlet.async-supported", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.async-supported", descriptor);
break;
}
case WebXml:
@@ -525,10 +536,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
registration.setAsyncSupported(val);
- _processor.setOrigin(servlet_name+"servlet.async-supported", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.async-supported", descriptor);
}
break;
}
@@ -546,14 +557,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (enabled!=null)
{
boolean val = enabled.length()==0||Boolean.valueOf(enabled);
- Origin o = _processor.getOrigin(servlet_name+".enabled");
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.enabled");
switch (o)
{
case NotSet:
{
//hasn't been set yet, so set it
//TODO
- _processor.setOrigin(servlet_name+".enabled", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.enabled", descriptor);
break;
}
case WebXml:
@@ -561,10 +572,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//was set in a web xml descriptor, only allow override from another web xml descriptor
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
//TODO
- _processor.setOrigin(servlet_name+".enabled", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.enabled", descriptor);
}
break;
}
@@ -594,14 +605,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
(maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
(threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
- Origin o = _processor.getOrigin(servlet_name+".multipart-config");
+ Origin o = _metaData.getOrigin(servlet_name+".servlet.multipart-config");
switch (o)
{
case NotSet:
{
//hasn't been set, so set it
registration.setMultipartConfig(element);
- _processor.setOrigin(servlet_name+".multipart-config", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.multipart-config", descriptor);
break;
}
case WebXml:
@@ -609,10 +620,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//was set in a web xml, only allow changes if we're parsing another web xml (web.xml/web-default.xml/web-override.xml)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
registration.setMultipartConfig(element);
- _processor.setOrigin(servlet_name+".multipart-config", descriptor);
+ _metaData.setOrigin(servlet_name+".servlet.multipart-config", descriptor);
}
break;
}
@@ -644,6 +655,9 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
ServletMapping mapping = new ServletMapping();
mapping.setServletName(servlet_name);
+ if (_metaData.getOrigin(servlet_name+".servlet.mappings") == Origin.NotSet)
+ _metaData.setOrigin(servlet_name+".servlet.mappings", descriptor);
+
ArrayList paths = new ArrayList();
Iterator iter = node.iterator("url-pattern");
while (iter.hasNext())
@@ -653,7 +667,6 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
paths.add(p);
}
mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
-
_servletMappings = LazyList.add(_servletMappings, mapping);
}
@@ -691,14 +704,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String name = cookieConfig.getString("name", false, true);
if (name != null)
{
- Origin o = _processor.getOrigin("cookie-config.name");
+ Origin o = _metaData.getOrigin("cookie-config.name");
switch (o)
{
case NotSet:
{
//no <cookie-config><name> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
- _processor.setOrigin("cookie-config.name", descriptor);
+ _metaData.setOrigin("cookie-config.name", descriptor);
break;
}
case WebXml:
@@ -706,10 +719,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><name> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
- _processor.setOrigin("cookie-config.name", descriptor);
+ _metaData.setOrigin("cookie-config.name", descriptor);
}
break;
}
@@ -727,14 +740,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String domain = cookieConfig.getString("domain", false, true);
if (domain != null)
{
- Origin o = _processor.getOrigin("cookie-config.domain");
+ Origin o = _metaData.getOrigin("cookie-config.domain");
switch (o)
{
case NotSet:
{
//no <cookie-config><domain> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
- _processor.setOrigin("cookie-config.domain", descriptor);
+ _metaData.setOrigin("cookie-config.domain", descriptor);
break;
}
case WebXml:
@@ -742,10 +755,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><domain> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
- _processor.setOrigin("cookie-config.domain", descriptor);
+ _metaData.setOrigin("cookie-config.domain", descriptor);
}
break;
}
@@ -763,14 +776,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String path = cookieConfig.getString("path", false, true);
if (path != null)
{
- Origin o = _processor.getOrigin("cookie-config.path");
+ Origin o = _metaData.getOrigin("cookie-config.path");
switch (o)
{
case NotSet:
{
//no <cookie-config><domain> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
- _processor.setOrigin("cookie-config.path", descriptor);
+ _metaData.setOrigin("cookie-config.path", descriptor);
break;
}
case WebXml:
@@ -778,10 +791,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><domain> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
- _processor.setOrigin("cookie-config.path", descriptor);
+ _metaData.setOrigin("cookie-config.path", descriptor);
}
break;
}
@@ -799,14 +812,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String comment = cookieConfig.getString("comment", false, true);
if (comment != null)
{
- Origin o = _processor.getOrigin("cookie-config.comment");
+ Origin o = _metaData.getOrigin("cookie-config.comment");
switch (o)
{
case NotSet:
{
//no <cookie-config><comment> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
- _processor.setOrigin("cookie-config.comment", descriptor);
+ _metaData.setOrigin("cookie-config.comment", descriptor);
break;
}
case WebXml:
@@ -814,10 +827,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><comment> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
- _processor.setOrigin("cookie-config.comment", descriptor);
+ _metaData.setOrigin("cookie-config.comment", descriptor);
}
break;
}
@@ -836,14 +849,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (tNode != null)
{
boolean httpOnly = Boolean.parseBoolean(tNode.toString(false,true));
- Origin o = _processor.getOrigin("cookie-config.http-only");
+ Origin o = _metaData.getOrigin("cookie-config.http-only");
switch (o)
{
case NotSet:
{
//no <cookie-config><http-only> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
- _processor.setOrigin("cookie-config.http-only", descriptor);
+ _metaData.setOrigin("cookie-config.http-only", descriptor);
break;
}
case WebXml:
@@ -851,10 +864,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><http-only> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
- _processor.setOrigin("cookie-config.http-only", descriptor);
+ _metaData.setOrigin("cookie-config.http-only", descriptor);
}
break;
}
@@ -873,14 +886,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (tNode != null)
{
boolean secure = Boolean.parseBoolean(tNode.toString(false,true));
- Origin o = _processor.getOrigin("cookie-config.secure");
+ Origin o = _metaData.getOrigin("cookie-config.secure");
switch (o)
{
case NotSet:
{
//no <cookie-config><secure> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
- _processor.setOrigin("cookie-config.secure", descriptor);
+ _metaData.setOrigin("cookie-config.secure", descriptor);
break;
}
case WebXml:
@@ -888,10 +901,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><secure> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
- _processor.setOrigin("cookie-config.secure", descriptor);
+ _metaData.setOrigin("cookie-config.secure", descriptor);
}
break;
}
@@ -910,14 +923,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (tNode != null)
{
int maxAge = Integer.parseInt(tNode.toString(false,true));
- Origin o = _processor.getOrigin("cookie-config.max-age");
+ Origin o = _metaData.getOrigin("cookie-config.max-age");
switch (o)
{
case NotSet:
{
//no <cookie-config><max-age> set yet, accept it
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
- _processor.setOrigin("cookie-config.max-age", descriptor);
+ _metaData.setOrigin("cookie-config.max-age", descriptor);
break;
}
case WebXml:
@@ -925,10 +938,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//<cookie-config><max-age> set in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
- _processor.setOrigin("cookie-config.max-age", descriptor);
+ _metaData.setOrigin("cookie-config.max-age", descriptor);
}
break;
}
@@ -952,14 +965,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String mimeType = node.getString("mime-type", false, true);
if (extension != null)
{
- Origin o = _processor.getOrigin("extension."+extension);
+ Origin o = _metaData.getOrigin("extension."+extension);
switch (o)
{
case NotSet:
{
//no mime-type set for the extension yet
_context.getMimeTypes().addMimeMapping(extension, mimeType);
- _processor.setOrigin("extension."+extension, descriptor);
+ _metaData.setOrigin("extension."+extension, descriptor);
break;
}
case WebXml:
@@ -967,10 +980,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//a mime-type was set for the extension in a web xml, only allow web-default/web-override to change
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.getMimeTypes().addMimeMapping(extension, mimeType);
- _processor.setOrigin("extension."+extension, descriptor);
+ _metaData.setOrigin("extension."+extension, descriptor);
}
break;
}
@@ -987,12 +1000,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
protected void visitWelcomeFileList(Descriptor descriptor, XmlParser.Node node)
{
- Origin o = _processor.getOrigin("welcome-file-list");
+ Origin o = _metaData.getOrigin("welcome-file-list");
switch (o)
{
case NotSet:
{
- _processor.setOrigin("weclome-file-list", descriptor);
+ _metaData.setOrigin("welcome-file-list", descriptor);
addWelcomeFiles(node);
break;
}
@@ -1004,13 +1017,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
case WebDefaults:
{
- //web-defaults.xml set the welcome-file-list. If we're processing web.xml we
- //should reset the list.
- Descriptor d = _processor.getOriginDescriptor("welcome-file-list");
//if web-defaults set the welcome-file-list first and
//we're processing web.xml then reset the welcome-file-list
- if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof Fragment))
+ if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof FragmentDescriptor))
+ {
_welcomeFiles = null;
+ }
addWelcomeFiles(node);
break;
}
@@ -1022,7 +1034,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
case WebFragment:
{
- //A web-fragment first set the welcome-file-list. Other descriptors just add.
+ //A web-fragment first set the welcome-file-list. Other descriptors just add.
addWelcomeFiles(node);
break;
}
@@ -1040,14 +1052,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (encoding != null)
{
- Origin o = _processor.getOrigin("locale-encoding."+locale);
+ Origin o = _metaData.getOrigin("locale-encoding."+locale);
switch (o)
{
case NotSet:
{
//no mapping for the locale yet, so set it
_context.addLocaleEncoding(locale, encoding);
- _processor.setOrigin("locale-encoding."+locale, descriptor);
+ _metaData.setOrigin("locale-encoding."+locale, descriptor);
break;
}
case WebXml:
@@ -1055,10 +1067,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//a value was set in a web descriptor, only allow another web descriptor to change it (web-default/web-override)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_context.addLocaleEncoding(locale, encoding);
- _processor.setOrigin("locale-encoding."+locale, descriptor);
+ _metaData.setOrigin("locale-encoding."+locale, descriptor);
}
break;
}
@@ -1083,14 +1095,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (_errorPages == null)
_errorPages = new HashMap();
- Origin o = _processor.getOrigin("error."+error);
+ Origin o = _metaData.getOrigin("error."+error);
switch (o)
{
case NotSet:
{
//no error page setup for this code or exception yet
_errorPages.put(error, location);
- _processor.setOrigin("error."+error, descriptor);
+ _metaData.setOrigin("error."+error, descriptor);
break;
}
case WebXml:
@@ -1098,10 +1110,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//an error page setup was set in web.xml, only allow other web xml descriptors to override it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_errorPages.put(error, location);
- _processor.setOrigin("error."+error, descriptor);
+ _metaData.setOrigin("error."+error, descriptor);
}
break;
}
@@ -1241,7 +1253,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
mapping.setMethod(method);
mapping.setPathSpec(url);
mapping.setConstraint(sc);
- _constraintMappings = LazyList.add(_constraintMappings, mapping);
+ _constraintMappings.add(mapping);
}
}
else
@@ -1249,7 +1261,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec(url);
mapping.setConstraint(sc);
- _constraintMappings = LazyList.add(_constraintMappings, mapping);
+ _constraintMappings.add(mapping);
}
}
}
@@ -1269,14 +1281,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (method != null)
{
//handle auth-method merge
- Origin o = _processor.getOrigin("auth-method");
+ Origin o = _metaData.getOrigin("auth-method");
switch (o)
{
case NotSet:
{
//not already set, so set it now
_securityHandler.setAuthMethod(method.toString(false, true));
- _processor.setOrigin("auth-method", descriptor);
+ _metaData.setOrigin("auth-method", descriptor);
break;
}
case WebXml:
@@ -1284,10 +1296,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//if it was already set by a web xml descriptor and we're parsing another web xml descriptor, then override it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_securityHandler.setAuthMethod(method.toString(false, true));
- _processor.setOrigin("auth-method", descriptor);
+ _metaData.setOrigin("auth-method", descriptor);
}
break;
}
@@ -1303,14 +1315,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
//handle realm-name merge
XmlParser.Node name = node.get("realm-name");
String nameStr = (name == null ? "default" : name.toString(false, true));
- o = _processor.getOrigin("realm-name");
+ o = _metaData.getOrigin("realm-name");
switch (o)
{
case NotSet:
{
//no descriptor has set the realm-name yet, so set it
_securityHandler.setRealmName(nameStr);
- _processor.setOrigin("realm-name", descriptor);
+ _metaData.setOrigin("realm-name", descriptor);
break;
}
case WebXml:
@@ -1318,10 +1330,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//set by a web xml file (web.xml/web-default.xm/web-override.xml), only allow it to be changed by another web xml file
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_securityHandler.setRealmName(nameStr);
- _processor.setOrigin("realm-name", descriptor);
+ _metaData.setOrigin("realm-name", descriptor);
}
break;
}
@@ -1349,14 +1361,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
errorPageName = errorPage.toString(false, true);
//handle form-login-page
- o = _processor.getOrigin("form-login-page");
+ o = _metaData.getOrigin("form-login-page");
switch (o)
{
case NotSet:
{
//Never been set before, so accept it
_securityHandler.setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
- _processor.setOrigin("form-login-page",descriptor);
+ _metaData.setOrigin("form-login-page",descriptor);
break;
}
case WebXml:
@@ -1364,10 +1376,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//a web xml descriptor previously set it, only allow another one to change it (web.xml/web-default.xml/web-override.xml)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_securityHandler.setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
- _processor.setOrigin("form-login-page",descriptor);
+ _metaData.setOrigin("form-login-page",descriptor);
}
break;
}
@@ -1381,14 +1393,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
//handle form-error-page
- o = _processor.getOrigin("form-error-page");
+ o = _metaData.getOrigin("form-error-page");
switch (o)
{
case NotSet:
{
//Never been set before, so accept it
_securityHandler.setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
- _processor.setOrigin("form-error-page",descriptor);
+ _metaData.setOrigin("form-error-page",descriptor);
break;
}
case WebXml:
@@ -1396,10 +1408,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//a web xml descriptor previously set it, only allow another one to change it (web.xml/web-default.xml/web-override.xml)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
_securityHandler.setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
- _processor.setOrigin("form-error-page",descriptor);
+ _metaData.setOrigin("form-error-page",descriptor);
}
break;
}
@@ -1443,14 +1455,16 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String filter_class = node.getString("filter-class", false, true);
if (filter_class != null)
{
- Origin o = _processor.getOrigin(name+".filter-class");
+ descriptor.addClassName(filter_class);
+
+ Origin o = _metaData.getOrigin(name+".filter.filter-class");
switch (o)
{
case NotSet:
{
//no class set yet
holder.setClassName(filter_class);
- _processor.setOrigin(name+".filter-class", descriptor);
+ _metaData.setOrigin(name+".filter.filter-class", descriptor);
break;
}
case WebXml:
@@ -1458,10 +1472,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//filter class was set in web.xml, only allow other web xml descriptors (override/default) to change it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
holder.setClassName(filter_class);
- _processor.setOrigin(name+".filter-class", descriptor);
+ _metaData.setOrigin(name+".filter.filter-class", descriptor);
}
break;
}
@@ -1483,14 +1497,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String pname = paramNode.getString("param-name", false, true);
String pvalue = paramNode.getString("param-value", false, true);
- Origin origin = _processor.getOrigin(name+"filter.init-param."+pname);
+ Origin origin = _metaData.getOrigin(name+".filter.init-param."+pname);
switch (origin)
{
case NotSet:
{
//init-param not already set, so set it
holder.setInitParameter(pname, pvalue);
- _processor.setOrigin(name+"filter.init-param."+pname, descriptor);
+ _metaData.setOrigin(name+".filter.init-param."+pname, descriptor);
break;
}
case WebXml:
@@ -1499,10 +1513,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{
//previously set by a web xml descriptor, if we're parsing another web xml descriptor allow override
//otherwise just ignore it
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
holder.setInitParameter(pname, pvalue);
- _processor.setOrigin(name+"filter.init-param."+pname, descriptor);
+ _metaData.setOrigin(name+".filter.init-param."+pname, descriptor);
}
break;
}
@@ -1522,14 +1536,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (async!=null)
{
boolean val = async.length()==0||Boolean.valueOf(async);
- Origin o = _processor.getOrigin(name+"filter.async-supported");
+ Origin o = _metaData.getOrigin(name+".filter.async-supported");
switch (o)
{
case NotSet:
{
//set it
holder.setAsyncSupported(val);
- _processor.setOrigin(name+"filter.async-supported", descriptor);
+ _metaData.setOrigin(name+".filter.async-supported", descriptor);
break;
}
case WebXml:
@@ -1537,10 +1551,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
case WebOverride:
{
//async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
- if (!(descriptor instanceof Fragment))
+ if (!(descriptor instanceof FragmentDescriptor))
{
holder.setAsyncSupported(val);
- _processor.setOrigin(name+"filter.async-supported", descriptor);
+ _metaData.setOrigin(name+".filter.async-supported", descriptor);
}
break;
}
@@ -1610,6 +1624,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{
if (className != null && className.length()> 0)
{
+ descriptor.addClassName(className);
+
//Servlet Spec 3.0 p 74
//Duplicate listener declarations don't result in duplicate listener instances
if (!LazyList.contains(_listenerClassNames, className))
@@ -1622,7 +1638,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
Log.warn("Not an EventListener: " + listener);
return;
}
-
+ _metaData.setOrigin(className+".listener", descriptor);
_listeners = LazyList.add(_listeners, listener);
}
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/TagLibConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/TagLibConfiguration.java
index d5b349b35c..f5dd88f39e 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/TagLibConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/TagLibConfiguration.java
@@ -45,7 +45,8 @@ import org.eclipse.jetty.xml.XmlParser;
* &lt;/bile&gt;
*
*
- *
+ * TODO - this has been superceded by the new TldScanner in jasper which uses ServletContainerInitializer to
+ * find all the listeners in tag libs and register them.
*/
public class TagLibConfiguration implements Configuration
{
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
index 59bebfdc0b..ca37ab4f42 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
@@ -31,6 +31,7 @@ import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
/* ------------------------------------------------------------ */
@@ -38,11 +39,11 @@ import org.eclipse.jetty.util.resource.Resource;
* Specializes URLClassLoader with some utility and file mapping
* methods.
*
- * This loader defaults to the 2.3 servlet spec behaviour where non
+ * This loader defaults to the 2.3 servlet spec behavior where non
* system classes are loaded from the classpath in preference to the
* parent loader. Java2 compliant loading, where the parent loader
* always has priority, can be selected with the
- * {@link org.eclipse.jetty.server.server.webapp.WebAppContext#setParentLoaderPriority(boolean)}
+ * {@link org.eclipse.jetty.webapp.WebAppContext#setParentLoaderPriority(boolean)}
* method and influenced with {@link WebAppContext#isServerClass(String)} and
* {@link WebAppContext#isSystemClass(String)}.
*
@@ -123,6 +124,26 @@ public class WebAppClassLoader extends URLClassLoader
{
return _context;
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param resource Comma or semicolon separated path of filenames or URLs
+ * pointing to directories or jar files. Directories should end
+ * with '/'.
+ */
+ public void addClassPath(Resource resource)
+ throws IOException
+ {
+ if (resource instanceof ResourceCollection)
+ {
+ for (Resource r : ((ResourceCollection)resource).getResources())
+ addClassPath(r);
+ }
+ else
+ {
+ addClassPath(resource.toString());
+ }
+ }
/* ------------------------------------------------------------ */
/**
@@ -180,9 +201,6 @@ public class WebAppClassLoader extends URLClassLoader
/** Add elements to the class path for the context from the jar and zip files found
* in the specified resource.
* @param lib the resource that contains the jar and/or zip files.
- * @param append true if the classpath entries are to be appended to any
- * existing classpath, or false if they replace the existing classpath.
- * @see #setClassPath(String)
*/
public void addJars(Resource lib)
{
@@ -191,10 +209,11 @@ public class WebAppClassLoader extends URLClassLoader
String[] files=lib.list();
for (int f=0;files!=null && f<files.length;f++)
{
- try {
+ try
+ {
Resource fn=lib.addPath(files[f]);
String fnlc=fn.getName().toLowerCase();
- if (isFileSupported(fnlc))
+ if (!fn.isDirectory() && isFileSupported(fnlc))
{
String jar=fn.toString();
jar=StringUtil.replace(jar, ",", "%2C");
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
index 17cf3bdd4d..0e77e9311f 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
@@ -16,10 +16,10 @@ package org.eclipse.jetty.webapp;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.net.URL;
import java.security.PermissionCollection;
import java.util.EventListener;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSessionActivationListener;
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.session.SessionHandler;
@@ -42,6 +43,7 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
/* ------------------------------------------------------------ */
/** Web Application Context Handler.
@@ -50,8 +52,8 @@ import org.eclipse.jetty.util.resource.Resource;
* {@link org.eclipse.jetty.security.ConstraintSecurityHandler}, {@link org.eclipse.jetty.server.session.SessionHandler}
* and {@link org.eclipse.jetty.servlet.ServletHandler}.
* The handlers are configured by pluggable configuration classes, with
- * the default being {@link org.eclipse.jetty.server.server.webapp.WebXmlConfiguration} and
- * {@link org.eclipse.jetty.server.server.webapp.JettyWebXmlConfiguration}.
+ * the default being {@link org.eclipse.jetty.webapp.WebXmlConfiguration} and
+ * {@link org.eclipse.jetty.webapp.JettyWebXmlConfiguration}.
*
* @org.apache.xbean.XBean description="Creates a servlet web application at a given context from a resource base"
*
@@ -61,9 +63,12 @@ import org.eclipse.jetty.util.resource.Resource;
public class WebAppContext extends ServletContextHandler
{
public static final String TEMPDIR = "javax.servlet.context.tempdir";
+ public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
public final static String SERVER_CONFIG = "org.eclipse.jetty.webapp.configuration";
+ public final static String SERVER_SYS_CLASSES = "org.eclipse.jetty.webapp.systemClasses";
+ public final static String SERVER_SRV_CLASSES = "org.eclipse.jetty.webapp.serverClasses";
private static String[] __dftConfigurationClasses =
{
@@ -74,7 +79,42 @@ public class WebAppContext extends ServletContextHandler
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration"//,
//"org.eclipse.jetty.webapp.TagLibConfiguration"
} ;
- private String[] _configurationClasses=null;
+
+ // System classes are classes that cannot be replaced by
+ // the web application, and they are *always* loaded via
+ // system classloader.
+ private final static String[] __dftSystemClasses =
+ {
+ "java.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+ "javax.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+ "org.xml.", // needed by javax.xml
+ "org.w3c.", // needed by javax.xml
+ "org.apache.commons.logging.", // TODO: review if special case still needed
+ "org.eclipse.jetty.continuation.", // webapp cannot change continuation classes
+ "org.eclipse.jetty.jndi.", // webapp cannot change naming classes
+ "org.eclipse.jetty.plus.jaas.", // webapp cannot change jaas classes
+ "org.eclipse.jetty.websocket.", // WebSocket is a jetty extension
+ "org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets
+ } ;
+
+ // Server classes are classes that are hidden from being
+ // loaded by the web application using system classloader,
+ // so if web application needs to load any of such classes,
+ // it has to include them in its distribution.
+ private final static String[] __dftServerClasses =
+ {
+ "-org.eclipse.jetty.continuation.", // don't hide continuation classes
+ "-org.eclipse.jetty.jndi.", // don't hide naming classes
+ "-org.eclipse.jetty.plus.jaas.", // don't hide jaas classes
+ "-org.eclipse.jetty.websocket.", // don't hide websocket extension
+ "-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet
+ "org.eclipse.jetty." // hide other jetty classes
+ } ;
+
+ private String[] _configurationClasses = __dftConfigurationClasses;
+ private ClasspathPattern _systemClasses = null;
+ private ClasspathPattern _serverClasses = null;
+
private Configuration[] _configurations;
private String _defaultsDescriptor=WEB_DEFAULTS_XML;
private String _descriptor=null;
@@ -85,26 +125,7 @@ public class WebAppContext extends ServletContextHandler
private boolean _logUrlOnStart =false;
private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
private PermissionCollection _permissions;
- private String[] _systemClasses = {
- "java.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
- "javax.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
- "org.xml.", // needed by javax.xml
- "org.w3c.", // needed by javax.xml
- "org.apache.commons.logging.", // special case.
- "org.eclipse.jetty.continuation.", // webapp cannot change continuation classes
- "org.eclipse.jetty.jndi.", // webapp cannot change naming classes
- "org.eclipse.jetty.plus.jaas.", // webapp cannot change jetty jaas classes
- "org.eclipse.jetty.servlet.DefaultServlet", // webapp cannot change default servlets
- "org.eclipse.jetty.websocket.", // WebSocket is a jetty extension
- };
- private String[] _serverClasses = {
- "-org.eclipse.jetty.continuation.", // don't hide continuation classes
- "-org.eclipse.jetty.jndi.", // don't hide naming classes
- "-org.eclipse.jetty.plus.jaas.", // don't hide jaas modules
- "-org.eclipse.jetty.servlet.DefaultServlet", // webapp cannot change default servlets
- "-org.eclipse.jetty.websocket.", // don't hide websocket extension
- "org.eclipse.jetty." // hide rest of jetty classes
- };
+
private File _tmpDir;
private String _war;
private String _extraClasspath;
@@ -113,15 +134,17 @@ public class WebAppContext extends ServletContextHandler
private Map _resourceAliases;
private boolean _ownClassLoader=false;
private boolean _configurationDiscovered=true;
+ private boolean _configurationClassesSet=false;
+ private boolean _configurationsSet=false;
- public static ContextHandler getCurrentWebAppContext()
+ public static WebAppContext getCurrentWebAppContext()
{
ContextHandler.Context context=ContextHandler.getCurrentContext();
if (context!=null)
{
ContextHandler handler = context.getContextHandler();
if (handler instanceof WebAppContext)
- return handler;
+ return (WebAppContext)handler;
}
return null;
}
@@ -130,6 +153,7 @@ public class WebAppContext extends ServletContextHandler
public WebAppContext()
{
super(SESSIONS|SECURITY);
+ _scontext=new Context();
setErrorHandler(new ErrorPageErrorHandler());
}
@@ -141,6 +165,7 @@ public class WebAppContext extends ServletContextHandler
public WebAppContext(String webApp,String contextPath)
{
super(null,contextPath,SESSIONS|SECURITY);
+ _scontext=new Context();
setContextPath(contextPath);
setWar(webApp);
setErrorHandler(new ErrorPageErrorHandler());
@@ -155,6 +180,7 @@ public class WebAppContext extends ServletContextHandler
public WebAppContext(HandlerContainer parent, String webApp, String contextPath)
{
super(parent,contextPath,SESSIONS|SECURITY);
+ _scontext=new Context();
setWar(webApp);
setErrorHandler(new ErrorPageErrorHandler());
}
@@ -165,7 +191,7 @@ public class WebAppContext extends ServletContextHandler
public WebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
{
super(null,sessionHandler,securityHandler,servletHandler,errorHandler);
-
+ _scontext=new Context();
setErrorHandler(errorHandler!=null?errorHandler:new ErrorPageErrorHandler());
}
@@ -299,7 +325,7 @@ public class WebAppContext extends ServletContextHandler
* <li>Web Fragments</li>
* <li>META-INF/resource directories</li>
* </ul>
- * @param servlet3autoConfig the servlet3autoConfig to set
+ * @param discovered true if configuration discovery is enabled for automatic configuration from the context
*/
public void setConfigurationDiscovered(boolean discovered)
{
@@ -318,7 +344,12 @@ public class WebAppContext extends ServletContextHandler
// Setup configurations
loadConfigurations();
+ // Setup system classes
+ loadSystemClasses();
+ // Setup server classes
+ loadServerClasses();
+
// Configure classloader
_ownClassLoader=false;
if (getClassLoader()==null)
@@ -342,11 +373,16 @@ public class WebAppContext extends ServletContextHandler
- // Prepare for configuration
+ // Prepare for configuration
+ //Make a new MetaData to hold descriptor and annotation metadata
+ MetaData metadata = new MetaData(this);
+ setAttribute(MetaData.METADATA, metadata);
+
for (int i=0;i<_configurations.length;i++)
_configurations[i].preConfigure(this);
super.doStart();
+
// Clean up after configuration
for (int i=0;i<_configurations.length;i++)
@@ -456,7 +492,6 @@ public class WebAppContext extends ServletContextHandler
{
return _permissions;
}
-
/* ------------------------------------------------------------ */
/**
@@ -465,25 +500,18 @@ public class WebAppContext extends ServletContextHandler
*/
public String[] getServerClasses()
{
- return _serverClasses;
+ if (_serverClasses == null)
+ loadServerClasses();
+
+ return _serverClasses.getPatterns();
}
-
+
public void addServerClass(String classname)
{
- for (int i = 0, n = _serverClasses.length; i < n; i++)
- {
- if (_serverClasses[i].equals(classname))
- {
- // Already present.
- return;
- }
- }
-
- int len = _serverClasses.length + 1;
- String sysclass[] = new String[len];
- System.arraycopy(_serverClasses,0,sysclass,0,len - 1);
- sysclass[len - 1] = classname;
- _serverClasses = sysclass;
+ if (_serverClasses == null)
+ loadServerClasses();
+
+ _serverClasses.addPattern(classname);
}
/* ------------------------------------------------------------ */
@@ -493,95 +521,75 @@ public class WebAppContext extends ServletContextHandler
*/
public String[] getSystemClasses()
{
- return _systemClasses;
+ if (_systemClasses == null)
+ loadSystemClasses();
+
+ return _systemClasses.getPatterns();
}
public void addSystemClass(String classname)
{
- for (int i = 0, n = _systemClasses.length; i < n; i++)
- {
- if (_systemClasses[i].equals(classname))
- {
- // Already present.
- return;
- }
- }
-
- int len = _systemClasses.length + 1;
- String sysclass[] = new String[len];
- System.arraycopy(_systemClasses,0,sysclass,0,len - 1);
- sysclass[len - 1] = classname;
- _systemClasses = sysclass;
+ if (_systemClasses == null)
+ loadSystemClasses();
+
+ _systemClasses.addPattern(classname);
}
/* ------------------------------------------------------------ */
public boolean isServerClass(String name)
{
- name=name.replace('/','.');
- while(name.startsWith("."))
- name=name.substring(1);
-
- String[] server_classes = getServerClasses();
- if (server_classes!=null)
- {
- for (int i=0;i<server_classes.length;i++)
- {
- boolean result=true;
- String c=server_classes[i];
- if (c.startsWith("-"))
- {
- c=c.substring(1); // TODO cache
- result=false;
- }
-
- if (c.endsWith("."))
- {
- if (name.startsWith(c))
- return result;
- }
- else if (name.equals(c))
- return result;
- }
- }
- return false;
+ if (_serverClasses == null)
+ loadServerClasses();
+
+ return _serverClasses.match(name);
}
/* ------------------------------------------------------------ */
public boolean isSystemClass(String name)
{
- name=name.replace('/','.');
- while(name.startsWith("."))
- name=name.substring(1);
- String[] system_classes = getSystemClasses();
- if (system_classes!=null)
+ if (_systemClasses == null)
+ loadSystemClasses();
+
+ return _systemClasses.match(name);
+ }
+
+ private void loadSystemClasses()
+ {
+ if (_systemClasses != null)
+ return;
+
+ //look for a Server attribute with the list of System classes
+ //to apply to every web application. If not present, use our defaults.
+ Server server = getServer();
+ if (server != null)
{
- for (int i=0;i<system_classes.length;i++)
- {
- boolean result=true;
- String c=system_classes[i];
-
- if (c.startsWith("-"))
- {
- c=c.substring(1); // TODO cache
- result=false;
- }
-
- if (c.endsWith("."))
- {
- if (name.startsWith(c))
- return result;
- }
- else if (name.equals(c))
- return result;
- }
+ Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
+ if (systemClasses != null && systemClasses instanceof String[])
+ _systemClasses = ClasspathPattern.fromArray((String[])systemClasses);
}
- return false;
-
+ if (_systemClasses == null)
+ _systemClasses = ClasspathPattern.fromArray(__dftSystemClasses);
}
-
-
+ private void loadServerClasses()
+ {
+ if (_serverClasses != null)
+ return;
+
+ //look for a Server attribute with the list of Server classes
+ //to apply to every web application. If not present, use our defaults.
+ Server server = getServer();
+ if (server != null)
+ {
+ Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
+ if (serverClasses != null || serverClasses instanceof String[])
+ _serverClasses = ClasspathPattern.fromArray((String[])serverClasses);
+ }
+
+ if (_serverClasses == null)
+ _serverClasses = ClasspathPattern.fromArray(__dftServerClasses);
+ }
/* ------------------------------------------------------------ */
/**
@@ -644,21 +652,26 @@ public class WebAppContext extends ServletContextHandler
return _parentLoaderPriority;
}
+
+ /* ------------------------------------------------------------ */
+ public String[] getDefaultConfigurationClasses ()
+ {
+ return __dftConfigurationClasses;
+ }
+
+
/* ------------------------------------------------------------ */
protected void loadConfigurations()
throws Exception
{
+ //if the configuration instances have been set explicitly, use them
if (_configurations!=null)
return;
- //look for a Server attribute with the list of names of Configuration classes
- //to apply to every web app. If not present, use our defaults.
- String[] serverConfigs = (String[])getServer().getAttribute(SERVER_CONFIG);
- if (serverConfigs != null)
- _configurationClasses = serverConfigs;
- if (_configurationClasses == null)
+ //if the configuration classnames have been set explicitly use them
+ if (!_configurationClassesSet)
_configurationClasses=__dftConfigurationClasses;
-
+
_configurations = new Configuration[_configurationClasses.length];
for (int i = 0; i < _configurationClasses.length; i++)
{
@@ -695,6 +708,7 @@ public class WebAppContext extends ServletContextHandler
public void setConfigurationClasses(String[] configurations)
{
_configurationClasses = configurations==null?null:(String[])configurations.clone();
+ _configurationClassesSet = true;
}
/* ------------------------------------------------------------ */
@@ -704,6 +718,7 @@ public class WebAppContext extends ServletContextHandler
public void setConfigurations(Configuration[] configurations)
{
_configurations = configurations==null?null:(Configuration[])configurations.clone();
+ _configurationsSet = true;
}
/* ------------------------------------------------------------ */
@@ -844,7 +859,7 @@ public class WebAppContext extends ServletContextHandler
*/
public void setServerClasses(String[] serverClasses)
{
- _serverClasses = serverClasses==null?null:(String[])serverClasses.clone();
+ _serverClasses = ClasspathPattern.fromArray(serverClasses);
}
/* ------------------------------------------------------------ */
@@ -864,7 +879,7 @@ public class WebAppContext extends ServletContextHandler
*/
public void setSystemClasses(String[] systemClasses)
{
- _systemClasses = systemClasses==null?null:(String[])systemClasses.clone();
+ _systemClasses = ClasspathPattern.fromArray(systemClasses);
}
@@ -950,19 +965,63 @@ public class WebAppContext extends ServletContextHandler
{
this._logUrlOnStart = logOnStart;
}
+
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void setServer(Server server)
+ {
+ super.setServer(server);
+ //if we haven't been given a set of configuration instances to
+ //use, and we haven't been given a set of configuration classes
+ //to use, use the configuration classes that came from the
+ //Server (if there are any)
+ if (!_configurationsSet && !_configurationClassesSet && server != null)
+ {
+ String[] serverConfigs = (String[])server.getAttribute(SERVER_CONFIG);
+ if (serverConfigs != null)
+ setConfigurationClasses(serverConfigs);
+ }
+ }
/* ------------------------------------------------------------ */
@Override
protected void startContext()
throws Exception
{
-
-
// Configure webapp
for (int i=0;i<_configurations.length;i++)
_configurations[i].configure(this);
-
+
+ //resolve the metadata
+ ((MetaData)getAttribute(MetaData.METADATA)).resolve();
super.startContext();
}
+
+ /* ------------------------------------------------------------ */
+ public class Context extends ServletContextHandler.Context
+ {
+ /* ------------------------------------------------------------ */
+ public URL getResource(String path) throws MalformedURLException
+ {
+ Resource resource=WebAppContext.this.getResource(path);
+ if (resource==null || !resource.exists())
+ return null;
+
+ // Should we go to the original war?
+ if (resource.isDirectory() && resource instanceof ResourceCollection && !WebAppContext.this.isExtractWAR())
+ {
+ Resource[] resources = ((ResourceCollection)resource).getResources();
+ for (int i=resources.length;i-->0;)
+ {
+ if (resources[i].getName().startsWith("jar:file"))
+ return resources[i].getURL();
+ }
+ }
+
+ return resource.getURL();
+ }
+ }
+
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
index 2098b22b56..a4fd810f3f 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -6,9 +6,7 @@ import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.jetty.server.Connector;
@@ -25,6 +23,7 @@ public class WebInfConfiguration implements Configuration
public static final String TEMPDIR_CREATED = "org.eclipse.jetty.tmpdirCreated";
public static final String CONTAINER_JAR_RESOURCES = "org.eclipse.jetty.containerJars";
public static final String WEB_INF_JAR_RESOURCES = "org.eclipse.jetty.webInfJars";
+ public static final String WEB_INF_ORDERED_JAR_RESOURCES = "org.eclipse.jetty.webInfOrderedJars";
public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern";
public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern";
@@ -139,7 +138,7 @@ public class WebInfConfiguration implements Configuration
// Look for classes directory
Resource classes= web_inf.addPath("classes/");
if (classes.exists())
- ((WebAppClassLoader)context.getClassLoader()).addClassPath(classes.toString());
+ ((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
// Look for jars
Resource lib= web_inf.addPath("lib/");
@@ -219,69 +218,53 @@ public class WebInfConfiguration implements Configuration
* contents if dir already exists.
* </li>
* </ol>
- *
- * @return
*/
public void resolveTempDirectory (WebAppContext context)
{
//If a tmp directory is already set, we're done
File tmpDir = context.getTempDirectory();
- if (tmpDir!=null && tmpDir.isDirectory() && tmpDir.canWrite())
- return; //Already have a suitable tmp dir configured
+ if (tmpDir != null && tmpDir.isDirectory() && tmpDir.canWrite())
+ {
+ return; // Already have a suitable tmp dir configured
+ }
- //None configured, try and come up with one
- //First ... see if one is configured in a context attribute
- //either as a File or name of a file
- Object t = context.getAttribute(WebAppContext.TEMPDIR);
- if (t != null)
+ // No temp directory configured, try to establish one.
+ // First we check the context specific, javax.servlet specified, temp directory attribute
+ File servletTmpDir = asFile(context.getAttribute(WebAppContext.TEMPDIR));
+ if (servletTmpDir != null && servletTmpDir.isDirectory() && servletTmpDir.canWrite())
+ {
+ // Use as tmpDir
+ tmpDir = servletTmpDir;
+ // Ensure Attribute has File object
+ context.setAttribute(WebAppContext.TEMPDIR,tmpDir);
+ // Set as TempDir in context.
+ context.setTempDirectory(tmpDir);
+ return;
+ }
+
+ try
{
- //Is it a File?
- if (t instanceof File)
+ // Put the tmp dir in the work directory if we had one
+ File work = new File(System.getProperty("jetty.home"),"work");
+ if (work.exists() && work.canWrite() && work.isDirectory())
{
- tmpDir=(File)t;
- if (tmpDir.isDirectory() && tmpDir.canWrite())
- {
- context.setTempDirectory(tmpDir);
- return;
- }
+ makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists
}
- // The context attribute specified a name not a File
- if (t instanceof String)
+ else
{
- try
+ File baseTemp = asFile(context.getAttribute(WebAppContext.BASETEMPDIR));
+ if (baseTemp != null && baseTemp.isDirectory() && baseTemp.canWrite())
{
- tmpDir=new File((String)t);
-
- if (tmpDir.isDirectory() && tmpDir.canWrite())
- {
- context.setAttribute(context.TEMPDIR,tmpDir);
- context.setTempDirectory(tmpDir);
- return;
- }
+ // Use baseTemp directory (allow the funky Jetty_0_0_0_0.. subdirectory logic to kick in
+ makeTempDirectory(baseTemp,context,false);
}
- catch(Exception e)
+ else
{
- Log.warn(Log.EXCEPTION,e);
+ makeTempDirectory(new File(System.getProperty("java.io.tmpdir")),context,true); //make a tmpdir, delete if it already exists
}
}
}
-
- // Second ... make a tmp directory, in a work directory if one exists
- String temp = getCanonicalNameForWebAppTmpDir(context);
-
- try
- {
- //Put the tmp dir in the work directory if we had one
- File work = new File(System.getProperty("jetty.home"),"work");
- if (!work.exists() || !work.canWrite() || !work.isDirectory())
- work = null;
-
- if (work!=null)
- makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists
- else
- makeTempDirectory(new File(System.getProperty("java.io.tmpdir")), context, true); //make a tmpdir, delete if it already exists
- }
catch(Exception e)
{
tmpDir=null;
@@ -309,7 +292,31 @@ public class WebInfConfiguration implements Configuration
}
}
-
+ /**
+ * Given an Object, return File reference for object.
+ * Typically used to convert anonymous Object from getAttribute() calls to a File object.
+ * @param fileattr the file attribute to analyze and return from (supports type File and type String, all others return null)
+ * @return the File object, null if null, or null if not a File or String
+ */
+ private File asFile(Object fileattr)
+ {
+ if (fileattr == null)
+ {
+ return null;
+ }
+ if (fileattr instanceof File)
+ {
+ return (File)fileattr;
+ }
+ if (fileattr instanceof String)
+ {
+ return new File((String)fileattr);
+ }
+ return null;
+ }
+
+
+
public void makeTempDirectory (File parent, WebAppContext context, boolean deleteExisting)
throws IOException
{
@@ -365,6 +372,7 @@ public class WebInfConfiguration implements Configuration
public void unpack (WebAppContext context) throws IOException
{
Resource web_app = context.getBaseResource();
+ _preUnpackBaseResource = context.getBaseResource();
if (web_app == null)
{
@@ -408,9 +416,12 @@ public class WebInfConfiguration implements Configuration
{
// look for a sibling like "foo/" to a "foo.war"
File warfile=Resource.newResource(war).getFile();
- File sibling = new File(warfile.getParent(),warfile.getName().substring(0,warfile.getName().length()-4));
- if (sibling.exists() && sibling.isDirectory() && sibling.canWrite())
- extractedWebAppDir=sibling;
+ if (warfile!=null)
+ {
+ File sibling = new File(warfile.getParent(),warfile.getName().substring(0,warfile.getName().length()-4));
+ if (sibling.exists() && sibling.isDirectory() && sibling.canWrite())
+ extractedWebAppDir=sibling;
+ }
}
if (extractedWebAppDir==null)
@@ -463,7 +474,7 @@ public class WebInfConfiguration implements Configuration
Log.debug("webapp=" + web_app);
}
- _preUnpackBaseResource = context.getBaseResource();
+
// Do we need to extract WEB-INF/lib?
Resource web_inf= web_app.addPath("WEB-INF/");
@@ -499,7 +510,7 @@ public class WebInfConfiguration implements Configuration
web_inf_classes.copyTo(webInfClassesDir);
}
- web_inf=Resource.newResource(extractedWebInfDir.toURL());
+ web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath());
ResourceCollection rc = new ResourceCollection(new Resource[]{web_inf,web_app});
@@ -530,7 +541,7 @@ public class WebInfConfiguration implements Configuration
/**
* Check if the tmpDir itself is called "work", or if the tmpDir
* is in a directory called "work".
- * @return
+ * @return true if File is a temporary or work directory
*/
public boolean isTempWorkDirectory (File tmpDir)
{
@@ -546,13 +557,13 @@ public class WebInfConfiguration implements Configuration
/**
- * Create a canonical name for a webapp tmp directory.
+ * Create a canonical name for a webapp temp directory.
* The form of the name is:
- * "Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36 hashcode of whole string
+ * <code>"Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string</code>
*
* host and port uniquely identify the server
* context and virtual host uniquely identify the webapp
- * @return
+ * @return the canonical name for the webapp temp directory
*/
public String getCanonicalNameForWebAppTmpDir (WebAppContext context)
{
@@ -643,7 +654,7 @@ public class WebInfConfiguration implements Configuration
/**
* Look for jars in WEB-INF/lib
* @param context
- * @return
+ * @return the list of jar resources found within context
* @throws Exception
*/
protected List<Resource> findJars (WebAppContext context)
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java
index 51a07da984..abb952d479 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2003-2009 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 2003-2010 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
@@ -34,20 +34,18 @@ public class WebXmlConfiguration implements Configuration
/* ------------------------------------------------------------------------------- */
/**
- * Process webdefaults.xml
+ *
*
*
*/
public void preConfigure (WebAppContext context) throws Exception
{
-
- WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (processor == null)
- {
- processor = new WebXmlProcessor (context);
- context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
- }
-
+
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException("No metadata");
+
+
//parse webdefault.xml
String defaultsDescriptor = context.getDefaultsDescriptor();
if (defaultsDescriptor != null && defaultsDescriptor.length() > 0)
@@ -55,7 +53,7 @@ public class WebXmlConfiguration implements Configuration
Resource dftResource = Resource.newSystemResource(defaultsDescriptor);
if (dftResource == null)
dftResource = context.newResource(defaultsDescriptor);
- processor.parseDefaults (dftResource);
+ metaData.setDefaults (dftResource);
}
@@ -63,7 +61,7 @@ public class WebXmlConfiguration implements Configuration
Resource webxml = findWebXml(context);
if (webxml != null)
{
- processor.parseWebXml(webxml);
+ metaData.setWebXml(webxml);
}
//parse but don't process override-web.xml
@@ -73,7 +71,7 @@ public class WebXmlConfiguration implements Configuration
Resource orideResource = Resource.newSystemResource(overrideDescriptor);
if (orideResource == null)
orideResource = context.newResource(overrideDescriptor);
- processor.parseOverride(orideResource);
+ metaData.setOverride(orideResource);
}
}
@@ -90,31 +88,35 @@ public class WebXmlConfiguration implements Configuration
if (Log.isDebugEnabled()) Log.debug("Cannot configure webapp after it is started");
return;
}
+
+ MetaData metaData = (MetaData)context.getAttribute(MetaData.METADATA);
+ if (metaData == null)
+ throw new IllegalStateException("No metadata");
+
+ metaData.addDescriptorProcessor(new StandardDescriptorProcessor());
- WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
- if (processor == null)
+ /*
+ StandardDescriptorProcessor descriptorProcessor = (StandardDescriptorProcessor)context.getAttribute(StandardDescriptorProcessor.STANDARD_PROCESSOR);
+ if (descriptorProcessor == null)
{
- processor = new WebXmlProcessor (context);
- context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
+ descriptorProcessor = new StandardDescriptorProcessor(metaData);
+ context.setAttribute(StandardDescriptorProcessor.STANDARD_PROCESSOR, descriptorProcessor);
}
-
//process web-default.xml
- processor.process(processor.getWebDefault());
+ descriptorProcessor.process(metaData.getWebDefault());
//process web.xml
- processor.process(processor.getWebXml());
+ descriptorProcessor.process(metaData.getWebXml());
//process override-web.xml
- processor.process(processor.getOverrideWeb());
-
+ descriptorProcessor.process(metaData.getOverrideWeb());
+ */
}
public void postConfigure(WebAppContext context) throws Exception
{
- context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, null);
- context.setAttribute(WebXmlProcessor.METADATA_COMPLETE, null);
- context.setAttribute(WebXmlProcessor.WEBXML_CLASSNAMES, null);
+ context.setAttribute(MetaData.WEBXML_CLASSNAMES, null);
}
/* ------------------------------------------------------------------------------- */
@@ -154,8 +156,6 @@ public class WebXmlConfiguration implements Configuration
context.setEventListeners(null);
context.setWelcomeFiles(null);
- if (_securityHandler instanceof ConstraintAware)
- ((ConstraintAware) _securityHandler).setConstraintMappings(new ConstraintMapping[]{}, Collections.EMPTY_SET);
if (context.getErrorHandler() instanceof ErrorPageErrorHandler)
((ErrorPageErrorHandler)
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlProcessor.java
deleted file mode 100644
index f069e16abd..0000000000
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlProcessor.java
+++ /dev/null
@@ -1,758 +0,0 @@
-// ========================================================================
-// Copyright (c) 2009 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.webapp;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
-
-import org.eclipse.jetty.util.Loader;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.xml.XmlParser;
-
-
-
-
-
-/**
- * WebXmlProcessor
- *
- *
- */
-public class WebXmlProcessor
-{
- public static final String WEB_PROCESSOR = "org.eclipse.jetty.webProcessor";
- public static final String METADATA_COMPLETE = "org.eclipse.jetty.metadataComplete";
- public static final String WEBXML_MAJOR_VERSION = "org.eclipse.jetty.webXmlMajorVersion";
- public static final String WEBXML_MINOR_VERSION = "org.eclipse.jetty.webXmlMinorVersion";
- public static final String WEBXML_CLASSNAMES = "org.eclipse.jetty.webXmlClassNames";
-
- public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment};
-
- protected WebAppContext _context;
- protected Map<String, Descriptor> _origins = new HashMap<String,Descriptor>();
- protected Descriptor _webDefaultsRoot;
- protected Descriptor _webXmlRoot;
- protected Descriptor _webOverrideRoot;
- protected List<Fragment> _webFragmentRoots = new ArrayList<Fragment>();
- protected Map<String,Fragment> _webFragmentNameMap = new HashMap<String,Fragment>();
- protected List<Fragment> _orderedFragments = new LinkedList<Fragment>();
- protected XmlParser _parser;
- protected Ordering _ordering;//can be set to RelativeOrdering by web-default.xml, web.xml, web-override.xml
- protected StandardDescriptorProcessor _standardDescriptorProcessor;
-
-
-
-
- public static XmlParser newParser()
- throws ClassNotFoundException
- {
- XmlParser xmlParser=new XmlParser();
- //set up cache of DTDs and schemas locally
- URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
- URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
- URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
- URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
- URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
- URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
- URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
- URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
- URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
- URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
- URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
- URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
- URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
-
- URL jsp20xsd = null;
- URL jsp21xsd = null;
-
- try
- {
- Class jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
- jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
- jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
- }
- catch (Exception e)
- {
- Log.ignore(e);
- }
- finally
- {
- if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
- if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
- }
-
- redirect(xmlParser,"web-app_2_2.dtd",dtd22);
- redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
- redirect(xmlParser,"web.dtd",dtd23);
- redirect(xmlParser,"web-app_2_3.dtd",dtd23);
- redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
- redirect(xmlParser,"XMLSchema.dtd",schemadtd);
- redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
- redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
- redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
- redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
- redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
- redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
- redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
- redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd);
- redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd);
- redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd);
- redirect(xmlParser,"xml.xsd",xmlxsd);
- redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
- redirect(xmlParser,"datatypes.dtd",datatypesdtd);
- redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
- redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
- redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
- redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
- redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
- return xmlParser;
- }
-
-
- protected static void redirect(XmlParser parser, String resource, URL source)
- {
- if (source != null) parser.redirectEntity(resource, source);
- }
-
- /**
- * Ordering
- *
- *
- */
- public interface Ordering
- {
- public List<Fragment> order();
- public boolean isAbsolute ();
- }
-
- /**
- * AbsoluteOrdering
- *
- * An <absolute-order> element in web.xml
- */
- public class AbsoluteOrdering implements Ordering
- {
- public static final String OTHER = "@@-OTHER-@@";
- protected List<String> _order = new ArrayList<String>();
- protected boolean _hasOther = false;
-
- public List<Fragment> order()
- {
- List<Fragment> orderedList = new ArrayList<Fragment>();
-
- //1. put everything into the list of named others, and take the named ones out of there,
- //assuming we will want to use the <other> clause
- Map<String,Fragment> others = new HashMap(getNamedFragments());
-
- //2. for each name, take out of the list of others, add to tail of list
- int index = -1;
- for (String item:_order)
- {
- if (!item.equals(OTHER))
- {
- Fragment f = others.remove(item);
- if (f != null)
- orderedList.add(f); //take from others and put into final list in order, ignoring duplicate names
- }
- else
- index = orderedList.size(); //remember the index at which we want to add in all the others
- }
-
- //3. if <other> was specified, insert the leftovers
- if (_hasOther)
- orderedList.addAll((index < 0? 0: index), others.values());
-
- return orderedList;
- }
-
- public boolean isAbsolute()
- {
- return true;
- }
-
- public void add (String name)
- {
- _order.add(name);
- }
-
- public void addOthers ()
- {
- if (_hasOther)
- throw new IllegalStateException ("Duplicate <other> element in absolute ordering");
-
- _hasOther = true;
- _order.add(OTHER);
- }
- }
-
-
- /**
- * RelativeOrdering
- *
- * A set of <order> elements in web-fragment.xmls.
- */
- public class RelativeOrdering implements Ordering
- {
- protected LinkedList<String> _beforeOthers = new LinkedList<String>();
- protected LinkedList<String> _afterOthers = new LinkedList<String>();
- protected LinkedList<String> _noOthers = new LinkedList<String>();
-
- public List<Fragment> order()
- {
- List<Fragment> orderedList = new ArrayList<Fragment>();
-
- int maxIterations = 2;
- boolean done = false;
- do
- {
- //1. order the before-others according to any explicit before/after relationships
- done = orderList(_beforeOthers);
-
- //2. order the after-others according to any explicit before/after relationships
- done = orderList(_afterOthers);
-
- //3. order the no-others according to their explicit before/after relationships
- done = orderList(_noOthers);
- }
- while (!done && (--maxIterations >0));
-
- //5. merge before-others + no-others +after-others
- if (!done)
- throw new IllegalStateException("Circular references for fragments");
-
- for (String s: _beforeOthers)
- orderedList.add(getFragment(s));
- for (String s: _noOthers)
- orderedList.add(getFragment(s));
- for(String s: _afterOthers)
- orderedList.add(getFragment(s));
-
- return orderedList;
- }
-
- public boolean isAbsolute ()
- {
- return false;
- }
-
- public void addBeforeOthers (Fragment d)
- {
- _beforeOthers.addLast(d.getName());
- }
-
- public void addAfterOthers (Fragment d)
- {
- _afterOthers.addLast(d.getName());
- }
-
- public void addNoOthers (Fragment d)
- {
- _noOthers.addLast(d.getName());
- }
-
- protected boolean orderList (LinkedList<String> list)
- {
- //Take a copy of the list so we can iterate over it and at the same time do random insertions
- boolean noChanges = true;
- List<String> iterable = new ArrayList(list);
- Iterator<String> itor = iterable.iterator();
-
- while (itor.hasNext())
- {
- String name = itor.next();
- Fragment f = _webFragmentNameMap.get(name);
- if (f == null)
- throw new IllegalStateException ("No fragment matching name "+name);
-
- //Handle any explicit <before> relationships for the fragment we're considering
- List<String> befores = f.getBefores();
- if (befores != null && !befores.isEmpty())
- {
- for (String b: befores)
- {
- //Fragment we're considering must be before this name
- //Check that we are already before it, if not, move us so that we are.
- //If the name does not exist in our list, then get it out of the no-other list
-
- if (!isBefore(list, name, b))
- {
- //b is not already before name, move it so that it is
- int idx1 = list.indexOf(name);
- int idx2 = list.indexOf(b);
-
- //if b is not in the same list
- if (idx2 < 0)
- {
- // must be in the noOthers list or it would have been an error
- _noOthers.remove(b);
-
- //If its in the no-others list, insert into this list so that we are before it
- insert(list, idx1+1, b);
- noChanges = false;
- }
- else
- {
- //b is in the same list but b is before name, so swap it around
- list.remove(name);
- insert(list, idx2, name);
- noChanges = false;
- }
- }
- }
- }
-
- //Handle any explicit <after> relationships
- List<String> afters = f.getAfters();
- if (afters != null && !afters.isEmpty())
- {
- for (String a: afters)
- {
- //Check that name is after a, moving it if possible if its not
- if (!isAfter(list, name, a))
- {
- //name is not after a, move it
- int idx1 = list.indexOf(name);
- int idx2 = list.indexOf(a);
-
- //if a is not in the same list as name
- if (idx2 < 0)
- {
- //take it out of the noOthers list and put it in the right place in this list
- _noOthers.remove(a);
- insert(list,idx1, a);
- noChanges = false;
- }
- else
- {
- //a is in the same list as name, but in the wrong place, so move it
- list.remove(a);
- insert(list,idx1, a);
- noChanges = false;
- }
- }
- //Name we're considering must be after this name
- //Check we're already after it, if not, move us so that we are.
- //If the name does not exist in our list, then get it out of the no-other list
- }
- }
- }
-
- return noChanges;
- }
-
- /**
- * Is a before b?
- * @param list
- * @param a
- * @param b
- * @return
- */
- protected boolean isBefore (List<String> list, String a, String b)
- {
- //check if a and b are already in the same list, and b is already
- //before a
- int idxa = list.indexOf(a);
- int idxb = list.indexOf(b);
-
-
- if (idxb >=0 && idxb < idxa)
- {
- //a and b are in the same list but a is not before b
- return false;
- }
-
- if (idxb < 0)
- {
- //a and b are not in the same list, but it is still possible that a is before
- //b, depending on which list we're examining
- if (list == _beforeOthers)
- {
- //The list we're looking at is the beforeOthers.If b is in the _afterOthers or the _noOthers, then by
- //definition a is before it
- return true;
- }
- else if (list == _afterOthers)
- {
- //The list we're looking at is the afterOthers, then a will be the tail of
- //the final list. If b is in the beforeOthers list, then b will be before a and an error.
- if (_beforeOthers.contains(b))
- throw new IllegalStateException("Incorrect relationship: "+a+" before "+b);
- else
- return false; //b could be moved to the list
- }
- }
-
- //a and b are in the same list and a is already before b
- return true;
- }
-
-
- /**
- * Is a after b?
- * @param list
- * @param a
- * @param b
- * @return
- */
- protected boolean isAfter(List<String> list, String a, String b)
- {
- int idxa = list.indexOf(a);
- int idxb = list.indexOf(b);
-
- if (idxb >=0 && idxa < idxb)
- {
- //a and b are both in the same list, but a is before b
- return false;
- }
-
- if (idxb < 0)
- {
- //a and b are in different lists. a could still be after b depending on which list it is in.
-
- if (list == _afterOthers)
- {
- //The list we're looking at is the afterOthers. If b is in the beforeOthers or noOthers then
- //by definition a is after b because a is in the afterOthers list.
- return true;
- }
- else if (list == _beforeOthers)
- {
- //The list we're looking at is beforeOthers, and contains a and will be before
- //everything else in the final ist. If b is in the afterOthers list, then a cannot be before b.
- if (_afterOthers.contains(b))
- throw new IllegalStateException("Incorrect relationship: "+b+" after "+a);
- else
- return false; //b could be moved from noOthers list
- }
- }
-
- return true; //a and b in the same list, a is after b
- }
-
- protected void insert(List<String> list, int index, String element)
- {
- if (index > list.size())
- list.add(element);
- else
- list.add(index, element);
- }
- }
-
-
-
- public WebXmlProcessor (WebAppContext context) throws ClassNotFoundException
- {
- _context = context;
- _parser = newParser();
- }
-
- public WebAppContext getContext()
- {
- return _context;
- }
-
- public XmlParser getParser()
- {
- return _parser;
- }
-
- public void parseDefaults (Resource webDefaults)
- throws Exception
- {
- _webDefaultsRoot = new DefaultsDescriptor(webDefaults, this);
- _webDefaultsRoot.parse();
- if (_webDefaultsRoot.isOrdered())
- {
- if (_ordering == null)
- _ordering = new AbsoluteOrdering();
-
- List<String> order = _webDefaultsRoot.getOrdering();
- for (String s:order)
- {
- if (s.equalsIgnoreCase("others"))
- ((AbsoluteOrdering)_ordering).addOthers();
- else
- ((AbsoluteOrdering)_ordering).add(s);
- }
- }
- }
-
- public void parseWebXml (Resource webXml)
- throws Exception
- {
- _webXmlRoot = new Descriptor(webXml, this);
- _webXmlRoot.parse();
- _webXmlRoot.processClassNames();
- if (_webXmlRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.True)
- _context.setAttribute(METADATA_COMPLETE, Boolean.TRUE);
- else
- _context.setAttribute(METADATA_COMPLETE, Boolean.FALSE);
- _context.getServletContext().setEffectiveMajorVersion(_webXmlRoot.getMajorVersion());
- _context.getServletContext().setEffectiveMinorVersion(_webXmlRoot.getMinorVersion());
- _context.setAttribute(WEBXML_CLASSNAMES, _webXmlRoot.getClassNames());
-
- if (_webXmlRoot.isOrdered())
- {
- if (_ordering == null)
- _ordering = new AbsoluteOrdering();
-
- List<String> order = _webXmlRoot.getOrdering();
- for (String s:order)
- {
- if (s.equalsIgnoreCase("others"))
- ((AbsoluteOrdering)_ordering).addOthers();
- else
- ((AbsoluteOrdering)_ordering).add(s);
- }
- }
- }
-
- public void parseOverride (Resource override)
- throws Exception
- {
- _webOverrideRoot = new OverrideDescriptor(override, this);
- _webOverrideRoot.setValidating(false);
- _webOverrideRoot.parse();
- if (_webOverrideRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.True)
- _context.setAttribute(METADATA_COMPLETE, Boolean.TRUE);
- else if (_webOverrideRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.False)
- _context.setAttribute(METADATA_COMPLETE, Boolean.FALSE);
-
- if (_webOverrideRoot.isOrdered())
- {
- if (_ordering == null)
- _ordering = new AbsoluteOrdering();
-
- List<String> order = _webOverrideRoot.getOrdering();
- for (String s:order)
- {
- if (s.equalsIgnoreCase("others"))
- ((AbsoluteOrdering)_ordering).addOthers();
- else
- ((AbsoluteOrdering)_ordering).add(s);
- }
- }
- }
-
-
- public void parseFragment (Resource fragment)
- throws Exception
- {
- Boolean metaComplete = (Boolean)_context.getAttribute(METADATA_COMPLETE);
- if (metaComplete != null && metaComplete.booleanValue())
- return; //do not process anything else if web.xml/web-override.xml set metadata-complete
-
- //Metadata-complete is not set, or there is no web.xml
- Fragment frag = new Fragment(fragment, this);
- frag.parse();
- _webFragmentRoots.add(frag);
- if (frag.getName() != null)
- _webFragmentNameMap.put(frag.getName(), frag);
-
- //If web.xml has specified an absolute ordering, ignore any relative ordering in the fragment
- if (_ordering != null && _ordering.isAbsolute())
- return;
-
- if (frag.isOrdered())
- {
- if (_ordering == null)
- _ordering = new RelativeOrdering();
-
- switch (frag.getOtherType())
- {
- case None:
- {
- ((RelativeOrdering)_ordering).addNoOthers(frag);
- break;
- }
- case Before:
- {
- ((RelativeOrdering)_ordering).addBeforeOthers(frag);
- break;
- }
- case After:
- {
- ((RelativeOrdering)_ordering).addAfterOthers(frag);
- break;
- }
- }
- }
- }
-
-
-
- public void orderFragments ()
- {
- if (_ordering != null)
- {
- _orderedFragments = _ordering.order();
-
- List<String> orderedJars = new ArrayList<String>();
- for (Descriptor frag: _orderedFragments)
- {
- //get just the name of the jar file
- String fullname = frag.getResource().getName();
- int i = fullname.indexOf(".jar");
- int j = fullname.lastIndexOf("/", i);
- orderedJars.add(fullname.substring(j+1,i+4));
- }
- _context.setAttribute(ServletContext.ORDERED_LIBS, orderedJars);
- }
- else
- _orderedFragments = _webFragmentRoots;
- }
-
-
- public void processFragments ()
- throws Exception
- {
- //Servlet Spec 3.0 p.74 says all descriptors must say distributable
- boolean distributable = ((_webDefaultsRoot != null && _webDefaultsRoot.isDistributable())
- || (_webXmlRoot != null && _webXmlRoot.isDistributable())
- || (_webOverrideRoot != null && _webOverrideRoot.isDistributable()));
- for (Fragment frag : _orderedFragments)
- {
- process(frag);
- distributable = distributable && frag.isDistributable();
- }
-
- _context.setDistributable(distributable);
- }
-
-
-
- public Descriptor getWebXml ()
- {
- return _webXmlRoot;
- }
-
- public Descriptor getOverrideWeb ()
- {
- return _webOverrideRoot;
- }
-
- public Descriptor getWebDefault ()
- {
- return _webDefaultsRoot;
- }
-
- public List<Fragment> getFragments ()
- {
- return _webFragmentRoots;
- }
-
- public List<Fragment> getOrderedFragments ()
- {
- return _orderedFragments;
- }
-
- public Ordering getOrdering()
- {
- return _ordering;
- }
-
- public void setOrdering (Ordering o)
- {
- _ordering = o;
- }
-
- public Fragment getFragment(String name)
- {
- return _webFragmentNameMap.get(name);
- }
-
- public Map<String,Fragment> getNamedFragments ()
- {
- return Collections.unmodifiableMap(_webFragmentNameMap);
- }
-
-
- /**
- * Convenience method. Process the standard elements of the web descriptor.
- * @param descriptor
- * @throws Exception
- */
- public void process (Descriptor descriptor)
- throws Exception
- {
- if (descriptor != null)
- {
- initStandardDescriptorProcessor();
- process(descriptor, _standardDescriptorProcessor);
- }
- }
-
-
-
- /**
- * Process the elements of the Descriptor according to the
- * given DescriptorProcessor.
- * @param descriptor
- * @param processor
- * @throws Exception
- */
- public void process (Descriptor descriptor, DescriptorProcessor processor)
- throws Exception
- {
- if (descriptor != null && processor != null)
- processor.process(descriptor);
- }
-
- public Origin getOrigin (String name)
- {
- Descriptor d = _origins.get(name);
- if (d == null)
- return Origin.NotSet;
- if (d instanceof Fragment)
- return Origin.WebFragment;
- if (d instanceof OverrideDescriptor)
- return Origin.WebOverride;
- if (d instanceof DefaultsDescriptor)
- return Origin.WebDefaults;
- return Origin.WebXml;
- }
-
- public Descriptor getOriginDescriptor (String name)
- {
- return _origins.get(name);
- }
-
- public void setOrigin (String name, Descriptor d)
- {
- _origins.put(name, d);
- }
-
- public void initStandardDescriptorProcessor ()
- {
- if (_standardDescriptorProcessor == null)
- _standardDescriptorProcessor = new StandardDescriptorProcessor(this);
- }
-}
diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java
index cb31c10366..7e20c21da2 100644
--- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java
+++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java
@@ -13,13 +13,20 @@
package org.eclipse.jetty.webapp;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebXmlProcessor.AbsoluteOrdering;
-import org.eclipse.jetty.webapp.WebXmlProcessor.RelativeOrdering;
+import org.eclipse.jetty.webapp.MetaData.AbsoluteOrdering;
+import org.eclipse.jetty.webapp.MetaData.RelativeOrdering;
/**
* OrderingTest
@@ -28,193 +35,415 @@ import org.eclipse.jetty.webapp.WebXmlProcessor.RelativeOrdering;
*/
public class OrderingTest extends TestCase
{
+ public class TestResource extends Resource
+ {
+ public String _name;
+
+ public TestResource (String name)
+ {
+ _name =name;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#addPath(java.lang.String)
+ */
+ public Resource addPath(String path) throws IOException, MalformedURLException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#delete()
+ */
+ public boolean delete() throws SecurityException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#exists()
+ */
+ public boolean exists()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#getFile()
+ */
+ public File getFile() throws IOException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#getName()
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#getOutputStream()
+ */
+ public OutputStream getOutputStream() throws IOException, SecurityException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#getURL()
+ */
+ public URL getURL()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#isContainedIn(org.eclipse.jetty.util.resource.Resource)
+ */
+ public boolean isContainedIn(Resource r) throws MalformedURLException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#isDirectory()
+ */
+ public boolean isDirectory()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#lastModified()
+ */
+ public long lastModified()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#length()
+ */
+ public long length()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#list()
+ */
+ public String[] list()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#release()
+ */
+ public void release()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * @see org.eclipse.jetty.util.resource.Resource#renameTo(org.eclipse.jetty.util.resource.Resource)
+ */
+ public boolean renameTo(Resource dest) throws SecurityException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+
public void testRelativeOrdering0 ()
throws Exception
{
//Example from ServletSpec p.70
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ List<Resource> resources = new ArrayList<Resource>();
+ metaData._ordering = metaData.new RelativeOrdering();
//A: after others, after C
- Fragment f1 = new Fragment((Resource)null, processor);
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
- f1._hasOther=true;
- ((RelativeOrdering)processor._ordering).addAfterOthers(f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1, f1);
+ f1._otherType = FragmentDescriptor.OtherType.After;
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(r1);
f1._afters.add("C");
//B: before others
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- f2._hasOther = true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2, f2);
+ f2._otherType = FragmentDescriptor.OtherType.Before;
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(r2);
//C: after others
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
- ((RelativeOrdering)processor._ordering).addAfterOthers(f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3, f3);
+ f3._otherType = FragmentDescriptor.OtherType.After;
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(r3);
//D: no ordering
- Fragment f4 = new Fragment((Resource)null, processor);
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor(r4, metaData);
f4._name="D";
- processor._webFragmentNameMap.put(f4._name, f4);
- ((RelativeOrdering)processor._ordering).addNoOthers(f4);
-
- //E: no ordering
- Fragment f5 = new Fragment((Resource)null, processor);
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4, f4);
+ f4._otherType = FragmentDescriptor.OtherType.None;
+ //((RelativeOrdering)metaData._ordering).addNoOthers(r4);
+
+ //E: no ordering
+ TestResource jar5 = new TestResource("E");
+ resources.add(jar5);
+ TestResource r5 = new TestResource("E/web-fragment.xml");
+ FragmentDescriptor f5 = new FragmentDescriptor(r5, metaData);
f5._name="E";
- processor._webFragmentNameMap.put(f5._name, f5);
- ((RelativeOrdering)processor._ordering).addNoOthers(f5);
+ metaData._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentResourceMap.put(jar5, f5);
+ f5._otherType = FragmentDescriptor.OtherType.None;
+ //((RelativeOrdering)metaData._ordering).addNoOthers(r5);
//F: before others, before B
- Fragment f6 = new Fragment((Resource)null, processor);
+ TestResource jar6 = new TestResource("F");
+ resources.add(jar6);
+ TestResource r6 = new TestResource("F/web-fragment.xml");
+ FragmentDescriptor f6 = new FragmentDescriptor(r6, metaData);
f6._name="F";
- processor._webFragmentNameMap.put(f6._name, f6);
- f6._hasOther=true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f6);
+ metaData._webFragmentNameMap.put(f6._name, f6);
+ metaData._webFragmentResourceMap.put(jar6,f6);
+ f6._otherType = FragmentDescriptor.OtherType.Before;
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(r6);
f6._befores.add("B");
- /*
- * p.70 outcome: F, B, D, E, C, A
- */
+ //
+ // p.70 outcome: F, B, D, E, C, A
+ //
String[] outcomes = {"FBDECA"};
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
String result = "";
- for (Fragment f:orderedList)
- result+=(f._name);
-
+ for (Resource r:orderedList)
+ result+=(((TestResource)r)._name);
+
if (!checkResult(result, outcomes))
fail("No outcome matched "+result);
}
-
+
+
public void testRelativeOrdering1 ()
throws Exception
{
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
//Example from ServletSpec p.70-71
//No name: after others, before C
- Fragment f1 = new Fragment((Resource)null, processor);
- f1._name = Fragment.NAMELESS+"1";
- processor._webFragmentNameMap.put(f1._name, f1);
- f1._hasOther=true;
- ((RelativeOrdering)processor._ordering).addAfterOthers(f1);
+ TestResource jar1 = new TestResource("plain");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("plain/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
+ f1._name = FragmentDescriptor.NAMELESS+"1";
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1,f1);
+ f1._otherType = FragmentDescriptor.OtherType.After;
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(f1);
f1._befores.add("C");
//B: before others
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- f2._hasOther = true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2,f2);
+ f2._otherType = FragmentDescriptor.OtherType.Before;
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(f2);
//C: no ordering
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
- ((RelativeOrdering)processor._ordering).addNoOthers(f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f3);
+ f3._otherType = FragmentDescriptor.OtherType.None;
//D: after others
- Fragment f4 = new Fragment((Resource)null, processor);
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor(r4, metaData);
f4._name="D";
- processor._webFragmentNameMap.put(f4._name, f4);
- f4._hasOther = true;
- ((RelativeOrdering)processor._ordering).addAfterOthers(f4);
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4,f4);
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(f4);
+ f4._otherType = FragmentDescriptor.OtherType.After;
//E: before others
- Fragment f5 = new Fragment((Resource)null, processor);
+ TestResource jar5 = new TestResource("E");
+ resources.add(jar5);
+ TestResource r5 = new TestResource("E/web-fragment.xml");
+ FragmentDescriptor f5 = new FragmentDescriptor(r5, metaData);
f5._name="E";
- processor._webFragmentNameMap.put(f5._name, f5);
- f5._hasOther=true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f5);
+ metaData._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentResourceMap.put(jar5,f5);
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(f5);
+ f5._otherType = FragmentDescriptor.OtherType.Before;
//F: no ordering
- Fragment f6 = new Fragment((Resource)null, processor);
+ TestResource jar6 = new TestResource("F");
+ resources.add(jar6);
+ TestResource r6 = new TestResource("F/web-fragment.xml");
+ FragmentDescriptor f6 = new FragmentDescriptor(r6, metaData);
f6._name="F";
- processor._webFragmentNameMap.put(f6._name, f6);
- ((RelativeOrdering)processor._ordering).addNoOthers(f6);
+ metaData._webFragmentNameMap.put(f6._name, f6);
+ metaData._webFragmentResourceMap.put(jar6,f6);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f6);
+ f6._otherType = FragmentDescriptor.OtherType.None;
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
- /* p.70-71 Possible outcomes are:
- * B, E, F, noname, C, D
- * B, E, F, noname, D, C
- * E, B, F, noname, C, D
- * E, B, F, noname, D, C
- * E, B, F, D, noname, C
- */
- String[] outcomes = {"BEF"+f1._name+"CD",
- "BEF"+ f1._name+ "DC",
- "EBF"+ f1._name+ "CD",
- "EBF"+ f1._name+ "DC",
- "EBFD"+ f1._name};
+ // p.70-71 Possible outcomes are:
+ // B, E, F, noname, C, D
+ // B, E, F, noname, D, C
+ // E, B, F, noname, C, D
+ // E, B, F, noname, D, C
+ // E, B, F, D, noname, C
+ //
+ String[] outcomes = {"BEFplainCD",
+ "BEFplainDC",
+ "EBFplainCD",
+ "EBFplainDC",
+ "EBFDplain"};
String orderedNames = "";
- for (Fragment f:orderedList)
- orderedNames+=(f._name);
+ for (Resource r:orderedList)
+ orderedNames+=(((TestResource)r)._name);
-
if (!checkResult(orderedNames, outcomes))
fail("No outcome matched "+orderedNames);
}
+
public void testRelativeOrdering2 ()
throws Exception
{
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
//Example from Spec p. 71-72
//A: after B
- Fragment f1 = new Fragment((Resource)null, processor);
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
- ((RelativeOrdering)processor._ordering).addNoOthers(f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1, f1);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f1);
+ f1._otherType = FragmentDescriptor.OtherType.None;
f1._afters.add("B");
//B: no order
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- ((RelativeOrdering)processor._ordering).addNoOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2, f2);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f2);
+ f2._otherType = FragmentDescriptor.OtherType.None;
//C: before others
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(f3);
+ f3._otherType = FragmentDescriptor.OtherType.Before;
//D: no order
- Fragment f4 = new Fragment((Resource)null, processor);
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor(r4, metaData);
f4._name="D";
- processor._webFragmentNameMap.put(f4._name, f4);
- ((RelativeOrdering)processor._ordering).addNoOthers(f4);
-
- /*
- * p.71-72 possible outcomes are:
- * C,B,D,A
- * C,D,B,A
- * C,B,A,D
- */
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4, f4);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f4);
+ f4._otherType = FragmentDescriptor.OtherType.None;
+ //
+ // p.71-72 possible outcomes are:
+ // C,B,D,A
+ // C,D,B,A
+ // C,B,A,D
+ //
String[] outcomes = {"CBDA",
"CDBA",
"CBAD"};
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
String result = "";
- for (Fragment f:orderedList)
- result+=(f._name);
+ for (Resource r:orderedList)
+ result+=(((TestResource)r)._name);
if (!checkResult(result, outcomes))
fail ("No outcome matched "+result);
@@ -224,73 +453,96 @@ public class OrderingTest extends TestCase
public void testRelativeOrdering3 ()
throws Exception
{
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
//A: after others, before C
- Fragment f1 = new Fragment((Resource)null, processor);
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
- f1._hasOther=true;
- ((RelativeOrdering)processor._ordering).addAfterOthers(f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1, f1);
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(f1);
+ f1._otherType = FragmentDescriptor.OtherType.After;
f1._befores.add("C");
//B: before others, before C
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- f2._hasOther = true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2,f2);
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(f2);
+ f2._otherType = FragmentDescriptor.OtherType.Before;
f2._befores.add("C");
//C: no ordering
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
- ((RelativeOrdering)processor._ordering).addNoOthers(f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f3);
+ f3._otherType = FragmentDescriptor.OtherType.None;
//result: BAC
String[] outcomes = {"BAC"};
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
String result = "";
- for (Fragment f:orderedList)
- result+=(f._name);
+ for (Resource r:orderedList)
+ result+=(((TestResource)r)._name);
if (!checkResult(result, outcomes))
fail ("No outcome matched "+result);
}
-
-
+
public void testCircular1 ()
throws Exception
{
//A: after B
//B: after A
-
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
//A: after B
- Fragment f1 = new Fragment((Resource)null, processor);
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
- ((RelativeOrdering)processor._ordering).addNoOthers(f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1, f1);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f1);
+ f1._otherType = FragmentDescriptor.OtherType.None;
f1._afters.add("B");
//B: after A
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- ((RelativeOrdering)processor._ordering).addNoOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2, f2);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f2);
+ f2._otherType = FragmentDescriptor.OtherType.None;
f2._afters.add("A");
try
{
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
fail("No circularity detected");
}
catch (Exception e)
@@ -300,38 +552,58 @@ public class OrderingTest extends TestCase
}
+
+
public void testInvalid1 ()
throws Exception
{
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new RelativeOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
//A: after others, before C
- Fragment f1 = new Fragment((Resource)null, processor);
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
- f1._hasOther=true;
- ((RelativeOrdering)processor._ordering).addAfterOthers(f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1,f1);
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(r1);
+ f1._otherType = FragmentDescriptor.OtherType.After;
f1._befores.add("C");
//B: before others, after C
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
- f2._hasOther = true;
- ((RelativeOrdering)processor._ordering).addBeforeOthers(f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2,f2);
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(r2);
+ f2._otherType = FragmentDescriptor.OtherType.Before;
f2._afters.add("C");
//C: no ordering
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
- ((RelativeOrdering)processor._ordering).addNoOthers(f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(r3);
+ f3._otherType = FragmentDescriptor.OtherType.None;
try
{
- List<Fragment> orderedList = processor._ordering.order();
+ List<Resource> orderedList = metaData._ordering.order(resources);
+ String result = "";
+ for (Resource r:orderedList)
+ result +=((TestResource)r)._name;
+ System.err.println("Invalid Result = "+result);
fail("A and B have an impossible relationship to C");
}
catch (Exception e)
@@ -344,111 +616,316 @@ public class OrderingTest extends TestCase
public void testAbsoluteOrdering1 ()
throws Exception
{
- /*
- * A,B,C,others
- */
+ //
+ // A,B,C,others
+ //
+ List<Resource> resources = new ArrayList<Resource>();
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new AbsoluteOrdering();
- ((AbsoluteOrdering)processor._ordering).add("A");
- ((AbsoluteOrdering)processor._ordering).add("B");
- ((AbsoluteOrdering)processor._ordering).add("C");
- ((AbsoluteOrdering)processor._ordering).addOthers();
-
- Fragment f1 = new Fragment((Resource)null, processor);
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new AbsoluteOrdering();
+ ((AbsoluteOrdering)metaData._ordering).add("A");
+ ((AbsoluteOrdering)metaData._ordering).add("B");
+ ((AbsoluteOrdering)metaData._ordering).add("C");
+ ((AbsoluteOrdering)metaData._ordering).addOthers();
+
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1,f1);
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2, f2);
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3, f3);
- Fragment f4 = new Fragment((Resource)null, processor);
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor((Resource)null, metaData);
f4._name="D";
- processor._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4, f4);
- Fragment f5 = new Fragment((Resource)null, processor);
+ TestResource jar5 = new TestResource("E");
+ resources.add(jar5);
+ TestResource r5 = new TestResource("E/web-fragment.xml");
+ FragmentDescriptor f5 = new FragmentDescriptor((Resource)null, metaData);
f5._name="E";
- processor._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentResourceMap.put(jar5, f5);
- Fragment f6 = new Fragment((Resource)null, processor);
- f6._name=Fragment.NAMELESS+"1";
- processor._webFragmentNameMap.put(f6._name, f6);
+ TestResource jar6 = new TestResource("plain");
+ resources.add(jar6);
+ TestResource r6 = new TestResource ("plain/web-fragment.xml");
+ FragmentDescriptor f6 = new FragmentDescriptor((Resource)null, metaData);
+ f6._name=FragmentDescriptor.NAMELESS+"1";
+ metaData._webFragmentNameMap.put(f6._name, f6);
+ metaData._webFragmentResourceMap.put(jar6, f6);
- List<Fragment> list = processor._ordering.order();
+ List<Resource> list = metaData._ordering.order(resources);
- String[] outcomes = {"ABCDE"+f6._name};
+ String[] outcomes = {"ABCDEplain"};
String result = "";
- for (Fragment f:list)
- result += f._name;
+ for (Resource r:list)
+ result += ((TestResource)r)._name;
if (!checkResult(result, outcomes))
fail("No outcome matched "+result);
}
-
+
public void testAbsoluteOrdering2 ()
throws Exception
{
- // A,B,C
- WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new AbsoluteOrdering();
- ((AbsoluteOrdering)processor._ordering).add("A");
- ((AbsoluteOrdering)processor._ordering).add("B");
- ((AbsoluteOrdering)processor._ordering).add("C");
+ // C,B,A
+ List<Resource> resources = new ArrayList<Resource>();
- Fragment f1 = new Fragment((Resource)null, processor);
+ WebAppContext wac = new WebAppContext();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new AbsoluteOrdering();
+ ((AbsoluteOrdering)metaData._ordering).add("C");
+ ((AbsoluteOrdering)metaData._ordering).add("B");
+ ((AbsoluteOrdering)metaData._ordering).add("A");
+
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
f1._name = "A";
- processor._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1,f1);
- Fragment f2 = new Fragment((Resource)null, processor);
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
f2._name="B";
- processor._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2,f2);
- Fragment f3 = new Fragment((Resource)null, processor);
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
f3._name="C";
- processor._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
- Fragment f4 = new Fragment((Resource)null, processor);
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor(r4, metaData);
f4._name="D";
- processor._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4,f4);
- Fragment f5 = new Fragment((Resource)null, processor);
+ TestResource jar5 = new TestResource("E");
+ resources.add(jar5);
+ TestResource r5 = new TestResource("E/web-fragment.xml");
+ FragmentDescriptor f5 = new FragmentDescriptor(r5, metaData);
f5._name="E";
- processor._webFragmentNameMap.put(f5._name, f5);
-
- Fragment f6 = new Fragment((Resource)null, processor);
- f6._name=Fragment.NAMELESS+"1";
- processor._webFragmentNameMap.put(f6._name, f6);
-
- List<Fragment> list = processor._ordering.order();
- String[] outcomes = {"ABC"};
+ metaData._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentResourceMap.put(jar5,f5);
+
+ TestResource jar6 = new TestResource("plain");
+ resources.add(jar6);
+ TestResource r6 = new TestResource("plain/web-fragment.xml");
+ FragmentDescriptor f6 = new FragmentDescriptor(r6, metaData);
+ f6._name=FragmentDescriptor.NAMELESS+"1";
+ metaData._webFragmentNameMap.put(f6._name, f6);
+ metaData._webFragmentResourceMap.put(jar6,f6);
+
+ List<Resource> list = metaData._ordering.order(resources);
+ String[] outcomes = {"CBA"};
String result = "";
- for (Fragment f:list)
- result += f._name;
+ for (Resource r:list)
+ result += ((TestResource)r)._name;
+
if (!checkResult(result, outcomes))
fail("No outcome matched "+result);
}
-
+
public void testAbsoluteOrdering3 ()
throws Exception
{
//empty <absolute-ordering>
WebAppContext wac = new WebAppContext();
- WebXmlProcessor processor = new WebXmlProcessor(wac);
- processor._ordering = processor.new AbsoluteOrdering();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new AbsoluteOrdering();
+ List<Resource> resources = new ArrayList<Resource>();
+
+ resources.add(new TestResource("A"));
+ resources.add(new TestResource("B"));
- List<Fragment> list = processor._ordering.order();
+ List<Resource> list = metaData._ordering.order(resources);
assertTrue(list.isEmpty());
}
+
+ public void testRelativeOrderingWithPlainJars ()
+ throws Exception
+ {
+ //B,A,C other jars with no fragments
+ List<Resource> resources = new ArrayList<Resource>();
+ WebAppContext wac = new WebAppContext();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new RelativeOrdering();
+
+ //A: after others, before C
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
+ f1._name = "A";
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1, f1);
+ //((RelativeOrdering)metaData._ordering).addAfterOthers(f1);
+ f1._otherType = FragmentDescriptor.OtherType.After;
+ f1._befores.add("C");
+
+ //B: before others, before C
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
+ f2._name="B";
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2,f2);
+ //((RelativeOrdering)metaData._ordering).addBeforeOthers(f2);
+ f2._otherType = FragmentDescriptor.OtherType.Before;
+ f2._befores.add("C");
+
+ //C: after A
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
+ f3._name="C";
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3,f3);
+ //((RelativeOrdering)metaData._ordering).addNoOthers(f3);
+ f3._otherType = FragmentDescriptor.OtherType.None;
+ f3._afters.add("A");
+
+ //No fragment jar 1
+ TestResource r4 = new TestResource("plain1");
+ resources.add(r4);
+
+ //No fragment jar 2
+ TestResource r5 = new TestResource("plain2");
+ resources.add(r5);
+
+ //result: BAC
+ String[] outcomes = {"Bplain1plain2AC"};
+
+ List<Resource> orderedList = metaData._ordering.order(resources);
+ String result = "";
+ for (Resource r:orderedList)
+ result+=(((TestResource)r)._name);
+
+ if (!checkResult(result, outcomes))
+ fail ("No outcome matched "+result);
+ }
+
+ public void testAbsoluteOrderingWithPlainJars()
+ throws Exception
+ {
+ //
+ // A,B,C,others
+ //
+ List<Resource> resources = new ArrayList<Resource>();
+ WebAppContext wac = new WebAppContext();
+ MetaData metaData = new MetaData(wac);
+ metaData._ordering = metaData.new AbsoluteOrdering();
+ ((AbsoluteOrdering)metaData._ordering).add("A");
+ ((AbsoluteOrdering)metaData._ordering).add("B");
+ ((AbsoluteOrdering)metaData._ordering).add("C");
+ ((AbsoluteOrdering)metaData._ordering).addOthers();
+
+ TestResource jar1 = new TestResource("A");
+ resources.add(jar1);
+ TestResource r1 = new TestResource("A/web-fragment.xml");
+ FragmentDescriptor f1 = new FragmentDescriptor(r1, metaData);
+ f1._name = "A";
+ metaData._webFragmentNameMap.put(f1._name, f1);
+ metaData._webFragmentResourceMap.put(jar1,f1);
+
+ TestResource jar2 = new TestResource("B");
+ resources.add(jar2);
+ TestResource r2 = new TestResource("B/web-fragment.xml");
+ FragmentDescriptor f2 = new FragmentDescriptor(r2, metaData);
+ f2._name="B";
+ metaData._webFragmentNameMap.put(f2._name, f2);
+ metaData._webFragmentResourceMap.put(jar2, f2);
+
+ TestResource jar3 = new TestResource("C");
+ resources.add(jar3);
+ TestResource r3 = new TestResource("C/web-fragment.xml");
+ FragmentDescriptor f3 = new FragmentDescriptor(r3, metaData);
+ f3._name="C";
+ metaData._webFragmentNameMap.put(f3._name, f3);
+ metaData._webFragmentResourceMap.put(jar3, f3);
+
+ TestResource jar4 = new TestResource("D");
+ resources.add(jar4);
+ TestResource r4 = new TestResource("D/web-fragment.xml");
+ FragmentDescriptor f4 = new FragmentDescriptor((Resource)null, metaData);
+ f4._name="D";
+ metaData._webFragmentNameMap.put(f4._name, f4);
+ metaData._webFragmentResourceMap.put(jar4, f4);
+
+ TestResource jar5 = new TestResource("E");
+ resources.add(jar5);
+ TestResource r5 = new TestResource("E/web-fragment.xml");
+ FragmentDescriptor f5 = new FragmentDescriptor((Resource)null, metaData);
+ f5._name="E";
+ metaData._webFragmentNameMap.put(f5._name, f5);
+ metaData._webFragmentResourceMap.put(jar5, f5);
+
+ TestResource jar6 = new TestResource("plain");
+ resources.add(jar6);
+ TestResource r6 = new TestResource("plain/web-fragment.xml");
+ FragmentDescriptor f6 = new FragmentDescriptor((Resource)null, metaData);
+ f6._name=FragmentDescriptor.NAMELESS+"1";
+ metaData._webFragmentNameMap.put(f6._name, f6);
+ metaData._webFragmentResourceMap.put(jar6, f6);
+
+ //plain jar
+ TestResource r7 = new TestResource("plain1");
+ resources.add(r7);
+
+ TestResource r8 = new TestResource("plain2");
+ resources.add(r8);
+
+ List<Resource> list = metaData._ordering.order(resources);
+
+ String[] outcomes = {"ABCDEplainplain1plain2"};
+ String result = "";
+ for (Resource r:list)
+ result += ((TestResource)r)._name;
+
+ if (!checkResult(result, outcomes))
+ fail("No outcome matched "+result);
+ }
+
+
+
public boolean checkResult (String result, String[] outcomes)
{
boolean matched = false;
diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java
index 9a8db2c868..469a28b091 100644
--- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java
+++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java
@@ -2,62 +2,61 @@ package org.eclipse.jetty.webapp;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.jetty.util.resource.Resource;
+import org.junit.Before;
+import org.junit.Test;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-public class WebAppClassLoaderTest extends TestCase
+public class WebAppClassLoaderTest
{
- WebAppContext _context;
- WebAppClassLoader _loader;
-
- /* ------------------------------------------------------------ */
- /**
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception
+ private WebAppContext _context;
+ private WebAppClassLoader _loader;
+
+ @Before
+ public void init() throws Exception
{
Resource webapp = Resource.newResource("./src/test/webapp");
-
+
_context = new WebAppContext();
_context.setBaseResource(webapp);
_context.setContextPath("/test");
-
+
_loader = new WebAppClassLoader(_context);
_loader.addJars(webapp.addPath("WEB-INF/lib"));
- _loader.addClassPath(webapp.addPath("WEB-INF/classes").toString());
+ _loader.addClassPath(webapp.addPath("WEB-INF/classes"));
_loader.setName("test");
-
}
-
-
+
+ @Test
public void testParentLoad() throws Exception
{
_context.setParentLoaderPriority(true);
assertTrue(canLoadClass("org.acme.webapp.ClassInJarA"));
assertTrue(canLoadClass("org.acme.webapp.ClassInJarB"));
assertTrue(canLoadClass("org.acme.other.ClassInClassesC"));
-
- assertFalse(canLoadClass("org.eclipse.jetty.webapp.Configuration"));
-
+
+ assertTrue(cantLoadClass("org.eclipse.jetty.webapp.Configuration"));
+
Class clazzA = _loader.loadClass("org.acme.webapp.ClassInJarA");
assertTrue(clazzA.getField("FROM_PARENT")!=null);
}
-
+
+ @Test
public void testWebAppLoad() throws Exception
{
_context.setParentLoaderPriority(false);
assertTrue(canLoadClass("org.acme.webapp.ClassInJarA"));
assertTrue(canLoadClass("org.acme.webapp.ClassInJarB"));
assertTrue(canLoadClass("org.acme.other.ClassInClassesC"));
-
- assertFalse(canLoadClass("org.eclipse.jetty.webapp.Configuration"));
-
+
+ assertTrue(cantLoadClass("org.eclipse.jetty.webapp.Configuration"));
+
Class<?> clazzA = _loader.loadClass("org.acme.webapp.ClassInJarA");
try
{
@@ -69,7 +68,8 @@ public class WebAppClassLoaderTest extends TestCase
assertTrue(true);
}
}
-
+
+ @Test
public void testExposedClass() throws Exception
{
String[] oldSC=_context.getServerClasses();
@@ -77,15 +77,16 @@ public class WebAppClassLoaderTest extends TestCase
newSC[0]="-org.eclipse.jetty.webapp.Configuration";
System.arraycopy(oldSC,0,newSC,1,oldSC.length);
_context.setServerClasses(newSC);
-
+
assertTrue(canLoadClass("org.acme.webapp.ClassInJarA"));
assertTrue(canLoadClass("org.acme.webapp.ClassInJarB"));
assertTrue(canLoadClass("org.acme.other.ClassInClassesC"));
-
+
assertTrue(canLoadClass("org.eclipse.jetty.webapp.Configuration"));
- assertFalse(canLoadClass("org.eclipse.jetty.webapp.JarScanner"));
+ assertTrue(cantLoadClass("org.eclipse.jetty.webapp.JarScanner"));
}
-
+
+ @Test
public void testSystemServerClass() throws Exception
{
String[] oldServC=_context.getServerClasses();
@@ -93,32 +94,33 @@ public class WebAppClassLoaderTest extends TestCase
newServC[0]="org.eclipse.jetty.webapp.Configuration";
System.arraycopy(oldServC,0,newServC,1,oldServC.length);
_context.setServerClasses(newServC);
-
+
String[] oldSysC=_context.getSystemClasses();
String[] newSysC=new String[oldSysC.length+1];
newSysC[0]="org.eclipse.jetty.webapp.";
System.arraycopy(oldSysC,0,newSysC,1,oldSysC.length);
_context.setSystemClasses(newSysC);
-
+
assertTrue(canLoadClass("org.acme.webapp.ClassInJarA"));
assertTrue(canLoadClass("org.acme.webapp.ClassInJarB"));
assertTrue(canLoadClass("org.acme.other.ClassInClassesC"));
-
- assertFalse(canLoadClass("org.eclipse.jetty.webapp.Configuration"));
- assertFalse(canLoadClass("org.eclipse.jetty.webapp.JarScanner"));
+
+ assertTrue(cantLoadClass("org.eclipse.jetty.webapp.Configuration"));
+ assertTrue(cantLoadClass("org.eclipse.jetty.webapp.JarScanner"));
}
-
+
+ @Test
public void testResources() throws Exception
{
List<URL> resources;
-
+
_context.setParentLoaderPriority(false);
resources =toList( _loader.getResources("org/acme/resource.txt"));
assertEquals(3,resources.size());
assertEquals(0,resources.get(0).toString().indexOf("jar:file:"));
assertEquals(-1,resources.get(1).toString().indexOf("test-classes"));
assertEquals(0,resources.get(2).toString().indexOf("file:"));
-
+
_context.setParentLoaderPriority(true);
resources =toList( _loader.getResources("org/acme/resource.txt"));
assertEquals(3,resources.size());
@@ -150,7 +152,7 @@ public class WebAppClassLoaderTest extends TestCase
assertEquals(1,resources.size());
assertEquals(0,resources.get(0).toString().indexOf("file:"));
}
-
+
private List<URL> toList(Enumeration<URL> e)
{
List<URL> list = new ArrayList<URL>();
@@ -159,15 +161,20 @@ public class WebAppClassLoaderTest extends TestCase
return list;
}
- private boolean canLoadClass(String clazz)
+ private boolean canLoadClass(String clazz) throws ClassNotFoundException
+ {
+ return _loader.loadClass(clazz)!=null;
+ }
+
+ private boolean cantLoadClass(String clazz)
{
try
{
- return _loader.loadClass(clazz)!=null;
+ return _loader.loadClass(clazz)==null;
}
catch(ClassNotFoundException e)
{
- return false;
+ return true;
}
}
}
diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java
new file mode 100644
index 0000000000..4fe342a346
--- /dev/null
+++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java
@@ -0,0 +1,79 @@
+// ========================================================================
+// Copyright (c) 2010 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.webapp;
+
+import java.util.Arrays;
+
+import org.eclipse.jetty.server.Server;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class WebAppContextTest
+{
+ @Test
+ public void testConfigurationClassesFromDefault ()
+ {
+ Server server = new Server();
+ //test if no classnames set, its the defaults
+ WebAppContext wac = new WebAppContext();
+ assertNull(wac.getConfigurations());
+ String[] classNames = wac.getConfigurationClasses();
+ assertNotNull(classNames);
+
+ //test if no classname set, and none from server its the defaults
+ wac.setServer(server);
+ assertTrue(Arrays.equals(classNames, wac.getConfigurationClasses()));
+ }
+
+ @Test
+ public void testConfigurationClassesExplicit ()
+ {
+ String[] classNames = {"x.y.z"};
+
+ Server server = new Server();
+ server.setAttribute(WebAppContext.SERVER_CONFIG, classNames);
+
+ //test an explicitly set classnames list overrides that from the server
+ WebAppContext wac = new WebAppContext();
+ String[] myClassNames = {"a.b.c", "d.e.f"};
+ wac.setConfigurationClasses(myClassNames);
+ wac.setServer(server);
+ String[] names = wac.getConfigurationClasses();
+ assertTrue(Arrays.equals(myClassNames, names));
+
+
+ //test if no explicit classnames, they come from the server
+ WebAppContext wac2 = new WebAppContext();
+ wac2.setServer(server);
+ assertTrue(Arrays.equals(classNames, wac2.getConfigurationClasses()));
+ }
+
+ @Test
+ public void testConfigurationInstances ()
+ {
+ Configuration[] configs = {new WebInfConfiguration()};
+ WebAppContext wac = new WebAppContext();
+ wac.setConfigurations(configs);
+ assertTrue(Arrays.equals(configs, wac.getConfigurations()));
+
+ //test that explicit config instances override any from server
+ String[] classNames = {"x.y.z"};
+ Server server = new Server();
+ server.setAttribute(WebAppContext.SERVER_CONFIG, classNames);
+ wac.setServer(server);
+ assertTrue(Arrays.equals(configs,wac.getConfigurations()));
+ }
+}
diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml
index cc3b9388db..195db55bf6 100644
--- a/jetty-websocket/pom.xml
+++ b/jetty-websocket/pom.xml
@@ -20,6 +20,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -61,16 +62,17 @@
</execution>
</executions>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include the sources to be able to prepare the eclipse-jetty-SDK feature
- with a snapshot. -->
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.websocket.*</onlyAnalyze>
+ </configuration>
</plugin>
</plugins>
</build>
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnection.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnection.java
index 5903481976..4da7611506 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnection.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnection.java
@@ -1,13 +1,22 @@
package org.eclipse.jetty.websocket;
import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.zip.Checksum;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.http.security.Credential.MD5;
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.thread.Timeout;
public class WebSocketConnection implements Connection, WebSocket.Outbound
{
@@ -17,11 +26,26 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
final WebSocketGenerator _generator;
final long _timestamp;
final WebSocket _websocket;
- final int _maxIdleTimeMs=300000;
+ String _key1;
+ String _key2;
+ ByteArrayBuffer _hixie;
- public WebSocketConnection(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, long maxIdleTime)
+ public WebSocketConnection(WebSocket websocket, EndPoint endpoint)
+ throws IOException
{
+ this(websocket,endpoint,new WebSocketBuffers(8192),System.currentTimeMillis(),300000);
+ }
+
+ public WebSocketConnection(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime)
+ throws IOException
+ {
+ // TODO - can we use the endpoint idle mechanism?
+ if (endpoint instanceof AsyncEndPoint)
+ ((AsyncEndPoint)endpoint).cancelIdle();
+
_endp = endpoint;
+ _endp.setMaxIdleTime(maxIdleTime);
+
_timestamp = timestamp;
_websocket = websocket;
_generator = new WebSocketGenerator(buffers, _endp);
@@ -71,10 +95,10 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
{
public void access(EndPoint endp)
{
- scep.getSelectSet().scheduleTimeout(scep.getTimeoutTask(),_maxIdleTimeMs);
+ scep.scheduleIdle();
}
};
- scep.getSelectSet().scheduleTimeout(scep.getTimeoutTask(),_maxIdleTimeMs);
+ scep.scheduleIdle();
}
else
{
@@ -85,6 +109,13 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
};
}
}
+
+ public void setHixieKeys(String key1,String key2)
+ {
+ _key1=key1;
+ _key2=key2;
+ _hixie=new IndirectNIOBuffer(16);
+ }
public Connection handle() throws IOException
{
@@ -92,6 +123,53 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
try
{
+ // handle stupid hixie random bytes
+ if (_hixie!=null)
+ {
+ while(progress)
+ {
+ // take bytes from the parser buffer.
+ if (_parser.getBuffer().length()>0)
+ {
+ int l=_parser.getBuffer().length();
+ if (l>8)
+ l=8;
+ _hixie.put(_parser.getBuffer().peek(_parser.getBuffer().getIndex(),l));
+ _parser.getBuffer().skip(l);
+ progress=true;
+ }
+
+ // do we have enough?
+ if (_hixie.length()<8)
+ {
+ // no, then let's fill
+ int filled=_endp.fill(_hixie);
+ progress |= filled>0;
+
+ if (filled<0)
+ {
+ _endp.close();
+ break;
+ }
+ }
+
+ // do we now have enough
+ if (_hixie.length()==8)
+ {
+ // we have the silly random bytes
+ // so let's work out the stupid 16 byte reply.
+ doTheHixieHixieShake();
+ _endp.flush(_hixie);
+ _hixie=null;
+ _endp.flush();
+ break;
+ }
+ }
+
+ return this;
+ }
+
+ // handle the framing protocol
while (progress)
{
int flushed=_generator.flush();
@@ -108,7 +186,6 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
}
catch(IOException e)
{
- e.printStackTrace();
throw e;
}
finally
@@ -125,6 +202,16 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
return this;
}
+ private void doTheHixieHixieShake()
+ {
+ byte[] result=WebSocketGenerator.doTheHixieHixieShake(
+ WebSocketParser.hixieCrypt(_key1),
+ WebSocketParser.hixieCrypt(_key2),
+ _hixie.asArray());
+ _hixie.clear();
+ _hixie.put(result);
+ }
+
public boolean isOpen()
{
return _endp!=null&&_endp.isOpen();
@@ -152,7 +239,7 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
public void sendMessage(byte frame, String content) throws IOException
{
- _generator.addFrame(frame,content,_maxIdleTimeMs);
+ _generator.addFrame(frame,content,_endp.getMaxIdleTime());
_generator.flush();
checkWriteable();
_idle.access(_endp);
@@ -165,7 +252,7 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
public void sendMessage(byte frame, byte[] content, int offset, int length) throws IOException
{
- _generator.addFrame(frame,content,offset,length,_maxIdleTimeMs);
+ _generator.addFrame(frame,content,offset,length,_endp.getMaxIdleTime());
_generator.flush();
checkWriteable();
_idle.access(_endp);
@@ -175,7 +262,7 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
{
try
{
- _generator.flush(_maxIdleTimeMs);
+ _generator.flush(_endp.getMaxIdleTime());
_endp.close();
}
catch(IOException e)
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
index cd8eb94748..37f5de71d0 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
@@ -16,7 +16,7 @@ import org.eclipse.jetty.server.HttpConnection;
public class WebSocketFactory
{
private WebSocketBuffers _buffers;
- private long _maxIdleTime=300000;
+ private int _maxIdleTime=300000;
/* ------------------------------------------------------------ */
public WebSocketFactory()
@@ -43,7 +43,7 @@ public class WebSocketFactory
/** Set the maxIdleTime.
* @param maxIdleTime the maxIdleTime to set
*/
- public void setMaxIdleTime(long maxIdleTime)
+ public void setMaxIdleTime(int maxIdleTime)
{
_maxIdleTime = maxIdleTime;
}
@@ -91,17 +91,38 @@ public class WebSocketFactory
HttpConnection http = HttpConnection.getCurrentConnection();
ConnectedEndPoint endp = (ConnectedEndPoint)http.getEndPoint();
WebSocketConnection connection = new WebSocketConnection(websocket,endp,_buffers,http.getTimeStamp(), _maxIdleTime);
-
+
String uri=request.getRequestURI();
+ String query=request.getQueryString();
+ if (query!=null && query.length()>0)
+ uri+="?"+query;
String host=request.getHeader("Host");
-
- response.setHeader("Upgrade","WebSocket");
- response.addHeader("Connection","Upgrade");
- response.addHeader("WebSocket-Origin",origin);
- response.addHeader("WebSocket-Location","ws://"+host+uri);
- if (protocol!=null)
- response.addHeader("WebSocket-Protocol",protocol);
- response.sendError(101,"Web Socket Protocol Handshake");
+
+ String key1 = request.getHeader("Sec-WebSocket-Key1");
+ if (key1!=null)
+ {
+ String key2 = request.getHeader("Sec-WebSocket-Key2");
+ connection.setHixieKeys(key1,key2);
+
+ response.setHeader("Upgrade","WebSocket");
+ response.addHeader("Connection","Upgrade");
+ response.addHeader("Sec-WebSocket-Origin",origin);
+ response.addHeader("Sec-WebSocket-Location",(request.isSecure()?"wss://":"ws://")+host+uri);
+ if (protocol!=null)
+ response.addHeader("Sec-WebSocket-Protocol",protocol);
+ response.sendError(101,"WebSocket Protocol Handshake");
+ }
+ else
+ {
+ response.setHeader("Upgrade","WebSocket");
+ response.addHeader("Connection","Upgrade");
+ response.addHeader("WebSocket-Origin",origin);
+ response.addHeader("WebSocket-Location",(request.isSecure()?"wss://":"ws://")+host+uri);
+ if (protocol!=null)
+ response.addHeader("WebSocket-Protocol",protocol);
+ response.sendError(101,"Web Socket Protocol Handshake");
+ }
+
response.flushBuffer();
connection.fill(((HttpParser)http.getParser()).getHeaderBuffer());
@@ -109,6 +130,5 @@ public class WebSocketFactory
websocket.onConnect(connection);
request.setAttribute("org.eclipse.jetty.io.Connection",connection);
- response.flushBuffer();
}
}
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGenerator.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGenerator.java
index 75b607d757..3666b3b07d 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGenerator.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGenerator.java
@@ -2,9 +2,14 @@ package org.eclipse.jetty.websocket;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
@@ -94,6 +99,8 @@ public class WebSocketGenerator
private synchronized void bufferPut(byte datum, long blockFor) throws IOException
{
+ if (_buffer==null)
+ _buffer=_buffers.getDirectBuffer();
_buffer.put(datum);
if (_buffer.space() == 0)
expelBuffer(blockFor);
@@ -124,7 +131,7 @@ public class WebSocketGenerator
private synchronized int flushBuffer() throws IOException
{
if (!_endp.isOpen())
- throw new IOException("Closed");
+ throw new EofException();
if (_buffer!=null)
return _endp.flush(_buffer);
@@ -134,6 +141,8 @@ public class WebSocketGenerator
private synchronized int expelBuffer(long blockFor) throws IOException
{
+ if (_buffer==null)
+ return 0;
int result = flushBuffer();
_buffer.compact();
if (!_endp.isBlocking())
@@ -157,4 +166,32 @@ public class WebSocketGenerator
{
return _buffer==null || _buffer.length()==0;
}
+
+ public static byte[] doTheHixieHixieShake(long key1,long key2,byte[] key3)
+ {
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte [] fodder = new byte[16];
+
+ fodder[0]=(byte)(0xff&(key1>>24));
+ fodder[1]=(byte)(0xff&(key1>>16));
+ fodder[2]=(byte)(0xff&(key1>>8));
+ fodder[3]=(byte)(0xff&key1);
+ fodder[4]=(byte)(0xff&(key2>>24));
+ fodder[5]=(byte)(0xff&(key2>>16));
+ fodder[6]=(byte)(0xff&(key2>>8));
+ fodder[7]=(byte)(0xff&key2);
+ for (int i=0;i<8;i++)
+ fodder[8+i]=key3[i];
+ md.update(fodder);
+ byte[] result=md.digest();
+ return result;
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
}
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParser.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParser.java
index e0a0160837..49449fbe52 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParser.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParser.java
@@ -190,10 +190,26 @@ public class WebSocketParser
_buffer.put(buffer);
buffer.clear();
}
-
-
}
-
+
+ /* ------------------------------------------------------------ */
+ static long hixieCrypt(String key)
+ {
+ // Don't ask me what all this is about.
+ // I think it's pretend secret stuff, kind of
+ // like talking in pig latin!
+ long number=0;
+ int spaces=0;
+ for (char c : key.toCharArray())
+ {
+ if (Character.isDigit(c))
+ number=number*10+(c-'0');
+ else if (c==' ')
+ spaces++;
+ }
+ return number/spaces;
+ }
+
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java
index e89d5f31d0..43abe6e7be 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java
@@ -49,7 +49,11 @@ public abstract class WebSocketServlet extends HttpServlet
{
if ("WebSocket".equals(request.getHeader("Upgrade")))
{
- String protocol=request.getHeader("WebSocket-Protocol");
+ boolean hixie = request.getHeader("Sec-WebSocket-Key1")!=null;
+
+ String protocol=request.getHeader(hixie?"Sec-WebSocket-Protocol":"WebSocket-Protocol");
+ if (protocol==null)
+ protocol=request.getHeader("Sec-WebSocket-Protocol");
WebSocket websocket=doWebSocketConnect(request,protocol);
String host=request.getHeader("Host");
@@ -59,7 +63,11 @@ public abstract class WebSocketServlet extends HttpServlet
if (websocket!=null)
_websocket.upgrade(request,response,websocket,origin,protocol);
else
+ {
+ if (hixie)
+ response.setHeader("Connection","close");
response.sendError(503);
+ }
}
else
super.service(request,response);
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorTest.java
index 1b2a67648d..755d905af1 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorTest.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorTest.java
@@ -1,34 +1,35 @@
package org.eclipse.jetty.websocket;
-import junit.framework.TestCase;
+import java.security.MessageDigest;
+
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.junit.Before;
+import org.junit.Test;
+import static junit.framework.Assert.assertEquals;
-/* ------------------------------------------------------------ */
/**
+ * @version $Revision: 1441 $ $Date: 2010-04-02 12:28:17 +0200 (Fri, 02 Apr 2010) $
*/
-public class WebSocketGeneratorTest extends TestCase
+public class WebSocketGeneratorTest
{
+ private ByteArrayBuffer _out;
+ private WebSocketGenerator _generator;
- WebSocketBuffers _buffers;
- ByteArrayBuffer _out;
- ByteArrayEndPoint _endp;
- WebSocketGenerator _generator;
-
- /* ------------------------------------------------------------ */
- @Override
- protected void setUp() throws Exception
+ @Before
+ public void setUp() throws Exception
{
- _buffers=new WebSocketBuffers(1024);
- _endp = new ByteArrayEndPoint();
- _generator = new WebSocketGenerator(_buffers,_endp);
+ WebSocketBuffers buffers = new WebSocketBuffers(1024);
+ ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
+ _generator = new WebSocketGenerator(buffers, endPoint);
_out = new ByteArrayBuffer(2048);
- _endp.setOut(_out);
+ endPoint.setOut(_out);
}
- /* ------------------------------------------------------------ */
+ @Test
public void testOneString() throws Exception
{
_generator.addFrame((byte)0x04,"Hell\uFF4F W\uFF4Frld",0);
@@ -52,6 +53,7 @@ public class WebSocketGeneratorTest extends TestCase
assertEquals(0xff,0xff&_out.get());
}
+ @Test
public void testOneBuffer() throws Exception
{
_generator.addFrame((byte)0x84,"Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8),0);
@@ -75,6 +77,7 @@ public class WebSocketGeneratorTest extends TestCase
assertEquals('d',_out.get());
}
+ @Test
public void testOneLongBuffer() throws Exception
{
byte[] b=new byte[150];
@@ -90,4 +93,35 @@ public class WebSocketGeneratorTest extends TestCase
for (int i=0;i<b.length;i++)
assertEquals('0'+(i%10),0xff&_out.get());
}
+
+ @Test
+ public void testHixie() throws Exception
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] result;
+ byte[] expected;
+
+ expected=md.digest(TypeUtil.fromHexString("00000000000000000000000000000000"));
+ result=WebSocketGenerator.doTheHixieHixieShake(
+ 0 ,0, new byte[8]);
+ assertEquals(TypeUtil.toHexString(expected),TypeUtil.toHexString(result));
+
+ expected=md.digest(TypeUtil.fromHexString("01020304050607080000000000000000"));
+ result=WebSocketGenerator.doTheHixieHixieShake(
+ 0x01020304,
+ 0x05060708,
+ new byte[8]);
+ assertEquals(TypeUtil.toHexString(expected),TypeUtil.toHexString(result));
+
+ byte[] random = new byte[8];
+ for (int i=0;i<8;i++)
+ random[i]=(byte)(0xff&"Tm[K T2u".charAt(i));
+ result=WebSocketGenerator.doTheHixieHixieShake(
+ 155712099,173347027,random);
+ StringBuilder b = new StringBuilder();
+
+ for (int i=0;i<16;i++)
+ b.append((char)result[i]);
+ assertEquals("fQJ,fN/4F4!~K~MH",b.toString());
+ }
}
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadTest.java
new file mode 100644
index 0000000000..0cb355b657
--- /dev/null
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadTest.java
@@ -0,0 +1,223 @@
+package org.eclipse.jetty.websocket;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.lang.management.ManagementFactory;
+import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class WebSocketLoadTest
+{
+ private static Server _server;
+ private static Connector _connector;
+
+ @BeforeClass
+ public static void startServer() throws Exception
+ {
+ _server = new Server();
+
+ _connector = new SelectChannelConnector();
+ _server.addConnector(_connector);
+
+ QueuedThreadPool threadPool = new QueuedThreadPool(200);
+ threadPool.setMaxStopTimeMs(1000);
+ _server.setThreadPool(threadPool);
+
+ WebSocketHandler wsHandler = new WebSocketHandler()
+ {
+ @Override
+ protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
+ {
+ return new EchoWebSocket();
+ }
+ };
+ wsHandler.setHandler(new DefaultHandler());
+ _server.setHandler(wsHandler);
+
+ _server.start();
+ }
+
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
+
+ @Test
+ public void testLoad() throws Exception
+ {
+ int count = 50;
+ int iterations = 10;
+
+ ExecutorService threadPool = Executors.newCachedThreadPool();
+ try
+ {
+ CountDownLatch latch = new CountDownLatch(count * iterations);
+ WebSocketClient[] clients = new WebSocketClient[count];
+ for (int i = 0; i < clients.length; ++i)
+ {
+ clients[i] = new WebSocketClient("localhost", _connector.getLocalPort(), 1000, latch, iterations);
+ clients[i].open();
+ }
+
+ long start = System.nanoTime();
+ for (WebSocketClient client : clients)
+ threadPool.execute(client);
+
+ int parallelism = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
+ long maxTimePerIteration = 5;
+ assertTrue(latch.await(iterations * (count / parallelism + 1) * maxTimePerIteration, TimeUnit.MILLISECONDS));
+ long end = System.nanoTime();
+ System.err.println("Elapsed: " + TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
+
+ for (WebSocketClient client : clients)
+ client.close();
+ }
+ finally
+ {
+ threadPool.shutdown();
+ assertTrue(threadPool.awaitTermination(2, TimeUnit.SECONDS));
+ }
+ }
+
+ private static class EchoWebSocket implements WebSocket
+ {
+ private volatile Outbound outbound;
+
+ public void onConnect(Outbound outbound)
+ {
+ this.outbound = outbound;
+ }
+
+ public void onMessage(byte frame, String data)
+ {
+ try
+ {
+ outbound.sendMessage(data);
+ }
+ catch (IOException x)
+ {
+ outbound.disconnect();
+ }
+ }
+
+ public void onMessage(byte frame, byte[] data, int offset, int length)
+ {
+ }
+
+ public void onDisconnect()
+ {
+ }
+ }
+
+ private class WebSocketClient implements Runnable
+ {
+ private final Socket socket;
+ private final BufferedWriter output;
+ private final BufferedReader input;
+ private final int iterations;
+ private final CountDownLatch latch;
+
+ public WebSocketClient(String host, int port, int readTimeout, CountDownLatch latch, int iterations) throws IOException
+ {
+ this.latch = latch;
+ socket = new Socket(host, port);
+ socket.setSoTimeout(readTimeout);
+ output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1"));
+ input = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
+ this.iterations = iterations;
+ }
+
+ private void open() throws IOException
+ {
+ output.write("GET /test HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "Upgrade: WebSocket\r\n" +
+ "Connection: Upgrade\r\n" +
+ "\r\n");
+ output.flush();
+
+ String responseLine = input.readLine();
+ assertTrue(responseLine.startsWith("HTTP/1.1 101 Web Socket Protocol Handshake"));
+ // Read until we find an empty line, which signals the end of the http response
+ String line;
+ while ((line = input.readLine()) != null)
+ if (line.length() == 0)
+ break;
+ }
+
+ public void run()
+ {
+ try
+ {
+ String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
+ for (int i = 0; i < iterations; ++i)
+ {
+ writeString(message);
+ String result = readString();
+ assertEquals(message, result);
+ latch.countDown();
+ }
+ }
+ catch (IOException x)
+ {
+ throw new RuntimeException(x);
+ }
+ }
+
+ private void writeString(String message) throws IOException
+ {
+ output.write(0x00);
+ output.write(message);
+ output.write(0xFF);
+ output.flush();
+ }
+
+ private String readString() throws IOException
+ {
+ StringBuilder result = new StringBuilder();
+ int frameStart = input.read();
+ assertEquals(0x00, frameStart);
+ while (true)
+ {
+ int read = input.read();
+ if (read == -1)
+ throw new EOFException();
+ char c = (char)read;
+ if (c == 0xFF)
+ break;
+ result.append(c);
+ }
+ return result.toString();
+ }
+
+ public void close() throws IOException
+ {
+ socket.close();
+ }
+ }
+}
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageTest.java
index c95f5fc459..96321f7fdd 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageTest.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageTest.java
@@ -10,24 +10,30 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
-import junit.framework.TestCase;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
/**
* @version $Revision$ $Date$
*/
-public class WebSocketMessageTest extends TestCase
+public class WebSocketMessageTest
{
- private Server _server;
- private Connector _connector;
- private TestWebSocket _serverWebSocket;
+ private static Server _server;
+ private static Connector _connector;
+ private static TestWebSocket _serverWebSocket;
- @Override
- protected void setUp() throws Exception
+ @BeforeClass
+ public static void startServer() throws Exception
{
_server = new Server();
_connector = new SelectChannelConnector();
@@ -45,13 +51,14 @@ public class WebSocketMessageTest extends TestCase
_server.start();
}
- @Override
- protected void tearDown() throws Exception
+ @AfterClass
+ public static void stopServer() throws Exception
{
_server.stop();
_server.join();
}
+ @Test
public void testServerSendBigStringMessage() throws Exception
{
Socket socket = new Socket("localhost", _connector.getLocalPort());
@@ -104,6 +111,7 @@ public class WebSocketMessageTest extends TestCase
assertEquals(message.length() + "0x00".length() + "0xFF".length(), result.length());
}
+ @Test
public void testServerSendBigBinaryMessage() throws Exception
{
Socket socket = new Socket("localhost", _connector.getLocalPort());
@@ -158,7 +166,7 @@ public class WebSocketMessageTest extends TestCase
}
}
- private class TestWebSocket implements WebSocket
+ private static class TestWebSocket implements WebSocket
{
private final CountDownLatch latch = new CountDownLatch(1);
private volatile Outbound outbound;
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserTest.java
index 419797b391..8fa1bd27d9 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserTest.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserTest.java
@@ -3,58 +3,61 @@ package org.eclipse.jetty.websocket;
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
-import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.StringUtil;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-/* ------------------------------------------------------------ */
/**
+ * @version $Revision: 1441 $ $Date: 2010-04-02 12:28:17 +0200 (Fri, 02 Apr 2010) $
*/
-public class WebSocketParserTest extends TestCase
-{
- WebSocketBuffers _buffers;
- ByteArrayBuffer _in;
- ByteArrayEndPoint _endp;
- Handler _handler;
- WebSocketParser _parser;
-
- /* ------------------------------------------------------------ */
- @Override
- protected void setUp() throws Exception
+public class WebSocketParserTest
+{
+ private ByteArrayBuffer _in;
+ private Handler _handler;
+ private WebSocketParser _parser;
+
+ @Before
+ public void setUp() throws Exception
{
- _buffers=new WebSocketBuffers(1024);
- _endp = new ByteArrayEndPoint();
+ WebSocketBuffers buffers = new WebSocketBuffers(1024);
+ ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
_handler = new Handler();
- _parser=new WebSocketParser(_buffers,_endp,_handler);
+ _parser=new WebSocketParser(buffers, endPoint,_handler);
_in = new ByteArrayBuffer(2048);
- _endp.setIn(_in);
+ endPoint.setIn(_in);
}
+ @Test
public void testCache() throws Exception
{
assertEquals(HttpHeaderValues.UPGRADE_ORDINAL ,((CachedBuffer)HttpHeaderValues.CACHE.lookup("Upgrade")).getOrdinal());
}
-
+
+ @Test
public void testOneUtf8() throws Exception
{
_in.put((byte)0x00);
_in.put("Hello World".getBytes(StringUtil.__UTF8));
_in.put((byte)0xff);
-
+
int filled =_parser.parseNext();
-
+
assertEquals(13,filled);
assertEquals("Hello World",_handler._data.get(0));
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
+ @Test
public void testTwoUtf8() throws Exception
{
_in.put((byte)0x00);
@@ -63,42 +66,44 @@ public class WebSocketParserTest extends TestCase
_in.put((byte)0x00);
_in.put("Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8));
_in.put((byte)0xff);
-
+
int filled =_parser.parseNext();
-
+
assertEquals(30,filled);
assertEquals("Hello World",_handler._data.get(0));
assertFalse(_parser.isBufferEmpty());
assertFalse(_parser.getBuffer()==null);
-
+
filled =_parser.parseNext();
-
+
assertEquals(0,filled);
assertEquals("Hell\uFF4f W\uFF4Frld",_handler._data.get(1));
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
+ @Test
public void testOneBinary() throws Exception
{
_in.put((byte)0x80);
_in.put((byte)11);
_in.put("Hello World".getBytes(StringUtil.__UTF8));
-
+
int filled =_parser.parseNext();
-
+
assertEquals(13,filled);
assertEquals("Hello World",_handler._data.get(0));
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
+ @Test
public void testTwoBinary() throws Exception
{
_in.put((byte)0x80);
_in.put((byte)11);
_in.put("Hello World".getBytes(StringUtil.__UTF8));
-
+
byte[] data = new byte[150];
for (int i=0;i<data.length;i++)
data[i]=(byte)('0'+(i%10));
@@ -107,14 +112,14 @@ public class WebSocketParserTest extends TestCase
_in.put((byte)(0x80|(data.length>>7)));
_in.put((byte)(data.length&0x7f));
_in.put(data);
-
-
+
+
int filled =_parser.parseNext();
assertEquals(13+3+data.length,filled);
assertEquals("Hello World",_handler._data.get(0));
assertFalse(_parser.isBufferEmpty());
assertFalse(_parser.getBuffer()==null);
-
+
filled =_parser.parseNext();
assertEquals(0,filled);
String got=_handler._data.get(1);
@@ -123,22 +128,23 @@ public class WebSocketParserTest extends TestCase
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
-
+
+
+ @Test
+ public void testHixieCrypt() throws Exception
+ {
+ assertEquals(155712099,WebSocketParser.hixieCrypt("18x 6]8vM;54 *(5: { U1]8 z [ 8"));
+ assertEquals(173347027,WebSocketParser.hixieCrypt("1_ tx7X d < nw 334J702) 7]o}` 0"));
+ }
// TODO test:
- // blocking,
+ // blocking,
// async
// full
// EOF
// errors
-
-
-
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- class Handler implements WebSocketParser.EventHandler
+
+ private class Handler implements WebSocketParser.EventHandler
{
public List<String> _data = new ArrayList<String>();
@@ -151,6 +157,5 @@ public class WebSocketParserTest extends TestCase
{
_data.add(data);
}
-
}
}
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTest.java
index 292eb67e4b..eb62f5a1eb 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTest.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTest.java
@@ -1,11 +1,8 @@
package org.eclipse.jetty.websocket;
import java.io.IOException;
-
import javax.servlet.http.HttpServletRequest;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.server.LocalConnector;
@@ -13,24 +10,26 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-public class WebSocketTest extends TestCase
+public class WebSocketTest
{
- TestWebSocket _websocket;
- LocalConnector _connector;
- Server _server;
- WebSocketHandler _handler;
-
-
-
- /* ------------------------------------------------------------ */
- @Override
- protected void setUp() throws Exception
+ private static TestWebSocket _websocket;
+ private static LocalConnector _connector;
+ private static Server _server;
+
+ @BeforeClass
+ public static void startServer() throws Exception
{
_server = new Server();
_connector = new LocalConnector();
_server.addConnector(_connector);
- _handler= new WebSocketHandler()
+ WebSocketHandler handler = new WebSocketHandler()
{
@Override
protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
@@ -39,24 +38,31 @@ public class WebSocketTest extends TestCase
return _websocket;
}
};
- _handler.setHandler(new DefaultHandler());
- _server.setHandler(_handler);
-
- _server.start();
+ handler.setHandler(new DefaultHandler());
+ _server.setHandler(handler);
+
+ _server.start();
}
-
-
+
+ @AfterClass
+ public static void stopServer() throws Exception
+ {
+ _server.stop();
+ _server.join();
+ }
+
+ @Test
public void testNoWebSocket() throws Exception
{
String response = _connector.getResponses(
"GET /foo HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n",false);
-
+
assertTrue(response.startsWith("HTTP/1.1 404 "));
}
- /* ------------------------------------------------------------ */
+ @Test
public void testOpenWebSocket() throws Exception
{
String response = _connector.getResponses(
@@ -65,45 +71,42 @@ public class WebSocketTest extends TestCase
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
"\r\n",false);
-
+
assertTrue(response.startsWith("HTTP/1.1 101 Web Socket Protocol Handshake"));
assertTrue(response.contains("Upgrade: WebSocket"));
assertTrue(response.contains("Connection: Upgrade"));
}
- /* ------------------------------------------------------------ */
+ @Test
public void testSendReceiveUtf8WebSocket() throws Exception
{
ByteArrayBuffer buffer = new ByteArrayBuffer(1024);
-
+
buffer.put(
("GET /demo HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
"\r\n").getBytes(StringUtil.__ISO_8859_1));
-
+
buffer.put((byte)0);
buffer.put("Hello World".getBytes(StringUtil.__UTF8));
buffer.put((byte)0xFF);
-
+
ByteArrayBuffer out = _connector.getResponses(buffer,true);
-
+
String response = StringUtil.printable(out.asArray());
System.err.println(response);
-
+
assertTrue(response.startsWith("HTTP/1.1 101 Web Socket Protocol Handshake"));
assertTrue(response.contains("Upgrade: WebSocket"));
assertTrue(response.contains("Connection: Upgrade"));
assertTrue(response.contains("0x00Roger That0xFF"));
-
+
assertEquals("Hello World",_websocket._utf8);
}
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- class TestWebSocket implements WebSocket
+ private static class TestWebSocket implements WebSocket
{
Outbound _outbound;
Buffer _binary;
@@ -122,7 +125,7 @@ public class WebSocketTest extends TestCase
Log.warn(e);
}
}
-
+
public void onMessage(byte frame, byte[] data,int offset, int length)
{
_binary=new ByteArrayBuffer(data,offset,length).duplicate(Buffer.READONLY);
@@ -138,5 +141,4 @@ public class WebSocketTest extends TestCase
_disconnected=true;
}
}
-
}
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTestServer.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTestServer.java
index 878c6c8601..e500b337c2 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTestServer.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketTestServer.java
@@ -1,34 +1,27 @@
package org.eclipse.jetty.websocket;
import java.io.IOException;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
-
import javax.servlet.http.HttpServletRequest;
-import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.websocket.WebSocketTest.TestWebSocket;
public class WebSocketTestServer extends Server
{
TestWebSocket _websocket;
SelectChannelConnector _connector;
WebSocketHandler _handler;
- ConcurrentLinkedQueue<TestWebSocket> _webSockets= new ConcurrentLinkedQueue<TestWebSocket>();
-
+ ConcurrentLinkedQueue<TestWebSocket> _webSockets = new ConcurrentLinkedQueue<TestWebSocket>();
+
public WebSocketTestServer()
{
_connector = new SelectChannelConnector();
_connector.setPort(8080);
-
+
addConnector(_connector);
- _handler= new WebSocketHandler()
+ _handler = new WebSocketHandler()
{
@Override
protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
@@ -37,7 +30,7 @@ public class WebSocketTestServer extends Server
return _websocket;
}
};
-
+
setHandler(_handler);
}
@@ -50,26 +43,26 @@ public class WebSocketTestServer extends Server
public void onConnect(Outbound outbound)
{
System.err.println("onConnect");
- _outbound=outbound;
+ _outbound = outbound;
_webSockets.add(this);
-
+
}
-
- public void onMessage(byte frame, byte[] data,int offset, int length)
+
+ public void onMessage(byte frame, byte[] data, int offset, int length)
{
}
public void onMessage(final byte frame, final String data)
{
- System.err.println("onMessage "+data);
+ System.err.println("onMessage " + data);
for (TestWebSocket ws : _webSockets)
{
- if (ws!=this)
+ if (ws != this)
{
try
{
if (ws._outbound.isOpen())
- ws._outbound.sendMessage(frame,data);
+ ws._outbound.sendMessage(frame, data);
}
catch (IOException e)
{
@@ -84,9 +77,8 @@ public class WebSocketTestServer extends Server
_webSockets.remove(this);
}
}
-
-
- public static void main(String[] args)
+
+ public static void main(String[] args)
{
try
{
@@ -94,12 +86,10 @@ public class WebSocketTestServer extends Server
server.start();
server.join();
}
- catch(Exception e)
+ catch (Exception e)
{
Log.warn(e);
}
}
-
-
-
+
}
diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml
index c55bb79b4f..87a1b7c83a 100644
--- a/jetty-xml/pom.xml
+++ b/jetty-xml/pom.xml
@@ -33,16 +33,11 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
+ <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
- <!-- always include sources since jetty-xbean makes use of them -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -62,6 +57,13 @@
</executions>
</plugin>
-->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <onlyAnalyze>org.eclipse.jetty.xml.*</onlyAnalyze>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
@@ -73,6 +75,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
index 8f51b03e95..ad2e51a261 100644
--- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
+++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
@@ -787,15 +787,12 @@ public class XmlConfiguration
{
String id = node.getAttribute("id");
String name = node.getAttribute("name");
- Object defval = node.getAttribute("default");
+ String defval = node.getAttribute("default");
Object prop=null;
if (_propertyMap!=null && _propertyMap.containsKey(name))
- {
prop=_propertyMap.get(name);
- }
- else if (defval != null)
- prop=defval;
-
+ else
+ prop=defval;
if (id != null)
_idMap.put(id, prop);
if (prop!=null)
diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java
index 3a5df4319f..7682376b04 100644
--- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java
+++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java
@@ -4,17 +4,21 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-package org.eclipse.jetty.xml;import java.net.URL;
+package org.eclipse.jetty.xml;
+
+import java.net.URL;
import java.util.HashMap;
+import org.junit.Ignore;
+@Ignore
public class TestConfiguration extends HashMap
{
public static int VALUE=77;
@@ -28,6 +32,7 @@ public class TestConfiguration extends HashMap
public int[] ia;
public int testField1;
public int testField2;
+ public int propValue;
public void setTest(Object value)
{
@@ -38,6 +43,12 @@ public class TestConfiguration extends HashMap
{
testInt=value;
}
+
+ public void setPropertyTest(int value)
+ {
+ propValue=value;
+ }
+
public void call()
{
diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
index 4d4a40b642..254c51fc1f 100644
--- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
+++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
@@ -4,11 +4,11 @@
// 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
+// 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.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.xml;
@@ -17,14 +17,15 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Map;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class XmlConfigurationTest extends TestCase
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class XmlConfigurationTest
{
- public final static String __CRLF = "\015\012";
-
- /* ------------------------------------------------------------ */
- public static void testXmlParser() throws Exception
+ @Test
+ public void testXmlParser() throws Exception
{
XmlParser parser = new XmlParser();
@@ -44,40 +45,41 @@ public class XmlConfigurationTest extends TestCase
parser.redirectEntity("configure_1_0.dtd", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure_1_0.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.0//EN", configURL);
-
+
URL url = XmlConfigurationTest.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure.xml");
XmlParser.Node testDoc = parser.parse(url.toString());
String testDocStr = testDoc.toString().trim();
-
+
assertTrue(testDocStr.startsWith("<Configure"));
assertTrue(testDocStr.endsWith("</Configure>"));
-
}
- /* ------------------------------------------------------------ */
- public static void testXmlConfiguration() throws Exception
+ @Test
+ public void testXmlConfiguration() throws Exception
{
Map properties = new HashMap();
properties.put("whatever", "xxx");
-
+
URL url = XmlConfigurationTest.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure.xml");
XmlConfiguration configuration =
new XmlConfiguration(url);
TestConfiguration tc = new TestConfiguration();
configuration.setProperties(properties);
configuration.configure(tc);
-
+
assertEquals("Set String","SetValue",tc.testObject);
assertEquals("Set Type",2,tc.testInt);
+ assertEquals(18080, tc.propValue);
+
assertEquals("Put","PutValue",tc.get("Test"));
assertEquals("Put dft","2",tc.get("TestDft"));
assertEquals("Put type",new Integer(2),tc.get("TestInt"));
-
+
assertEquals("Trim","PutValue",tc.get("Trim"));
assertEquals("Null",null,tc.get("Null"));
assertEquals("NullTrim",null,tc.get("NullTrim"));
-
+
assertEquals("ObjectTrim",new Double(1.2345),tc.get("ObjectTrim"));
assertEquals("Objects","-1String",tc.get("Objects"));
assertEquals( "ObjectsTrim", "-1String",tc.get("ObjectsTrim"));
@@ -87,49 +89,45 @@ public class XmlConfigurationTest extends TestCase
assertEquals( "ObjectString", "\n 1.2345\n ",tc.get("ObjectString"));
assertEquals( "ObjectsString", "-1String",tc.get("ObjectsString"));
assertEquals( "ObjectsWhiteString", "-1\n String",tc.get("ObjectsWhiteString"));
-
+
assertEquals( "SystemProperty", System.getProperty("user.dir")+"/stuff",tc.get("SystemProperty"));
assertEquals( "Property", "xxx", tc.get("Property"));
-
-
+
+
assertEquals( "Called", "Yes",tc.get("Called"));
-
+
assertTrue(TestConfiguration.called);
-
+
assertEquals("oa[0]","Blah",tc.oa[0]);
assertEquals("oa[1]","1.2.3.4:5678",tc.oa[1]);
assertEquals("oa[2]",new Double(1.2345),tc.oa[2]);
assertEquals("oa[3]",null,tc.oa[3]);
-
+
assertEquals("ia[0]",1,tc.ia[0]);
assertEquals("ia[1]",2,tc.ia[1]);
assertEquals("ia[2]",3,tc.ia[2]);
assertEquals("ia[3]",0,tc.ia[3]);
-
+
TestConfiguration tc2=tc.nested;
assertTrue(tc2!=null);
assertEquals( "Called(bool)", new Boolean(true),tc2.get("Arg"));
-
+
assertEquals("nested config",null,tc.get("Arg"));
assertEquals("nested config",new Boolean(true),tc2.get("Arg"));
-
+
assertEquals("nested config","Call1",tc2.testObject);
assertEquals("nested config",4,tc2.testInt);
assertEquals( "nested call", "http://www.eclipse.com/",tc2.url.toString());
-
+
configuration =
new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"Test\">SetValue</Set><Set name=\"Test\" type=\"int\">2</Set></Configure>");
TestConfiguration tc3 = new TestConfiguration();
configuration.configure(tc3);
assertEquals("Set String 3","SetValue",tc3.testObject);
assertEquals("Set Type 3",2,tc3.testInt);
-
+
assertEquals("static to field",tc.testField1,77);
assertEquals("field to field",tc.testField2,2);
assertEquals("literal to static",TestConfiguration.VALUE,42);
-
}
-
-
-
}
diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
index e8ef9d28ee..784cca9193 100644
--- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
+++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
@@ -5,6 +5,8 @@
<Set name="Test">SetValue</Set>
<Set name="Test" type="int">2</Set>
+
+ <Set name="PropertyTest"><Property name="anIntegerNoActualPropDefined" default="18080"/></Set>
<Put name="Test">PutValue</Put>
<Put name="TestDft">2</Put>
diff --git a/linux-packaging.xml b/linux-packaging.xml
new file mode 100644
index 0000000000..4da7c80062
--- /dev/null
+++ b/linux-packaging.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<linux-packaging>
+ <mapping>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jsp-api-2.1-glassfish</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <required-classes>
+ <class>ch.qos.logback.classic.LoggerContext</class>
+ </required-classes>
+ <debian criteria="&gt;= 0.9.18">liblogback-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <required-classes>
+ <class>javax.servlet.http.HttpServlet</class>
+ </required-classes>
+ <debian available="false"/>
+ <redhat avaialble="false">tomcat6-servlet-2.5-api</redhat>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <!-- In order to assure proper packaging setup, a few classes
+ should be specified to check for on the classpath.
+ If these classes are not present on the classpath, then
+ the jar is downloaded from the maven repo and used in
+ an embedded fashion. -->
+ <required-classes>
+ <class>junit.framework.Assert</class>
+ <class>junit.framework.TestCase</class>
+ </required-classes>
+ <!-- The debian packaging refers to the version-less package name.
+ An optional criteria can be specified that would indicate
+ a minimum version to be present on the system.
+ This information will (eventually) be verified against
+ the debian/control file to ensure that the packaging
+ is still valid.
+ If the information is determined to not be present
+ in the debian/control file than a build error is
+ (hopefully) produced to let the maintainers know
+ that this information is now out of date. -->
+ <debian criteria="&gt;= 3.8">junit</debian>
+ <redhat>junit</redhat>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jdt.core.compiler</groupId>
+ <artifactId>ecj</artifactId>
+ <debian available="false"/>
+ <redhat>ecj</redhat>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jsp-2.1-glassfish</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <required-classes>
+ <class>ch.qos.logback.core.joran.JoranConfiguratorBase</class>
+ </required-classes>
+ <debian criteria="&gt;= 0.9.18">liblogback-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jaspic_1.0_spec</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.equinox.http</groupId>
+ <artifactId>servlet</artifactId>
+ <debian criteria="&gt;= 3.5">eclipse-platform</debian>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.osgi</groupId>
+ <artifactId>services</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jta_1.1_spec</artifactId>
+ <debian available="false">libgeronimo-jta-1.1-spec-1.1.1-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse</groupId>
+ <artifactId>osgi</artifactId>
+ <required-classes>
+ <class>org.osgi.framework.BundleContext</class>
+ </required-classes>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <debian criteria="&gt;= 1.5.10">libslf4j-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm-commons</artifactId>
+ <debian criteria="&gt;= 3.1">libasm3-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ <debian criteria="&gt;= 1.6">ant</debian>
+ <redhat>ant</redhat>
+ </dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <debian criteria="&gt;= 3.1">libasm3-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm-tree</artifactId>
+ <debian criteria="&gt;= 3.1">libasm3-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <required-classes>
+ <class>javax.mail.Authenticator</class>
+ <class>javax.mail.PasswordAuthentication</class>
+ <class>javax.mail.Session</class>
+ </required-classes>
+ <debian>libgnumail-java</debian>
+ <redhat>sun-mail</redhat>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-annotation_1.0_spec</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <debian criteria="&gt;= 1.5.10">libslf4j-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <debian criteria="&gt;= 5.8">testng</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>3.0.20100224</version>
+ <required-classes>
+ <class>javax.servlet.AsyncContext</class>
+ <class>javax.servlet.AsyncEvent</class>
+ <class>javax.servlet.AsyncListener</class>
+ </required-classes>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <required-classes>
+ <class>org.slf4j.Logger</class>
+ </required-classes>
+ <debian criteria="&gt;= 1.5.10">libslf4j-java</debian>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <debian available="false"/>
+ <redhat available="false"/>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <debian>libgnujav-java</debian>
+ <redhat>sun-jaf</redhat>
+ </dependency>
+ </mapping>
+ <!-- Excluding due to Geronimo Dependency Requirements -->
+ <project groupId="org.eclipse.jetty">
+ <exclude>jetty-annotations</exclude>
+ <exclude>jetty-jaspi</exclude>
+ <exclude>jetty-plus</exclude>
+ <exclude>example-jetty-embedded</exclude>
+ <exclude>test-continuation</exclude>
+ <exclude>test-continuation-jetty6</exclude>
+ <exclude>test-jetty-servlet</exclude>
+ </project>
+ <!-- Dependencies for OSGI are too complicated to deal with right now -->
+ <project groupId="org.eclipse.jetty.osgi">
+ <exclude>jetty-osgi</exclude>
+ <exclude>jetty-osgi-boot</exclude>
+ <exclude>jetty-osgi-boot-jsp</exclude>
+ <exclude>jetty-osgi-boot-logback</exclude>
+ <exclude>jetty-osgi-boot-warurl</exclude>
+ <exclude>jetty-httpservice</exclude>
+ </project>
+ <!-- Aggregate Projects need not be built by linux-packaging -->
+ <project groupId="org.eclipse.jetty.aggregate">
+ <exclude>jetty-server</exclude>
+ <exclude>jetty-client</exclude>
+ <exclude>jetty-servlet</exclude>
+ <exclude>jetty-webapp</exclude>
+ <exclude>jetty-plus</exclude>
+ <exclude>jetty-all-server</exclude>
+ <exclude>jetty-all</exclude>
+ </project>
+ <project groupId="org.eclipse.jetty.tests">
+ <exclude>test-sessions-common</exclude>
+ <exclude>test-jdbc-sessions</exclude>
+ <exclude>test-hash-sessions</exclude>
+ <exclude>test-integration</exclude>
+ <exclude>test-webapp-rfc2616</exclude>
+ </project>
+ <daemon>
+ <script>jetty-distribution/src/main/resources/bin/jetty.sh</script>
+ <debian>debian/jetty.init</debian>
+ <redhat>rpm/jetty.init</redhat>
+ </daemon>
+</linux-packaging>
+
diff --git a/pom.xml b/pom.xml
index a37ce3d011..a10fad4555 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,10 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-parent</artifactId>
- <version>12</version>
+ <version>15</version>
</parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
@@ -13,20 +12,19 @@
<url>${jetty.url}</url>
<packaging>pom</packaging>
<properties>
- <jetty.url>http://www.eclipse.org/jetty</jetty.url>
<felix.bundle.version>2.0.0</felix.bundle.version>
- <activation-version>1.1</activation-version>
- <ant-version>1.6.5</ant-version>
- <jta-spec-version>1.1.1</jta-spec-version>
+ <javax-activation-version>1.1</javax-activation-version>
+ <javax-mail-version>1.4.1</javax-mail-version>
+ <javax-transaction-version>1.1.1</javax-transaction-version>
+ <jetty.url>http://www.eclipse.org/jetty</jetty.url>
<junit-version>3.8.2</junit-version>
- <mail-version>1.4</mail-version>
- <slf4j-version>1.5.10</slf4j-version>
- <eclipse-compiler-version>3.1.1</eclipse-compiler-version>
- <cometd-version>1.0.1</cometd-version>
+ <junit4-version>4.8.1</junit4-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <slf4j-version>1.5.10</slf4j-version>
<servlet.spec.groupId>org.mortbay.jetty</servlet.spec.groupId>
<servlet.spec.artifactId>servlet-api</servlet.spec.artifactId>
<servlet.spec.version>3.0.20100224</servlet.spec.version>
+ <build-support-version>1.0</build-support-version>
</properties>
<scm>
<connection>scm:svn:http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags/jetty-8.0.0.M1</connection>
@@ -48,26 +46,54 @@
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagBase>svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags</tagBase>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-remote-resources-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>process</goal>
- </goals>
- <configuration>
- <resourceBundles>
- <resourceBundle>org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.0</resourceBundle>
- </resourceBundles>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.0</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- source maven plugin creates the source bundle and adds manifest -->
+ <plugin>
+ <inherited>true</inherited>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
+ <Bundle-Name>${project.name}</Bundle-Name>
+ <Bundle-SymbolicName>${bundle-symbolic-name}.source;singleton:=true</Bundle-SymbolicName>
+ <Bundle-Vendor>Eclipse.org - Jetty</Bundle-Vendor>
+ <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
+ <Eclipse-SourceBundle>${bundle-symbolic-name};version="${parsedVersion.osgiVersion}";roots:="."</Eclipse-SourceBundle>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<!-- Build helper maven plugin sets the parsedVersion.osgiVersion property -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -76,58 +102,111 @@
<executions>
<execution>
<id>set-osgi-version</id>
- <phase>compile</phase>
+ <phase>validate</phase>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
- </plugin>
- </plugins>
- <pluginManagement>
- <plugins>
- <plugin>
+ </plugin>
+ <!-- Enforcer Plugin -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-4</version>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>[2.0.6,)</version>
+ </requireMavenVersion>
+ <requireJavaVersion>
+ <version>[1.5,)</version>
+ </requireJavaVersion>
+ <versionTxtRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.VersionTxtRule" />
+ <versionOsgiRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireOsgiCompatibleVersionRule" />
+ <versionRedhatRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireRedhatCompatibleVersionRule" />
+ <versionDebianRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireDebianCompatibleVersionRule" />
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>jetty-build-support</artifactId>
+ <version>${build-support-version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>2.5</version>
<configuration>
- <archive>
- <manifestEntries>
- <Implementation-Version>${project.version}</Implementation-Version>
- <Implementation-Vendor>Eclipse.org - Jetty</Implementation-Vendor>
- <url>${jetty.url}</url>
- </manifestEntries>
- </archive>
+ <targetJdk>1.5</targetJdk>
+ <rulesets>
+ <ruleset>jetty/pmd_ruleset.xml</ruleset>
+ </rulesets>
</configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.4.2</version>
- <configuration>
- <failIfNoTests>false</failIfNoTests>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.0.0</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
- <Bundle-DocURL>${jetty.url}</Bundle-DocURL>
- <Bundle-Vendor>Eclipse Jetty Project</Bundle-Vendor>
- <Bundle-Localization>plugin</Bundle-Localization>
- <Bundle-Classpath>.</Bundle-Classpath>
- <Bundle-Copyright>Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.</Bundle-Copyright>
- <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>jetty-build-support</artifactId>
+ <version>${build-support-version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>Eclipse.org - Jetty</Implementation-Vendor>
+ <url>${jetty.url}</url>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.2</version>
+ <configuration>
+ <failIfNoTests>false</failIfNoTests>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.0.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
+ <Bundle-DocURL>${jetty.url}</Bundle-DocURL>
+ <Bundle-Vendor>Eclipse Jetty Project</Bundle-Vendor>
+ <Bundle-Localization>plugin</Bundle-Localization>
+ <Bundle-Classpath>.</Bundle-Classpath>
+ <Bundle-Copyright>Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.</Bundle-Copyright>
+ <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
- <version>2.2-beta-3</version>
+ <version>2.2-beta-5</version>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
@@ -135,39 +214,63 @@
<version>1.0</version>
</dependency>
</dependencies>
- </plugin>
-
- <!-- source maven plugin creates the source bundle and adds manifest -->
- <plugin>
- <inherited>true</inherited>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <phase>process-classes</phase>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
- <Bundle-Name>${name}</Bundle-Name>
- <Bundle-SymbolicName>${bundle-symbolic-name}.source;singleton:=true</Bundle-SymbolicName>
- <Bundle-Vendor>Eclipse.org - Jetty</Bundle-Vendor>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Eclipse-SourceBundle>${bundle-symbolic-name};version="${parsedVersion.osgiVersion}";roots:="."</Eclipse-SourceBundle>
- </manifestEntries>
- </archive>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <findbugsXmlOutput>true</findbugsXmlOutput>
+ <xmlOutput>true</xmlOutput>
+ <effort>Max</effort>
+ <onlyAnalyze>org.eclipse.jetty.*</onlyAnalyze>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <additionalJOption>-J-Xmx128m</additionalJOption>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <configuration>
+ <targetJdk>1.5</targetJdk>
+ <rulesets>
+ <ruleset>jetty/pmd_ruleset.xml</ruleset>
+ </rulesets>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+ <!--
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>sonatype-snapshots</id>
+ <name>Sonatype Jetty Snapshots</name>
+ <url>http://oss.sonatype.org/content/groups/jetty</url>
+ </repository>
+ </repositories>
+ -->
<modules>
<module>jetty-util</module>
<module>jetty-io</module>
@@ -235,28 +338,23 @@
<version>${slf4j-version}</version>
</dependency>
<dependency>
- <groupId>ant</groupId>
- <artifactId>ant</artifactId>
- <version>${ant-version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
- <version>${jta-spec-version}</version>
+ <version>${javax-transaction-version}</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
- <version>${mail-version}</version>
+ <version>${javax-mail-version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
- <version>${activation-version}</version>
+ <version>${javax-activation-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
- <!--
+ <!--
Usage:
configure settings.xml for jetty.eclipse.website server entry
> mvn -Paggregate-site javadoc:aggregate jxr:jxr
@@ -277,27 +375,26 @@
</configuration>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <configuration>
- <excludePackageNames>com.acme</excludePackageNames>
- <links>
- <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
- <link>http://java.sun.com/javaee/5/docs/api</link>
- <link>http://junit.sourceforge.net/javadoc/</link>
- </links>
- </configuration>
- </plugin>
- </plugins>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <excludePackageNames>com.acme</excludePackageNames>
+ <links>
+ <link>http://java.sun.com/javase/6/docs/api/</link>
+ <link>http://java.sun.com/javaee/6/docs/api</link>
+ <link>http://junit.sourceforge.net/javadoc/</link>
+ </links>
+ <tags>
+ <tag>
+ <name>org.apache.xbean.XBean</name>
+ <placement>X</placement>
+ <head />
+ </tag>
+ </tags>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
</profile>
- <profile>
- <id>jetty-spec</id>
- <properties>
- <servlet.spec.groupId>org.mortbay.jetty</servlet.spec.groupId>
- <servlet.spec.artifactId>servlet-api</servlet.spec.artifactId>
- <servlet.spec.version>3.0.20100224</servlet.spec.version>
- </properties>
- </profile>
</profiles>
</project>
diff --git a/test-continuation-jetty6/pom.xml b/test-continuation-jetty6/pom.xml
index 25d4c40bb8..62d987e8f5 100644
--- a/test-continuation-jetty6/pom.xml
+++ b/test-continuation-jetty6/pom.xml
@@ -10,6 +10,16 @@
<name>Test :: Continuation - (Jetty 6)</name>
<description>Asynchronous API</description>
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <!-- DO NOT DEPLOY (or Release) -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
<dependencies>
<dependency>
@@ -50,7 +60,7 @@
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
- <version>6.1.18</version>
+ <version>6.1.24</version>
<type>jar</type>
<scope>test</scope>
</dependency>
diff --git a/test-continuation/pom.xml b/test-continuation/pom.xml
index 004da4642b..ab44d1f3e5 100644
--- a/test-continuation/pom.xml
+++ b/test-continuation/pom.xml
@@ -10,6 +10,16 @@
<name>Test :: Continuation</name>
<description>Asynchronous API</description>
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <!-- DO NOT DEPLOY (or Release) -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
<dependencies>
<dependency>
diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
index 83bd0578a2..edbcd5a4bd 100644
--- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
+++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
@@ -314,7 +314,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
* @param cookie
- * @see org.eclipse.jetty.http.HttpFields#addSetCookie(javax.servlet.http.Cookie)
+ * @see org.eclipse.jetty.http.HttpFields#addSetCookie(org.eclipse.jetty.http.HttpCookie)
*/
public void addSetCookie(Cookie cookie)
{
@@ -333,7 +333,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
* @param name
- * @return
+ * @return the header value as a date
* @see org.eclipse.jetty.http.HttpFields#getDateField(java.lang.String)
*/
public long getDateHeader(String name)
@@ -343,7 +343,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
- * @return
+ * @return the header value names
* @see org.eclipse.jetty.http.HttpFields#getFieldNames()
*/
public Enumeration getHeaderNames()
@@ -354,7 +354,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
* @param name
- * @return
+ * @return the header value as a long
* @throws NumberFormatException
* @see org.eclipse.jetty.http.HttpFields#getLongField(java.lang.String)
*/
@@ -366,7 +366,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
* @param name
- * @return
+ * @return the header value
* @see org.eclipse.jetty.http.HttpFields#getStringField(java.lang.String)
*/
public String getHeader(String name)
@@ -377,7 +377,7 @@ public class HttpTester
/* ------------------------------------------------------------ */
/**
* @param name
- * @return
+ * @return the header values
* @see org.eclipse.jetty.http.HttpFields#getValues(java.lang.String)
*/
public Enumeration getHeaderValues(String name)
diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java
index 640f8b5778..a1aec59a57 100644
--- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java
+++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java
@@ -24,6 +24,7 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
@@ -63,6 +64,7 @@ public class ServletTester
{
try
{
+ _server.addBean(new ErrorHandler());
_server.setSendServerVersion(false);
_server.addConnector(_connector);
_server.setHandler(_context);
@@ -142,7 +144,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/** Create a Socket connector.
* This methods adds a socket connector to the server
- * @param locahost if true, only listen on local host, else listen on all interfaces.
+ * @param localhost if true, only listen on local host, else listen on all interfaces.
* @return A URL to access the server via the socket connector.
* @throws Exception
*/
@@ -214,7 +216,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param listener
- * @see org.eclipse.jetty.handler.ContextHandler#addEventListener(java.util.EventListener)
+ * @see org.eclipse.jetty.server.handler.ContextHandler#addEventListener(java.util.EventListener)
*/
public void addEventListener(EventListener listener)
{
@@ -226,8 +228,8 @@ public class ServletTester
* @param filterClass
* @param pathSpec
* @param dispatches
- * @return
- * @see org.eclipse.jetty.servlet.Scope#addFilter(java.lang.Class, java.lang.String, int)
+ * @return the FilterHolder
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#addFilter(java.lang.Class, java.lang.String, int)
*/
public FilterHolder addFilter(Class filterClass, String pathSpec, EnumSet<DispatcherType> dispatches)
{
@@ -239,8 +241,8 @@ public class ServletTester
* @param filterClass
* @param pathSpec
* @param dispatches
- * @return
- * @see org.eclipse.jetty.servlet.Scope#addFilter(java.lang.String, java.lang.String, int)
+ * @return the FilterHolder
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#addFilter(java.lang.String, java.lang.String, int)
*/
public FilterHolder addFilter(String filterClass, String pathSpec, EnumSet<DispatcherType> dispatches)
{
@@ -251,8 +253,8 @@ public class ServletTester
/**
* @param servlet
* @param pathSpec
- * @return
- * @see org.eclipse.jetty.servlet.Scope#addServlet(java.lang.Class, java.lang.String)
+ * @return the ServletHolder
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#addServlet(java.lang.Class, java.lang.String)
*/
public ServletHolder addServlet(Class servlet, String pathSpec)
{
@@ -263,8 +265,8 @@ public class ServletTester
/**
* @param className
* @param pathSpec
- * @return
- * @see org.eclipse.jetty.servlet.Scope#addServlet(java.lang.String, java.lang.String)
+ * @return the ServletHolder
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#addServlet(java.lang.String, java.lang.String)
*/
public ServletHolder addServlet(String className, String pathSpec)
{
@@ -274,8 +276,8 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param name
- * @return
- * @see org.eclipse.jetty.handler.ContextHandler#getAttribute(java.lang.String)
+ * @return the Attribute object
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#getAttribute(java.lang.String)
*/
public Object getAttribute(String name)
{
@@ -284,8 +286,8 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
- * @return
- * @see org.eclipse.jetty.handler.ContextHandler#getAttributeNames()
+ * @return the Attribute Names
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#getAttributeNames()
*/
public Enumeration getAttributeNames()
{
@@ -294,8 +296,8 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
- * @return
- * @see org.eclipse.jetty.handler.ContextHandler#getAttributes()
+ * @return the attributes
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#getAttributes()
*/
public Attributes getAttributes()
{
@@ -304,8 +306,8 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
- * @return
- * @see org.eclipse.jetty.handler.ContextHandler#getResourceBase()
+ * @return the resource base
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#getResourceBase()
*/
public String getResourceBase()
{
@@ -316,7 +318,7 @@ public class ServletTester
/**
* @param name
* @param value
- * @see org.eclipse.jetty.handler.ContextHandler#setAttribute(java.lang.String, java.lang.Object)
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#setAttribute(java.lang.String, java.lang.Object)
*/
public void setAttribute(String name, Object value)
{
@@ -326,7 +328,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param classLoader
- * @see org.eclipse.jetty.handler.ContextHandler#setClassLoader(java.lang.ClassLoader)
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#setClassLoader(java.lang.ClassLoader)
*/
public void setClassLoader(ClassLoader classLoader)
{
@@ -336,7 +338,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param contextPath
- * @see org.eclipse.jetty.handler.ContextHandler#setContextPath(java.lang.String)
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#setContextPath(java.lang.String)
*/
public void setContextPath(String contextPath)
{
@@ -346,7 +348,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param eventListeners
- * @see org.eclipse.jetty.handler.ContextHandler#setEventListeners(java.util.EventListener[])
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#setEventListeners(java.util.EventListener[])
*/
public void setEventListeners(EventListener[] eventListeners)
{
@@ -356,7 +358,7 @@ public class ServletTester
/* ------------------------------------------------------------ */
/**
* @param resourceBase
- * @see org.eclipse.jetty.handler.ContextHandler#setResourceBase(java.lang.String)
+ * @see org.eclipse.jetty.servlet.ServletContextHandler#setResourceBase(java.lang.String)
*/
public void setResourceBase(String resourceBase)
{
diff --git a/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/ServletTest.java b/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/ServletTest.java
index 22e2bba9b0..48a34c137d 100644
--- a/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/ServletTest.java
+++ b/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/ServletTest.java
@@ -252,7 +252,7 @@ public class ServletTest extends TestCase
ByteArrayBuffer out = new ByteArrayBuffer(4096);
out.put(request0.getBytes("iso8859-1"));
String responses = tester.getResponses(out).toString();
-
+
int offset = responses.indexOf("HTTP/1.1 500");
assertTrue(offset>=0);
offset = responses.indexOf("Content-Length: ",offset);
diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml
index 4b34394048..ca891bdd20 100644
--- a/test-jetty-webapp/pom.xml
+++ b/test-jetty-webapp/pom.xml
@@ -38,16 +38,67 @@
<configuration>
<descriptors>
<descriptor>config.xml</descriptor>
+ <descriptor>src/main/assembly/web-bundle.xml</descriptor>
</descriptors>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
</configuration>
</execution>
</executions>
</plugin>
+ <!-- also make this webapp an osgi bundle -->
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${felix.bundle.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <supportedProjectTypes>
+ <supportedProjectType>war</supportedProjectType>
+ </supportedProjectTypes>
+ </configuration>
+ <executions>
+ <execution>
+ <id>bundle-manifest</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.eclipse.jetty.test-jetty-webapp</Bundle-SymbolicName>
+ <Import-Package>javax.servlet,*</Import-Package>
+ <Export-Package>!com.acme*</Export-Package>
+ <!-- the test webapp is configured via a jetty xml file
+ in order to add the security handler. -->
+ <Web-ContextPath>/</Web-ContextPath>
+ <!-- in fact the '.' must not be there
+ but Felix-BND has a bug:
+ http://www.mail-archive.com/users@felix.apache.org/msg04730.html
+ https://issues.apache.org/jira/browse/FELIX-1571
+ -->
+ <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
+ <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
+ </instructions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
<!--
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
- <version>7.0.0.RC2-SNAPSHOT</version>
+ <version>7.1.1-SNAPSHOT</version>
<configuration>
<stopPort>8087</stopPort>
<stopKey>foo</stopKey>
@@ -70,13 +121,12 @@
<loginServices>
<loginService implementation="org.eclipse.jetty.security.HashLoginService">
<name>Test Realm</name>
- <config>../jetty-server/src/main/config/etc/realm.properties</config>
+ <config>src/main/config/etc/realm.properties</config>
</loginService>
</loginServices>
</configuration>
</plugin>
-->
-
<!-- uncomment to precompile jsps -->
<!--
<plugin>
@@ -152,5 +202,11 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>2.1</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml b/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml
new file mode 100644
index 0000000000..c181c35eac
--- /dev/null
+++ b/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- ==================================================================
+Configure and deploy the test web application in $(jetty.home)/webapps/test
+
+Note. If this file did not exist or used a context path other that /test
+then the default configuration of jetty.xml would discover the test
+webapplication with a WebAppDeployer. By specifying a context in this
+directory, additional configuration may be specified and hot deployments
+detected.
+===================================================================== -->
+
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+
+
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- Required minimal context configuration : -->
+ <!-- + contextPath -->
+ <!-- + war OR resourceBase -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <Set name="contextPath">/</Set>
+ <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test.war</Set>
+
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- Optional context configuration -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <Set name="extractWAR">true</Set>
+ <Set name="copyWebDir">false</Set>
+ <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+ <Set name="overrideDescriptor"><SystemProperty name="jetty.home" default="."/>/contexts/test.d/override-web.xml</Set>
+
+ <!-- virtual hosts
+ <Set name="virtualHosts">
+ <Array type="String">
+ <Item>www.myVirtualDomain.com</Item>
+ <Item>localhost</Item>
+ <Item>127.0.0.1</Item>
+ </Array>
+ </Set>
+ -->
+
+ <!-- disable cookies
+ <Get name="sessionHandler">
+ <Get name="sessionManager">
+ <Set name="usingCookies" type="boolean">false</Set>
+ </Get>
+ </Get>
+ -->
+
+ <Get name="securityHandler">
+ <Set name="loginService">
+ <New class="org.eclipse.jetty.security.HashLoginService">
+ <Set name="name">Test Realm</Set>
+ <Set name="config"><Property name="this.web-inf.url"/>realm.properties</Set>
+ <!-- To enable reload of realm when properties change, uncomment the following lines -->
+ <!-- changing refreshInterval (in seconds) as desired -->
+ <!--
+ <Set name="refreshInterval">5</Set>
+ <Call name="start"></Call>
+ -->
+ </New>
+ </Set>
+ <Set name="checkWelcomeFiles">true</Set>
+ </Get>
+
+ <!-- Non standard error page mapping -->
+ <!--
+ <Get name="errorHandler">
+ <Call name="addErrorPage">
+ <Arg type="int">500</Arg>
+ <Arg type="int">599</Arg>
+ <Arg type="String">/dump/errorCodeRangeMapping</Arg>
+ </Call>
+ </Get>
+ -->
+
+ <!-- Add context specific logger
+ <Set name="handler">
+ <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
+ <Set name="requestLog">
+ <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
+ <Set name="filename"><Property name="jetty.logs" default="./logs"/>/test-yyyy_mm_dd.request.log</Set>
+ <Set name="filenameDateFormat">yyyy_MM_dd</Set>
+ <Set name="append">true</Set>
+ <Set name="LogTimeZone">GMT</Set>
+ </New>
+ </Set>
+ </New>
+ </Set>
+ -->
+
+</Configure>
diff --git a/test-jetty-webapp/src/main/assembly/web-bundle.xml b/test-jetty-webapp/src/main/assembly/web-bundle.xml
new file mode 100644
index 0000000000..b80faf973d
--- /dev/null
+++ b/test-jetty-webapp/src/main/assembly/web-bundle.xml
@@ -0,0 +1,35 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>webbundle</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <!-- baseDirectory>${basedir}/${project.build.directory}/${project.build.finalName}</baseDirectory -->
+ <fileSets>
+ <fileSet>
+ <directory>${basedir}/${project.build.directory}/${project.build.finalName}/</directory>
+ <outputDirectory></outputDirectory>
+ <includes>
+ <include>**/*.*</include>
+ </includes>
+ <excludes>
+ <exclude>WEB-INF/lib/**</exclude>
+ <exclude>WEB-INF/jetty-web.xml</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+ <files>
+ <file>
+ <source>src/main/assembly/embedded-jetty-web-for-webbundle.xml</source>
+ <outputDirectory>WEB-INF</outputDirectory>
+ <destName>jetty-web.xml</destName>
+ </file>
+ <file>
+ <source>src/main/config/etc/realm.properties</source>
+ <outputDirectory>WEB-INF</outputDirectory>
+ <destName>realm.properties</destName>
+ </file>
+ </files>
+</assembly>
diff --git a/test-jetty-webapp/src/main/config/contexts/demo.xml b/test-jetty-webapp/src/main/config/contexts-available/move-context.xml
index 5e1ed11be9..7821b3d903 100644
--- a/test-jetty-webapp/src/main/config/contexts/demo.xml
+++ b/test-jetty-webapp/src/main/config/contexts-available/move-context.xml
@@ -2,8 +2,8 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.server.handler.MovedContextHandler">
- <Set name="contextPath">/demo</Set>
- <Set name="newContextURL">/test</Set>
+ <Set name="contextPath">/oldContextPath</Set>
+ <Set name="newContextURL">/test/dump/newContextPath</Set>
<Set name="permanent">false</Set>
<Set name="discardPathInfo">false</Set>
<Set name="discardQuery">false</Set>
diff --git a/test-jetty-webapp/src/main/config/contexts/test.d/override-web.xml b/test-jetty-webapp/src/main/config/contexts/test.d/override-web.xml
index 432ba81344..9e42d6d5ef 100644
--- a/test-jetty-webapp/src/main/config/contexts/test.d/override-web.xml
+++ b/test-jetty-webapp/src/main/config/contexts/test.d/override-web.xml
@@ -15,6 +15,16 @@
<param-value>a context value</param-value>
</context-param>
+ <!-- Add or override filter init parameter -->
+ <filter>
+ <filter-name>TestFilter</filter-name>
+ <filter-class>com.acme.TestFilter</filter-class>
+ <init-param>
+ <param-name>remote</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </filter>
+
<!-- Add or override servlet init parameter -->
<servlet>
<servlet-name>Dump</servlet-name>
diff --git a/test-jetty-webapp/src/main/config/contexts/test.xml b/test-jetty-webapp/src/main/config/contexts/test.xml
index fb5f7d31c5..3c36173b13 100644
--- a/test-jetty-webapp/src/main/config/contexts/test.xml
+++ b/test-jetty-webapp/src/main/config/contexts/test.xml
@@ -75,4 +75,19 @@ detected.
</Get>
-->
+ <!-- Add context specific logger
+ <Set name="handler">
+ <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
+ <Set name="requestLog">
+ <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
+ <Set name="filename"><Property name="jetty.logs" default="./logs"/>/test-yyyy_mm_dd.request.log</Set>
+ <Set name="filenameDateFormat">yyyy_MM_dd</Set>
+ <Set name="append">true</Set>
+ <Set name="LogTimeZone">GMT</Set>
+ </New>
+ </Set>
+ </New>
+ </Set>
+ -->
+
</Configure>
diff --git a/test-jetty-webapp/src/main/config/etc/jetty-testrealm.xml b/test-jetty-webapp/src/main/config/etc/jetty-testrealm.xml
new file mode 100644
index 0000000000..5926b19c89
--- /dev/null
+++ b/test-jetty-webapp/src/main/config/etc/jetty-testrealm.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Configure Authentication Login Service -->
+ <!-- Realms may be configured for the entire server here, or -->
+ <!-- they can be configured for a specific web app in a context -->
+ <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
+ <!-- example). -->
+ <!-- =========================================================== -->
+ <Call name="addBean">
+ <Arg>
+ <New class="org.eclipse.jetty.security.HashLoginService">
+ <Set name="name">Test Realm</Set>
+ <Set name="config"><Property name="jetty.home" default="."/>/etc/realm.properties</Set>
+ <Set name="refreshInterval">0</Set>
+ </New>
+ </Arg>
+ </Call>
+
+</Configure>
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/realm.properties b/test-jetty-webapp/src/main/config/etc/realm.properties
index cbf905de9f..cbf905de9f 100644
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/realm.properties
+++ b/test-jetty-webapp/src/main/config/etc/realm.properties
diff --git a/test-jetty-webapp/src/main/java/com/acme/Counter.java b/test-jetty-webapp/src/main/java/com/acme/Counter.java
index 62b89abe42..d5546e5be9 100644
--- a/test-jetty-webapp/src/main/java/com/acme/Counter.java
+++ b/test-jetty-webapp/src/main/java/com/acme/Counter.java
@@ -1,20 +1,20 @@
-// ========================================================================
-// Copyright (c) 2004-2009 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.
-// ========================================================================
+//========================================================================
+//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
+//------------------------------------------------------------------------
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//http://www.apache.org/licenses/LICENSE-2.0
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+//========================================================================
package com.acme;
-
-public class Counter
+public class Counter implements java.io.Serializable
{
int counter=0;
String last;
diff --git a/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java b/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java
new file mode 100644
index 0000000000..de9c9f49b6
--- /dev/null
+++ b/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java
@@ -0,0 +1,49 @@
+//========================================================================
+//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
+//------------------------------------------------------------------------
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//http://www.apache.org/licenses/LICENSE-2.0
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+//========================================================================
+
+package com.acme;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+import javax.servlet.jsp.JspContext;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.JspFragment;
+import javax.servlet.jsp.tagext.SimpleTagSupport;
+
+public class Date2Tag extends SimpleTagSupport
+{
+ String format;
+
+ public void setFormat(String value) {
+ this.format = value;
+ }
+
+ public void doTag() throws JspException, IOException {
+ String formatted =
+ new SimpleDateFormat("long".equals(format)?"EEE 'the' d:MMM:yyyy":"d:MM:yy")
+ .format(new Date());
+ StringTokenizer tok = new StringTokenizer(formatted,":");
+ JspContext context = getJspContext();
+ context.setAttribute("day", tok.nextToken() );
+ context.setAttribute("month", tok.nextToken() );
+ context.setAttribute("year", tok.nextToken() );
+
+ JspFragment fragment = getJspBody();
+ fragment.invoke(null);
+ }
+}
+
diff --git a/test-jetty-webapp/src/main/java/com/acme/DateTag.java b/test-jetty-webapp/src/main/java/com/acme/DateTag.java
new file mode 100644
index 0000000000..a54c72dda7
--- /dev/null
+++ b/test-jetty-webapp/src/main/java/com/acme/DateTag.java
@@ -0,0 +1,66 @@
+//========================================================================
+//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
+//------------------------------------------------------------------------
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//http://www.apache.org/licenses/LICENSE-2.0
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+//========================================================================
+
+package com.acme;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.BodyContent;
+import javax.servlet.jsp.tagext.BodyTagSupport;
+import javax.servlet.jsp.tagext.Tag;
+
+public class DateTag extends BodyTagSupport
+{
+ Tag parent;
+ BodyContent body;
+ String tz="GMT";
+
+ public void setParent(Tag parent) {this.parent=parent;}
+ public Tag getParent() {return parent;}
+ public void setBodyContent(BodyContent content) {body=content;}
+ public void setPageContext(PageContext pageContext) {}
+
+ public void setTz(String value) {tz=value;}
+
+ public int doStartTag() throws JspException {return EVAL_BODY_TAG;}
+
+ public int doEndTag() throws JspException {return EVAL_PAGE;}
+
+ public void doInitBody() throws JspException {}
+
+ public int doAfterBody() throws JspException {
+ try
+ {
+ SimpleDateFormat format = new SimpleDateFormat(body.getString());
+ format.setTimeZone(TimeZone.getTimeZone(tz));
+ body.getEnclosingWriter().write(format.format(new Date()));
+ return SKIP_BODY;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ throw new JspTagException(ex.toString());
+ }
+ }
+
+ public void release()
+ {
+ body=null;
+ }
+}
+
diff --git a/test-jetty-webapp/src/main/java/com/acme/Dump.java b/test-jetty-webapp/src/main/java/com/acme/Dump.java
index 399d8cd6a6..86a04ffbd0 100644
--- a/test-jetty-webapp/src/main/java/com/acme/Dump.java
+++ b/test-jetty-webapp/src/main/java/com/acme/Dump.java
@@ -13,6 +13,7 @@
package com.acme;
import java.io.BufferedWriter;
+import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -20,10 +21,12 @@ import java.io.PrintWriter;
import java.io.Reader;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
@@ -551,7 +554,6 @@ public class Dump extends HttpServlet
pout.write("</pre></td>");
}
-
pout.write("</tr><tr>\n");
pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Request Attributes:</big></th>");
Enumeration a= request.getAttributeNames();
@@ -560,8 +562,16 @@ public class Dump extends HttpServlet
name= (String)a.nextElement();
pout.write("</tr><tr>\n");
pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
- pout.write("<td>"+"<pre>" + toString(request.getAttribute(name)) + "</pre>"+"</td>");
- }
+ Object value=request.getAttribute(name);
+ if (value instanceof File)
+ {
+ File file = (File)value;
+ pout.write("<td>"+"<pre>" + file.getName()+" ("+file.length()+" "+new Date(file.lastModified())+ ")</pre>"+"</td>");
+ }
+ else
+ pout.write("<td>"+"<pre>" + toString(request.getAttribute(name)) + "</pre>"+"</td>");
+ }
+ request.setAttribute("org.eclipse.jetty.servlet.MultiPartFilter.files",null);
pout.write("</tr><tr>\n");
@@ -597,13 +607,28 @@ public class Dump extends HttpServlet
pout.write("<td>"+"<pre>" + toString(getServletContext().getAttribute(name)) + "</pre>"+"</td>");
}
-
String res= request.getParameter("resource");
if (res != null && res.length() > 0)
{
pout.write("</tr><tr>\n");
pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Get Resource: \""+res+"\"</big></th>");
+
+ pout.write("</tr><tr>\n");
+ pout.write("<th align=\"right\">getServletContext().getContext(...):&nbsp;</th>");
+
+ ServletContext context = getServletContext().getContext(res);
+ pout.write("<td>"+context+"</td>");
+ if (context!=null)
+ {
+ String cp=context.getContextPath();
+ if (cp==null || "/".equals(cp))
+ cp="";
+ pout.write("</tr><tr>\n");
+ pout.write("<th align=\"right\">getServletContext().getContext(...),getRequestDispatcher(...):&nbsp;</th>");
+ pout.write("<td>"+getServletContext().getContext(res).getRequestDispatcher(res.substring(cp.length()))+"</td>");
+ }
+
pout.write("</tr><tr>\n");
pout.write("<th align=\"right\">this.getClass().getResource(...):&nbsp;</th>");
pout.write("<td>"+this.getClass().getResource(res)+"</td>");
diff --git a/test-jetty-webapp/src/main/java/com/acme/TestFilter.java b/test-jetty-webapp/src/main/java/com/acme/TestFilter.java
index 5c2c367360..0d43e8158e 100644
--- a/test-jetty-webapp/src/main/java/com/acme/TestFilter.java
+++ b/test-jetty-webapp/src/main/java/com/acme/TestFilter.java
@@ -14,6 +14,8 @@
package com.acme;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -25,15 +27,23 @@ import javax.servlet.ServletRequestWrapper;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
/** TestFilter.
*
- *
+ * This filter checks for a none local request, and if the init parameter
+ * "remote" is not set to true, then all non local requests are forwarded
+ * to /remote.html
+ *
*/
public class TestFilter implements Filter
{
+ private boolean _remote;
private ServletContext _context;
+ private final Set<String> _allowed = new HashSet<String>();
/* ------------------------------------------------------------ */
/*
@@ -42,6 +52,11 @@ public class TestFilter implements Filter
public void init(FilterConfig filterConfig) throws ServletException
{
_context= filterConfig.getServletContext();
+ _remote=Boolean.parseBoolean(filterConfig.getInitParameter("remote"));
+ _allowed.add("/favicon.ico");
+ _allowed.add("/jetty_banner.gif");
+
+ Log.debug("TestFilter#remote="+_remote);
}
/* ------------------------------------------------------------ */
@@ -51,6 +66,21 @@ public class TestFilter implements Filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
+ String from = request.getRemoteHost();
+ String to = request.getServerName();
+ String path=((HttpServletRequest)request).getServletPath();
+
+ if (!_remote && !_allowed.contains(path) && (
+ !from.equals("localhost") && !from.startsWith("127.") ||
+ !to.equals("localhost")&&!to.startsWith("127.0.0.")))
+ {
+ if ("/".equals(path))
+ _context.getRequestDispatcher("/remote.html").forward(request,response);
+ else
+ ((HttpServletResponse)response).sendRedirect("/remote.html");
+ return;
+ }
+
Integer old_value=null;
ServletRequest r = request;
while (r instanceof ServletRequestWrapper)
diff --git a/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java b/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java
index 4ba4b54204..3b1e3090f4 100644
--- a/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java
+++ b/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java
@@ -50,16 +50,21 @@ public class WebSocketChatServlet extends WebSocketServlet
public void onMessage(byte frame, String data)
{
- // Log.info(this+" onMessage: "+data);
- for (ChatWebSocket member : _members)
+ if (data.indexOf("disconnect")>=0)
+ _outbound.disconnect();
+ else
{
- try
+ // Log.info(this+" onMessage: "+data);
+ for (ChatWebSocket member : _members)
{
- member._outbound.sendMessage(frame,data);
- }
- catch(IOException e)
- {
- Log.warn(e);
+ try
+ {
+ member._outbound.sendMessage(frame,data);
+ }
+ catch(IOException e)
+ {
+ Log.warn(e);
+ }
}
}
}
diff --git a/test-jetty-webapp/src/main/webapp/META-INF/MANIFEST.MF b/test-jetty-webapp/src/main/webapp/META-INF/MANIFEST.MF
index 5e9495128c..cc61b1a652 100644
--- a/test-jetty-webapp/src/main/webapp/META-INF/MANIFEST.MF
+++ b/test-jetty-webapp/src/main/webapp/META-INF/MANIFEST.MF
@@ -1,3 +1,23 @@
Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: TestIt
+Bundle-SymbolicName: TestIt
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: testit.Activator
+Import-Package: javax.servlet,
+ javax.servlet.http,
+ javax.servlet.jsp,
+ javax.servlet.jsp.tagext
+Require-Bundle: org.eclipse.jetty.client,
+ org.eclipse.jetty.continuation,
+ org.eclipse.jetty.http,
+ org.eclipse.jetty.io,
+ org.eclipse.jetty.servlets,
+ org.eclipse.jetty.util,
+ org.eclipse.jetty.websocket
+Bundle-ClassPath: WEB-INF/classes
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Web-ContextPath: /
Class-Path:
diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib.tld b/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib.tld
new file mode 100644
index 0000000000..03adecef5e
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib.tld
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE taglib
+ PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
+ "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
+
+<taglib>
+
+ <tlib-version>1.0</tlib-version>
+ <jsp-version>1.2</jsp-version>
+ <short-name>acme</short-name>
+ <uri>http://www.acme.com/taglib</uri>
+ <description>taglib example</description>
+ <listener>
+ <listener-class>com.acme.TagListener</listener-class>
+ </listener>
+
+ <tag>
+ <name>date</name>
+ <tag-class>com.acme.DateTag</tag-class>
+ <body-content>TAGDEPENDENT</body-content>
+ <description>Display Date</description>
+ <attribute>
+ <name>tz</name>
+ <required>false</required>
+ </attribute>
+ </tag>
+
+</taglib>
diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib2.tld b/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib2.tld
new file mode 100644
index 0000000000..3edb7bb14f
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/WEB-INF/acme-taglib2.tld
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
+ version="2.0">
+ <description>Acme JSP2 tags</description>
+ <tlib-version>1.0</tlib-version>
+ <short-name>acme2</short-name>
+ <uri>http://www.acme.com/taglib2</uri>
+ <tag>
+ <description>Simple Date formatting</description>
+ <name>date2</name>
+ <tag-class>com.acme.Date2Tag</tag-class>
+ <body-content>scriptless</body-content>
+ <variable>
+ <description>Day of the Month</description>
+ <name-given>day</name-given>
+ </variable>
+ <variable>
+ <description>Month of the Year</description>
+ <name-given>month</name-given>
+ </variable>
+ <variable>
+ <description>Year</description>
+ <name-given>year</name-given>
+ </variable>
+ <attribute>
+ <name>format</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+ </tag>
+</taglib>
+
diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/tags/panel.tag b/test-jetty-webapp/src/main/webapp/WEB-INF/tags/panel.tag
new file mode 100644
index 0000000000..fa0540a61d
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/WEB-INF/tags/panel.tag
@@ -0,0 +1,17 @@
+<%--
+ - Copyright (c) 2002 The Apache Software Foundation. All rights
+ - reserved.
+--%>
+<%@ attribute name="color" %>
+<%@ attribute name="bgcolor" %>
+<%@ attribute name="title" %>
+<table border="1" bgcolor="${color}">
+ <tr>
+ <td><b>${title}</b></td>
+ </tr>
+ <tr>
+ <td bgcolor="${bgcolor}">
+ <jsp:doBody/>
+ </td>
+ </tr>
+</table>
diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
index c962d53c99..9cb725596a 100644
--- a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
+++ b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
@@ -9,7 +9,7 @@
<context-param>
<param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
- <param-value>org.eclipse.jetty.servlets.ProxyServlet.Logger,org.eclipse.jetty.servlets.ProxyServlet.ThreadPool,org.eclipse.jetty.servlets.ProxyServlet.HttpClient</param-value>
+ <param-value>QoSFilter,TransparentProxy.Logger,TransparentProxy.ThreadPool,TransparentProxy.HttpClient</param-value>
</context-param>
<!-- Declare TestListener, which declares TestFilter -->
@@ -18,19 +18,37 @@
</listener>
<filter>
+ <filter-name>TestFilter</filter-name>
+ <filter-class>com.acme.TestFilter</filter-class>
+ <init-param>
+ <param-name>remote</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </filter>
+ <filter-mapping>
+ <filter-name>TestFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+
+ <filter>
<filter-name>QoSFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.QoSFilter</filter-class>
<init-param>
<param-name>maxRequests</param-name>
<param-value>20</param-value>
</init-param>
- </filter>
-
+ <init-param>
+ <param-name>managedAttr</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
<filter-mapping>
<filter-name>QoSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+
<filter>
<filter-name>MultiPart</filter-name>
<filter-class>org.eclipse.jetty.servlets.MultiPartFilter</filter-class>
@@ -44,6 +62,7 @@
<url-pattern>/dump/*</url-pattern>
</filter-mapping>
+
<filter>
<filter-name>GzipFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.IncludableGzipFilter</filter-class>
@@ -216,17 +235,19 @@
<servlet-name>TransparentProxy</servlet-name>
<servlet-class>org.eclipse.jetty.servlets.ProxyServlet$Transparent</servlet-class>
<init-param>
- <param-name>Prefix</param-name><param-value>/google</param-value>
+ <param-name>Prefix</param-name><param-value>/javadoc</param-value>
+ </init-param>
+ <init-param>
+ <param-name>ProxyTo</param-name><param-value>http://download.eclipse.org/jetty/stable-7/apidocs</param-value>
</init-param>
<init-param>
- <param-name>ProxyTo</param-name><param-value>http://www.google.com</param-value>
+ <param-name>HostHeader</param-name><param-value>download.eclipse.org</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
-
<servlet-mapping>
<servlet-name>TransparentProxy</servlet-name>
- <url-pattern>/google/*</url-pattern>
+ <url-pattern>/javadoc/*</url-pattern>
</servlet-mapping>
<error-page>
@@ -284,12 +305,10 @@
</user-data-constraint>
</security-constraint>
-<!--
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Test Realm</realm-name>
</login-config>
--->
<!--
<login-config>
@@ -298,6 +317,7 @@
</login-config>
-->
+<!--
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Test Realm</realm-name>
@@ -306,6 +326,7 @@
<form-error-page>/logonError.html?param=test</form-error-page>
</form-login-config>
</login-config>
+-->
<session-config>
<session-timeout>5</session-timeout>
diff --git a/test-jetty-webapp/src/main/webapp/index.html b/test-jetty-webapp/src/main/webapp/index.html
index bf44fdd476..f96f625d95 100644
--- a/test-jetty-webapp/src/main/webapp/index.html
+++ b/test-jetty-webapp/src/main/webapp/index.html
@@ -10,8 +10,8 @@
<p>
This is the Test webapp for the Jetty 8 HTTP Server and Servlet Container.
For more information about Jetty, please visit our
-<a href="http://jetty.eclipse.org">website</a>
-or <a href="http://docs.codehaus.org/display/JETTY/Jetty+Wiki">wiki</a>.
+<a href="http://www.eclipse.org/jetty">website</a>
+or <a href="http://wiki.eclipse.org/Jetty">wiki</a>.
Commercial support for Jetty is available via <a href="http://www.webtide.com">webtide</a>.
</p>
<p>
@@ -28,7 +28,8 @@ This is a test context that serves:
<li>Dump: <a href="dump/info">Request</a>, <a href="session/">Session</a>, <a href="cookie/">Cookie</a></li>
<li><a href="dispatch">Dispatcher Servlet</a></li>
<li><a href="rewrite/">Request Rewrite Servlet</a></li>
-<li><a href="google/">Transparent Proxy</a> (to www.google.com)</li>
+<li><a href="jsp/">JSP examples</a></li>
+<li><a href="javadoc/">Transparent Proxy</a> (to javadoc @ eclipse.org)</li>
<li>Comet Chat: <a href="chat/">Long Polling</a>, <a href="ws">WebSocket</a></li>
<li><a href="auth.html">Authentication</a></li>
</ul>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/bean1.jsp b/test-jetty-webapp/src/main/webapp/jsp/bean1.jsp
new file mode 100644
index 0000000000..0c15da2ca4
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/bean1.jsp
@@ -0,0 +1,15 @@
+<html>
+<%@ page session="true"%>
+<body>
+<jsp:useBean id='counter' scope='session' class='com.acme.Counter' type="com.acme.Counter" />
+
+<h1>JSP1.2 Beans: 1</h1>
+
+Counter accessed <jsp:getProperty name="counter" property="count"/> times.<br/>
+Counter last accessed by <jsp:getProperty name="counter" property="last"/><br/>
+<jsp:setProperty name="counter" property="last" value="<%= request.getRequestURI()%>"/>
+
+<a href="bean2.jsp">Goto bean2.jsp</a>
+
+</body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/bean2.jsp b/test-jetty-webapp/src/main/webapp/jsp/bean2.jsp
new file mode 100644
index 0000000000..624dc2e59d
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/bean2.jsp
@@ -0,0 +1,15 @@
+<html>
+<%@ page session="true"%>
+<body>
+<jsp:useBean id='counter' scope='session' class='com.acme.Counter' type="com.acme.Counter" />
+
+<h1>JSP1.2 Beans: 2</h1>
+
+Counter accessed <jsp:getProperty name="counter" property="count"/> times.<br/>
+Counter last accessed by <jsp:getProperty name="counter" property="last"/><br/>
+<jsp:setProperty name="counter" property="last" value="<%= request.getRequestURI()%>"/>
+
+<a href="bean1.jsp">Goto bean1.jsp</a>
+
+</body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/dump.jsp b/test-jetty-webapp/src/main/webapp/jsp/dump.jsp
new file mode 100644
index 0000000000..fb73b0b000
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/dump.jsp
@@ -0,0 +1,23 @@
+<html><head>
+<%@ page import="java.util.Enumeration" %>
+</head><body>
+<h1>JSP Dump</h1>
+
+<table border="1">
+<tr><th>Request URI:</th><td><%= request.getRequestURI() %></td></tr>
+<tr><th>ServletPath:</th><td><%= request.getServletPath() %></td></tr>
+<tr><th>PathInfo:</th><td><%= request.getPathInfo() %></td></tr>
+
+<%
+ Enumeration e =request.getParameterNames();
+ while(e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+%>
+<tr>
+ <th>getParameter("<%= name %>")</th>
+ <td><%= request.getParameter(name) %></td></tr>
+<% } %>
+
+</table>
+</body></html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/expr.jsp b/test-jetty-webapp/src/main/webapp/jsp/expr.jsp
new file mode 100644
index 0000000000..e0b25e2020
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/expr.jsp
@@ -0,0 +1,23 @@
+<html>
+<h1>JSP2.0 Expressions</h1>
+
+<table border="1">
+ <tr><th>Expression</th><th>Result</th></tr>
+ <tr>
+ <td>\${param["A"]}</td>
+ <td>${param["A"]}&nbsp;</td>
+ </tr><tr>
+ <td>\${header["host"]}</td>
+ <td>${header["host"]}</td>
+ </tr><tr>
+ <td>\${header["user-agent"]}</td>
+ <td>${header["user-agent"]}</td>
+ </tr><tr>
+ <td>\${1+1}</td>
+ <td>${1+1}</td>
+ </tr><tr>
+ <td>\${param["A"] * 2}</td>
+ <td>${param["A"] * 2}&nbsp;</td>
+ </tr>
+</table>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/index.html b/test-jetty-webapp/src/main/webapp/jsp/index.html
new file mode 100644
index 0000000000..935f85bc7a
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/index.html
@@ -0,0 +1,18 @@
+<html>
+<body>
+
+<h1>JSP Examples</h1>
+
+<ul>
+<li><a href="dump.jsp">JSP 1.2 embedded java</a><br/>
+<li><a href="bean1.jsp">JSP 1.2 Bean demo</a><br/>
+<li><a href="tag.jsp">JSP 1.2 BodyTag demo</a><br/>
+<li><a href="tag2.jsp">JSP 2.0 SimpleTag demo</a><br/>
+<li><a href="tagfile.jsp">JSP 2.0 Tag File demo</a><br/>
+<li><a href="expr.jsp?A=1">JSP 2.0 Tag Expression</a><br/>
+</ul>
+<a href="/">Main Menu</a>
+
+
+</body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/tag.jsp b/test-jetty-webapp/src/main/webapp/jsp/tag.jsp
new file mode 100644
index 0000000000..069d8c67b1
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/tag.jsp
@@ -0,0 +1,16 @@
+<html>
+<body>
+
+<%@ taglib uri="http://www.acme.com/taglib" prefix="acme" %>
+
+<small>&lt;acme:date tz="GMT"&gt;EEE, dd/MMM/yyyy HH:mm:ss ZZZ&lt;/acme:date&gt;
+==&gt;</small>
+<acme:date tz="GMT">EEE, dd/MMM/yyyy HH:mm:ss ZZZ</acme:date>
+<br/>
+<small>&lt;acme:date tz="EST"&gt;EEE, dd-MMM-yyyy HH:mm:ss ZZZ&lt;/acme:date&gt;
+==&gt;</small>
+<acme:date tz="EST">EEE, dd-MMM-yyyy HH:mm:ss ZZZ</acme:date>
+<br/>
+
+</body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/tag2.jsp b/test-jetty-webapp/src/main/webapp/jsp/tag2.jsp
new file mode 100644
index 0000000000..8071927562
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/tag2.jsp
@@ -0,0 +1,19 @@
+<html>
+<body>
+
+<%@ taglib uri="http://www.acme.com/taglib2" prefix="acme" %>
+
+<acme:date2 format="long">
+ On ${day} of ${month} in the year ${year}
+</acme:date2>
+
+<br/>
+
+<acme:date2 format="short">
+ ${day} - ${month} - ${year}
+</acme:date2>
+
+<br/>
+
+</body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/jsp/tagfile.jsp b/test-jetty-webapp/src/main/webapp/jsp/tagfile.jsp
new file mode 100644
index 0000000000..67299f0229
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/jsp/tagfile.jsp
@@ -0,0 +1,37 @@
+<%@ taglib prefix="acme" tagdir="/WEB-INF/tags" %>
+<html>
+ <head>
+ </head>
+ <body>
+ <h1>JSP 2.0 Tag File Example</h1>
+ <hr>
+ <p>Panel tag created from JSP fragment file in WEB-INF/tags
+ <hr>
+ <table border="0">
+ <tr valign="top">
+ <td>
+ <acme:panel color="#ff8080" bgcolor="#ffc0c0" title="Panel 1">
+ First panel.<br/>
+ </acme:panel>
+ </td>
+ <td>
+ <acme:panel color="#80ff80" bgcolor="#c0ffc0" title="Panel 2">
+ Second panel.<br/>
+ Second panel.<br/>
+ Second panel.<br/>
+ Second panel.<br/>
+ </acme:panel>
+ </td>
+ <td>
+ <acme:panel color="#8080ff" bgcolor="#c0c0ff" title="Panel 3">
+ Third panel.<br/>
+ <acme:panel color="#ff80ff" bgcolor="#ffc0ff" title="Inner">
+ A panel in a panel.
+ </acme:panel>
+ Third panel.<br/>
+ </acme:panel>
+ </td>
+ </tr>
+ </table>
+ </body>
+</html>
diff --git a/test-jetty-webapp/src/main/webapp/remote.html b/test-jetty-webapp/src/main/webapp/remote.html
new file mode 100644
index 0000000000..f979afc369
--- /dev/null
+++ b/test-jetty-webapp/src/main/webapp/remote.html
@@ -0,0 +1,33 @@
+<HTML>
+ <HEAD>
+ <TITLE>Powered By Jetty</TITLE>
+ <META http-equiv="Pragma" content="no-cache">
+ <META http-equiv="Cache-Control" content="no-cache,no-store">
+ </HEAD>
+<BODY>
+<A HREF="http://jetty.eclipse.org"><IMG SRC="jetty_banner.gif"></A>
+<h1>Welcome to Jetty 7 - REMOTE ACCESS!!</h1>
+<p>
+This is the Test webapp for the Jetty 7 HTTP Server and Servlet Container.
+For more information about Jetty, please visit our
+<a href="http://jetty.eclipse.org">website</a>
+or <a href="http://docs.codehaus.org/display/JETTY/Jetty+Wiki">wiki</a>.
+Commercial support for Jetty is available via <a href="http://www.webtide.com">webtide</a>.
+</p>
+<p>
+This is a test context that serves several demo filters and servlets. However, these
+test servlets are not safe for deployment on the internet as (by design) they contain
+cross domain scripting vulnerabilities and reveal private information. This page
+is displayed because you have access the context from a non local IP address.
+</p>
+<p>
+You can disable the remote address checking by editing contexts/test.d/override-web.xml and changing the
+"remote" init parameter to true for the TestFilter.
+</p>
+<p>
+This webapp is deployed in $JETTY_HOME/webapp/test and configured by $JETTY_HOME/contexts/test.xml
+and $JETTY_HOME/contexts/test.d/override-web.xml
+</p>
+
+</BODY>
+</HTML>
diff --git a/test-jetty-webapp/src/main/webapp/ws/index.html b/test-jetty-webapp/src/main/webapp/ws/index.html
index 9e801eebe0..a88db337ab 100644
--- a/test-jetty-webapp/src/main/webapp/ws/index.html
+++ b/test-jetty-webapp/src/main/webapp/ws/index.html
@@ -14,7 +14,7 @@
var room = {
join: function(name) {
this._username=name;
- var location = document.location.toString().replace('http:','ws:');
+ var location = document.location.toString().replace('http://','ws://').replace('https://','wss://');
this._ws=new WebSocket(location);
this._ws.onopen=this._onopen;
this._ws.onmessage=this._onmessage;
diff --git a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
index eeb1a0b379..952752173b 100644
--- a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
+++ b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty;
+import java.io.File;
import java.lang.management.ManagementFactory;
import org.eclipse.jetty.jmx.MBeanContainer;
@@ -28,6 +29,7 @@ import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.StdErrLog;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -35,8 +37,10 @@ public class TestServer
{
public static void main(String[] args) throws Exception
{
- String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution");
- System.setProperty("jetty.home",jetty_home);
+ Log.getLog().setDebugEnabled(true);
+ ((StdErrLog)Log.getLog()).setSource(false);
+
+ String jetty_root = "..";
Server server = new Server();
server.setSendDateHeader(true);
@@ -63,10 +67,10 @@ public class TestServer
SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector();
ssl_connector.setPort(8443);
- ssl_connector.setKeystore(jetty_home + "/etc/keystore");
+ ssl_connector.setKeystore(jetty_root + "/jetty-server/src/main/config/etc/keystore");
ssl_connector.setPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
ssl_connector.setKeyPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
- ssl_connector.setTruststore(jetty_home + "/etc/keystore");
+ ssl_connector.setTruststore(jetty_root + "/jetty-server/src/main/config/etc/keystore");
ssl_connector.setTrustPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
server.addConnector(ssl_connector);
@@ -82,24 +86,24 @@ public class TestServer
HashLoginService login = new HashLoginService();
login.setName("Test Realm");
- login.setConfig(jetty_home + "/etc/realm.properties");
+ login.setConfig(jetty_root + "/test-jetty-webapp/src/main/config/etc/realm.properties");
server.addBean(login);
- NCSARequestLog requestLog = new NCSARequestLog(jetty_home + "/logs/jetty-yyyy_mm_dd.log");
+ File log=File.createTempFile("jetty-yyyy_mm_dd", "log");
+ NCSARequestLog requestLog = new NCSARequestLog(log.toString());
requestLog.setExtended(false);
requestLogHandler.setRequestLog(requestLog);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
-
WebAppContext webapp = new WebAppContext();
webapp.setParentLoaderPriority(true);
webapp.setResourceBase("./src/main/webapp");
+ webapp.setAttribute("testAttribute","testValue");
contexts.addHandler(webapp);
-
server.start();
server.join();
}
diff --git a/tests/pom.xml b/tests/pom.xml
index b476b4f47f..1fb4d64c6b 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -28,10 +28,29 @@
<name>Jetty Tests :: Parent</name>
<packaging>pom</packaging>
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <!-- No Point running Findbugs on testing projects -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <!-- DO NOT DEPLOY (or Release) -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
<modules>
<module>test-integration</module>
<module>test-webapps</module>
<module>test-sessions</module>
+ <module>test-loginservice</module>
</modules>
</project>
diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml
index 97b18517cb..06b584d6ee 100644
--- a/tests/test-integration/pom.xml
+++ b/tests/test-integration/pom.xml
@@ -75,7 +75,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.6</version>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/AbstractJettyTestCase.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/AbstractJettyTestCase.java
deleted file mode 100644
index 900aa7cf54..0000000000
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/AbstractJettyTestCase.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// ========================================================================
-// Copyright (c) Webtide LLC
-// ------------------------------------------------------------------------
-// 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.apache.org/licenses/LICENSE-2.0.txt
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-
-package org.eclipse.jetty.test;
-
-import java.io.File;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Server;
-
-public abstract class AbstractJettyTestCase extends TestCase
-{
- public static final boolean IS_ON_WINDOWS = System.getProperty("os.name").startsWith("Windows");
- private File baseDir;
-
- public File getBaseDir()
- {
- if (baseDir == null)
- {
- String baseDirPath = System.getProperty("basedir");
- if (baseDirPath == null)
- {
- baseDirPath = System.getProperty("user.dir",".");
- }
- baseDir = new File(baseDirPath);
- }
-
- return baseDir;
- }
-
- public File getTargetDir()
- {
- File path = new File(getBaseDir(),"target");
- assertDirExists("target dir",path);
- return path;
- }
-
- public File getTestResourcesDir()
- {
- File path = new File(getBaseDir(),"src/test/resources");
- assertDirExists("test resources dir",path);
- return path;
- }
-
- public File getDocRootBase()
- {
- File path = new File(getTestResourcesDir(),"docroots");
- assertDirExists("docroot base dir",path);
- return path;
- }
-
- public void assertDirExists(String msg, File path)
- {
- assertNotNull(msg + " should not be null",path);
- assertTrue(msg + " should exist",path.exists());
- assertTrue(msg + " should be a directory",path.isDirectory());
- }
-
- /**
- * Return the port that the server is listening on.
- *
- * Assumes 1 connector, and that server is started already.
- *
- * @param server
- * the server port.
- * @return the port that the server is listening on.
- */
- public int findServerPort(Server server)
- {
- Connector connectors[] = server.getConnectors();
- for (int i = 0; i < connectors.length; i++)
- {
- Connector connector = connectors[i];
- if (connector.getLocalPort() > 0)
- {
- return connector.getLocalPort();
- }
- }
-
- throw new AssertionFailedError("No valid connector port found.");
- }
-}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java
index 0906e7835f..402f7521ba 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java
@@ -31,41 +31,42 @@ import org.eclipse.jetty.test.support.rawhttp.HttpResponseTester;
import org.eclipse.jetty.test.support.rawhttp.HttpSocketImpl;
import org.eclipse.jetty.test.support.rawhttp.HttpTesting;
import org.eclipse.jetty.util.IO;
-import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
/**
* Tests against the facilities within the TestSuite to ensure that the various
* org.eclipse.jetty.test.support.* classes do what they are supposed to.
*/
-public class DefaultHandlerTest extends AbstractJettyTestCase
+public class DefaultHandlerTest
{
- private boolean debug = true;
- private TestableJettyServer server;
+ private boolean debug = false;
+ private static TestableJettyServer server;
private int serverPort;
- @Override
- @Before
- public void setUp() throws Exception
+ @BeforeClass
+ public static void setUpServer() throws Exception
{
- super.setUp();
-
server = new TestableJettyServer();
server.setScheme(HttpSchemes.HTTP);
server.addConfiguration("DefaultHandler.xml");
server.load();
server.start();
+ }
+
+ @Before
+ public void testInit() {
serverPort = server.getServerPort();
}
- @Override
- @After
- public void tearDown() throws Exception
+ @AfterClass
+ public static void tearDownServer() throws Exception
{
server.stop();
- super.tearDown();
}
@Test
@@ -80,7 +81,7 @@ public class DefaultHandlerTest extends AbstractJettyTestCase
String response = IO.toString(in);
String expected = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
- assertEquals("Response",expected,response);
+ Assert.assertEquals("Response",expected,response);
}
@Test
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java
index 12c6c490b6..60a1569333 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java
@@ -5,13 +5,12 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.security.MessageDigest;
+import java.util.Collections;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import junit.framework.TestCase;
-
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.security.Realm;
@@ -34,9 +33,12 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
-
-public class DigestPostTest extends TestCase
+public class DigestPostTest
{
private static final String NC = "00000001";
@@ -52,10 +54,10 @@ public class DigestPostTest extends TestCase
"The quick brown fox jumped over the lazy dog.\n";
public volatile static String _received = null;
- private Server _server;
+ private static Server _server;
- @Override
- public void setUp()
+ @BeforeClass
+ public static void setUpServer()
{
try
{
@@ -81,7 +83,7 @@ public class DigestPostTest extends TestCase
mapping.setConstraint(constraint);
mapping.setPathSpec("/*");
- security.setConstraintMappings(new ConstraintMapping[]{mapping});
+ security.setConstraintMappings(Collections.singletonList(mapping));
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[]
@@ -96,16 +98,13 @@ public class DigestPostTest extends TestCase
}
}
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception
+ @AfterClass
+ public static void tearDownServer() throws Exception
{
_server.stop();
}
+ @Test
public void testServerDirectlyHTTP10() throws Exception
{
Socket socket = new Socket("127.0.0.1",_server.getConnectors()[0].getLocalPort());
@@ -122,8 +121,8 @@ public class DigestPostTest extends TestCase
String result = IO.toString(socket.getInputStream());
- assertTrue(result.startsWith("HTTP/1.1 401 Unauthorized"));
- assertEquals(null,_received);
+ Assert.assertTrue(result.startsWith("HTTP/1.1 401 Unauthorized"));
+ Assert.assertEquals(null,_received);
int n=result.indexOf("nonce=");
String nonce=result.substring(n+7,result.indexOf('"',n+7));
@@ -149,10 +148,11 @@ public class DigestPostTest extends TestCase
result = IO.toString(socket.getInputStream());
- assertTrue(result.startsWith("HTTP/1.1 200 OK"));
- assertEquals(__message,_received);
+ Assert.assertTrue(result.startsWith("HTTP/1.1 200 OK"));
+ Assert.assertEquals(__message,_received);
}
+ @Test
public void testServerDirectlyHTTP11() throws Exception
{
Socket socket = new Socket("127.0.0.1",_server.getConnectors()[0].getLocalPort());
@@ -173,8 +173,8 @@ public class DigestPostTest extends TestCase
int len=socket.getInputStream().read(buf);
String result=new String(buf,0,len,"UTF-8");
- assertTrue(result.startsWith("HTTP/1.1 401 Unauthorized"));
- assertEquals(null,_received);
+ Assert.assertTrue(result.startsWith("HTTP/1.1 401 Unauthorized"));
+ Assert.assertEquals(null,_received);
int n=result.indexOf("nonce=");
String nonce=result.substring(n+7,result.indexOf('"',n+7));
@@ -197,10 +197,11 @@ public class DigestPostTest extends TestCase
result = IO.toString(socket.getInputStream());
- assertTrue(result.startsWith("HTTP/1.1 200 OK"));
- assertEquals(__message,_received);
+ Assert.assertTrue(result.startsWith("HTTP/1.1 200 OK"));
+ Assert.assertEquals(__message,_received);
}
+ @Test
public void testServerWithHttpClientStringContent() throws Exception
{
HttpClient client = new HttpClient();
@@ -219,11 +220,11 @@ public class DigestPostTest extends TestCase
client.send(ex);
ex.waitForDone();
- assertEquals(__message,_received);
- assertEquals(200,ex.getResponseStatus());
+ Assert.assertEquals(__message,_received);
+ Assert.assertEquals(200,ex.getResponseStatus());
}
-
+ @Test
public void testServerWithHttpClientStreamContent() throws Exception
{
HttpClient client = new HttpClient();
@@ -243,9 +244,8 @@ public class DigestPostTest extends TestCase
ex.waitForDone();
String sent = IO.toString(new FileInputStream("src/test/resources/message.txt"));
- assertEquals(sent,_received);
-
- assertEquals(200,ex.getResponseStatus());
+ Assert.assertEquals(sent,_received);
+ Assert.assertEquals(200,ex.getResponseStatus());
}
public static class TestRealm implements Realm
@@ -268,6 +268,7 @@ public class DigestPostTest extends TestCase
public static class PostServlet extends HttpServlet
{
+ private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/MavenTestingUtils.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/MavenTestingUtils.java
new file mode 100644
index 0000000000..3c36256025
--- /dev/null
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/MavenTestingUtils.java
@@ -0,0 +1,220 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// 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.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.jetty.util.IO;
+
+/**
+ * Common utility methods for working with JUnit tests cases in a maven friendly way.
+ */
+public class MavenTestingUtils
+{
+ private static File basedir;
+ private static File testResourcesDir;
+ private static File targetDir;
+
+ // private static Boolean surefireRunning;
+
+ public static File getBasedir()
+ {
+ if (basedir == null)
+ {
+ String cwd = System.getProperty("basedir");
+
+ if (cwd == null)
+ {
+ cwd = System.getProperty("user.dir");
+ }
+
+ basedir = new File(cwd);
+ }
+
+ return basedir;
+ }
+
+ /**
+ * Get the directory to the /target directory for this project.
+ *
+ * @return the directory path to the target directory.
+ */
+ public static File getTargetDir()
+ {
+ if (targetDir == null)
+ {
+ targetDir = new File(getBasedir(),"target");
+ PathAssert.assertDirExists("Target Dir",targetDir);
+ }
+ return targetDir;
+ }
+
+ /**
+ * Create a {@link File} object for a path in the /target directory.
+ *
+ * @param path
+ * the path desired, no validation of existence is performed.
+ * @return the File to the path.
+ */
+ public static File getTargetFile(String path)
+ {
+ return new File(getTargetDir(),path.replace("/",File.separator));
+ }
+
+ public static File getTargetTestingDir()
+ {
+ File dir = new File(getTargetDir(),"testing");
+ if (!dir.exists())
+ {
+ dir.mkdirs();
+ }
+ return dir;
+ }
+
+ /**
+ * Get a dir in /target/ that uses the JUnit 3.x {@link TestCase#getName()} to make itself unique.
+ *
+ * @param test
+ * the junit 3.x testcase to base this new directory on.
+ * @return the dir in /target/ that uses the JUnit 3.x {@link TestCase#getName()} to make itself unique.
+ */
+ public static File getTargetTestingDir(TestCase test)
+ {
+ return getTargetTestingDir(test.getName());
+ }
+
+ /**
+ * Get a dir in /target/ that uses the an arbitrary name.
+ *
+ * @param testname
+ * the testname to create directory against.
+ * @return the dir in /target/ that uses the an arbitrary name.
+ */
+ public static File getTargetTestingDir(String testname)
+ {
+ File dir = new File(getTargetDir(),"test-" + testname);
+ return dir;
+ }
+
+ /**
+ * Get a dir from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a dir)
+ * @return the dir in src/test/resource
+ */
+ public static File getTestResourceDir(String name)
+ {
+ File dir = new File(getTestResourcesDir(),name);
+ PathAssert.assertDirExists("Test Resource Dir",dir);
+ return dir;
+ }
+
+ /**
+ * Get a file from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a file)
+ * @return the file in src/test/resource
+ */
+ public static File getTestResourceFile(String name)
+ {
+ File file = new File(getTestResourcesDir(),name);
+ PathAssert.assertFileExists("Test Resource File",file);
+ return file;
+ }
+
+ /**
+ * Get a path resource (File or Dir) from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist)
+ * @return the path in src/test/resource
+ */
+ public static File getTestResourcePath(String name)
+ {
+ File path = new File(getTestResourcesDir(),name);
+ PathAssert.assertExists("Test Resource Path",path);
+ return path;
+ }
+
+ /**
+ * Get the directory to the src/test/resource directory
+ *
+ * @return the directory {@link File} to the src/test/resources directory
+ */
+ public static File getTestResourcesDir()
+ {
+ if (testResourcesDir == null)
+ {
+ testResourcesDir = new File(basedir,"src/test/resources".replace("/",File.separator));
+ PathAssert.assertDirExists("Test Resources Dir",testResourcesDir);
+ }
+ return testResourcesDir;
+ }
+
+ /**
+ * Read the contents of a file into a String and return it.
+ *
+ * @param file
+ * the file to read.
+ * @return the contents of the file.
+ * @throws IOException
+ * if unable to read the file.
+ */
+ public static String readToString(File file) throws IOException
+ {
+ FileReader reader = null;
+ try
+ {
+ reader = new FileReader(file);
+ return IO.toString(reader);
+ }
+ finally
+ {
+ IO.close(reader);
+ }
+ }
+
+ public static String getTestID()
+ {
+ StackTraceElement stacked[] = new Throwable().getStackTrace();
+
+ String name = null;
+
+ for (StackTraceElement stack : stacked)
+ {
+ if (stack.getClassName().endsWith("Test"))
+ {
+ name = stack.getClassName();
+ if (stack.getMethodName().startsWith("test"))
+ {
+ return stack.getClassName() + "#" + stack.getMethodName();
+ }
+ }
+ }
+
+ if (name == null)
+ {
+ return "Unidentified_Test";
+ }
+ return name;
+ }
+}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/PathAssert.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/PathAssert.java
new file mode 100644
index 0000000000..4eb6c6539e
--- /dev/null
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/PathAssert.java
@@ -0,0 +1,40 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// 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.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.test;
+
+import java.io.File;
+
+import org.junit.Assert;
+
+public class PathAssert
+{
+ public static void assertDirExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a Dir : " + path.getAbsolutePath(),path.isDirectory());
+ }
+
+ public static void assertFileExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a File : " + path.getAbsolutePath(),path.isFile());
+ }
+
+ public static void assertExists(String msg, File path)
+ {
+ Assert.assertTrue(msg + " path should exist: " + path.getAbsolutePath(),path.exists());
+ }
+}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpTest.java
index ad59455b50..9ca740b056 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpTest.java
@@ -16,20 +16,19 @@
package org.eclipse.jetty.test.rfcs;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.test.support.TestableJettyServer;
import org.eclipse.jetty.test.support.rawhttp.HttpSocket;
import org.eclipse.jetty.test.support.rawhttp.HttpSocketImpl;
+import org.junit.BeforeClass;
/**
* Perform the RFC2616 tests against a server running with the Jetty BIO Connector and listening on standard HTTP.
*/
public class RFC2616BIOHttpTest extends RFC2616BaseTest
{
- @Override
- public TestableJettyServer getJettyServer() throws IOException
+ @BeforeClass
+ public static void setupServer() throws Exception
{
TestableJettyServer server = new TestableJettyServer();
server.setScheme(HttpSchemes.HTTP);
@@ -37,7 +36,7 @@ public class RFC2616BIOHttpTest extends RFC2616BaseTest
server.addConfiguration("RFC2616_Redirects.xml");
server.addConfiguration("RFC2616_Filters.xml");
server.addConfiguration("BIOHttp.xml");
- return server;
+ setUpServer(server);
}
@Override
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpsTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpsTest.java
index 7faa84b358..dc2f814806 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpsTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BIOHttpsTest.java
@@ -16,20 +16,20 @@
package org.eclipse.jetty.test.rfcs;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.test.support.TestableJettyServer;
import org.eclipse.jetty.test.support.rawhttp.HttpSocket;
import org.eclipse.jetty.test.support.rawhttp.HttpsSocketImpl;
+import org.junit.BeforeClass;
/**
- * Perform the RFC2616 tests against a server running with the Jetty BIO Connector and listening on HTTPS (HTTP over SSL).
+ * Perform the RFC2616 tests against a server running with the Jetty BIO Connector and listening on HTTPS (HTTP over
+ * SSL).
*/
public class RFC2616BIOHttpsTest extends RFC2616BaseTest
{
- @Override
- public TestableJettyServer getJettyServer() throws IOException
+ @BeforeClass
+ public static void setupServer() throws Exception
{
TestableJettyServer server = new TestableJettyServer();
server.setScheme(HttpSchemes.HTTPS);
@@ -37,7 +37,7 @@ public class RFC2616BIOHttpsTest extends RFC2616BaseTest
server.addConfiguration("RFC2616_Redirects.xml");
server.addConfiguration("RFC2616_Filters.xml");
server.addConfiguration("BIOHttps.xml");
- return server;
+ setUpServer(server);
}
@Override
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java
index 984191c175..026b1a4bfd 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java
@@ -31,29 +31,30 @@ import java.util.TimeZone;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.test.AbstractJettyTestCase;
+import org.eclipse.jetty.test.MavenTestingUtils;
import org.eclipse.jetty.test.StringAssert;
import org.eclipse.jetty.test.support.StringUtil;
import org.eclipse.jetty.test.support.TestableJettyServer;
import org.eclipse.jetty.test.support.rawhttp.HttpResponseTester;
import org.eclipse.jetty.test.support.rawhttp.HttpSocket;
import org.eclipse.jetty.test.support.rawhttp.HttpTesting;
-import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a> (HTTP/1.1) Test Case
*/
-public abstract class RFC2616BaseTest extends AbstractJettyTestCase
+public abstract class RFC2616BaseTest
{
private static final String ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
/** STRICT RFC TESTS */
private static final boolean STRICT = false;
+ private static TestableJettyServer server;
private List<HttpResponseTester> responses;
private HttpResponseTester response;
private HttpTesting http;
- private TestableJettyServer server;
class TestFile
{
@@ -78,13 +79,12 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
}
}
- @Override
- @Before
- public void setUp() throws Exception
+ public static void setUpServer(TestableJettyServer testableserver) throws Exception
{
- super.setUp();
-
- File testWorkDir = new File(getTargetDir(),"work" + File.separator + getClass().getSimpleName() + File.separator + getName());
+ File targetDir = MavenTestingUtils.getTargetDir();
+ String testId = MavenTestingUtils.getTestID();
+
+ File testWorkDir = new File(targetDir,"work" + File.separator + testId);
if (!testWorkDir.exists())
{
testWorkDir.mkdirs();
@@ -92,22 +92,23 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
System.setProperty("java.io.tmpdir",testWorkDir.getAbsolutePath());
- server = getJettyServer();
+ server = testableserver;
server.load();
server.start();
+ }
+
+ @Before
+ public void setUp() throws Exception
+ {
http = new HttpTesting(getHttpClientSocket(),server.getServerPort());
}
- @Override
- @After
- public void tearDown() throws Exception
+ @AfterClass
+ public static void tearDownServer() throws Exception
{
server.stop();
- super.tearDown();
}
- public abstract TestableJettyServer getJettyServer() throws IOException;
-
public abstract HttpSocket getHttpClientSocket() throws Exception;
/**
@@ -145,7 +146,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
// Test formatting
fields.putDateField("Date",expected.getTime().getTime());
- assertEquals("3.3.1 RFC 822 preferred","Sun, 06 Nov 1994 08:49:37 GMT",fields.getStringField("Date"));
+ Assert.assertEquals("3.3.1 RFC 822 preferred","Sun, 06 Nov 1994 08:49:37 GMT",fields.getStringField("Date"));
}
/**
@@ -170,7 +171,16 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
response = http.request(req1);
response.assertStatus("3.6 Transfer Coding / Bad 400",HttpStatus.BAD_REQUEST_400);
-
+ }
+
+ /**
+ * Test Transfer Codings
+ *
+ * @see <a href="http://tools.ietf.org/html/rfc2616#section-3.6">RFC 2616 (section 3.6)</a>
+ */
+ @Test
+ public void test3_6_2() throws Throwable
+ {
// Chunked
StringBuffer req2 = new StringBuffer();
req2.append("GET /echo/R1 HTTP/1.1\n");
@@ -201,7 +211,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("\n");
responses = http.requests(req2);
- assertEquals("Response Count",3,responses.size());
+ Assert.assertEquals("Response Count",3,responses.size());
response = responses.get(0); // Response 1
response.assertStatusOK("3.6.1 Transfer Codings / Response 1 Code");
@@ -214,9 +224,17 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
response = responses.get(2); // Response 3
response.assertStatusOK("3.6.1 Transfer Codings / Response 3 Code");
response.assertNoBody("3.6.1 Transfer Codings / No Body");
+ }
+ /**
+ * Test Transfer Codings
+ *
+ * @see <a href="http://tools.ietf.org/html/rfc2616#section-3.6">RFC 2616 (section 3.6)</a>
+ */
+ @Test
+ public void test3_6_3() throws Throwable
+ {
// Chunked
-
StringBuffer req3 = new StringBuffer();
req3.append("POST /echo/R1 HTTP/1.1\n");
req3.append("Host: localhost\n");
@@ -246,7 +264,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req3.append("\n");
responses = http.requests(req3);
- assertEquals("Response Count",3,responses.size());
+ Assert.assertEquals("Response Count",3,responses.size());
response = responses.get(0); // Response 1
response.assertStatusOK("3.6.1 Transfer Codings / Response 1 Code");
@@ -260,8 +278,17 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
response.assertStatusOK("3.6.1 Transfer Codings / Response 3 Code");
response.assertNoBody("3.6.1 Transfer Codings / No Body");
- // Chunked and keep alive
+ }
+ /**
+ * Test Transfer Codings
+ *
+ * @see <a href="http://tools.ietf.org/html/rfc2616#section-3.6">RFC 2616 (section 3.6)</a>
+ */
+ @Test
+ public void test3_6_4() throws Throwable
+ {
+ // Chunked and keep alive
StringBuffer req4 = new StringBuffer();
req4.append("GET /echo/R1 HTTP/1.1\n");
req4.append("Host: localhost\n");
@@ -281,7 +308,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req4.append("\n");
responses = http.requests(req4);
- assertEquals("Response Count",2,responses.size());
+ Assert.assertEquals("Response Count",2,responses.size());
response = responses.get(0); // Response 1
response.assertStatusOK("3.6.1 Transfer Codings / Response 1 Code");
@@ -305,12 +332,12 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
fields.put("Q","bbb;q=0.5,aaa,ccc;q=0.002,d;q=0,e;q=0.0001,ddd;q=0.001,aa2,abb;q=0.7");
Enumeration<String> qualities = fields.getValues("Q",", \t");
List<?> list = HttpFields.qualityList(qualities);
- assertEquals("Quality parameters","aaa",HttpFields.valueParameters(list.get(0).toString(),null));
- assertEquals("Quality parameters","aa2",HttpFields.valueParameters(list.get(1).toString(),null));
- assertEquals("Quality parameters","abb",HttpFields.valueParameters(list.get(2).toString(),null));
- assertEquals("Quality parameters","bbb",HttpFields.valueParameters(list.get(3).toString(),null));
- assertEquals("Quality parameters","ccc",HttpFields.valueParameters(list.get(4).toString(),null));
- assertEquals("Quality parameters","ddd",HttpFields.valueParameters(list.get(5).toString(),null));
+ Assert.assertEquals("Quality parameters","aaa",HttpFields.valueParameters(list.get(0).toString(),null));
+ Assert.assertEquals("Quality parameters","aa2",HttpFields.valueParameters(list.get(1).toString(),null));
+ Assert.assertEquals("Quality parameters","abb",HttpFields.valueParameters(list.get(2).toString(),null));
+ Assert.assertEquals("Quality parameters","bbb",HttpFields.valueParameters(list.get(3).toString(),null));
+ Assert.assertEquals("Quality parameters","ccc",HttpFields.valueParameters(list.get(4).toString(),null));
+ Assert.assertEquals("Quality parameters","ddd",HttpFields.valueParameters(list.get(5).toString(),null));
}
/**
@@ -340,7 +367,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req1.append("\n");
responses = http.requests(req1);
- assertEquals("Response Count",2,responses.size());
+ Assert.assertEquals("Response Count",2,responses.size());
response = responses.get(0);
response.assertStatusOK("4.4.2 Message Length / Response Code");
@@ -377,7 +404,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("7890AB");
responses = http.requests(req2);
- assertEquals("Response Count",2,responses.size());
+ Assert.assertEquals("Response Count",2,responses.size());
response = responses.get(0); // response 1
response.assertStatusOK("4.4.3 Ignore Content-Length / Response Code");
@@ -630,7 +657,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("\n");
responses = http.requests(req2);
- assertEquals("Response Count",2,responses.size()); // Should not have a R3 response.
+ Assert.assertEquals("Response Count",2,responses.size()); // Should not have a R3 response.
response = responses.get(0); // response 1
response.assertStatusOK("8.1 Persistent Connections");
@@ -660,7 +687,8 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("Expect: unknown\n"); // Invalid Expect header.
req2.append("Content-Type: text/plain\n");
req2.append("Content-Length: 8\n");
- req2.append("\n"); // No body
+ req2.append("\n");
+ req2.append("12345678\n");
response = http.request(req2);
@@ -838,7 +866,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
responses = http.requests(req2);
- assertEquals("Response Count",2,responses.size()); // Should have 2 responses
+ Assert.assertEquals("Response Count",2,responses.size()); // Should have 2 responses
response = responses.get(0); // Only interested in first response
response.assertHeaderExists("9.2 OPTIONS","Allow");
@@ -975,7 +1003,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("Range: bytes=1-3\n"); // request first 3 bytes
req2.append("\n");
- http.enableDebug();
response = http.request(req2);
response.assertStatus("10.2.7 Partial Content",HttpStatus.PARTIAL_CONTENT_206);
@@ -1070,7 +1097,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req2.append("\n");
responses = http.requests(req2);
- assertEquals("Response Count",2,responses.size());
+ Assert.assertEquals("Response Count",2,responses.size());
response = responses.get(0);
String specId = "10.3 Redirection HTTP/1.1 - basic (response 1)";
@@ -1259,7 +1286,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req1.append("\n");
http.setTimeoutMillis(60000);
- http.enableDebug();
response = http.request(req1);
String msg = "Partial Range (Mixed): 'bytes=a-b,5-8'";
@@ -1448,7 +1474,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req1.append("Connection: close\n");
req1.append("\n");
- http.enableDebug();
response = http.request(req1);
String msg = "Partial (Byte) Range: '" + rangedef + "'";
@@ -1522,16 +1547,16 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
if (parts[i].trim().startsWith("boundary="))
{
String boundparts[] = StringUtil.split(parts[i],'=');
- assertEquals(msg + " Boundary parts.length",2,boundparts.length);
+ Assert.assertEquals(msg + " Boundary parts.length",2,boundparts.length);
boundary = boundparts[1];
}
}
- assertNotNull(msg + " Should have found boundary in Content-Type header",boundary);
+ Assert.assertNotNull(msg + " Should have found boundary in Content-Type header",boundary);
// Find boundary offsets within body
List<HttpResponseTester> multiparts = response.findBodyMultiparts(boundary);
- assertEquals(msg + " multiparts in body (count)",2,multiparts.size());
+ Assert.assertEquals(msg + " multiparts in body (count)",2,multiparts.size());
// Validate multipart #1
HttpResponseTester multipart1 = multiparts.get(0);
@@ -1566,7 +1591,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req1.append("Connection: close\n");
req1.append("\n");
- http.enableDebug();
response = http.request(req1);
String msg = "Partial (Byte) Range: '" + rangedef + "'";
@@ -1584,16 +1608,16 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
if (parts[i].trim().startsWith("boundary="))
{
String boundparts[] = StringUtil.split(parts[i],'=');
- assertEquals(msg + " Boundary parts.length",2,boundparts.length);
+ Assert.assertEquals(msg + " Boundary parts.length",2,boundparts.length);
boundary = boundparts[1];
}
}
- assertNotNull(msg + " Should have found boundary in Content-Type header",boundary);
+ Assert.assertNotNull(msg + " Should have found boundary in Content-Type header",boundary);
// Find boundary offsets within body
List<HttpResponseTester> multiparts = response.findBodyMultiparts(boundary);
- assertEquals(msg + " multiparts in body (count)",3,multiparts.size());
+ Assert.assertEquals(msg + " multiparts in body (count)",3,multiparts.size());
// Validate multipart #1
HttpResponseTester multipart1 = multiparts.get(0);
@@ -1688,7 +1712,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req1.append("Connection: close\n");
req1.append("\n");
- http.enableDebug();
response = http.request(req1);
specId = "14.39 TE Header";
response.assertStatusOK(specId);
@@ -1767,7 +1790,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
responses = http.requests(req2);
// Since R2 closes the connection, should only get 2 responses (R1 &
// R2), not (R3)
- assertEquals("Response Count",2,responses.size());
+ Assert.assertEquals("Response Count",2,responses.size());
response = responses.get(0); // response 1
specId = "19.6.2 Compatibility with previous HTTP - Keep-alive";
@@ -1808,7 +1831,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
req3.append("Connection: close\n");
req3.append("\n");
responses = http.requests(req3);
- assertEquals("Response Count",3,responses.size());
+ Assert.assertEquals("Response Count",3,responses.size());
specId = "19.6.2 Compatibility with HTTP/1.0- Keep-alive";
response = responses.get(0);
@@ -1834,6 +1857,6 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase
String actual = sdf.format(new Date(actualTime));
String expected = sdf.format(expectedTime.getTime());
- assertEquals(msg,expected,actual);
+ Assert.assertEquals(msg,expected,actual);
}
}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java
index 4fbfcaf95c..9e254a4420 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java
@@ -16,20 +16,19 @@
package org.eclipse.jetty.test.rfcs;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.test.support.TestableJettyServer;
import org.eclipse.jetty.test.support.rawhttp.HttpSocket;
import org.eclipse.jetty.test.support.rawhttp.HttpSocketImpl;
+import org.junit.BeforeClass;
/**
* Perform the RFC2616 tests against a server running with the Jetty NIO Connector and listening on standard HTTP.
*/
public class RFC2616NIOHttpTest extends RFC2616BaseTest
{
- @Override
- public TestableJettyServer getJettyServer() throws IOException
+ @BeforeClass
+ public static void setupServer() throws Exception
{
TestableJettyServer server = new TestableJettyServer();
server.setScheme(HttpSchemes.HTTP);
@@ -37,7 +36,7 @@ public class RFC2616NIOHttpTest extends RFC2616BaseTest
server.addConfiguration("RFC2616_Redirects.xml");
server.addConfiguration("RFC2616_Filters.xml");
server.addConfiguration("NIOHttp.xml");
- return server;
+ setUpServer(server);
}
@Override
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java
index 0d9accfd61..88e3262d9f 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java
@@ -16,20 +16,19 @@
package org.eclipse.jetty.test.rfcs;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.test.support.TestableJettyServer;
import org.eclipse.jetty.test.support.rawhttp.HttpSocket;
import org.eclipse.jetty.test.support.rawhttp.HttpsSocketImpl;
+import org.junit.BeforeClass;
/**
* Perform the RFC2616 tests against a server running with the Jetty NIO Connector and listening on HTTPS (HTTP over SSL).
*/
public class RFC2616NIOHttpsTest extends RFC2616BaseTest
{
- @Override
- public TestableJettyServer getJettyServer() throws IOException
+ @BeforeClass
+ public static void setupServer() throws Exception
{
TestableJettyServer server = new TestableJettyServer();
server.setScheme(HttpSchemes.HTTPS);
@@ -37,7 +36,7 @@ public class RFC2616NIOHttpsTest extends RFC2616BaseTest
server.addConfiguration("RFC2616_Redirects.xml");
server.addConfiguration("RFC2616_Filters.xml");
server.addConfiguration("NIOHttps.xml");
- return server;
+ setUpServer(server);
}
@Override
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java
index bc520d15d7..3d845bec6d 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java
@@ -118,7 +118,7 @@ public class StringUtil
*
* @param str
* input string.
- * @return
+ * @return the same string, with any LF or CR returned as system default.
*/
public static String toSystemLN(String str)
{
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
index deb66de87b..b4b377e61d 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
@@ -90,7 +90,7 @@ public class TestableJettyServer
public void addConfiguration(File xmlConfigFile) throws MalformedURLException
{
- xmlConfigurations.add(xmlConfigFile.toURL());
+ xmlConfigurations.add(xmlConfigFile.toURI().toURL());
}
public void addConfiguration(String testConfigName) throws MalformedURLException
@@ -103,6 +103,7 @@ public class TestableJettyServer
properties.setProperty(key,value);
}
+ @SuppressWarnings("unchecked")
public void load() throws Exception
{
XmlConfiguration last = null;
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTester.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTester.java
index 4361533bb1..34293bf70f 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTester.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTester.java
@@ -173,7 +173,7 @@ public class HttpRequestTester
/**
* @param cookie
- * @see org.eclipse.jetty.http.HttpFields#addSetCookie(javax.servlet.http.Cookie)
+ * @see org.eclipse.jetty.http.HttpFields#addSetCookie(org.eclipse.jetty.http.HttpCookie)
*/
public void addSetCookie(Cookie cookie)
{
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java
index 308bf429be..602d247da4 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java
@@ -18,10 +18,12 @@ package org.eclipse.jetty.test.support.rawhttp;
import java.io.IOException;
-import org.eclipse.jetty.test.AbstractJettyTestCase;
+import org.junit.Assert;
+import org.junit.Test;
-public class HttpRequestTesterTest extends AbstractJettyTestCase
+public class HttpRequestTesterTest
{
+ @Test
public void testBasicHttp10Request() throws IOException
{
HttpRequestTester request = new HttpRequestTester();
@@ -37,9 +39,10 @@ public class HttpRequestTesterTest extends AbstractJettyTestCase
expectedRequest.append("Host: fakehost\r\n");
expectedRequest.append("\r\n");
- assertEquals("Basic Request",expectedRequest.toString(),rawRequest);
+ Assert.assertEquals("Basic Request",expectedRequest.toString(),rawRequest);
}
+ @Test
public void testBasicHttp11Request() throws IOException
{
HttpRequestTester request = new HttpRequestTester();
@@ -59,6 +62,6 @@ public class HttpRequestTesterTest extends AbstractJettyTestCase
expectedRequest.append("0\r\n");
expectedRequest.append("\r\n");
- assertEquals("Basic Request",expectedRequest.toString(),rawRequest);
+ Assert.assertEquals("Basic Request",expectedRequest.toString(),rawRequest);
}
}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTester.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTester.java
index 07deaf0028..3eaa47039f 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTester.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTester.java
@@ -226,7 +226,7 @@ public class HttpResponseTester
/**
* @param name
- * @return
+ * @return the header value as a date
* @see org.eclipse.jetty.http.HttpFields#getDateField(java.lang.String)
*/
public long getDateHeader(String name)
@@ -236,7 +236,7 @@ public class HttpResponseTester
/**
* @param name
- * @return
+ * @return the header value as a long
* @throws NumberFormatException
* @see org.eclipse.jetty.http.HttpFields#getLongField(java.lang.String)
*/
@@ -247,7 +247,7 @@ public class HttpResponseTester
/**
* @param name
- * @return
+ * @return the header value
* @see org.eclipse.jetty.http.HttpFields#getStringField(java.lang.String)
*/
public String getHeader(String name)
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java
index be22a94b73..5330a3dfff 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java
@@ -23,10 +23,10 @@ import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.List;
-import org.eclipse.jetty.test.AbstractJettyTestCase;
+import org.junit.Assert;
import org.junit.Test;
-public class HttpResponseTesterTest extends AbstractJettyTestCase
+public class HttpResponseTesterTest
{
@Test
public void testHttp11Response() throws IOException
@@ -46,17 +46,17 @@ public class HttpResponseTesterTest extends AbstractJettyTestCase
HttpResponseTester response = new HttpResponseTester();
response.parse(rawResponse);
- assertEquals("Response.version","HTTP/1.1",response.getVersion());
- assertEquals("Response.status",200,response.getStatus());
- assertEquals("Response.reason","OK",response.getReason());
+ Assert.assertEquals("Response.version","HTTP/1.1",response.getVersion());
+ Assert.assertEquals("Response.status",200,response.getStatus());
+ Assert.assertEquals("Response.reason","OK",response.getReason());
- assertEquals("Response[Content-Type]","text/plain",response.getContentType());
- assertEquals("Response[Content-Length]",28,response.getLongHeader("Content-Length"));
- assertEquals("Response[Connection]","close",response.getHeader("Connection"));
+ Assert.assertEquals("Response[Content-Type]","text/plain",response.getContentType());
+ Assert.assertEquals("Response[Content-Length]",28,response.getLongHeader("Content-Length"));
+ Assert.assertEquals("Response[Connection]","close",response.getHeader("Connection"));
String expected = "ABCDEFGHIJKLMNOPQRSTTUVWXYZ\n";
- assertEquals("Response.content",expected,response.getContent().toString());
+ Assert.assertEquals("Response.content",expected,response.getContent().toString());
}
@Test
@@ -93,8 +93,8 @@ public class HttpResponseTesterTest extends AbstractJettyTestCase
rawResponse.append("\n");
List<HttpResponseTester> responses = HttpResponseTester.parseMulti(rawResponse);
- assertNotNull("Responses should not be null",responses);
- assertEquals("Responses.size",3,responses.size());
+ Assert.assertNotNull("Responses should not be null",responses);
+ Assert.assertEquals("Responses.size",3,responses.size());
HttpResponseTester resp1 = responses.get(0);
resp1.assertStatusOK();
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java
index 27d58e426b..312d9369cc 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java
@@ -144,7 +144,7 @@ public class HttpTesting
* Read the raw response from the socket.
*
* @param sock
- * @return
+ * @return all of the the data from the socket as a String
* @throws IOException
*/
public String readRaw(Socket sock) throws IOException
@@ -157,10 +157,12 @@ public class HttpTesting
}
/**
- * Read the raw response from the socket, reading whatever is available. Any SocketTimeoutException is consumed and just stops the reading.
+ * Read the raw response from the socket, reading whatever is available.
+ * Any {@link SocketTimeoutException} is consumed and just stops the reading.
*
* @param sock
- * @return
+ * @return the raw data from the socket in string form, reading whatever is available.
+ * a {@link SocketTimeoutException} will result in the read stopping.
* @throws IOException
*/
public String readRawAvailable(Socket sock) throws IOException
@@ -190,7 +192,7 @@ public class HttpTesting
*
* Note: not for HTTPS requests.
*
- * @param request
+ * @param rawRequest
* the request
* @return the response
* @throws IOException
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java
index 7ddba4ec20..a2552a402e 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java
@@ -61,6 +61,7 @@ public class HttpsSocketImpl implements HttpSocket
}
} };
+ @SuppressWarnings("unused")
HostnameVerifier hostnameVerifier = new HostnameVerifier()
{
public boolean verify(String urlHostName, SSLSession session)
diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml
new file mode 100644
index 0000000000..e995f9db4d
--- /dev/null
+++ b/tests/test-loginservice/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// ========================================================================
+// Copyright (c) Webtide LLC
+//
+// 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.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.jetty.tests</groupId>
+ <artifactId>tests-parent</artifactId>
+ <version>8.0.0.M1</version>
+ </parent>
+ <artifactId>test-loginservice</artifactId>
+ <name>Jetty Tests :: Login Service</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.4.1.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derbytools</artifactId>
+ <version>10.4.1.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tests/test-loginservice/src/test/java/org/eclipse/jetty/JdbcLoginServiceTest.java b/tests/test-loginservice/src/test/java/org/eclipse/jetty/JdbcLoginServiceTest.java
new file mode 100644
index 0000000000..6eb658dd57
--- /dev/null
+++ b/tests/test-loginservice/src/test/java/org/eclipse/jetty/JdbcLoginServiceTest.java
@@ -0,0 +1,453 @@
+// ========================================================================
+// Copyright (c) 2010 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.derby.tools.ij;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.security.Realm;
+import org.eclipse.jetty.client.security.SimpleRealmResolver;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.security.Constraint;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.JDBCLoginService;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.security.authentication.BasicAuthenticator;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Loader;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JdbcLoginServiceTest
+{
+ private static String _content =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
+ "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
+ "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
+ "Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
+ "at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
+ "velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
+ "Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
+ "eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
+ "sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
+ "consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
+ "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
+ "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
+
+ private static File _docRoot;
+ private static Server _server;
+ private static HttpClient _client;
+ private static Realm _realm;
+ private static String _protocol;
+ private static String _baseUrl;
+ private static String _requestContent;
+
+ protected static boolean createDB(String homeDir, String fileName, String dbUrl)
+ {
+ FileInputStream fileStream = null;
+ try
+ {
+ File scriptFile = new File(fileName);
+ fileStream = new FileInputStream(scriptFile);
+
+ Loader.loadClass(fileStream.getClass(), "org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+ Connection connection = DriverManager.getConnection(dbUrl, "", "");
+
+ OutputStream out = new ByteArrayOutputStream();
+ int result = ij.runScript(connection, fileStream, "UTF-8", out, "UTF-8");
+
+ return (result==0);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ finally {
+ if (fileStream!=null)
+ {
+ try
+ {
+ fileStream.close();
+ }
+ catch (IOException e) {}
+ }
+ }
+ }
+
+ protected static void configureServer(Server server)
+ throws Exception
+ {
+ setProtocol("http");
+ setRealm(new Realm()
+ {
+ public String getId()
+ {
+ return "JdbcRealm";
+ }
+
+ public String getPrincipal()
+ {
+ return "jetty";
+ }
+
+ public String getCredentials()
+ {
+ return "jetty";
+ }
+ });
+
+ SelectChannelConnector connector = new SelectChannelConnector();
+ server.addConnector(connector);
+
+ LoginService loginService = new JDBCLoginService("JdbcRealm", "./src/test/resources/jdbcrealm.properties");
+ server.addBean(loginService);
+
+ ConstraintSecurityHandler security = new ConstraintSecurityHandler();
+ server.setHandler(security);
+
+ Constraint constraint = new Constraint();
+ constraint.setName("auth");
+ constraint.setAuthenticate( true );
+ constraint.setRoles(new String[]{"user", "admin"});
+
+ ConstraintMapping mapping = new ConstraintMapping();
+ mapping.setPathSpec( "/*" );
+ mapping.setConstraint( constraint );
+
+ Set<String> knownRoles = new HashSet<String>();
+ knownRoles.add("user");
+ knownRoles.add("admin");
+
+ security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
+ security.setAuthenticator(new BasicAuthenticator());
+ security.setLoginService(loginService);
+ security.setStrict(false);
+
+ ServletContextHandler root = new ServletContextHandler();
+ root.setContextPath("/");
+ root.setResourceBase(getBasePath());
+ ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
+ servletHolder.setInitParameter( "gzip", "true" );
+ root.addServlet( servletHolder, "/*" );
+
+ Handler handler = new TestHandler(getBasePath());
+
+ HandlerCollection handlers = new HandlerCollection();
+ handlers.setHandlers(new Handler[]{handler, root});
+ security.setHandler(handlers);
+ }
+
+ @BeforeClass
+ public static void setUp()
+ throws Exception
+ {
+ _docRoot = new File("target/test-output/docroot/");
+ _docRoot.mkdirs();
+ _docRoot.deleteOnExit();
+
+ File content = new File(_docRoot,"input.txt");
+ FileOutputStream out = new FileOutputStream(content);
+ out.write(_content.getBytes("utf-8"));
+ out.close();
+
+ File dbRoot = new File("target/test-output/derby");
+ String dbPath = dbRoot.getAbsolutePath();
+ System.setProperty("derby.system.home", dbPath);
+ if (!dbRoot.exists())
+ {
+ dbRoot.mkdirs();
+ createDB(dbPath, "src/test/resources/createdb.sql", "jdbc:derby:jdbcrealm;create=true");
+ }
+
+ _server = new Server();
+ configureServer(_server);
+ _server.start();
+
+ int port = _server.getConnectors()[0].getLocalPort();
+ _baseUrl = _protocol+"://localhost:"+port+ "/";
+ }
+
+ @AfterClass
+ public static void tearDown()
+ throws Exception
+ {
+ if (_server != null)
+ {
+ _server.stop();
+ _server = null;
+ }
+ }
+
+ @Test
+ public void testPut() throws Exception
+ {
+ startClient(_realm);
+
+ ContentExchange putExchange = new ContentExchange();
+ putExchange.setURL(getBaseUrl() + "output.txt");
+ putExchange.setMethod(HttpMethods.PUT);
+ putExchange.setRequestContent(new ByteArrayBuffer(_content.getBytes()));
+
+ _client.send(putExchange);
+ int state = putExchange.waitForDone();
+
+ int responseStatus = putExchange.getResponseStatus();
+
+ stopClient();
+
+ boolean statusOk = (responseStatus == 200 || responseStatus == 201);
+ assertTrue(statusOk);
+
+ String content = IO.toString(new FileInputStream(new File(_docRoot,"output.txt")));
+ assertEquals(_content,content);
+ }
+
+ @Test
+ public void testGet() throws Exception
+ {
+ startClient(_realm);
+
+ ContentExchange getExchange = new ContentExchange();
+ getExchange.setURL(getBaseUrl() + "input.txt");
+ getExchange.setMethod(HttpMethods.GET);
+
+ _client.send(getExchange);
+ int state = getExchange.waitForDone();
+
+ String content = "";
+ int responseStatus = getExchange.getResponseStatus();
+ if (responseStatus == HttpStatus.OK_200)
+ {
+ content = getExchange.getResponseContent();
+ }
+
+ stopClient();
+
+ assertEquals(HttpStatus.OK_200,responseStatus);
+ assertEquals(_content,content);
+ }
+
+ @Test
+ public void testHead() throws Exception
+ {
+ startClient(_realm);
+
+ ContentExchange getExchange = new ContentExchange();
+ getExchange.setURL(getBaseUrl() + "input.txt");
+ getExchange.setMethod(HttpMethods.HEAD);
+
+ _client.send(getExchange);
+ int state = getExchange.waitForDone();
+
+ int responseStatus = getExchange.getResponseStatus();
+
+ stopClient();
+
+ assertEquals(HttpStatus.OK_200,responseStatus);
+ }
+
+ @Test
+ public void testPost() throws Exception
+ {
+ startClient(_realm);
+
+ ContentExchange postExchange = new ContentExchange();
+ postExchange.setURL(getBaseUrl() + "test");
+ postExchange.setMethod(HttpMethods.POST);
+ postExchange.setRequestContent(new ByteArrayBuffer(_content.getBytes()));
+
+ _client.send(postExchange);
+ int state = postExchange.waitForDone();
+
+ int responseStatus = postExchange.getResponseStatus();
+
+ stopClient();
+
+ assertEquals(HttpStatus.OK_200,responseStatus);
+ assertEquals(_content,_requestContent);
+ }
+
+ protected void startClient(Realm realm)
+ throws Exception
+ {
+ _client = new HttpClient();
+ _client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+ if (realm != null)
+ _client.setRealmResolver(new SimpleRealmResolver(realm));
+ _client.start();
+ }
+
+ protected void stopClient()
+ throws Exception
+ {
+ if (_client != null)
+ {
+ _client.stop();
+ _client = null;
+ }
+ }
+
+ protected static String getBasePath()
+ {
+ return _docRoot.getAbsolutePath();
+ }
+
+ protected String getBaseUrl()
+ {
+ return _baseUrl;
+ }
+
+ protected HttpClient getClient()
+ {
+ return _client;
+ }
+
+ protected Realm getRealm()
+ {
+ return _realm;
+ }
+
+ protected String getContent()
+ {
+ return _content;
+ }
+
+ protected static void setProtocol(String protocol)
+ {
+ _protocol = protocol;
+ }
+
+ protected static void setRealm(Realm realm)
+ {
+ _realm = realm;
+ }
+
+ public static void copyStream(InputStream in, OutputStream out)
+ {
+ try
+ {
+ byte[] buffer=new byte[1024];
+ int len;
+ while ((len=in.read(buffer))>=0)
+ {
+ out.write(buffer,0,len);
+ }
+ }
+ catch (EofException e)
+ {
+ System.err.println(e);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ protected static class TestHandler extends AbstractHandler {
+ private final String resourcePath;
+
+ public TestHandler(String repositoryPath) {
+ this.resourcePath = repositoryPath;
+ }
+
+ public void handle(String target, Request baseRequest,
+ HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ if (baseRequest.isHandled())
+ {
+ return;
+ }
+
+ OutputStream out = null;
+
+ if (baseRequest.getMethod().equals("PUT"))
+ {
+ baseRequest.setHandled(true);
+
+ File file = new File(resourcePath, URLDecoder.decode(request.getPathInfo()));
+ file.getParentFile().mkdirs();
+ file.deleteOnExit();
+
+ out = new FileOutputStream(file);
+
+ response.setStatus(HttpServletResponse.SC_CREATED);
+ }
+
+ if (baseRequest.getMethod().equals("POST"))
+ {
+ baseRequest.setHandled(true);
+ out = new ByteArrayOutputStream();
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+
+ if (out != null)
+ {
+ ServletInputStream in = request.getInputStream();
+ try
+ {
+ copyStream( in, out );
+ }
+ finally
+ {
+ in.close();
+ out.close();
+ }
+
+ if (!(out instanceof FileOutputStream))
+ _requestContent = out.toString();
+ }
+
+ }
+ }
+}
diff --git a/tests/test-loginservice/src/test/resources/createdb.sql b/tests/test-loginservice/src/test/resources/createdb.sql
new file mode 100644
index 0000000000..3953b668a4
--- /dev/null
+++ b/tests/test-loginservice/src/test/resources/createdb.sql
@@ -0,0 +1,40 @@
+CREATE TABLE roles
+(
+ id INT NOT NULL PRIMARY KEY,
+ role VARCHAR(100) NOT NULL UNIQUE
+);
+
+CREATE TABLE users
+(
+ id INT NOT NULL PRIMARY KEY,
+ username VARCHAR(100) NOT NULL UNIQUE,
+ pwd VARCHAR(50) NOT NULL
+);
+
+CREATE TABLE user_roles
+(
+ user_id INT NOT NULL,
+ role_id INT NOT NULL,
+ UNIQUE(user_id, role_id)
+);
+
+INSERT INTO roles VALUES
+(0,'user'),
+(1,'admin');
+
+INSERT INTO users VALUES
+(1,'jetty','MD5:164c88b302622e17050af52c89945d44'),
+(2,'admin','CRYPT:adpexzg3FUZAk'),
+(3,'other','OBF:1xmk1w261u9r1w1c1xmq'),
+(4,'plain','plain'),
+(5,'user','password'),
+(6,'digest','MD5:6e120743ad67abfbc385bc2bb754e297');
+
+INSERT INTO user_roles VALUES
+(1,1),
+(2,1),
+(2,2),
+(3,1),
+(4,1),
+(5,1),
+(6,1); \ No newline at end of file
diff --git a/tests/test-loginservice/src/test/resources/jdbcrealm.properties b/tests/test-loginservice/src/test/resources/jdbcrealm.properties
new file mode 100644
index 0000000000..bb79638ed6
--- /dev/null
+++ b/tests/test-loginservice/src/test/resources/jdbcrealm.properties
@@ -0,0 +1,15 @@
+jdbcdriver = org.apache.derby.jdbc.EmbeddedDriver
+url = jdbc:derby:jdbcrealm
+username =
+password =
+usertable = users
+usertablekey = id
+usertableuserfield = username
+usertablepasswordfield = pwd
+roletable = roles
+roletablekey = id
+roletablerolefield = role
+userroletable = user_roles
+userroletableuserkey = user_id
+userroletablerolekey = role_id
+cachetime = 300 \ No newline at end of file
diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml
index 7613428682..72178b47fb 100644
--- a/tests/test-sessions/test-hash-sessions/pom.xml
+++ b/tests/test-sessions/test-hash-sessions/pom.xml
@@ -34,13 +34,6 @@
<target>1.5</target>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <groups>hash-all</groups>
- </configuration>
- </plugin>
</plugins>
</build>
<dependencies>
@@ -65,10 +58,9 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>5.8</version>
- <classifier>jdk15</classifier>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
index f5da28ceed..5069ae462d 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
@@ -13,10 +13,7 @@
package org.eclipse.jetty.server.session;
-
-import org.testng.annotations.Test;
-
-
+import org.junit.Test;
public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
{
@@ -25,7 +22,7 @@ public class ClientCrossContextSessionTest extends AbstractClientCrossContextSes
return new HashTestServer(port);
}
- @Test(groups={"hash-all"})
+ @Test
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/LightLoadTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/LightLoadTest.java
index 5de13caaf2..839e266f42 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/LightLoadTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/LightLoadTest.java
@@ -12,13 +12,11 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
+
/**
* LightLoadTest
- *
- *
*/
-
public class LightLoadTest extends AbstractLightLoadTest
{
@@ -27,7 +25,7 @@ public class LightLoadTest extends AbstractLightLoadTest
return new HashTestServer(port);
}
- @Test(groups={"hash-all"})
+ @Test
public void testLightLoad() throws Exception
{
super.testLightLoad();
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
index d06df8ee8c..3d58bc72f2 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
@@ -12,14 +12,11 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* NewSessionTest
- *
- *
*/
-
public class NewSessionTest extends AbstractNewSessionTest
{
@@ -28,10 +25,9 @@ public class NewSessionTest extends AbstractNewSessionTest
return new HashTestServer(port,max,scavenge);
}
- @Test(groups={"hash-all"})
+ @Test
public void testNewSession() throws Exception
{
super.testNewSession();
}
-
}
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
index dd6312b8c8..5be9208c1e 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
@@ -12,25 +12,21 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* OrphanedSessionTest
- *
- *
*/
public class OrphanedSessionTest extends AbstractOrphanedSessionTest
{
-
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new HashTestServer(port,max,scavenge);
}
- @Test(groups={"hash-all"})
+ @Test
public void testOrphanedSession() throws Exception
{
super.testOrphanedSession();
}
-
}
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
index ef29ba1764..35a9c2bb27 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
@@ -12,12 +12,10 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* ReentrantRequestSessionTest
- *
- *
*/
public class ReentrantRequestSessionTest extends AbstractReentrantRequestSessionTest
{
@@ -26,7 +24,7 @@ public class ReentrantRequestSessionTest extends AbstractReentrantRequestSession
return new HashTestServer(port);
}
- @Test(groups={"hash-all"})
+ @Test
public void testReentrantRequestSession() throws Exception
{
super.testReentrantRequestSession();
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
index 15a6a93bc2..c95f8dd81c 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
@@ -13,22 +13,18 @@
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
-
-
+import org.junit.Test;
public class ServerCrossContextSessionTest extends AbstractServerCrossContextSessionTest
{
-
public AbstractTestServer createServer(int port)
{
return new HashTestServer(port);
}
- @Test(groups={"hash-all"})
+ @Test
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();
}
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml
index 4df99280f1..7645612f87 100644
--- a/tests/test-sessions/test-jdbc-sessions/pom.xml
+++ b/tests/test-sessions/test-jdbc-sessions/pom.xml
@@ -34,13 +34,6 @@
<target>1.5</target>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <groups>jdbc-all</groups>
- </configuration>
- </plugin>
</plugins>
</build>
<dependencies>
@@ -77,10 +70,9 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>5.8</version>
- <classifier>jdk15</classifier>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
index 8bfaf60916..4195058cad 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
@@ -12,7 +12,7 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* ClientCrossContextSessionTest
@@ -22,19 +22,14 @@ import org.testng.annotations.Test;
public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
{
-
-
public AbstractTestServer createServer(int port)
{
return new JdbcTestServer(port);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();
}
-
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
index 538419db9f..2d7ac694ac 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
@@ -12,7 +12,7 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* ImmortalSessionTest
@@ -22,18 +22,14 @@ import org.testng.annotations.Test;
public class ImmortalSessionTest extends AbstractImmortalSessionTest
{
-
-
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs)
{
return new JdbcTestServer(port, maxInactiveMs, scavengeMs);
}
-
- @Test(groups={"jdbc-all"})
+ @Test
public void testImmortalSession() throws Exception
{
super.testImmortalSession();
}
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
index 6babe36161..124486363a 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
@@ -12,14 +12,11 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* InvalidationSessionTest
- *
- *
*/
-
public class InvalidationSessionTest extends AbstractInvalidationSessionTest
{
public AbstractTestServer createServer(int port)
@@ -43,10 +40,9 @@ public class InvalidationSessionTest extends AbstractInvalidationSessionTest
}
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testInvalidation() throws Exception
{
super.testInvalidation();
}
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
index d3c805a0ad..1e900108b2 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
@@ -14,11 +14,10 @@ package org.eclipse.jetty.server.session;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.session.test.MavenTestingUtils;
/**
* JdbcTestServer
- *
- *
*/
public class JdbcTestServer extends AbstractTestServer
{
@@ -29,7 +28,7 @@ public class JdbcTestServer extends AbstractTestServer
static
{
- System.setProperty("derby.system.home", System.getProperty("java.io.tmpdir"));
+ System.setProperty("derby.system.home", MavenTestingUtils.getTargetTestingDir().getAbsolutePath());
}
public JdbcTestServer(int port)
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
index 82e89ef0dd..77c96a7afb 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
@@ -12,27 +12,21 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* LastAccessTimeTest
- *
- *
*/
-
public class LastAccessTimeTest extends AbstractLastAccessTimeTest
{
-
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new JdbcTestServer(port,max,scavenge);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LocalSessionScavengingTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LocalSessionScavengingTest.java
index 773e5df07b..535ceec460 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LocalSessionScavengingTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/LocalSessionScavengingTest.java
@@ -12,14 +12,11 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* LocalSessionScavengingTest
- *
- *
*/
-
public class LocalSessionScavengingTest extends AbstractLocalSessionScavengingTest
{
public void pause (int scavenge)
@@ -44,7 +41,7 @@ public class LocalSessionScavengingTest extends AbstractLocalSessionScavengingTe
return new JdbcTestServer(port,max,scavenge);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testLocalSessionsScavenging() throws Exception
{
super.testLocalSessionsScavenging();
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
index 5fd1d18873..7264696269 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
@@ -12,16 +12,13 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* NewSessionTest
- *
- *
*/
public class NewSessionTest extends AbstractNewSessionTest
{
-
/**
* @see org.eclipse.jetty.server.session.AbstractNewSessionTest#createServer(int, int, int)
*/
@@ -30,7 +27,7 @@ public class NewSessionTest extends AbstractNewSessionTest
return new JdbcTestServer(port,max,scavenge);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testNewSession() throws Exception
{
super.testNewSession();
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
index 5b565bf941..b5e415dce6 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
@@ -12,27 +12,21 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* OrphanedSessionTest
- *
- *
*/
public class OrphanedSessionTest extends AbstractOrphanedSessionTest
{
-
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new JdbcTestServer(port,max,scavenge);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testOrphanedSession() throws Exception
{
super.testOrphanedSession();
}
-
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
index 407ccc4352..5bab446e04 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
@@ -12,12 +12,11 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
+
/**
* ReentrantRequestSessionTest
- *
- *
*/
public class ReentrantRequestSessionTest extends AbstractReentrantRequestSessionTest
{
@@ -27,11 +26,9 @@ public class ReentrantRequestSessionTest extends AbstractReentrantRequestSession
return new JdbcTestServer(port);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testReentrantRequestSession() throws Exception
{
super.testReentrantRequestSession();
}
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
index d7d4a6038d..c6732c34a5 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
@@ -12,12 +12,10 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* ServerCrossContextSessionTest
- *
- *
*/
public class ServerCrossContextSessionTest extends AbstractServerCrossContextSessionTest
{
@@ -27,12 +25,9 @@ public class ServerCrossContextSessionTest extends AbstractServerCrossContextSes
return new JdbcTestServer(port);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();
}
-
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionMigrationTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionMigrationTest.java
index d0a3995de3..3400628007 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionMigrationTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionMigrationTest.java
@@ -1,6 +1,5 @@
//========================================================================
-//$Id$
-//Copyright 2010 Mort Bay Consulting Pty. Ltd.
+// Copyright 2010 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
@@ -13,11 +12,10 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
+
/**
* SessionMigrationTest
- *
- *
*/
public class SessionMigrationTest extends AbstractSessionMigrationTest
{
@@ -27,12 +25,9 @@ public class SessionMigrationTest extends AbstractSessionMigrationTest
return new JdbcTestServer(port);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
-
-
-
}
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java
index 43b1ddabf9..4389143b8b 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java
@@ -12,7 +12,8 @@
// ========================================================================
package org.eclipse.jetty.server.session;
-import org.testng.annotations.Test;
+import org.junit.Test;
+
/**
* WebAppObjectInSessionTest
*
@@ -26,11 +27,9 @@ public class WebAppObjectInSessionTest extends AbstractWebAppObjectInSessionTest
return new JdbcTestServer(port);
}
- @Test(groups={"jdbc-all"})
+ @Test
public void testWebappObjectInSession() throws Exception
{
super.testWebappObjectInSession();
}
-
-
}
diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml
index 5f704c2cf4..36898d6e0e 100644
--- a/tests/test-sessions/test-sessions-common/pom.xml
+++ b/tests/test-sessions/test-sessions-common/pom.xml
@@ -44,10 +44,9 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>5.8</version>
- <classifier>jdk15</classifier>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit4-version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClientCrossContextSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClientCrossContextSessionTest.java
index e79ed1bcc9..0674120620 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClientCrossContextSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClientCrossContextSessionTest.java
@@ -22,19 +22,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
-import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.junit.Test;
/**
* AbstractClientCrossContextSessionTest
- *
- *
*/
-
public abstract class AbstractClientCrossContextSessionTest
{
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
index 54506a5de8..89f16737b3 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
@@ -23,18 +23,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractImmortalSessionTest
- *
- *
*/
-
public abstract class AbstractImmortalSessionTest
{
public abstract AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
index aee0b40297..ecf1008985 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
@@ -22,19 +22,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
-
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractInvalidationSessionTest
* Goal of the test is to be sure that invalidating a session on one node
* result in the session being unavailable in the other node also.
- *
*/
-
public abstract class AbstractInvalidationSessionTest
{
public abstract AbstractTestServer createServer(int port);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
index cac47f0e61..379f6b3b45 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
@@ -21,17 +21,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractLastAccessTimeTest
- *
- *
*/
-
public abstract class AbstractLastAccessTimeTest
{
public abstract AbstractTestServer createServer(int port, int max, int scavenge);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLightLoadTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLightLoadTest.java
index 0df0f27e9a..588ed2b6c8 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLightLoadTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLightLoadTest.java
@@ -27,18 +27,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractLightLoadTest
- *
- *
*/
-
public abstract class AbstractLightLoadTest
{
protected boolean _stress = Boolean.getBoolean( "STRESS" );
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
index 386c14d8aa..03f8db0c97 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
@@ -21,20 +21,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.client.ContentExchange;
-import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
-
+import org.junit.Test;
/**
* AbstractLocalSessionScavengingTest
- *
- *
*/
-
public abstract class AbstractLocalSessionScavengingTest
{
public abstract AbstractTestServer createServer(int port, int max, int scavenge);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractNewSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractNewSessionTest.java
index fa5f53f3c9..4c3867344c 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractNewSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractNewSessionTest.java
@@ -21,18 +21,15 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpMethods;
-import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.junit.Test;
/**
* AbstractNewSessionTest
- *
- *
*/
-
public abstract class AbstractNewSessionTest
{
public abstract AbstractTestServer createServer(int port, int max, int scavenge);
@@ -48,6 +45,7 @@ public abstract class AbstractNewSessionTest
e.printStackTrace();
}
}
+
@Test
public void testNewSession() throws Exception
{
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractOrphanedSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractOrphanedSessionTest.java
index e223bdaa81..29be97b5f2 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractOrphanedSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractOrphanedSessionTest.java
@@ -23,17 +23,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractOrphanedSessionTest
- *
- *
*/
-
public abstract class AbstractOrphanedSessionTest
{
@@ -51,18 +48,18 @@ public abstract class AbstractOrphanedSessionTest
// Disable scavenging for the first server, so that we simulate its "crash".
String contextPath = "";
String servletMapping = "/server";
- int port1 = random.nextInt(50000) + 10000;
int inactivePeriod = 5;
- AbstractTestServer server1 = createServer(port1, inactivePeriod, -1);
+ AbstractTestServer server1 = createServer(0, inactivePeriod, -1);
server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
server1.start();
+ int port1 = server1.getPort();
try
{
- int port2 = random.nextInt(50000) + 10000;
int scavengePeriod = 2;
- AbstractTestServer server2 = createServer(port2, inactivePeriod, scavengePeriod);
+ AbstractTestServer server2 = createServer(0, inactivePeriod, scavengePeriod);
server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
server2.start();
+ int port2 = server2.getPort();
try
{
HttpClient client = new HttpClient();
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractReentrantRequestSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractReentrantRequestSessionTest.java
index ad776a332d..d8d5064172 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractReentrantRequestSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractReentrantRequestSessionTest.java
@@ -22,18 +22,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractReentrantRequestSessionTest
- *
- *
*/
-
public abstract class AbstractReentrantRequestSessionTest
{
public abstract AbstractTestServer createServer(int port);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractServerCrossContextSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractServerCrossContextSessionTest.java
index fe07c05da0..e91fffd402 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractServerCrossContextSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractServerCrossContextSessionTest.java
@@ -25,18 +25,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
-import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.junit.Test;
/**
* AbstractServerCrossContextSessionTest
- *
- *
*/
-
public abstract class AbstractServerCrossContextSessionTest
{
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionMigrationTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionMigrationTest.java
index 511efbe161..b4584fd5ae 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionMigrationTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionMigrationTest.java
@@ -23,17 +23,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
-import org.testng.annotations.Test;
+import org.eclipse.jetty.http.HttpMethods;
+import org.junit.Test;
/**
* AbstractSessionMigrationTest
- *
- *
*/
-
public abstract class AbstractSessionMigrationTest
{
public abstract AbstractTestServer createServer (int port);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
index 8edde246bc..71f592ebc9 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
@@ -60,6 +60,11 @@ public abstract class AbstractTestServer
_server.setHandler(_contexts);
_server.start();
}
+
+ public int getPort()
+ {
+ return _server.getConnectors()[0].getLocalPort();
+ }
public ServletContextHandler addContext(String contextPath)
{
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java
index aaaa3c19c3..3679dc9d42 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java
@@ -21,13 +21,12 @@ import java.util.Random;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.client.ContentExchange;
-import org.eclipse.jetty.client.HttpClient;
-
-import org.testng.annotations.Test;
+import org.junit.Test;
/**
* AbstractWebAppObjectInSessionTest
@@ -37,9 +36,7 @@ import org.testng.annotations.Test;
* the same webapp on nodeB is able to load that object from the session.
*
* This test is only appropriate for clustered session managers.
- *
*/
-
public abstract class AbstractWebAppObjectInSessionTest
{
public abstract AbstractTestServer createServer(int port);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/MavenTestingUtils.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/MavenTestingUtils.java
new file mode 100644
index 0000000000..028afd3ce1
--- /dev/null
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/MavenTestingUtils.java
@@ -0,0 +1,221 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// 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.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.server.session.test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.jetty.util.IO;
+
+/**
+ * Common utility methods for working with JUnit tests cases in a maven friendly way.
+ */
+public class MavenTestingUtils
+{
+ private static File basedir;
+ private static File testResourcesDir;
+ private static File targetDir;
+
+ // private static Boolean surefireRunning;
+
+ public static File getBasedir()
+ {
+ if (basedir == null)
+ {
+ String cwd = System.getProperty("basedir");
+
+ if (cwd == null)
+ {
+ cwd = System.getProperty("user.dir");
+ }
+
+ basedir = new File(cwd);
+ }
+
+ return basedir;
+ }
+
+ /**
+ * Get the directory to the /target directory for this project.
+ *
+ * @return the directory path to the target directory.
+ */
+ public static File getTargetDir()
+ {
+ if (targetDir == null)
+ {
+ targetDir = new File(getBasedir(),"target");
+ PathAssert.assertDirExists("Target Dir",targetDir);
+ }
+ return targetDir;
+ }
+
+ /**
+ * Create a {@link File} object for a path in the /target directory.
+ *
+ * @param path
+ * the path desired, no validation of existence is performed.
+ * @return the File to the path.
+ */
+ public static File getTargetFile(String path)
+ {
+ return new File(getTargetDir(),path.replace("/",File.separator));
+ }
+
+ public static File getTargetTestingDir()
+ {
+ File dir = new File(getTargetDir(),"testing");
+ if (!dir.exists())
+ {
+ dir.mkdirs();
+ }
+ return dir;
+ }
+
+ /**
+ * Get a dir in /target/ that uses the JUnit 3.x {@link TestCase#getName()} to make itself unique.
+ *
+ * @param test
+ * the junit 3.x testcase to base this new directory on.
+ * @return the File path to the testcase specific testing directory underneath the
+ * <code>${basedir}/target</code> sub directory
+ */
+ public static File getTargetTestingDir(TestCase test)
+ {
+ return getTargetTestingDir(test.getName());
+ }
+
+ /**
+ * Get a dir in /target/ that uses the an arbitrary name.
+ *
+ * @param testname
+ * the testname to create directory against.
+ * @return the File path to the testname sepecific testing directory underneath the
+ * <code>${basedir}/target</code> sub directory
+ */
+ public static File getTargetTestingDir(String testname)
+ {
+ File dir = new File(getTargetDir(),"test-" + testname);
+ return dir;
+ }
+
+ /**
+ * Get a dir from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a dir)
+ * @return the dir in src/test/resource
+ */
+ public static File getTestResourceDir(String name)
+ {
+ File dir = new File(getTestResourcesDir(),name);
+ PathAssert.assertDirExists("Test Resource Dir",dir);
+ return dir;
+ }
+
+ /**
+ * Get a file from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a file)
+ * @return the file in src/test/resource
+ */
+ public static File getTestResourceFile(String name)
+ {
+ File file = new File(getTestResourcesDir(),name);
+ PathAssert.assertFileExists("Test Resource File",file);
+ return file;
+ }
+
+ /**
+ * Get a path resource (File or Dir) from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist)
+ * @return the path in src/test/resource
+ */
+ public static File getTestResourcePath(String name)
+ {
+ File path = new File(getTestResourcesDir(),name);
+ PathAssert.assertExists("Test Resource Path",path);
+ return path;
+ }
+
+ /**
+ * Get the directory to the src/test/resource directory
+ *
+ * @return the directory {@link File} to the src/test/resources directory
+ */
+ public static File getTestResourcesDir()
+ {
+ if (testResourcesDir == null)
+ {
+ testResourcesDir = new File(basedir,"src/test/resources".replace("/",File.separator));
+ PathAssert.assertDirExists("Test Resources Dir",testResourcesDir);
+ }
+ return testResourcesDir;
+ }
+
+ /**
+ * Read the contents of a file into a String and return it.
+ *
+ * @param file
+ * the file to read.
+ * @return the contents of the file.
+ * @throws IOException
+ * if unable to read the file.
+ */
+ public static String readToString(File file) throws IOException
+ {
+ FileReader reader = null;
+ try
+ {
+ reader = new FileReader(file);
+ return IO.toString(reader);
+ }
+ finally
+ {
+ IO.close(reader);
+ }
+ }
+
+ public static String getTestID()
+ {
+ StackTraceElement stacked[] = new Throwable().getStackTrace();
+
+ String name = null;
+
+ for(StackTraceElement stack: stacked) {
+ if(stack.getClassName().endsWith("Test"))
+ {
+ name = stack.getClassName();
+ if (stack.getMethodName().startsWith("test"))
+ {
+ return stack.getClassName() + "#" + stack.getMethodName();
+ }
+ }
+ }
+
+ if(name == null)
+ {
+ return "Unidentified_Test";
+ }
+ return name;
+ }
+}
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/PathAssert.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/PathAssert.java
new file mode 100644
index 0000000000..f85a0976df
--- /dev/null
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/test/PathAssert.java
@@ -0,0 +1,40 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// 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.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.server.session.test;
+
+import java.io.File;
+
+import org.junit.Assert;
+
+public class PathAssert
+{
+ public static void assertDirExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a Dir : " + path.getAbsolutePath(),path.isDirectory());
+ }
+
+ public static void assertFileExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a File : " + path.getAbsolutePath(),path.isFile());
+ }
+
+ public static void assertExists(String msg, File path)
+ {
+ Assert.assertTrue(msg + " path should exist: " + path.getAbsolutePath(),path.exists());
+ }
+}

Back to the top